Rustam A. Gasanov

$ echo "Inspired developer's blog" > /dev/null

Google Places: Limit Autocomplete Results to Cities Only, Hints

| Comments

If you ever used Google Places API, you’re probably familiar with types option, which allows you to restrict autocomplete results in different ways. I had a requirement to show only cities in UK. So, first of all I tried (cities) type in conjunction with componentRestrictions:

application.html.haml
1
2
3
...
= javascript_include_tag "http://maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=places"
...
google_places_autocomplete.js.coffee
1
2
3
4
5
6
7
8
9
10
11
12
$ ->
  initialize = () ->
    options = {
      language: 'en-GB',
      types: ['(cities)'],
      componentRestrictions: { country: "uk" }
    }

    input = $('.address-search')
    autocomplete = new google.maps.places.Autocomplete(input[0], options)

  google.maps.event.addDomListener(window, 'load', initialize)

As a result I’ve got following places picker:

Good enough, but my goal was to show and prefill input with cities only. For now, after picking a city it’ll put “City, Country” in box. The solution is quite simple, you just need to specify the country in the Google API call with a help of &region= parameter:

application.html.haml
1
= javascript_include_tag "http://maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=places&region=UK"

Other Hints

During the search for this solution I’ve collected other tips for Google places autocomplete. I’m going to post them below, hope they will be useful.

  • To get rid of the pins on the left side of the list add following css:
1
2
3
4
.pac-icon {
  width: 0;
  background-image: none;
}

Result:

  • To handle list items returned by the Google API
1
2
3
4
5
6
7
document.addEventListener('DOMNodeInserted', (event) ->
  target = $(event.target)
  if target.hasClass('pac-item')
    # replacing "Some City United Kingdom" to "Some City" for each list element
    # warning: on click it will still autofill input with "Some City, United Kingdom"
    target.html(target.html().replace(/ United Kingdom<\/span>$/, "</span>"))
)

  • To handle place selection you should add an event listener. It’s helpful if you want, for example, to perform AJAX call, since regular onChange won’t work.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
google.maps.event.addListener(autocomplete, 'place_changed', ->
  # Here you can use:
  # $('.your-input').val() to get the value from your input
  # autocomplete.getPlace() to get detailed information about place chosen

  # Below is the hack to replace input content from "City, Country" to "City"
  # when using 'types': ('cities') without specific region.
  # And although I don't recommend to use it, since it flashes while
  # changing an input content; maybe someone will need it for other purpose
  place = autocomplete.getPlace()
  if place.address_components
    city = place.address_components[0] && place.address_components[0].short_name || ''

    input.blur()
    setTimeout(
      -> input.val(city)
      10
    )
)

Comments