+ Start a Discussion
Nitin Saxena 17Nitin Saxena 17 

Salesforce integration with Google Java script API

I had a requirement where i will have Billing address & Shipping address on Same VF page in Salesforce.

I am using Autocomplete for both address & i have created a component which i am using it twice on VF page .

Issue : When i am using VF component once on VF page everything is working fine but when i am adding the same component of the VF page twice it stop working. I am not getting Address

Please suggest how to fix this issue

I had also posted this query on Stackoverflow: http://stackoverflow.com/questions/32907416/salesforce-integration-with-google-java-script-api

Component code :
<apex:component controller="GoogleComponentController">

 <apex:attribute type="string" name="idcomponent" required="true" description="Unique id for this component in the page" assignTo="{!componentid}"/>
<html>
  <head>
    <title>Place Autocomplete Address Form</title>
    {!componentid}
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
    <meta charset="utf-8"/>
    <style>
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 100%;
      }
    </style>
    <link type="text/css" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"/>
    <style>
      #locationField, #controls {
        position: relative;
        width: 480px;
      }
      #autocomplete {
        position: absolute;
        top: 0px;
        left: 0px;
        width: 99%;
      }
      .label {
        text-align: right;
        font-weight: bold;
        width: 100px;
        color: #303030;
      }
      #address {
        border: 1px solid #000090;
        background-color: #f0f0ff;
        width: 480px;
        padding-right: 2px;
      }
      #address td {
        font-size: 10pt;
      }
      .field {
        width: 99%;
      }
      .slimField {
        width: 80px;
      }
      .wideField {
        width: 200px;
      }
      #locationField {
        height: 20px;
        margin-bottom: 2px;
      }
    </style>
  </head>

  <body>
    <div id="locationField">
      <input id="autocomplete" placeholder="Enter your address"
             onFocus="geolocate()" type="text"></input>
    </div>

    <table id="address">
      <tr>
        <td class="label">Street address</td>
        <td class="slimField"><input class="field" id="street_number"
              disabled="true"></input></td>
        <td class="wideField" colspan="2"><input class="field" id="route"
              disabled="true"></input></td>
      </tr>
      <tr>
        <td class="label">City</td>
        <td class="wideField" colspan="3"><input class="field" id="locality"
              disabled="true"></input></td>
      </tr>
      <tr>
        <td class="label">State</td>
        <td class="slimField"><input class="field"
              id="administrative_area_level_1" disabled="true"></input></td>
        <td class="label">Zip code</td>
        <td class="wideField"><input class="field" id="postal_code"
              disabled="true"></input></td>
      </tr>
      <tr>
        <td class="label">Country</td>
        <td class="wideField" colspan="3"><input class="field"
              id="country" disabled="true"></input></td>
      </tr>
    </table>

    <script>
// This example displays an address form, using the autocomplete feature
// of the Google Places API to help users fill in the information.

var placeSearch, autocomplete;
var componentForm = {
  street_number: 'short_name',
  route: 'long_name',
  locality: 'long_name',
  administrative_area_level_1: 'short_name',
  country: 'long_name',
  postal_code: 'short_name'
};

function initAutocomplete() {
  // Create the autocomplete object, restricting the search to geographical
  // location types.
  autocomplete = new google.maps.places.Autocomplete(
      (document.getElementById('autocomplete')),
      {types: ['geocode']});

  // When the user selects an address from the dropdown, populate the address
  // fields in the form.
  autocomplete.addListener('place_changed', fillInAddress);
}

// [START region_fillform]
function fillInAddress() {
  // Get the place details from the autocomplete object.
  var place = autocomplete.getPlace();

  for (var component in componentForm) {
    document.getElementById(component).value = '';
    document.getElementById(component).disabled = false;
  }

  // Get each component of the address from the place details
  // and fill the corresponding field on the form.
  for (var i = 0; i < place.address_components.length; i++) {
    var addressType = place.address_components[i].types[0];
    if (componentForm[addressType]) {
      var val = place.address_components[i][componentForm[addressType]];
      document.getElementById(addressType).value = val;
    }
  }
}
// [END region_fillform]

// [START region_geolocation]
// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
function geolocate() {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      var geolocation = {
        lat: position.coords.latitude,
        lng: position.coords.longitude
      };
      var circle = new google.maps.Circle({
        center: geolocation,
        radius: position.coords.accuracy
      });
      autocomplete.setBounds(circle.getBounds());
    });
  }
}
// [END region_geolocation]

    </script>
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBJpqM1gX8A3tzRBb13op5ci9tiZOJZWeY&signed_in=true&libraries=places&callback=initAutocomplete"></script>
  </body>
</html>

</apex:component>


VF page:

<apex:page >
<c:Google_Component id="billing" idcomponent="billingid" ></c:Google_Component>
<!--<c:Google_Component id="shipping" idcomponent="shipping" ></c:Google_Component> -->
</apex:page>

Controller:

public class GoogleComponentController{
public string componentid{get;set;
}
public void GoogleComponentController(){
system.debug('@@@@>'+componentid);
}
}

 
Daniel BallingerDaniel Ballinger

You will need to isolate any of the global variables in the components JavaScript so they are unique to each usage of the component.

As it is, vars like `autocomplete` will be duplicated by both components. The Javascript code won't be able to isolate one from the other.

One option would be to identify all the locations in the code where a common var or id are used. Then modify the component code so the identifiers will be unique for each component. There is probably a more refined way to share common.

Cross posted from StackOverflow (http://stackoverflow.com/a/33249682/54026).