Skip to content

Instantly share code, notes, and snippets.

@HenokT
Last active September 1, 2015 04:09
Show Gist options
  • Save HenokT/a0137e1ad9b070b5ac99 to your computer and use it in GitHub Desktop.
Save HenokT/a0137e1ad9b070b5ac99 to your computer and use it in GitHub Desktop.
AngularJS directive for address autocompletion using Google Places Autocomplete API
###
This directive is based on an example on google's developers website that shows how to use
the places api to implement an address autocomplete textbox:
https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform
Here is an example of how to use it in your application:
<html ng-app="your-app">
<head>
<!-- jQuery, AngularJs and Google Places libraries must be imported in your index.html-->
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
<!-- The application module definition, controllers and directives are all assumed to be in app.js-->
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl as mainCtrl">
<input type="text" google-places-autocomplete on-place-selected="mainCtrl.placeSelected(place, address)" />
</body>
</html>
###
angular.module 'your-app', []
.directive 'googlePlacesAutocomplete', ($window) ->
'ngInject'
ctrl = ()->
vm = this
### use a default options if none is given ###
if not vm.options?
vm.options =
types: ['geocode']
componentRestrictions:
country: 'us'
return
directive =
restrict: 'A'
scope:
options: "="
onPlaceSelected: "&"
controller: ctrl
controllerAs: 'ctrl'
bindToController: true
link: (scope, element, attrs, ctrl) ->
###Map defines the forms of the address components we are interested in###
addressComponentForm =
street_number: 'short_name',
route: 'long_name',
locality: 'long_name',
administrative_area_level_1: 'short_name',
country: 'long_name',
postal_code: 'short_name'
###Throw an error if this directive is not associated with an input element of type text###
if not element.is("input[type='text']") then throw new Error "element must be of type input[type='text']"
###Create the autocomplete object, restricting the search to geographical location types. ###
###TODO: Validate ctrl.options ###
autocomplete = new google.maps.places.Autocomplete(element.get(0), ctrl.options)
### Bias the autocomplete object to the user's geographical location, as supplied by the browser's 'navigator.geolocation' object. ###
element.focus ()->
### Make sure the browser supports geolocation###
if $window.navigator.geolocation?
$window.navigator.geolocation.getCurrentPosition (position)->
geolocation = lat: position.coords.latitude, lng: position.coords.longitude
circle = new google.maps.Circle(center: geolocation, radius: position.coords.accuracy)
autocomplete.setBounds(circle.getBounds())
###Add a callback to get notified when a place is selected from the dropdown###
autocomplete.addListener 'place_changed', () ->
###use scope.$apply to execute the callback from google places in angular context###
scope.$apply ()->
###Parse the address of the selected place###
place = autocomplete.getPlace()
address = {}
for addressComponent in place.address_components
do (addressComponent) ->
addressComponentType = addressComponent.types[0]
if addressComponentForm[addressComponentType]?
address[addressComponentType] = addressComponent[addressComponentForm[addressComponentType]]
ctrl.onPlaceSelected(place: place, address: address)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment