diff --git a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue index 74c1866f1..28df3c5e8 100644 --- a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue +++ b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue @@ -12,7 +12,8 @@ aria-haspopup="" hasIcon disableAutoFill - validationRules="street-address-required" /> + validationRules="street-address-required" + @keydown.enter.prevent /> @@ -109,6 +110,9 @@ export default { alertCopyVerificationWarning: "", alertHeadlineNoMatchWarning: "", alertCopyNoMatchWarning: "", + matchingIndirectly: false, + matchFound: false, + enterPressed: false }; }, computed: { @@ -213,11 +217,11 @@ export default { fillInAddress ); - // Wrapping the addressField1 element in the Google Address Autocomplete object - // will cause "autocomplete='off'" which Chrome completely ignores. This event - // handler will set the value to something arbitrary so autofill doesn't work. - // https://stackoverflow.com/a/30976223 addressField1.addEventListener("focus", () => { + // Wrapping the addressField1 element in the Google Address Autocomplete object + // will cause "autocomplete='off'" which Chrome completely ignores. This event + // handler will set the value to something arbitrary so autofill doesn't work. + // https://stackoverflow.com/a/30976223 addressField1.setAttribute("autocomplete", "do-not-autofill"); // Make place results box stick to the input on scroll @@ -229,27 +233,56 @@ export default { } }); + addressField1.addEventListener("keydown", (e) => { + if (e.code === "Enter" || e.code === "NumpadEnter" || e.code === "Tab") { + if (e.code === "Tab") { + self.matchingIndirectly = true; + } else { + self.enterPressed = true; + } + + addressField1.blur(); + + } else { + return; + } + }); + addressField1.addEventListener("change", () => { - const hover = document.querySelector(".pac-container .pac-item:hover"); - // if an item has been clicked, do nothing, otherwise get first solution and use Geocoder to get the place - if (hover === null) { + // NOTE: The standard "place_changed" handler of the autocomplete will use the address the user had chosen + // using either the down / up arrows or the address the user was hovering over when they pressed "Enter." + + // If there has already been a match found then do nothing + // OR + // If the user pressed "Enter" then do nothing + if (self.matchFound || self.enterPressed) { + return; + } + + // Get the address that the user clicked on (if any) + const clickedAddress = document.querySelector(".pac-container .pac-item:hover"); + + // If the Street Address field changed without clicking (by pressing Tab, or clicking outside the field) + if (clickedAddress === null) { + // Select for the user, fill-in the address using first item in the list. const item = document.querySelector(".pac-container .pac-item"); if (item != null) { + self.matchingIndirectly = true; + const firstResult = item.textContent; const geocoder = new window.google.maps.Geocoder(); - geocoder.geocode( - { - address: firstResult, + geocoder.geocode({ + address: firstResult, }, function (results, status) { if (status === window.google.maps.GeocoderStatus.OK) { - fillInAddress(results[0]); - self.displayVerificationWarning = true; + fillInAddress(results[0]); self.displayNoMatchWarning = false; } } ); } else { + // If there are no addresses found for the input then display empty address fields and warnings self.addressModel.city = ""; self.addressModel.state = ""; self.addressModel.zipCode = ""; @@ -258,6 +291,7 @@ export default { self.displayNoMatchWarning = true; } } + }); function fillInAddress(place) { @@ -266,50 +300,55 @@ export default { } if (place && place.address_components) { + self.matchFound = true; self.addressModel.streetAddress = ""; - self.showAddressFields = true; + self.$nextTick(function () { + self.showAddressFields = true; - for (const component of place.address_components) { - const componentType = component.types[0]; + for (const component of place.address_components) { + const componentType = component.types[0]; - switch (componentType) { - case "street_number": { - self.addressModel.streetAddress = component.long_name; - break; - } - case "route": { - self.addressModel.streetAddress += - " " + component.short_name; - break; - } - case "locality": { - self.addressModel.city = component.long_name; - break; - } - case "administrative_area_level_1": { - self.addressModel.state = component.short_name; - break; - } - case "postal_code": { - self.addressModel.zipCode = component.long_name; - break; + switch (componentType) { + case "street_number": { + self.addressModel.streetAddress = component.long_name; + break; + } + case "route": { + self.addressModel.streetAddress += " " + component.short_name; + break; + } + case "locality": { + self.addressModel.city = component.long_name; + break; + } + case "administrative_area_level_1": { + self.addressModel.state = component.short_name; + break; + } + case "postal_code": { + self.addressModel.zipCode = component.long_name; + break; + } } } - } - self.displayVerificationWarning = false; - self.displayNoMatchWarning = false; + self.displayVerificationWarning = self.matchingIndirectly; + + // after showing the address fields, disable the address autocomplete + window.google.maps.event.removeListener(autocompleteListener); + window.google.maps.event.clearInstanceListeners(autocomplete); + addressField1.onchange = null; + const pacContainer = document.querySelector(".pac-container"); + if (pacContainer) { + pacContainer.remove(); + } + + }); } else { self.displayVerificationWarning = true; self.displayNoMatchWarning = false; } - // after showing the address fields, disable the address autocomplete - window.google.maps.event.removeListener(autocompleteListener); - window.google.maps.event.clearInstanceListeners(autocomplete); - addressField1.onchange = null; - const pacContainer = document.querySelector(".pac-container"); - pacContainer.remove(); } }) .catch(() => { @@ -322,15 +361,13 @@ export default { this.setupAddressLookup(); }, watch: { - addressModel: { + matchFound: { handler(newValue) { - // Clear no match warning on address change - if (newValue.city || newValue.state || newValue.zipCode) { + if (newValue) { this.displayNoMatchWarning = false; } - }, - deep: true, - }, + }, + } }, components: { textboxQuestion,