var app = angular.module('plunker', ['vsGoogleAutocomplete']);

app.controller('MainCtrl', function($scope) {
  
  $scope.options = {
    componentRestrictions: { country: 'MX' }
  };
});
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>vsHandyStorage Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link data-require="bootstrap-css" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
    
    <!-- Google Maps JavaScript API -->
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
    
    <!-- vsGoogleAutocomplete -->
    <script src="vs-google-autocomplete.js"></script>
    
    <script src="app.js"></script>
  </head>


  <!-- 
  * Dependency: Google Maps JavaScript API v3
  * Google Maps API info: https://developers.google.com/maps/documentation/javascript/places-autocomplete
  * Usage: 
  *   1. add <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
  *   2. add vs-google-autocomplete.js
  *   3. add vs-google-autocomplete directive to input field
  -->
  <body ng-controller="MainCtrl">
    <div class="container">
      
      <h3>Example of vsGoogleAutocomplete module</h3>
      <h5>Also look at <a href="http://plnkr.co/edit/u91e8N?p=preview">example</a> of a autocomplete validation through embedded validator</h5>
      
      <form>

        <!-- vs-google-autocomplete -->
        <div class="form-group">
          <label for="place">Place</label>
          <input vs-google-autocomplete
                 ng-model="place" 
                 type="text" 
                 name="place"
                 id="place"
                 class="form-control" 
                 placeholder="Enter any address">
          <span class="help-block"><b>Model: </b>{{place}}</span>
        </div>
        
        <!-- vs-google-autocomplete="{ types:['(cities)'] }" -->
        <div class="form-group">
          <label for="city">City</label>
          <input vs-google-autocomplete="{ types:['(cities)'] }"
                 ng-model="city" 
                 type="text" 
                 name="city"
                 id="city"
                 class="form-control" 
                 placeholder="Enter city name">
          <span class="help-block"><b>Model: </b>{{city}}</span>
        </div>
        
        <!-- vs-google-autocomplete="options" -->
        <div class="form-group">
          <label for="city">City of France</label>
          <input vs-google-autocomplete="options"
                 ng-model="cityFR" 
                 type="text" 
                 name="cityFR"
                 id="cityFR"
                 class="form-control" 
                 placeholder="Enter city name of France">
          <span class="help-block"><b>Model: </b>{{cityFR}}</span>
        </div>
        
        <!-- parsing address components -->
        <div class="form-group">
          <label for="address">Address</label>
          <span>(parsing address components example)</span>
          <input vs-google-autocomplete
                 
                 ng-model="address.name"
                 vs-place="address.place" 


                 
                 type="text" 
                 name="address"
                 id="address"
                 class="form-control" 
                 placeholder="Enter address">
                 {{ address.place.address_components[3].long_name }}
          <span class="help-block"><b>Model: </b>{{address.name}}</span>
          <span class="help-block"><b>Place id: </b>{{address.components.placeId}}</span>
          <span class="help-block"><b>Street number: </b>{{address.components.streetNumber}}</span>
          <span class="help-block"><b>Street: </b>{{address.components.street}}</span>
          <span class="help-block"><b>City: </b>{{address.components.city}}</span>
          <span class="help-block"><b>State: </b>{{address.components.state}}</span>
          <span class="help-block"><b>Country code: </b>{{address.components.countryCode}}</span>
          <span class="help-block"><b>Country: </b>{{address.components.country}}</span>
          <span class="help-block"><b>Postcode: </b>{{address.components.postCode}}</span>
          <span class="help-block"><b>District: </b>{{address.components.district}}</span>
          <span class="help-block"><b>Latitude: </b>{{address.components.location.lat}}</span>
          <span class="help-block"><b>Longitude: </b>{{address.components.location.long}}</span>
          <span class="help-block"><b>Longitude: </b>{{address.components.location.long}}</span>
          <pre class="help-block"><b>Place: </b>{{address.place | json}}</pre>
        </div>
        
      </form>

    </div>
  </body>

</html>
/**
 * vsGoogleAutocomplete - v0.5.0 - 2015-11-29
 * https://github.com/vskosp/vsGoogleAutocomplete
 * Copyright (c) 2015 K.Polishchuk
 * License: MIT
 */
(function (window, document) {
    'use strict';
    angular.module('vsGoogleAutocomplete', []);
    
    angular.module('vsGoogleAutocomplete').service('vsGooglePlaceUtility', function() {
        function isGooglePlace(place) {
          if (!place)
        		return false;
        	return !!place.place_id;
        }
     
        function isContainTypes(place, types) {
          var placeTypes,
        	    placeType,
        	    type;	
        	if (!isGooglePlace(place))
        	  return false;
        	placeTypes = place.types;
        	for (var i = 0; i < types.length; i++) {
        	  type = types[i];
            for (var j = 0; j < placeTypes.length; j++) {
        	    placeType = placeTypes[j];
              if (placeType === type) {
          	    return true;
          	}
          }
      	}
      	return false;
      }
    	
    	function getAddrComponent(place, componentTemplate) {
        var result;
        if (!isGooglePlace(place))
          return;
        for (var i = 0; i < place.address_components.length; i++) {
          var addressType = place.address_components[i].types[0];
          if (componentTemplate[addressType]) {
            result = place.address_components[i][componentTemplate[addressType]];
            return result;
          }
        }
        return;
      }
    	
    	  function getPlaceId(place) {
          if (!isGooglePlace(place))
        	    return;
        	return place.place_id;
        }
    	
        function getStreetNumber(place) {
          var COMPONENT_TEMPLATE = { street_number: 'short_name' },
        	    streetNumber = getAddrComponent(place, COMPONENT_TEMPLATE);
    		  return streetNumber;
        }
    	
        function getStreet(place) {
          var COMPONENT_TEMPLATE = { route: 'long_name' },
        	    street = getAddrComponent(place, COMPONENT_TEMPLATE);
    		  return street;
        }
    	
        function getCity(place) {
          var COMPONENT_TEMPLATE = { locality: 'long_name' },
        	    city = getAddrComponent(place, COMPONENT_TEMPLATE);
    		  return city;
        }
    	
        function getState(place) {
          var COMPONENT_TEMPLATE = { administrative_area_level_1: 'short_name' },
        	    state = getAddrComponent(place, COMPONENT_TEMPLATE);
        	return state;
        }
        
        function getDistrict(place) {
          var COMPONENT_TEMPLATE = { administrative_area_level_2: 'short_name' },
      	      state = getAddrComponent(place, COMPONENT_TEMPLATE);
        	return state;
        }
    	
        function getCountryShort(place) {
          var COMPONENT_TEMPLATE = { country: 'short_name' },
        	    countryShort = getAddrComponent(place, COMPONENT_TEMPLATE);
        	return countryShort;
        }
    	
        function getCountry(place) {
        var COMPONENT_TEMPLATE = { country: 'long_name' },
            country = getAddrComponent(place, COMPONENT_TEMPLATE);
      	return country;
      }
      
      function getPostCode(place) {
        var COMPONENT_TEMPLATE = { postal_code: 'long_name' },
            postCode = getAddrComponent(place, COMPONENT_TEMPLATE);
        return postCode;
      }
      
      function isGeometryExist(place) {
        return angular.isObject(place) && angular.isObject(place.geometry);
      }
      
      function getLatitude(place) {
        if (!isGeometryExist(place)) return;
        return place.geometry.location.lat();
      }
      
      function getLongitude(place) {
        if (!isGeometryExist(place)) return;
        return place.geometry.location.lng();
      }
    	
    	return {
    	  isGooglePlace: isGooglePlace,
        isContainTypes: isContainTypes,
        getPlaceId: getPlaceId,
        getStreetNumber: getStreetNumber,
        getStreet: getStreet,
        getCity: getCity,
        getState: getState,
        getCountryShort: getCountryShort,
        getCountry: getCountry,
        getLatitude: getLatitude,
        getLongitude: getLongitude,
        getPostCode: getPostCode,
        getDistrict: getDistrict
    	};
    });
    
    angular.module('vsGoogleAutocomplete').directive('vsGoogleAutocomplete', ['vsGooglePlaceUtility', '$timeout', function(vsGooglePlaceUtility, $timeout) {
      return {
        restrict: 'A',
        require: ['vsGoogleAutocomplete', 'ngModel'],
    	 	scope: {
     			vsGoogleAutocomplete: '=',
          vsPlace: '=?',
    			vsPlaceId: '=?',
    			vsStreetNumber: '=?',
    			vsStreet: '=?',
    			vsCity: '=?',
    			vsState: '=?',
    			vsCountryShort: '=?',
    			vsCountry: '=?',
    			vsPostCode: '=?',
    			vsLatitude: '=?',
    			vsLongitude: '=?',
    			vsDistrict: '=?'
        },
    		controller: ['$scope', '$attrs', function($scope, $attrs) {
    			this.isolatedScope = $scope;
    			
    			/**
          * Updates address components associated with scope model.
          * @param {google.maps.places.PlaceResult} place PlaceResult object
          */
    			this.updatePlaceComponents = function(place) {
    			  $scope.vsPlaceId      = !!$attrs.vsPlaceId  && place     ? vsGooglePlaceUtility.getPlaceId(place)      : undefined;
    				$scope.vsStreetNumber = !!$attrs.vsStreetNumber && place ? vsGooglePlaceUtility.getStreetNumber(place) : undefined;
    				$scope.vsStreet       = !!$attrs.vsStreet && place       ? vsGooglePlaceUtility.getStreet(place)       : undefined;
    				$scope.vsCity         = !!$attrs.vsCity && place         ? vsGooglePlaceUtility.getCity(place)         : undefined;
    				$scope.vsPostCode     = !!$attrs.vsPostCode && place     ? vsGooglePlaceUtility.getPostCode(place)     : undefined;
    				$scope.vsState        = !!$attrs.vsState && place        ? vsGooglePlaceUtility.getState(place)        : undefined;
    				$scope.vsCountryShort = !!$attrs.vsCountryShort && place ? vsGooglePlaceUtility.getCountryShort(place) : undefined;
    				$scope.vsCountry      = !!$attrs.vsCountry && place      ? vsGooglePlaceUtility.getCountry(place)      : undefined;
    				$scope.vsLatitude     = !!$attrs.vsLatitude && place     ? vsGooglePlaceUtility.getLatitude(place)     : undefined;
    				$scope.vsLongitude    = !!$attrs.vsLongitude && place    ? vsGooglePlaceUtility.getLongitude(place)    : undefined;
    				$scope.vsDistrict     = !!$attrs.vsDistrict && place     ? vsGooglePlaceUtility.getDistrict(place)     : undefined;
    			};
    		}],
        link: function(scope, element, attrs, ctrls) {
    			// controllers
    			var autocompleteCtrl = ctrls[0],
    			    modelCtrl = ctrls[1];
    			
    			// google.maps.places.Autocomplete instance (support google.maps.places.AutocompleteOptions)
    			var autocompleteOptions = scope.vsGoogleAutocomplete || {},
    			    autocomplete = new google.maps.places.Autocomplete(element[0], autocompleteOptions);
    			
    			// google place object
    			var place;
    			
    			// value for updating view
    			var	viewValue;
    				
    			// updates view value and address components on place_changed google api event
    			google.maps.event.addListener(autocomplete, 'place_changed', function() {
    				place = autocomplete.getPlace();
    				viewValue = place.formatted_address || modelCtrl.$viewValue;
    				scope.$apply(function() {
    			    scope.vsPlace = place;
    					autocompleteCtrl.updatePlaceComponents(place);
    					modelCtrl.$setViewValue(viewValue);
              modelCtrl.$render();					    
    				});
          });
    			
    			// updates view value on focusout
    			element.on('blur', function(event) {
            viewValue = (place && place.formatted_address) ? viewValue : modelCtrl.$viewValue;
				    $timeout(function() {
				      scope.$apply(function() {
				    	  modelCtrl.$setViewValue(viewValue);
                modelCtrl.$render();
				      });
				    });
          });
    			
    			// prevent submitting form on enter
    			google.maps.event.addDomListener(element[0], 'keydown', function(e) { 
            if (e.keyCode == 13) { 
              e.preventDefault(); 
            }
          });
        } 
      };
    }]);
})(window, document);