Gecoder - Open map infowindow from external link

By aev - February 14, 2014

Hi,

we just bought the Gecoder addon and so far it is working great for gecoding and getting a map with multiple tags up and running, but we would like to add a feature not provided by the included example page.

We want to make the addresses we output to our page from a Multi Record CMSB section have a link or onclick event to open the corresponding "infowindow" on the Google map. Has anyone done this? Code or tips are greatly appreciated :)

-aev-

By ross - February 18, 2014

Hi aev

Thanks for posting!  I just want to confirm that what you are looking for is the same thing in this example:

https://developers.google.com/maps/documentation/javascript/examples/infowindow-simple

That map has one point on it and when you click it, a window pops up above it and displays some extra details.  Is that what you are looking to do?

Thanks!

-----------------------------------------------------------
Cheers,
Ross Fairbairn - Consulting
consulting@interactivetools.com

Hire me! Save time by getting our experts to help with your project.
Template changes, advanced features, full integration, whatever you
need. Whether you need one hour or fifty, get it done fast with
Priority Consulting: http://www.interactivetools.com/consulting/

By Dave - February 20, 2014

I'll ask Chris if he has any ideas on this one, he's our Google Maps expert! :) 

Dave Edis - Senior Developer
interactivetools.com

Hi aev,

I've done some testing using the example code that comes with the geocoder plugin, and I've created the functionality you're after. If you create a PHP file with the following code:

<?php header('Content-type: text/html; charset=utf-8'); ?>
<?php
  /* STEP 1: LOAD RECORDS - Copy this PHP code block near the TOP of your page */
  
  // load viewer library
  $libraryPath = 'cmsAdmin/lib/viewer_functions.php';
  $dirsToCheck = array('/home/greg/www/','','../','../../','../../../');
  foreach ($dirsToCheck as $dir) { if (@include_once("$dir$libraryPath")) { break; }}
  if (!function_exists('getRecords')) { die("Couldn't load viewer library, check filepath in sourcecode."); }
  // error checking
  if (!@$GLOBALS['GEOCODER_PLUGIN']) { die("You must activate the Geocoder plugin before you can access this page."); }

 
  // get records
  list($myRecords, $myMetaData) = getRecords(array(
    'tableName' => $GLOBALS['GEOCODER_SAMPLE_TABLENAME'],
  ));

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Show map with multiple addresses (using Google Maps API V3)</title>
 <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<style type="text/css">
  body, td { font-family: arial; font-size: 14px; }
</style>

<!-- STEP1: Map with multiple addresses: Put this in the <head> of your page, rename $myRecords if needed -->
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
function initialize() {
  var mapCanvasId = 'map_canvas';
  var mapOptions  = { 
    mapTypeId:   google.maps.MapTypeId.ROADMAP,
    scrollwheel: false,
    zoomControl: false     
  };
  var map         = new google.maps.Map(document.getElementById(mapCanvasId), mapOptions);
  var bounds      = new google.maps.LatLngBounds();
  var infowindow  = new google.maps.InfoWindow();
  var gmarkers = [];

<?php
foreach ($myRecords as $record) {
  if (!$record['latitude'] || !$record['longitude']) { continue; }
  $jsFunctionArgs = "{$record['latitude']}, {$record['longitude']}, {$record['num']}, '" .escapeJs($record['_link']). "'";
  print "  _geocoder_addMarker($jsFunctionArgs);\n";
}
?>

  //
  function _geocoder_addMarker(latitude, longitude, recordNum, detailLink) {
    var latLng       = new google.maps.LatLng(latitude, longitude);
    var infowindowEl = document.getElementById('marker_infowindow_' + recordNum);
    var marker       = new google.maps.Marker({ map: map, position: latLng });
    google.maps.event.addListener(marker, 'click', function() {
      if (infowindowEl) {
        infowindow.setContent(infowindowEl.innerHTML);
        infowindow.open(map, marker);
      }
      else {
        window.location = detailLink;
      }
    });

    //Add the marker object to an array.
    gmarkers.push(marker);
    bounds.extend(latLng);
  }

  //
  map.fitBounds(bounds);

  //This function fires when a user clicks a link.
  $( ".openMarker" ).click(function() {

    //Get the data key variable from the link
    var key = $(this).data("key");

    //Call the trigger event for the map market from the gmarkers array 
    google.maps.event.trigger(gmarkers[key],'click');
  });
}

</script>
<!-- STEP1: Map with multiple addresses -->


</head>


<!-- STEP2: Map with multiple addresses: add this to body tag: onload="initialize() -->
<body onload="initialize()">
<!-- STEP2: Map with multiple addresses -->


  <h1>Show map with multiple addresses (using Google Maps API V3)</h1>


  <!-- STEP3: Map with multiple addresses: Put this where you want your map displayed, rename $myRecords if needed -->
  <?php $hasAddresses = array_filter(array_pluck($myRecords, 'latitude')); ?>
  <?php if ($hasAddresses): ?>
    <div id="map_canvas" style="width: 599px; height: 599px; float: left; margin: 0px 15px;"></div>
    <ul id="linkList" >
      <?php foreach($myRecords as $key => $record): ?>
        <li><a class="openMarker" data-key="<?php echo $key; ?>" href="#"><?php echo $record['address']; ?></a></li>
      <?php endforeach; ?>
    </ul>
  <?php endif ?>

  <?php if (!$hasAddresses): ?>
    <div style="width: 599px; height: 599px; float: left; margin: 0px 15px; border: 1px solid #000;">
      <div style="text-align: center; padding-top: 135px">
        No map available!
      </div>
    </div>
  <?php endif ?>
  <!-- STEP3: /Map with multiple addresses -->


  <p>TIP: Click on markers for more details.</p>


  <!-- STEP4: Map with multiple addresses: Set the popup window content, rename $myrecords if needed -->
  <div id="marker_details" style="display: none;">
    <?php foreach ($myRecords as $record): ?>

      <?php // marker_infowindow_### is the content displayed in the info-window on click ?>
      <div id="marker_infowindow_<?php echo $record['num']; ?>">
        <h3><?php echo htmlspecialchars( @$record['address']); ?></h3>
        Add any extra content you like here...<br/>
        <a href="<?php echo $record['_link']; ?>">details</a>
      </div>

    <?php endforeach ?>
  </div>
  <!-- STEP4: Map with multiple addresses -->


</body>
</html>

You might have to change the code that loads the viewer functions at the top of the page to work with your install, otherwise the code should work without any issues, I've also attached a screenshot of what is created. The changes I've made to the default code are highlighted in green.

So the code works by copying the marker object that is created for each pin to an array called gmarkers.

Then I cycle through each record and create a HTML list of links with the class openMarker, and the key for the value set to the data tag data-key. 

The final step is to create a jquery on click function that fires when the user clicks on a link with the class openMarker. The function will get the data-key variable, then launch the corresponding open marker event from the marker array.

Let me know if you have any questions, or if you have any issues getting this system working.

Thanks!

Greg

Greg Thomas







PHP Programmer - interactivetools.com

By aev - February 26, 2014

Hi Greg,

I added your changes and it works as expected.

Thanks!

-aev-