WIP
This commit is contained in:
parent
6762416281
commit
8746851f79
2 changed files with 146 additions and 167 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 }) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue