nilesvm
nilesvm

Reputation: 339

How do you add an infowindow to a cluster marker?

The documentation and stackoverflow tickets are very sparse in this area.

I want to open an infowindow when a user mouseover's a cluster marker. I want this infowindow to be generated using two things, a piece of data from the clusters's markers, and a rails partial.

How do I:

  1. add a mouseover listener to a cluster
  2. get the markers inside the cluster (select the right object) create an infowindow for this
  3. cluster based on a partial (using data from the above)

I am using google maps for rail's gem and the Marker Clusterer Plus libary.

I have the following in my builder:

handler = Gmaps.build("Google",
  { markers:
    { clusterer: {
        gridSize: 8,
        maxZoom: 12,
        zoomOnClick: true,
        styles: [ {
              textSize: 1,
              textColor: '#45A6DD',
              url: 'images/maps/cluster.marker.png',
              height: 51,
              width: 51 }
            ]
      }
    },
    builders: {
      Marker: KhMarker
    }
  });

And I have added the following script onto the page with the map. This listens for the 'clusterclick' event. I would like to use the MarkerClustererPlus mouseover event, but I can't figure out which js object I should pass into the addListener event.

    google.maps.event.addListener(handler.clusterer.getServiceObject(), 'clusterclick', function(cluster) {
      // console.log("Cluster clicked")

      var content = '';

      content = this;
      console.log (content)

      // Convert lat/long from cluster object to a usable MVCObject
      // var info = new google.maps.MVCObject;
      // info.set('position', cluster.center_);

      // var infowindow = new google.maps.InfoWindow();
      // infowindow.close();
      // infowindow.setContent();

      // infowindow.open(handler.map.getServiceObject(), info);
    });

In the console I am seeing the MarkerClusterer object, but what I am trying to get is the specific cluster I just moused over and the markers it contains. I need to grab the city name (or lat/long) of the first marker to then get the region it is from so I can pass this data to the infowindow.

I can get a basic infowindow to open on click. I want to have the infowindow open from a partial similar to the way that my markers do.

  marker.infowindow render_to_string(partial: "/destinations/map_tile.html", locals: { city: city })

How do I do these 3 things?

Upvotes: 0

Views: 1534

Answers (1)

nilesvm
nilesvm

Reputation: 339

UPDATE:

Using google maps api, and the marker cluster plus documentation I was able to piece most of this together.

I was able to add these 3 things, but I now need 1 last piece (answered out of order):

  1. add a mouseover listener to a cluster

      google.maps.event.addListener(handler.clusterer.getServiceObject(), 'mouseover', function(cluster) {
          // Convert lat/long from cluster object to a usable MVCObject
          var info = new google.maps.MVCObject;
          info.set('position', cluster.center_);
    
          var city_lat = cluster.getMarkers().shift().position.d
    
          if (city_lat !== undefined) {
            var cluster_stuff = cities_with_lat[city_lat]
    
            var infowindow = new google.maps.InfoWindow({
              content: cluster_stuff
            });
            infowindow.open(handler.map.getServiceObject(), info);
          };
      });
    
  2. cluster infowindow based on a partial (using data from the above)

I also created an object with latitudes for keys, and values with the partials.

var cities_with_lat = {
  <% @cities_for_map.each do |city| %>
    <% if city.areas.present? %>
      <% render 'map_tile', city: nil, area_info: city.areas.first %>
      <%= city.latitude %>: "<%= escape_javascript(render 'map_tile', city: nil, area_info: city.areas.first)  %>",
    <% end %>
  <% end %>
}
  1. get the markers inside the cluster (select the right object) create an infowindow for this

I then found marker and matched it with the city via the latitude key. See the above 2 code snippets.

  1. Lastly I wanted the infowindow Look and behave like the regular markers, to do this I created a new function:

    clusterMarker: function(cluster, cities_with_lat) { var city_lat = cluster.getMarkers();

    cluster_marker = new google.maps.Marker({
     map: handler.map.getServiceObject(),
     position: new google.maps.LatLng(cluster.center_.d, cluster.center_.e),
     visible: false
    });
    
    var boxText = document.createElement("div");
    boxText.innerHTML = cities_with_lat[city_lat[0].position.d];
    
    var myOptions = {
       content: boxText
      ,disableAutoPan: true
      ,closeBoxURL: ""
      ,pane: "floatPane"
      ,enableEventPropagation: false
    };
    
    ib = new InfoBox(myOptions);
    ib.open(handler.map.getServiceObject(), cluster_marker);
    _closeClusterInfowindow(ib);
    

    } };

I fed this function an object with compiled partials from a rails helper. This object was escaped and passed to javascript. This object had the latitude of the city as a key and the partial of its respective area as a value.

  var cities_with_lat = <%= cities_with_lat_obj %>;

Upvotes: 1

Related Questions