-
-
Save whoisthisstud/b74eac356e669cf9886d8224e294d849 to your computer and use it in GitHub Desktop.
AlpineJS implementation of Google Places Autocomplete
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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