Search code examples
javascriptgoogle-mapsmarkerclusterer

How can i open an infowindow on markerclusterer click


I'm trying to open an infowindow on markerClusterer click

The plugin file contains:-

(function( $ ){
$.extend({
    mapsearch: function(options){
        options = $.extend({
        map:null,
        searchWhere:null,
        searchWhat:null,
        activeInfowindow:null,
    }, options);

    var markersFeed ={"recordsFiltered":5,"data":[{"id":"19","records":"1","geohash":"dpxpqjc","location":{"minlat":43.493499755859,"minlon":-79.891204833984,"maxlat":43.494873046875,"maxlon":-79.889831542969,"medlat":43.49,"medlon":-79.89}},{"id":"18","records":"1","geohash":"dpxrcqy","location":{"minlat":43.586883544922,"minlon":-79.741516113281,"maxlat":43.588256835938,"maxlon":-79.740142822266,"medlat":43.59,"medlon":-79.74}},{"id":"14","records":"2","geohash":"dpzc2cm","location":{"minlat":43.820343017578,"minlon":-79.061737060547,"maxlat":43.821716308594,"maxlon":-79.060363769531,"medlat":43.82,"medlon":-79.06}},{"id":"16","records":"1","geohash":"dpzc3t4","location":{"minlat":43.840942382812,"minlon":-79.032897949219,"maxlat":43.842315673828,"maxlon":-79.031524658203,"medlat":43.84,"medlon":-79.03}}],"zoom":"10"};

plugin = this;



plugin.markerCombine = function(markers) {
    var index = 0;
    var total = 0;
    for (var i = 0;i < markers.length; i++) {
        console.log(markers[i].records);
        total = parseInt(total) + parseInt(markers[i].records);
        index++;
    }


    return {
        text: total,
        index: index
    };
}


plugin.addMarker=function(lat,lng,records,geohash, map){
    var marker = options.map.addMarker({
        lat: lat,
        lng: lng,
        records: records,
        label:records,
        geohash: geohash,     
    });

    google.maps.event.addListener(marker,'click',function() {
        plugin.markerClick(marker,options.map); 
    });

}



plugin.clearMarkers=function(){
    options.map.markerClusterer.clearMarkers();

    var i = 0,
        l = options.map.markers.length;
    for (i; i < l; i++) {
        options.map.markers[i].setMap(null)
    }
    options.map.markerClusterer.markers = []
    options.map.markers = []; 

}

plugin.bindMapListeners = function(map){

map.addListener(options.map.markerClusterer,'clusterclick', function(cluster){
    plugin.clusterClick(cluster,options.map);   
}); 

}

plugin.clusterClick = function(cluster,map){

    var content = '<div id="iw-container">' +
                '<div class="iw-title">Loading</div>' +
                '<div class="iw-content">' +
                '<br/>Searching<br/>'+
                '</div>' +
              '</div>';
    options.activeInfowindow = new google.maps.InfoWindow();
    var pos = cluster.getCenter();
    options.activeInfowindow.setPosition(pos);
    options.activeInfowindow.setContent(content2);
    options.activeInfowindow.open(map);
}

plugin.mapSearchEvents = function(map){


    google.maps.event.addListener(map.map, 'dragend', function() {

    plugin.search(map);


    }); 
    google.maps.event.addListener(map.map, 'zoom_changed', function() {

    plugin.search(map);
    }); 
}




//retrieve markers for existing bounds and apply
plugin.search =function(map, params){
    //remove existing markers
    plugin.clearMarkers();

    var mapBounds = options.map.getBounds();

    var bounds = {}
    bounds.latMax = mapBounds.getNorthEast().lat();
    bounds.latMin = mapBounds.getSouthWest().lat();
    bounds.lonMax = mapBounds.getNorthEast().lng();
    bounds.lonMin = mapBounds.getSouthWest().lng();

    zoom = options.map.getZoom();


    $.each( markersFeed.data, function( list, blip ) {
        console.log(blip);
    plugin.addMarker(blip.location.medlat,blip.location.medlon,blip.records,blip.geohash, options.map);

    });
    options.map.markerClusterer.setCalculator(plugin.markerCombine);

    plugin.bindMapListeners(options.map);





}


plugin.markerClick = function(marker){
url="/ajaxSearch/searchGeohash/"

    var content = '<div id="iw-container">' +
                '<div class="iw-title">Loading</div>' +
                '<div class="iw-content" id="'+marker.geohash+'">' +
                '<br/>Searching<br/>'+
                '</div>' +
                //'<div class="iw-bottom-gradient"></div>' +
              '</div>';
    options.activeInfowindow = new google.maps.InfoWindow({
        content: content,
        pixelOffset: new google.maps.Size(100,100),

    // Assign a maximum value for the width of the infowindow allows
    // greater control over the various content elements
        maxWidth: 340
    });

    options.activeInfowindow.close();
    options.activeInfowindow.open(options.map,marker);

}





plugin.drawMap =function(lat,lng, target, zoom, params,bounds){
if (options.map !== null) {
options.map.markerClusterer.clearMarkers(); 
}
   map = new GMaps({
    div: target,
    lat: lat,
    lng: lng,
    zoom: zoom,
   scrollwheel: false,
     markerClusterer: function(map) {
        options= {
        zoomOnClick: false, 
        gridSize: 50,
        styles: [{
            height: 39,
            width: 43,
        }],
        }
      return new MarkerClusterer(map, [], options);


    }

    });
    options.map = map;
    //options.map = options.map;
    //console.log(options);
    if(typeof bounds != 'undefined'){
        options.map.fitBounds(bounds);

    }

    //bind info box to popup and get gridsquare bound submit mapsearch



    //full map search
    google.maps.event.addListenerOnce(options.map.map, 'bounds_changed', function() {
    plugin.search();

    });

plugin.mapSearchEvents(options.map);

    return options.map;
}



    return this;



    }
});
})( jQuery ); 

The html:-

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">

<title>Membawhen</title>
<style>
#homeMap{width:100%; height:400px;}
</style>

</head>

<body >

<div id="homeMap"></div>

<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=yourkey&sensor=true"></script>
   <script type="text/javascript" src="https://google-maps-utility-library-v3.googlecode.com/svn-history/r287/trunk/markerclusterer/src/markerclusterer.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gmaps.js/0.4.21/gmaps.js"></script>    
<script type="text/javascript">

$(document).ready(function () {


var map =  $.mapsearch();
map.drawMap(43.653226,-79.383184, '#homeMap', 9);    
});


 </script>


 </body> 
 </html>

The first marker to be clicked opens fine but no subsequent clicks on any marker will open.

The cluster infowindows never open

The clicks are calling the functions (I can alert and log etc) but I can't get the infowindow to open, in console the only error showing is:

Uncaught TypeError: Cannot read property 'get' of undefined    from infowindow.js

Solution

  • I get a javascript error with your code Uncaught TypeError: Cannot read property 'get' of undefined on this line:

    options.activeInfowindow.open(options.map, marker);
    

    Because options.map is a Gmaps object, not a google.maps.Map object. If I change that to options.map.map (which is a reference to the google.map.Map object), that error goes away and the InfoWindows on the markers work.

    proof of concept fiddle

    When I look at the 'clusterclick' issue, if I change this:

    map.addListener(options.map.markerClusterer, 'clusterclick', function(cluster) {
          plugin.clusterClick(cluster, options.map);
    });
    

    To:

    google.maps.event.addListener(options.map.markerClusterer, 'clusterclick', function(cluster) {
          plugin.clusterClick(cluster, options.map);
    });
    

    I get a javascript error: Uncaught ReferenceError: content2 is not defined. If I fix that (by using content instead, which is defined), I get an InfoWindow on the marker cluster.

    proof of concept fiddle

    If you want a single infowindow open at a time, you need to create it once and reuse that marker as needed:

    proof of concept fiddle

    code snippet:

    $(document).ready(function() {
      var map = $.mapsearch();
      map.drawMap(43.653226, -79.383184, '#homeMap', 9);
    });
    (function($) {
      $.extend({
        mapsearch: function(options) {
          options = $.extend({
            map: null,
            searchWhere: null,
            searchWhat: null,
            activeInfowindow: null,
          }, options);
          plugin = this;
          plugin.markerCombine = function(markers) {
            var index = 0;
            var total = 0;
            for (var i = 0; i < markers.length; i++) {
              console.log(markers[i].records);
              total = parseInt(total) + parseInt(markers[i].records);
              index++;
            }
            return {
              text: total,
              index: index
            };
          }
          plugin.addMarker = function(lat, lng, records, geohash, map) {
            var marker = options.map.addMarker({
              lat: lat,
              lng: lng,
              records: records,
              label: records,
              geohash: geohash,
            });
            google.maps.event.addListener(marker, 'click', function() {
              plugin.markerClick(marker, options.map);
            });
          }
          plugin.clearMarkers = function() {
            options.map.markerClusterer.clearMarkers();
            var i = 0,
              l = options.map.markers.length;
            for (i; i < l; i++) {
              options.map.markers[i].setMap(null)
            }
            options.map.markerClusterer.markers = []
            options.map.markers = [];
          }
          plugin.bindMapListeners = function(map) {
            google.maps.event.addListener(options.map.markerClusterer, 'clusterclick', function(cluster) {
              plugin.clusterClick(cluster, options.map.map);
            });
          }
          plugin.clusterClick = function(cluster, map) {
            var content = '<div id="iw-container">' +
              '<h4>Cluster</h4><div class="iw-title">Loading</div>' +
              '<div class="iw-content">' +
              '<br/>Searching<br/>' +
              '</div>' +
              '</div>';
            if (!options.activeInfowindow || !options.activeInfowindow.setContent) {
              options.activeInfowindow = new google.maps.InfoWindow({
                maxWidth: 340
              });
            }
            // options.activeInfowindow = new google.maps.InfoWindow();
            var pos = cluster.getCenter();
            options.activeInfowindow.setPosition(pos);
            options.activeInfowindow.setContent(content);
            options.activeInfowindow.open(map);
          }
          plugin.mapSearchEvents = function(map) {
              google.maps.event.addListener(map.map, 'dragend', function() {
                plugin.search(map);
              });
              google.maps.event.addListener(map.map, 'zoom_changed', function() {
                plugin.search(map);
              });
            }
            //retrieve markers for existing bounds and apply
          plugin.search = function(map, params) {
            //remove existing markers
            plugin.clearMarkers();
            var mapBounds = options.map.getBounds();
            var bounds = {}
            bounds.latMax = mapBounds.getNorthEast().lat();
            bounds.latMin = mapBounds.getSouthWest().lat();
            bounds.lonMax = mapBounds.getNorthEast().lng();
            bounds.lonMin = mapBounds.getSouthWest().lng();
            zoom = options.map.getZoom();
            $.each(markersFeed.data, function(list, blip) {
              console.log(blip);
              plugin.addMarker(blip.location.medlat, blip.location.medlon, blip.records, blip.geohash, options.map);
            });
            options.map.markerClusterer.setCalculator(plugin.markerCombine);
            plugin.bindMapListeners(options.map);
          }
          plugin.markerClick = function(marker) {
            url = "/ajaxSearch/searchGeohash/"
    
            var content = '<div id="iw-container">' +
              '<h4>Marker</h4><div class="iw-title">Loading</div>' +
              '<div class="iw-content" id="' + marker.geohash + '">' +
              '<br/>Searching<br/>' +
              '</div>' +
              //'<div class="iw-bottom-gradient"></div>' +
              '</div>';
            if (!options.activeInfowindow || !options.activeInfowindow.setContent) {
              options.activeInfowindow = new google.maps.InfoWindow({
                maxWidth: 340
              });
            }
            /* options.activeInfowindow = new google.maps.InfoWindow({
              content: content,
              maxWidth: 340
            }); */
            options.activeInfowindow.setContent(content);
            options.activeInfowindow.close();
            options.activeInfowindow.open(options.map.map, marker);
          }
          plugin.drawMap = function(lat, lng, target, zoom, params, bounds) {
            if (options.map !== null) {
              options.map.markerClusterer.clearMarkers();
            }
            map = new GMaps({
              div: target,
              lat: lat,
              lng: lng,
              zoom: zoom,
              scrollwheel: false,
              markerClusterer: function(map) {
                options = {
                  zoomOnClick: false,
                  gridSize: 50,
                  styles: [{
                    height: 39,
                    width: 43,
                    url: 'http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m1.png',
                    anchor: [20, 0],
                  }]
                }
                return new MarkerClusterer(map, [], options);
              }
            });
            options.map = map;
            if (typeof bounds != 'undefined') {
              options.map.fitBounds(bounds);
            }
            google.maps.event.addListenerOnce(options.map.map, 'bounds_changed', function() {
              plugin.search();
            });
            plugin.mapSearchEvents(options.map);
            return options.map;
          }
          return this;
        }
      });
    })(jQuery);
    var markersFeed = {
      "recordsFiltered": 5,
      "data": [{
        "id": "19",
        "records": "1",
        "geohash": "dpxpqjc",
        "location": {
          "minlat": 43.493499755859,
          "minlon": -79.891204833984,
          "maxlat": 43.494873046875,
          "maxlon": -79.889831542969,
          "medlat": 43.49,
          "medlon": -79.89
        }
      }, {
        "id": "18",
        "records": "1",
        "geohash": "dpxrcqy",
        "location": {
          "minlat": 43.586883544922,
          "minlon": -79.741516113281,
          "maxlat": 43.588256835938,
          "maxlon": -79.740142822266,
          "medlat": 43.59,
          "medlon": -79.74
        }
      }, {
        "id": "14",
        "records": "2",
        "geohash": "dpzc2cm",
        "location": {
          "minlat": 43.820343017578,
          "minlon": -79.061737060547,
          "maxlat": 43.821716308594,
          "maxlon": -79.060363769531,
          "medlat": 43.82,
          "medlon": -79.06
        }
      }, {
        "id": "16",
        "records": "1",
        "geohash": "dpzc3t4",
        "location": {
          "minlat": 43.840942382812,
          "minlon": -79.032897949219,
          "maxlat": 43.842315673828,
          "maxlon": -79.031524658203,
          "medlat": 43.84,
          "medlon": -79.03
        }
      }],
      "zoom": "10"
    };
    #homeMap {
      width: 100%;
      height: 400px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gmaps.js/0.4.21/gmaps.js"></script>
    <script src="https://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js"></script>
    <div id="homeMap"></div>