Homepage / Doc / Google Map & Places Autocomplete

Google Map & Places Autocomplete

This sample will demonstrate how to utilize Google’s Places and Maps Javascript APIs to display both a map to the user and an auto complete text box for the user to enter a location. Both of these features require that you have an API key from Google, which you can sign up for and request here: https://developers.google.com/maps/documentation/javascript/

Google’s API website also contains detailed information on other features that you can leverage within Checkbox.

Here are the goals of our sample survey:

  • Allow the user to enter in an address. The address field should auto complete utilizing Google’s Places API
  • Display a map with a marker at the selected address
  • Store both the address and the coordinates of the address in the survey response

google_map_sample


To start this process, we will need a survey with two single line text items. The first item will contain both the space for the map as well as the address field. The second will be an item that we hide using javascript and will store the coordinate data of the address.

First, the coordinates item. You will want to create a single line text item, and supply the question text as Coordinates. You can change this to whatever you would like as it will not be displayed to the user.

NOTE: There is no way to hide this item from an email response or alert. If you are utilizing these features, please keep this in mind.

To make accessing the item easier, we suggest that you navigate to the behavior tab of the item editor, and supply a class name of coordinates. This will make it possible to select the item using jQuery later quickly.

Here is the HTML from the item we created.

<div id="_responseView__pageView_Layout___defaultZone_218652__containerPanel" class="itemContainer itemPositionLeft coordinates">
    <div id="_responseView__pageView_Layout___defaultZone_218652__contentPanel" class="itemContent">
        <div id="_responseView__pageView_Layout___defaultZone_218652__topAndOrLeftPanel" class="topAndOrLeftContainer labelTop">
            <div id="_responseView__pageView_Layout___defaultZone_218652__textContainer" class="textContainer">
                <div id="_responseView__pageView_Layout___defaultZone_218652__questionText__questionPanel" class="questionTextContainer Question">
                    <label for="_responseView__pageView_Layout___defaultZone_218652__textInput">Coordinates</label>
                </div>
                <div style="clear:both;"></div>
                <div id="_responseView__pageView_Layout___defaultZone_218652__questionText__descriptionPanel" class="descriptionTextContainer Description">
                </div>
                <div style="clear:both;"></div>
                <div style="clear:both;"></div>
            </div>
        </div>
        <div id="_responseView__pageView_Layout___defaultZone_218652__bottomAndOrRightPanel" class="bottomAndOrRightContainer inputForLabelTop">
            <div id="_responseView__pageView_Layout___defaultZone_218652__inputPanel" class="inputContainer">
                <input name="_responseView$_pageView$Layout_$_defaultZone$218652$_textInput" type="text" id="_responseView__pageView_Layout___defaultZone_218652__textInput" datadefaultvalue="" class="uniform-input text">
            </div>
        </div>
    </div>
</div>

Next, we need to create the address field and the placeholder for our map. You will want to create an additional single line text item. This item will require a bit of custom HTML to support displaying the map. We need an area of space to display the map, to do this we are going to create a div, with a specified id of “map,” and set the div to be 500×300 pixels. We will also want to enter the question text for our address field here as well.

This is how our sample item’s question text appears:

<div id="map" style="width: 500px; height: 300px;">&nbsp;</div>
<div>Please enter your address: </div>

Once the survey itself is set up, we will need to access the survey-wide javascript feature and reference Google’s Map API. On the “Third Party References” tab you can supply a reference to Google’s API. This will look something like:

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=[YourApiKey]&libraries=places"></script>

The javascript provided below is a modified version of the javascript from Googles Places API documentation.

The sample javascript below will do several things in this order:

  • Hide the coordinates field
  • Set the starting location of the map and its zoom level
  • Bind Google’s Places API autocomplete to the address field
  • Add a listener to the address field to facilitate the auto complete
  • Populate the coordinates field
  • Set the location of the marker on the map when an address is selected
    $(document).ready(function(e) {

        //hide Coordinates field which should be not edited by the user

        $(".Coordinates").hide();
        //initialize map and center on default coordinates
        var map = new google.maps.Map(document.getElementById('map'), {
            center: {
                lat: 42.3657771,
                lng: -71.1899801
            },
            zoom: 13
        });


        var input = document.getElementById('_responseView__pageView_Layout___defaultZone_218650__textInput');

        var autocomplete = new google.maps.places.Autocomplete(input);
        autocomplete.bindTo('bounds', map);

        var infowindow = new google.maps.InfoWindow();
        var marker = new google.maps.Marker({
            map: map,
            anchorPoint: new google.maps.Point(0, -29)
        });


        autocomplete.addListener('place_changed', function() {
            infowindow.close();
            marker.setVisible(false);
            var place = autocomplete.getPlace();
            if (!place.geometry) {
                window.alert("No details available for input: '" + place.name + "'");
                return;
            }

            //store coordinates within the coordinates item field
            $(".Coordinates :input").val(place.geometry.location);

            if (place.geometry.viewport) {
                map.fitBounds(place.geometry.viewport);
            } else {
                map.setCenter(place.geometry.location);
                map.setZoom(17);
            }

            //set the marker icon within the map 

            marker.setIcon(({
                url: place.icon,
                size: new google.maps.Size(71, 71),
                origin: new google.maps.Point(0, 0),
                anchor: new google.maps.Point(17, 34),
                scaledSize: new google.maps.Size(35, 35)
            }));
            marker.setPosition(place.geometry.location);
            marker.setVisible(true);

            var address = '';
            if (place.address_components) {
                address = [
                    (place.address_components[0] && place.address_components[0].short_name || ''),
                    (place.address_components[1] && place.address_components[1].short_name || ''),
                    (place.address_components[2] && place.address_components[2].short_name || '')
                ].join(' ');
            }

            infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
            infowindow.open(map, marker);
        });

    });
April 5, 2018