Fix mobile location auto-complete defect and defect 1328
This commit is contained in:
parent
1a6db3df0f
commit
dc309e1dae
4 changed files with 91 additions and 115 deletions
|
|
@ -90,12 +90,12 @@ export default {
|
|||
openModal() {
|
||||
const modal = Modal.getOrCreateInstance(document.getElementById(this.modalId));
|
||||
modal.show();
|
||||
this.$emit("modalOpened", true);
|
||||
this.$emit("isModalOpened", true);
|
||||
},
|
||||
closeModal() {
|
||||
const modal = Modal.getInstance(document.getElementById(this.modalId));
|
||||
modal.hide();
|
||||
this.$emit("modalOpened", false);
|
||||
this.$emit("isModalOpened", false);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
|
|
|||
|
|
@ -122,17 +122,15 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
componentKey: 0,
|
||||
displayVerificationWarning: false,
|
||||
displayNoMatchWarning: false,
|
||||
alertHeadlineVerificationWarning: "",
|
||||
alertCopyVerificationWarning: "",
|
||||
alertHeadlineNoMatchWarning: "",
|
||||
alertCopyNoMatchWarning: "",
|
||||
scriptLoaded: null,
|
||||
addressField1: null,
|
||||
autocomplete: null,
|
||||
autocompleteListener: null,
|
||||
showAddressFields: false,
|
||||
matchFound: null, // null = no attempted match, true = match was found, false = match was not found
|
||||
};
|
||||
},
|
||||
|
|
@ -202,27 +200,30 @@ 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;
|
||||
},
|
||||
},
|
||||
addressField1: {
|
||||
get: function () {
|
||||
return document.getElementById("autocomplete");
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadGooglePlacesAutocompleteScript() {
|
||||
// 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.initializeAutocomplete();
|
||||
});
|
||||
},
|
||||
initializeAutocomplete() {
|
||||
this.addressField1 = document.getElementById("autocomplete");
|
||||
|
||||
// initialize the Google Places Autocomplete
|
||||
// Initialize the Google Places Autocomplete
|
||||
this.autocomplete = new window.google.maps.places.Autocomplete(this.addressField1, {
|
||||
componentRestrictions: { country: ["us"] },
|
||||
fields: ["address_components"],
|
||||
|
|
@ -236,18 +237,21 @@ export default {
|
|||
this.fillInAddress
|
||||
);
|
||||
|
||||
// When the Street Address textbox receives focus,
|
||||
// append the search results list container to the bottom of the textbox
|
||||
// and disable browser autofill
|
||||
this.addressField1.addEventListener("focus", (e) => {
|
||||
// Unfortunately this is the only place we can set the autocomplete attribute without the
|
||||
// Google Places object resetting it to "off" which does nothing to prevent browser autofill
|
||||
this.addressField1.setAttribute("autocomplete", "do-not-autofill");
|
||||
|
||||
// Make place results box stick to the input on scroll
|
||||
// Due to the different ways we're using this component it is necessary to do this here instead of ahead of time
|
||||
const streetAddressField = document.getElementById("streetAddressField");
|
||||
const autocompleteResultsContainer = document.getElementsByClassName("pac-container")[0];
|
||||
const autocompleteResultsContainer =
|
||||
document.getElementsByClassName("pac-container")[0];
|
||||
if (autocompleteResultsContainer) {
|
||||
streetAddressField.appendChild(autocompleteResultsContainer);
|
||||
}
|
||||
|
||||
// Unfortunately this is the only place we can set the autocomplete attribute without the
|
||||
// Google Places object resetting it to "off" which does nothing to prevent browser autofill
|
||||
this.addressField1.setAttribute("autocomplete", "do-not-autofill");
|
||||
});
|
||||
|
||||
this.addressField1.addEventListener("keydown", (e) => {
|
||||
|
|
@ -260,18 +264,36 @@ export default {
|
|||
".pac-container .pac-item-selected"
|
||||
);
|
||||
|
||||
// If an item was selected then fill in the address with the selected item
|
||||
if (selectedItem !== null) {
|
||||
// Fill-in the address using selected item in the list.
|
||||
// If an item was selected then fill in the address with the selected item
|
||||
// by triggering the "place_changed" event of the Autocomplete object
|
||||
this.autocomplete.dispatchEvent(event);
|
||||
} else {
|
||||
// Fill-in the address using first item in the list.
|
||||
// Otherwise fill-in the address using first item from the list.
|
||||
this.fillInAddressUsingFirstItem();
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
this.addressField1.addEventListener("change", () => {
|
||||
// If a match has been previously attempted then do nothing
|
||||
if (this.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.
|
||||
this.fillInAddressUsingFirstItem();
|
||||
}
|
||||
});
|
||||
},
|
||||
fillInAddress(place) {
|
||||
if (!place) {
|
||||
|
|
@ -312,14 +334,8 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
// After filling in the address fields, disable the address autocomplete
|
||||
this.unloadAutocomplete();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -348,39 +364,30 @@ export default {
|
|||
resetAlerts() {
|
||||
this.displayVerificationWarning = false;
|
||||
},
|
||||
forceRerender() {
|
||||
this.componentKey.value += 1;
|
||||
unloadAutocomplete() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log("mounted")
|
||||
// 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;
|
||||
});
|
||||
// If we already have a full address, show it
|
||||
this.showAddressFields = this.addressModel.streetAddress &&
|
||||
this.addressModel.city &&
|
||||
this.addressModel.state &&
|
||||
this.addressModel.zipCode;
|
||||
|
||||
this.loadGooglePlacesAutocompleteScript();
|
||||
},
|
||||
unmounted() {
|
||||
console.log("unmounted")
|
||||
},
|
||||
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);
|
||||
}
|
||||
this.unloadAutocomplete();
|
||||
},
|
||||
watch: {
|
||||
scriptLoaded: {
|
||||
handler() {
|
||||
// After script is loaded, initialize the autocomplete textbox
|
||||
this.initializeAutocomplete();
|
||||
},
|
||||
},
|
||||
matchFound: {
|
||||
handler(newValue) {
|
||||
if (newValue === null) {
|
||||
|
|
@ -398,7 +405,7 @@ export default {
|
|||
this.addressModel.state = "";
|
||||
this.addressModel.zipCode = "";
|
||||
}
|
||||
this.showAddressFields = true;
|
||||
|
||||
this.displayVerificationWarning = false;
|
||||
|
||||
// Only deep watch the Address Model after a failed match
|
||||
|
|
@ -421,6 +428,7 @@ export default {
|
|||
alert,
|
||||
},
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
|||
|
|
@ -95,8 +95,11 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.list-card img {
|
||||
height: auto;
|
||||
width: 3.417rem;
|
||||
.appointment-type-question {
|
||||
|
||||
.list-card img {
|
||||
height: auto;
|
||||
width: 3.417rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@
|
|||
:footerButtonText="modalFooterText"
|
||||
:onModalOpenedCallback="onModalOpened"
|
||||
:onModalClosedCallback="onModalClosed"
|
||||
@modalOpened="setModalOpened"
|
||||
@isModalOpened="setModalStatus"
|
||||
@footer-button-event="setMobileLocation">
|
||||
<template v-if="modalOpened">
|
||||
<addressQuestions
|
||||
<template v-if="isModalOpened">
|
||||
<addressQuestions
|
||||
ref="addressQuestions"
|
||||
v-model="internalModel.addressQuestions"
|
||||
captureApartmentNumberOrBusinessName="true"
|
||||
|
|
@ -54,7 +54,6 @@
|
|||
alertClass="alert-danger"
|
||||
v-bind:isDismissible="false" />
|
||||
</template>
|
||||
|
||||
</modal>
|
||||
</div>
|
||||
</transition>
|
||||
|
|
@ -87,7 +86,7 @@ export default {
|
|||
internalModel: deepClone(this.modelValue),
|
||||
displayInvalidZipAlert: false,
|
||||
addressQuestionsKey: 0,
|
||||
modalOpened: false,
|
||||
isModalOpened: false,
|
||||
};
|
||||
},
|
||||
setup(props) {
|
||||
|
|
@ -191,6 +190,9 @@ export default {
|
|||
modalFooterText() {
|
||||
return this.getCmsContent(this.modalWidgetName, "FooterText");
|
||||
},
|
||||
modal() {
|
||||
return this.$refs[this.modalName];
|
||||
},
|
||||
addressModel: {
|
||||
get: function () {
|
||||
return this.modelValue.addressQuestions;
|
||||
|
|
@ -199,52 +201,23 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
openModal() {
|
||||
this.$refs[this.modalName].openModal();
|
||||
},
|
||||
setModalOpened(isOpened) {
|
||||
this.modalOpened = isOpened;
|
||||
console.log(this.modalOpened)
|
||||
},
|
||||
closeModal() {
|
||||
this.$refs[this.modalName].closeModal();
|
||||
this.modal.openModal();
|
||||
},
|
||||
onModalOpened() {
|
||||
this.internalModel = deepClone(this.modelValue);
|
||||
},
|
||||
setModalStatus(isOpened) {
|
||||
this.isModalOpened = isOpened;
|
||||
},
|
||||
closeModal() {
|
||||
this.modal.closeModal();
|
||||
},
|
||||
onModalClosed() {
|
||||
this.displayInvalidZipAlert = false;
|
||||
this.internalModel = deepClone(this.modelValue);
|
||||
this.resetValidation();
|
||||
},
|
||||
resetComponent(updatedServiceZipCodeInfo) {
|
||||
// Reset the validation form, setting the initial values
|
||||
// for the state and zipCode to those that were entered
|
||||
// on the service-zip-modal-question component
|
||||
this.$refs[this.modalName].resetForm({
|
||||
values: {
|
||||
autocomplete: updatedServiceZipCodeInfo.streetAddress,
|
||||
city: updatedServiceZipCodeInfo.city,
|
||||
state: updatedServiceZipCodeInfo.state,
|
||||
zipCode: updatedServiceZipCodeInfo.zipCode,
|
||||
isVehicleProtected: updatedServiceZipCodeInfo.isVehicleProtected,
|
||||
},
|
||||
});
|
||||
},
|
||||
resetModalButtonStyle() {
|
||||
this.$refs[this.modalName].resetButtonStyle();
|
||||
},
|
||||
resetValidation() {
|
||||
//this.$refs.addressQuestions.resetAlerts();
|
||||
|
||||
// this.$refs[this.modalName].resetForm({
|
||||
// values: {
|
||||
// autocomplete: this.internalModel.addressQuestions.streetAddress,
|
||||
// city: this.internalModel.addressQuestions.city,
|
||||
// state: this.internalModel.addressQuestions.state,
|
||||
// zipCode: this.internalModel.addressQuestions.zipCode,
|
||||
// isVehicleProtected: this.internalModel.isVehicleProtected,
|
||||
// },
|
||||
// });
|
||||
this.modal.resetButtonStyle();
|
||||
},
|
||||
async setMobileLocation() {
|
||||
if (
|
||||
|
|
@ -294,14 +267,6 @@ export default {
|
|||
this.internalModel = deepClone(newValue);
|
||||
|
||||
this.handleChange(newValue);
|
||||
|
||||
this.resetComponent({
|
||||
streetAddress: newValue.addressQuestions.streetAddress,
|
||||
city: newValue.addressQuestions.city,
|
||||
state: newValue.addressQuestions.state,
|
||||
zipCode: newValue.addressQuestions.zipCode,
|
||||
isVehicleProtected: newValue.isVehicleProtected,
|
||||
});
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue