Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save whoisthisstud/b74eac356e669cf9886d8224e294d849 to your computer and use it in GitHub Desktop.

Select an option

Save whoisthisstud/b74eac356e669cf9886d8224e294d849 to your computer and use it in GitHub Desktop.
AlpineJS implementation of Google Places Autocomplete
<div x-data="googlePlacesAutocomplete">
<div>
<label>Address</label>
<input type="hidden">
<input type="text" name="no-auto-fill" x-model="address.address1" x-ref="googleAutocomplete" autocomplete="no-auto-fill">
</div>
<div>
<label>Address 2</label>
<input type="text" name="address2" x-model="address.address2">
</div>
<div>
<label>City</label>
<input type="text" name="city" x-model="address.city">
</div>
<div>
<label>State</label>
<input type="text" name="state" x-model="address.state">
</div>
<div>
<label>Zip</label>
<input type="text" name="zip" x-model="address.zip">
</div>
<div>
<label>Country</label>
<input type="text" name="country" x-model="address.country">
</div>
</div>
<script async src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY_HERE&libraries=places&callback=googleReady"></script>
<script>
function googleReady() {
document.dispatchEvent(new Event('google:init'));
}
document.addEventListener('alpine:init', () => {
Alpine.data('googlePlacesAutocomplete', () => ({
address: {
address1: '',
address2: '',
city: '',
state: '',
zip: '',
country: '',
},
fullResultData: {},
element: null,
autocomplete: null,
init() {
this.element = this.$el.querySelector(':scope [x-ref="googleAutocomplete"]');
if (this.element === null) {
console.error("Cannot find Google Places Autocomplete input [x-ref=\"googleAutocomplete\"]");
return;
}
if (typeof window.google === 'undefined') {
document.addEventListener('google:init', () => {
this.initAutocomplete();
});
} else {
this.initAutocomplete();
}
},
resetData() {
this.address = {
address2: '',
city: '',
state: '',
zip: '',
country: '',
};
},
initAutocomplete() {
this.autocomplete = new window.google.maps.places.Autocomplete(this.element, {
types: ['address']
});
window.google.maps.event.addListener(this.autocomplete, 'place_changed', ()=>this.handleResponse(this.autocomplete.getPlace()));
},
handleResponse(placeResultData) {
this.fullResultData = placeResultData;
const componentMap = {
street_number: {
short_name: true,
property: 'streetNumber',
},
route: {
short_name: true,
property: 'streetName',
},
administrative_area_level_1: {
short_name: false,
property: 'state',
},
locality: {
short_name: false,
property: 'city',
},
administrative_area_level_2: {
short_name: false,
property: 'county',
},
country: {
short_name: true,
property: 'country',
},
postal_code: {
short_name: true,
property: 'zip',
},
postal_code_suffix: {
short_name: true,
property: 'zipSuffix',
},
}
const location = {
streetNumber : '',
streetName : '',
city: '',
state: '',
zip: '',
zipSuffix: '',
country: '',
};
placeResultData.address_components.forEach(component => {
const type = component.types.find(t => typeof componentMap[t] !== 'undefined');
if (type) {
const m = componentMap[type];
location[m.property] = component[m.short_name ? 'short_name' : 'long_name'];
}
});
this.populateData(location);
},
populateData(location) {
this.resetData();
this.address.address1 = `${location.streetNumber} ${location.streetName}`;
this.address.city = location.city;
this.address.state = location.state;
this.address.zip = location.zip;
if (location.zipSuffix.length) {
this.address.zip += `-${location.zipSuffix}`;
}
this.address.country = location.country;
this.$dispatch('place-chosen', {address: this.address, locationData: location, resultResponse: this.fullResultData});
}
}))
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment