Basic auto-complete function complete with standard html elements
This commit is contained in:
parent
36756df098
commit
45f048b906
6 changed files with 405 additions and 0 deletions
0
src/layouts/address-lookup/address-lookup.spec.js
Normal file
0
src/layouts/address-lookup/address-lookup.spec.js
Normal file
81
src/layouts/address-lookup/address-lookup.vue
Normal file
81
src/layouts/address-lookup/address-lookup.vue
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
<template>
|
||||||
|
<div class="container-fluid shadow rounded-3 p-2 position-relative make-tall">
|
||||||
|
<funnelHeader ref="funnelHeader" />
|
||||||
|
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=false />
|
||||||
|
<funnelSubHeader ref="funnelSubHeader" />
|
||||||
|
<customerQuestions ref="customerQuestions" />
|
||||||
|
<funnelFooter ref="funnelFooter" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Components
|
||||||
|
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
||||||
|
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
|
||||||
|
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||||
|
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
||||||
|
import customerQuestions from "@/layouts/address-lookup/customer-questions/customer-questions";
|
||||||
|
|
||||||
|
// Supporting files
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
import store from "@/store";
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "address-lookup",
|
||||||
|
async beforeRouteEnter(to, from, next) {
|
||||||
|
// Call APIs
|
||||||
|
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
||||||
|
|
||||||
|
// Settle promises and get results
|
||||||
|
const promiseResultMap = [
|
||||||
|
{
|
||||||
|
resultKey: "cmsContent",
|
||||||
|
promise: cmsContentPromise,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
|
// Call the "next" function to complete the transition to this page.
|
||||||
|
next((vm) => {
|
||||||
|
vm.$refs.funnelHeader.initializeComponent(
|
||||||
|
resultMap.cmsContent.FunnelHeaderWidget
|
||||||
|
);
|
||||||
|
vm.$refs.vehicleBanner.initializeComponent(
|
||||||
|
resultMap.cmsContent.VehicleBannerWidget
|
||||||
|
);
|
||||||
|
vm.$refs.funnelSubHeader.initializeComponent(
|
||||||
|
resultMap.cmsContent.FunnelSubHeaderWidget
|
||||||
|
);
|
||||||
|
vm.$refs.funnelFooter.initializeComponent(
|
||||||
|
resultMap.cmsContent.FunnelFooterWidget
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
selectedDamageLocations: [],
|
||||||
|
driverSideOptionsData: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
arePagePrerequisitesValid() {
|
||||||
|
return store.getters.vehicle.carId !== null;
|
||||||
|
},
|
||||||
|
resetDependentState() {
|
||||||
|
// Invokes
|
||||||
|
store.dispatch(storeActions.RESET_PARTS_AND_DEPS);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
funnelHeader,
|
||||||
|
funnelFooter,
|
||||||
|
vehicleBanner,
|
||||||
|
funnelSubHeader,
|
||||||
|
customerQuestions,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,254 @@
|
||||||
|
<template>
|
||||||
|
<form>
|
||||||
|
<div class="row my-4">
|
||||||
|
<div class="col">
|
||||||
|
<label for="autocomplete">Street address</label>
|
||||||
|
<input ref="autocomplete"
|
||||||
|
id="autocomplete"
|
||||||
|
placeholder="Search"
|
||||||
|
class="form-control search-location"
|
||||||
|
type="text"
|
||||||
|
autocomplete="off" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<form>
|
||||||
|
<div v-show="showAddressFields" class="row my-4">
|
||||||
|
<div class="col">
|
||||||
|
<label for="city">City</label>
|
||||||
|
<input ref="city"
|
||||||
|
id="city"
|
||||||
|
class="form-control"
|
||||||
|
type="text"
|
||||||
|
autocomplete="off" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<form>
|
||||||
|
<div v-show="showAddressFields" class="row my-4">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="state">State</label>
|
||||||
|
<select ref="state"
|
||||||
|
id="state"
|
||||||
|
class="form-control">
|
||||||
|
<option value="AL">Alabama</option>
|
||||||
|
<option value="AK">Alaska</option>
|
||||||
|
<option value="AZ">Arizona</option>
|
||||||
|
<option value="AR">Arkansas</option>
|
||||||
|
<option value="CA">California</option>
|
||||||
|
<option value="CO">Colorado</option>
|
||||||
|
<option value="CT">Connecticut</option>
|
||||||
|
<option value="DE">Delaware</option>
|
||||||
|
<option value="DC">District Of Columbia</option>
|
||||||
|
<option value="FL">Florida</option>
|
||||||
|
<option value="GA">Georgia</option>
|
||||||
|
<option value="HI">Hawaii</option>
|
||||||
|
<option value="ID">Idaho</option>
|
||||||
|
<option value="IL">Illinois</option>
|
||||||
|
<option value="IN">Indiana</option>
|
||||||
|
<option value="IA">Iowa</option>
|
||||||
|
<option value="KS">Kansas</option>
|
||||||
|
<option value="KY">Kentucky</option>
|
||||||
|
<option value="LA">Louisiana</option>
|
||||||
|
<option value="ME">Maine</option>
|
||||||
|
<option value="MD">Maryland</option>
|
||||||
|
<option value="MA">Massachusetts</option>
|
||||||
|
<option value="MI">Michigan</option>
|
||||||
|
<option value="MN">Minnesota</option>
|
||||||
|
<option value="MS">Mississippi</option>
|
||||||
|
<option value="MO">Missouri</option>
|
||||||
|
<option value="MT">Montana</option>
|
||||||
|
<option value="NE">Nebraska</option>
|
||||||
|
<option value="NV">Nevada</option>
|
||||||
|
<option value="NH">New Hampshire</option>
|
||||||
|
<option value="NJ">New Jersey</option>
|
||||||
|
<option value="NM">New Mexico</option>
|
||||||
|
<option value="NY">New York</option>
|
||||||
|
<option value="NC">North Carolina</option>
|
||||||
|
<option value="ND">North Dakota</option>
|
||||||
|
<option value="OH">Ohio</option>
|
||||||
|
<option value="OK">Oklahoma</option>
|
||||||
|
<option value="OR">Oregon</option>
|
||||||
|
<option value="PA">Pennsylvania</option>
|
||||||
|
<option value="RI">Rhode Island</option>
|
||||||
|
<option value="SC">South Carolina</option>
|
||||||
|
<option value="SD">South Dakota</option>
|
||||||
|
<option value="TN">Tennessee</option>
|
||||||
|
<option value="TX">Texas</option>
|
||||||
|
<option value="UT">Utah</option>
|
||||||
|
<option value="VT">Vermont</option>
|
||||||
|
<option value="VA">Virginia</option>
|
||||||
|
<option value="WA">Washington</option>
|
||||||
|
<option value="WV">West Virginia</option>
|
||||||
|
<option value="WI">Wisconsin</option>
|
||||||
|
<option value="WY">Wyoming</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="zip">Zip</label>
|
||||||
|
<input ref="zip"
|
||||||
|
id="zip"
|
||||||
|
class="form-control"
|
||||||
|
type="text"
|
||||||
|
autocomplete="off" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<alert v-show="displayVerificationWarning"
|
||||||
|
alertClass="alert-warning"
|
||||||
|
alertHeadline="Please verify your address."
|
||||||
|
alertCopy="We've selected the closest location match. Please revise as needed."
|
||||||
|
v-bind:isDismissible="false"
|
||||||
|
/>
|
||||||
|
<alert v-show="displayNoMatchWarning"
|
||||||
|
alertClass="alert-warning"
|
||||||
|
alertHeadline="Please verify your address."
|
||||||
|
alertCopy="We were unable to find a location match. Please re-enter your street address."
|
||||||
|
v-bind:isDismissible="false"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import alert from "@/ux-components/alert/alert";
|
||||||
|
//import store from "@/store";
|
||||||
|
|
||||||
|
export default ({
|
||||||
|
name: "address-questions",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showAddressFields: false,
|
||||||
|
displayVerificationWarning: false,
|
||||||
|
displayNoMatchWarning: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
modelValue: Array,
|
||||||
|
groupName: String,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initializeComponent(cmsContent, damageOptions){
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
let addressField1 = document.getElementById("autocomplete");
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
let apiKey = "AIzaSyDptGCkOPgN2uWJOy4ou4M33phRD4MAoJo"; // localhost:8080
|
||||||
|
//let apiKey = "AIzaSyBji_2ApAj2vE_XNGyV-LaUEKrmuElpJ1w"; // Dev and above
|
||||||
|
|
||||||
|
this.$loadScript(`https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places`)
|
||||||
|
.then(() => {
|
||||||
|
// Script is loaded, initialize the autocomplete textbox
|
||||||
|
const autocomplete = new window.google.maps.places.Autocomplete(
|
||||||
|
addressField1,
|
||||||
|
{
|
||||||
|
componentRestrictions: { country: ["us"] },
|
||||||
|
fields: ["address_components"],
|
||||||
|
types: ["address"],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Standard place_changed event handling
|
||||||
|
autocomplete.addListener('place_changed', fillInAddress);
|
||||||
|
|
||||||
|
addressField1.onblur = function() {
|
||||||
|
var 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) {
|
||||||
|
var item = document.querySelector(".pac-container .pac-item");
|
||||||
|
if (item != null) {
|
||||||
|
var firstResult = item.textContent;
|
||||||
|
var 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;
|
||||||
|
self.displayNoMatchWarning = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let city = document.querySelector("#city");
|
||||||
|
let state = document.querySelector("#state");
|
||||||
|
let zip = document.querySelector("#zip");
|
||||||
|
|
||||||
|
city.value = "";
|
||||||
|
state.value = "";
|
||||||
|
zip.value = "";
|
||||||
|
|
||||||
|
self.displayVerificationWarning = false;
|
||||||
|
self.displayNoMatchWarning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function fillInAddress(place) {
|
||||||
|
if (!place) {
|
||||||
|
place = autocomplete.getPlace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (place && place.address_components) {
|
||||||
|
let address1 = "";
|
||||||
|
let city = document.querySelector("#city");
|
||||||
|
let state = document.querySelector("#state");
|
||||||
|
let zip = document.querySelector("#zip");
|
||||||
|
self.showAddressFields = true;
|
||||||
|
|
||||||
|
for (const component of place.address_components) {
|
||||||
|
const componentType = component.types[0];
|
||||||
|
|
||||||
|
switch (componentType) {
|
||||||
|
case "street_number": {
|
||||||
|
address1 = `${component.long_name} ${address1}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "route": {
|
||||||
|
address1 += component.short_name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "locality": {
|
||||||
|
city.value = component.long_name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "administrative_area_level_1": {
|
||||||
|
state.value = component.short_name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "postal_code": {
|
||||||
|
zip.value = component.long_name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addressField1.value = address1;
|
||||||
|
self.displayVerificationWarning = false;
|
||||||
|
self.displayNoMatchWarning = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.displayVerificationWarning = true;
|
||||||
|
self.displayNoMatchWarning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
// Failed to fetch script
|
||||||
|
console.log("Unable to load Google Places API script");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
alert,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
<template>
|
||||||
|
<addressQuestions />
|
||||||
|
<div class="row my-4">
|
||||||
|
<div class="col">
|
||||||
|
<label for="firstName">First name</label>
|
||||||
|
<input ref="firstName"
|
||||||
|
id="firstName"
|
||||||
|
class="form-control"
|
||||||
|
type="text"
|
||||||
|
autocomplete="off" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row my-4">
|
||||||
|
<div class="col">
|
||||||
|
<label for="lastName">Last name</label>
|
||||||
|
<input ref="lastName"
|
||||||
|
id="lastName"
|
||||||
|
class="form-control"
|
||||||
|
type="text"
|
||||||
|
autocomplete="off" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<emailQuestion />
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import addressQuestions from "@/layouts/address-lookup/customer-questions/address-questions/address-questions";
|
||||||
|
import emailQuestion from "@/layouts/address-lookup/customer-questions/email-question/email-question";
|
||||||
|
|
||||||
|
//import store from "@/store";
|
||||||
|
|
||||||
|
export default ({
|
||||||
|
name: "customer-questions",
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
modelValue: Array,
|
||||||
|
groupName: String,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initializeComponent(cmsContent, damageOptions){
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
addressQuestions,
|
||||||
|
emailQuestion,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<template>
|
||||||
|
<div class="row my-4">
|
||||||
|
<div class="col">
|
||||||
|
<label for="email">Email address</label>
|
||||||
|
<input ref="email"
|
||||||
|
id="email"
|
||||||
|
class="form-control"
|
||||||
|
type="text"
|
||||||
|
autocomplete="off" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -4,6 +4,7 @@ const fmgPageValues = {
|
||||||
VEHICLE_MODEL: "vehicle-model",
|
VEHICLE_MODEL: "vehicle-model",
|
||||||
VEHICLE_STYLE: "vehicle-style",
|
VEHICLE_STYLE: "vehicle-style",
|
||||||
VEHICLE_DAMAGE: "vehicle-damage",
|
VEHICLE_DAMAGE: "vehicle-damage",
|
||||||
|
ADDRESS_LOOKUP: "address-lookup",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { fmgPageValues };
|
export { fmgPageValues };
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue