5

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());
}
}

1 Answer 1

9

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

3
  • That worked perfectly, thank you so much. One additional question, how would you implement that when the marker is highlighted and you click it again to set the default marker? Commented Jan 27, 2015 at 17:32
  • In the click handler before executing the removeHighlight function, check if a highlight is set, if so, store the id of the highlighted marker. Then execute the removeHighlight method. Wrap the setIcon method and the assignment of the highlight variable in a condional block, where you check if the previous id does not equal the id of the clicked marker. If it doesn't equal, set the highlight, else do nothing. Here's fork of the Plunker demonstrating that: plnkr.co/edit/aqiImS?p=preview
    – iH8
    Commented Jan 27, 2015 at 17:47
  • Great! Thank you so much for taking your time and explaining. got ti working as I wanted with jQuery Birdseye. Commented Jan 27, 2015 at 18:00

Not the answer you're looking for? Browse other questions tagged or ask your own question.