Gmaps4rails : How to change appearance of marker w

2019-08-17 09:45发布

问题:

I'm trying to get this behavior with gmaps4rails : User clicks link in the sidebar, corresponding marker on the map changes image/color in order to make the selected one stand out from the others.

I've tried with this code

Gmaps.map.callback = function(){
        var len = Gmaps.map.markers.length;
        for(var i = 0; i < len; i++){
            marker = Gmaps.map.markers[i];
            google.maps.event.addListener(marker.serviceObject, 'click', (function(i){
                return function(){
                    console.log($(Gmaps.map.markers[i].serviceObject.ne.ga).attr("src", "/assets/marker_sprite2.png"));
                }
            })(i));
        }
    }

But this changes every marker's appearance, which is not very useful for what I'm trying to do !

Is there anyway to achieve this ?

EDIT : Made it work see answer below

EDIT 2 : While this solution worked for what I wanted, I stumbled upon an other issue with this method, see comment to answer below

回答1:

You've a javascript issue. Actually, you can't make a closure with a changing counter: it will always be referenced with it's last value.

Gmaps.map.callback = function(){
  for(var i = 0; i < Gmaps.map.markers.length; i++){
    marker = Gmaps.map.markers[i];
    google.maps.event.addListener(marker.serviceObject, 'click', 
      (function(marker){
        return function(){
         console.log($(marker.serviceObject.ne.ga).attr("src", "/assets/marker_sprite2.png"));
        }
      })(marker)
    )
  }
}

Your main issue is a bit long, not complex but long. The idea is the following:

  • add an id to each marker, you could use the block argument of the to_gmaps4rails method and add some more json

  • create the sidebar yourself and add the id to each line to know which marker you want when you click the li

  • loop all markers to get the one with the proper id

  • change it's picture



回答2:

I made it work with this code :

Gmaps.map.callback = function(e){
        var len = Gmaps.map.markers.length;
        var markers = Gmaps.map.markers;
        for(var i = 0; i < len; i++){
            m = Gmaps.map.markers[i];
            google.maps.event.addListener(m.serviceObject, 'click',
                (function(m, markers){
                    return function(){
                        for(a in markers){
                            markers[a].serviceObject.setIcon("/assets/marker_sprite.png");
                        }
                        m.serviceObject.setIcon("/assets/marker_sprite2.png");
                    }
                }(m, markers))
            )
        }
    }

What's happening is we add a click listener to each marker and pass to this listener function the marker itself. I also pass in the whole markers array to reset them all on each click and then make the one I'm interested stand out. This is the simple version, my final version gives this :

 Gmaps.map.callback = function(){
        var len = Gmaps.map.markers.length;
        var markers = Gmaps.map.markers;
        var anchor = new google.maps.Point(9.5, 34);
        var sAnchor = new google.maps.Point(0, 34);
        var origin = new google.maps.Point(0, 0);
        var sOrigin = new google.maps.Point(28.5, 0);
        var size = new google.maps.Size(28.5,34);

        var markerNormal = new google.maps.MarkerImage("/assets/marker_sprite.png", size, origin, anchor);
        var markerHighlight = new google.maps.MarkerImage("/assets/marker_sprite_bleu.png", size, origin, anchor);
        var shadow = new google.maps.MarkerImage("/assets/marker_sprite.png", size, sOrigin, sAnchor);
        for(var i = 0; i < len; i++){
            m = Gmaps.map.markers[i];
            google.maps.event.addListener(m.serviceObject, 'click',
                (function(m, markers){
                    return function(){
                        console.log(m);
                        for(a in markers){
                            markers[a].serviceObject.setIcon(markerNormal);
                            markers[a].serviceObject.setZIndex(1);
                            markers[a].serviceObject.shadow = shadow;
                        }
                        Gmaps.map.map.setZoom(7);
                        m.serviceObject.setZIndex(99);
                        m.serviceObject.setIcon(markerHighlight);
                    }
                }(m, markers))
            )
        }
    }    

If you see anything that could be improved feel free to comment :)