This commit is contained in:
Leah Schumann 2023-06-14 14:51:22 -04:00
parent 6762416281
commit 8746851f79
2 changed files with 146 additions and 167 deletions

View file

@ -122,13 +122,16 @@ export default {
},
data() {
return {
showAddressFields: false,
displayVerificationWarning: false,
displayNoMatchWarning: false,
alertHeadlineVerificationWarning: "",
alertCopyVerificationWarning: "",
alertHeadlineNoMatchWarning: "",
alertCopyNoMatchWarning: "",
scriptLoaded: null,
addressField1: null,
autocomplete: null,
autocompleteListener: null,
matchFound: null, // null = no attempted match, true = match was found, false = match was not found
};
},
@ -198,6 +201,14 @@ export default {
this.$emit("update:modelValue", newValue);
},
},
showAddressFields: {
get: function() {
return this.addressModel.streetAddress &&
this.addressModel.city &&
this.addressModel.state &&
this.addressModel.zipCode
}
},
showApartmentNumberOrBusinessNameField: {
get: function () {
return this.captureApartmentNumberOrBusinessName;
@ -205,182 +216,148 @@ export default {
},
},
methods: {
setupAddressLookup() {
this.showAddressFields = false;
if (
this.addressModel.streetAddress &&
this.addressModel.city &&
this.addressModel.state &&
this.addressModel.zipCode
) {
this.showAddressFields = true;
return;
initializeAutocomplete() {
this.addressField1 = document.getElementById("autocomplete");
this.autocomplete = new window.google.maps.places.Autocomplete(this.addressField1, {
componentRestrictions: { country: ["us"] },
fields: ["address_components"],
types: ["geocode"],
});
// Standard place_changed event handling
this.autocompleteListener = window.google.maps.event.addListener(
this.autocomplete,
"place_changed",
this.fillInAddress
);
this.addressField1.addEventListener("focus", (e) => {
this.addressField1.setAttribute("autocomplete", "do-not-autofill");
});
this.addressField1.addEventListener("keydown", (e) => {
const event = new Event("place_changed");
if (e.code === "Enter" || e.code === "NumpadEnter" || e.code === "Tab") {
const selectedItem = document.querySelector(
".pac-container .pac-item-selected"
);
if (selectedItem !== null) {
// Fill-in the address using selected item in the list.
this.autocomplete.dispatchEvent(event);
} else {
// Fill-in the address using first item in the list.
this.fillInAddressUsingFirstItem();
}
} else {
return;
}
});
},
fillInAddress(place) {
if (!place) {
place = this.autocomplete.getPlace();
}
const addressField1 = document.getElementById("autocomplete");
const self = this;
if (place && place.address_components) {
this.matchFound = true;
const apiKey = applicationConfig.GOOGLE_PLACES_API_KEY;
const self = this;
this.$nextTick(function () {
self.showAddressFields = true;
this.$loadScript(
`https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=Function.prototype`
)
.then(() => {
// Script is loaded, initialize the autocomplete textbox
const autocomplete = new window.google.maps.places.Autocomplete(addressField1, {
componentRestrictions: { country: ["us"] },
fields: ["address_components"],
types: ["geocode"],
});
for (const component of place.address_components) {
const componentType = component.types[0];
// Standard place_changed event handling
const autocompleteListener = window.google.maps.event.addListener(
autocomplete,
"place_changed",
fillInAddress
);
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
const streetAddressField = document.getElementById("streetAddressField");
const autocompleteResultsContainer =
document.getElementsByClassName("pac-container")[0];
if (autocompleteResultsContainer) {
streetAddressField.appendChild(autocompleteResultsContainer);
}
});
addressField1.addEventListener("keydown", (e) => {
const autocomplete = document.getElementById("autocomplete");
const event = new Event("place_changed");
if (e.code === "Enter" || e.code === "NumpadEnter" || e.code === "Tab") {
const selectedItem = document.querySelector(
".pac-container .pac-item-selected"
);
if (selectedItem !== null) {
// Fill-in the address using selected item in the list.
autocomplete.dispatchEvent(event);
//fillInAddress(selectedItem.textContent);
} else {
// Fill-in the address using first item in the list.
fillInAddressUsingFirstItem();
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;
}
} else {
return;
}
});
addressField1.addEventListener("change", () => {
// If a match has been previously attempted then do nothing
if (self.matchFound !== null) {
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 (i.e. by pressing Tab, or clicking outside the field)
if (clickedAddress === null) {
// Fill-in the address using first item in the list.
fillInAddressUsingFirstItem();
}
});
function fillInAddressUsingFirstItem() {
// Fill-in the address using first item in the list.
const item = document.querySelector(".pac-container .pac-item");
if (item != null) {
const firstResult = item.textContent;
const geocoder = new window.google.maps.Geocoder();
geocoder.geocode(
{
address: firstResult,
},
function (results, status) {
if (status === window.google.maps.GeocoderStatus.OK) {
fillInAddress(results[0]);
self.displayVerificationWarning = true;
}
}
);
} else {
self.matchFound = false;
}
}
function fillInAddress(place) {
if (!place) {
place = autocomplete.getPlace();
}
if (place && place.address_components) {
self.matchFound = true;
self.$nextTick(function () {
self.showAddressFields = true;
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;
}
}
}
// 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();
}
});
}
// after showing the address fields, disable the address autocomplete
window.google.maps.event.removeListener(this.autocompleteListener);
window.google.maps.event.clearInstanceListeners(this.autocomplete);
this.addressField1.onchange = null;
const pacContainer = document.querySelector(".pac-container");
if (pacContainer) {
pacContainer.remove();
}
})
.catch(() => {
// Failed to fetch script
console.log("Unable to load Google Places API script");
});
}
},
fillInAddressUsingFirstItem() {
// Fill-in the address using first item in the list.
const item = document.querySelector(".pac-container .pac-item");
if (item != null) {
const firstResult = item.textContent;
const geocoder = new window.google.maps.Geocoder();
const self = this;
geocoder.geocode(
{
address: firstResult,
},
function (results, status) {
if (status === window.google.maps.GeocoderStatus.OK) {
self.fillInAddress(results[0]);
self.displayVerificationWarning = true;
}
}
);
} else {
this.matchFound = false;
}
},
resetAlerts() {
this.displayVerificationWarning = false;
},
},
mounted() {
this.setupAddressLookup();
// Load the Google Places Autocomplete script
const apiKey = applicationConfig.GOOGLE_PLACES_API_KEY;
this.$loadScript(
`https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=Function.prototype`
).then(() => {
// When loaded trigger the setup
this.scriptLoaded = true;
});
},
beforeUpdate() {
// Make place results box stick to the input on scroll
const streetAddressField = document.getElementById("streetAddressField");
const autocompleteResultsContainer =
document.getElementsByClassName("pac-container")[0];
if (autocompleteResultsContainer) {
streetAddressField.appendChild(autocompleteResultsContainer);
}
},
watch: {
scriptLoaded: {
handler() {
// After script is loaded, initialize the autocomplete textbox
this.initializeAutocomplete();
},
},
matchFound: {
handler(newValue) {
if (newValue === null) {
@ -414,11 +391,6 @@ export default {
}
},
},
modelValue: {
handler() {
this.setupAddressLookup();
},
},
},
components: {
textboxQuestion,

View file

@ -1105,10 +1105,17 @@ export const actions = {
"glassPieces"
);
return globalMethods.callHttpClient({
method: endpoints.GetServiceabilityDetails.method,
endpoint: `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}&${lineItems}&${glassPieces}`,
});
return Promise.resolve({
"isGlassServiceableInshop": true,
"isRecalibrationServiceableInshop": true,
"isGlassServiceableMobile": true,
"isRecalibrationServiceableMobile": true
})
// return globalMethods.callHttpClient({
// method: endpoints.GetServiceabilityDetails.method,
// endpoint: `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}&${lineItems}&${glassPieces}`,
// });
},
getProviders(context, { serviceZipCode }) {