How to highlight marker on click with leaflet and jQuery Birdseye

Pascal vant picture Pascal vant · Jan 27, 2015 · Viewed 9.2k times · Source

I'm very new with leaflet, trying to duplicate the function on foursquare, highlight the clicked marker and reset it to the original maker when map is clicked or if another marker is selected and highlighted.

I'm using jQuery Birdseye (http://ajb.github.io/jquery-birdseye/) to learn and get some kind of interactive map going. I changed the numbered marker icon to a numbered marker sprite.The sprite works fine, and the position is controlled by the pin (0=blue, 1=highlighted, blue, 2=orange, 3= highlighted orange) and "state" inside L.marker. I know the new_marker click function only sets the targeted marker to highlighted. have not been able to find a solution to reproduce the function as on the foursquare map to highlight the marker when clicked. Please point me into the right direction.

L.NumberedDivIcon = L.Icon.extend({
  options: {
    sprite:"images/mappin-sprite.png",
    number: '',
    iconSize: new L.Point(29, 39),
    iconAnchor: new L.Point(15, 37),
    gridSize: new L.Point(35, 45),
    popupAnchor: new L.Point(0, -33),
    shadowUrl:"images/mappin-shadow.png",
    shadowSize:new L.Point(29, 15),
    shadowAnchor:new L.Point(15, 10),
    state: ''
  },

  createIcon: function () {
    var div = document.createElement('div');
    div.style.backgroundImage="url("+this.options.sprite+")";
    div.className="leaflet-marker-icon";
    div.style.marginLeft=-this.options.iconAnchor.x+"px";
    div.style.marginTop=-this.options.iconAnchor.y+"px";
    var b=this.options.gridSize||this.iconSize;
    var c=this.options['number'] || '';
var cd=this.options['state'] || '';


    var d= this.options.gridSize.y+this.options.iconSize.y+cd;

div.style.backgroundPosition=-(c*b.x+(b.x-this.options.iconSize.x)/2)+"px "+-(d*b.y+(b.y-this.options.iconSize.y)/2)+"px";

    this._setIconStyles(div, 'icon');
    return div;
  },

  //you could change this to add a shadow like in the normal marker if you really wanted
  createShadow: function () {
    var a=this.options.shadowSize;
    var img = this._createImg(this.options['shadowUrl']);
    img.style.marginLeft=-this.options.shadowAnchor.x+"px";
    img.style.marginTop=-this.options.shadowAnchor.y+"px";
    img.style.width=a.x+"px",img.style.height=a.y+"px";
    img.className="leaflet-marker-icon";

    return img;
  }
});

Marker code jQuery Birdseye

processResults = function(results) {
        var marker, _i, _len;
        settings.results_el.html('');
        for (_i = 0, _len = markers.length; _i < _len; _i++) {
          marker = markers[_i];
          map.removeLayer(marker);
        }
        if (results.length > 0) {

          return $(results).each(function(key, result) {
            var new_marker;

            if (result.women == true) {
            var pin = 2;
          }
          else
          {
            var pin = 0;
          }

            new_marker = L.marker(settings.response_params_latlng(result),{
              icon: new L.NumberedDivIcon({
                number: key,
                state: pin
              })
            });

            function setHighlightIcon(e) {
              new_marker = e.target;
var pinselected = pin+1;

                new_marker.setIcon(new L.NumberedDivIcon({number: key, state:pinselected}));
                new_marker.setZIndexOffset(+100)
    }

function setDefaultIcon() {
var pindeselected = pin;              
new_marker.setIcon(new L.NumberedDivIcon({number: key, state: pindeselected}));  
   }

new_marker.on({
    'click': setHighlightIcon
});

   markers.push(new_marker.addTo(map));

   return settings.results_el.append(settings.results_template(key, result));
          })
} else {
   return settings.results_el.append(settings.no_results_template());
}
}

Answer

iH8 picture iH8 · Jan 27, 2015

You could use a variable to keep track of the highlighted marker. In the click handler for each marker, you would first need to check if a marker is already assigned to that variable, if so, remove the highlight and remove the marker from the variable, then highlight the new marker and assign the marker to the variable. You would also need to set an onclick handler on the map, which checks if the variable is assigned to a marker, then remove the highlight and remove the marker from the variable.

An example in code:

// Default map
var map = L.map('map', {
  'center': [0, 0],
  'zoom': 0,
  'layers': [
    L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      'attribution': 'Map data &copy; OpenStreetMap contributors'
    })
  ]
});

// Custom icon class without iconUrl
var customIcon = L.Icon.extend({
  options: {
    shadowUrl: 'http://leafletjs.com/docs/images/leaf-shadow.png',
    iconSize: [38, 95],
    shadowSize: [50, 64],
    iconAnchor: [22, 94],
    shadowAnchor: [4, 62],
    popupAnchor: [-3, -76]
  }
});

// Some positions for creating markers
var positions = [
  [0, 120],
  [0, 60],
  [0, 0],
  [0, -60],
  [0, -120]
];

// Function for getting new default icon
function getDefaultIcon() {
  return new customIcon({
    iconUrl: 'http://leafletjs.com/docs/images/leaf-green.png'
  });
}

// Function for getting new highlight icon
function getHighlightIcon() {
  return new customIcon({
    iconUrl: 'http://leafletjs.com/docs/images/leaf-red.png'
  });
}

// Variable to keep track of highlighted marker
var highlight = null;

// Function for removing highlight 
function removeHighlight() {
  // Check for highlight
  if (highlight !== null) {
    // Set default icon
    highlight.setIcon(getDefaultIcon());
    // Unset highlight
    highlight = null;
  }
}

// Loop over positions
positions.forEach(function(position) {

  // Create new marker
  var marker = L.marker(position, {
    // Set default icon
    icon: getDefaultIcon()
  })

  // Marker click
  marker.on('click', function() {
    // Remove highlight
    removeHighlight();
    // Set highlight icon
    marker.setIcon(getHighlightIcon());
    // Assign highlight
    highlight = marker;
  });

  // Add marker to map;
  marker.addTo(map);

});

// Add map click handler, remove highlight
map.on('click', removeHighlight);
body {
  margin: 0;
}
html,
body,
#map {
  height: 100%;
}
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.css" data-require="[email protected]" data-semver="0.7.3" />
<link rel="stylesheet" href="style.css" />
<div id="map"></div>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.js" data-require="[email protected]" data-semver="0.7.3"></script>

Here's the working example on Plunker: http://plnkr.co/edit/K9XmMz?p=preview