Currently Being Moderated

1. Introduction

 

Google maps has a Places Autocomplete API that can be used with any input field in CRM. This feature can save time and help validate addresses.

 

Once autocomplete is attached to a field, Google will present a list of suggested locations as you type.

suggestions.png

 

Upon selecting one of the suggestions, the address fields will be populated with the location details.

filled.png

 

The API homepage is at https://developers.google.com/maps/documentation/javascript/places#places_autocomplete

 

To add this feature, the BSP containing the autocomplete field must be enhanced. This instructions in this article assume that the reader knows how to find the component and view containing a chosen input field and enhance that view's html file.

 

2. Including the Google Places Library

 

The Google Places library can be included by adding the following code to your BSP:

<script type="text/javascript" src="//www.google.com/jsapi"></script>

<script type="text/javascript">
/* Load google maps placesAPI */
google.
load("maps", "3", {other_params: "libraries=places&sensor=false", "callback": mapsLoaded });

 

function mapsLoaded(){
   
/* Setup after loading Google Places library goes here */
}

</script>

 

 

3. Attaching Autocomplete to an Input Field

 

3.1 Getting the Field ID

First you will need the id of the input field you want to use. This can be easily obtained using the Firebug extension for Firefox or Internet Explorer Developer Tools. To start IE Developer Tools, press F12 on any webpage in Internet Explorer. To get Firebug go to http://getfirebug.com/.

 

Enter inspection mode and click on the field.

firebuginspectionmode.png

 

After you click on the field, the id attribute should be easy to find in the HTML panel. In the example screenshot below I have selected the Street / House Number field.

firebugid.png

 

The ID of your element will probably look something like 'C17_W59_V60_V61_defaultaddressvalnode_struct.street'. The C##_W##_V##_V##_ part of the ID is dynamically generated and can change. To avoid any potential issues that could be caused by changing identifiers, I have used a jQuery selector that requires only the remainder of the ID.

 

3.2 jQuery and Selectors

To use the jQuery selectors, we need to include the jQuery library. This library can be pulled from Google by including the following tag in your BSP. This must come before any calls to jQuery functions.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>

 

jQuery uses $ as an alias for jQuery, however CRM also uses $ as a function name. Since we do not want to overwrite this function, we must return control of the $ variable to CRM using a call to jQuery.noConflict().

 

Example selector for a CRM input field with a partly dynamic identifier:

var streetInputField = jQuery('input[id*="defaultaddressvalnode_struct.street"]')[0];

 

In the code examples below there are several identifiers for different input fields. To use autocomplete with other fields in CRM, simply replace the identifiers in the example with the identifiers of other CRM fields.

 

The jQuery homepage is at http://api.jquery.com/

More information on jQuery selectors is available at http://api.jquery.com/category/selectors/

More information on the noConflict function is available at http://api.jquery.com/jQuery.noConflict/

 

3.3 Attaching Autocomplete to a Field

Attaching the autocomplete feature to an input field requires only a single line of code. This code should be placed in the mapsLoaded callback function to ensure that the API has been loaded before trying to use it:

var autocomplete = new google.maps.places.Autocomplete(inputField);

 

3.4 Listening for Events

The selection of a place suggestion will trigger the place_changed event. The following code can be used to listen for this event and should also be placed in the mapsLoaded callback.

 

google.maps.event.addListener(autocomplete,'place_changed', function()
{
   
/* Get place details */
   
var place = autocomplete.getPlace();
   
if (!place.geometry) {
       
return;
    }
  
    /* Do something with place information */

});

 

4. Complete Example

This code was written for the BuPaCreate.htm view from the component ICCMP_BP_DETAIL. In this example the values of several input fields are set using data from the place details. In order for these new values to persist, they must be saved to the buffer using the thtmlb_toggleInput function.

 

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<script type="text/javascript" src="//www.google.com/jsapi"></script>
<script type="text/javascript">
/* jQuery noconflict is required for CRM */
var jqnc =
jQuery.noConflict();

 

/* Load google maps places API */
google.
load("maps", "3", {other_params: "libraries=places&sensor=false", "callback": mapsLoaded });

 

/* Once the API has been loaded, we can use this callback function to attach the autocomplete feature */
function mapsLoaded(){

    /* Get input fields */
   
var streetInputField = jqnc('input[id*="defaultaddressvalnode_struct.street"]')[0];
   
var cityInputField = jqnc('input[id*="defaultaddressvalnode_struct.city"]')[0];
   
var postalInputfield = jqnc('input[id*="defaultaddressvalnode_struct.postl_cod1"]')[0];
   
var stateInputField = jqnc('input[id*="defaultaddressvalnode_struct.region"]')[0];
   
var countryInputField = jqnc('input[id*="defaultaddressvalnode_struct.country"]')[0];

  
    /* Attach the geo-autocomplete feature to the street input field */

   
var autocomplete = new google.maps.places.Autocomplete(streetInputField);

 


    /* Set up event listener for place selection */

    google.maps.
event.addListener(autocomplete, 'place_changed', function() {
       
/* Get place details */
       
var place = autocomplete.getPlace();
       
if (!place.geometry) {
           
return;
        }

        /* Loop through the address components for the selected place and fill
         the corresponding input fields in CRM */

       
var streetString = "";
       
for (i = 0; i < place.address_components.length; i++){
           
var type = place.address_components[i].types[0];
           
if (type == 'street_number'){
                streetString
= place.address_components[i].long_name + " ";
            }
           
if (type == 'route'){
                streetString
+= place.address_components[i].long_name;
            }
           
if (type == 'locality' || type == 'administrative_area_level_3'){
                thtmlb_toggleInput(cityInputField);
                cityInputField.
value = place.address_components[i].long_name;
            }
           
if (type == 'administrative_area_level_1'){
                thtmlb_toggleInput(stateInputField);
                stateInputField.
value = place.address_components[i].short_name;
            }
           
if (type == 'postal_code'){
                thtmlb_toggleInput(postalInputfield);
                postalInputfield.
value = place.address_components[i].long_name;
            }
           
if (type == 'country'){       
                thtmlb_toggleInput(countryInputField);
                countryInputField.
value = place.address_components[i].short_name;
            }
        }

 

 

        /* Either CRM or the Places API would restore the value of the
         autocomplete field after this event is fired, so we set the street name in a
         timeout shortly after we a selection is made. */

       
window.setTimeout(function() {
            thtmlb_toggleInput(streetInputField);
            streetInputField.
value = streetString;
            countryInputField.
focus();
        },
200);
    });
}

</script>

Comments

Actions

Filter Blog

By author:
By date:
By tag: