Leaflet List Markers – How to Sort Items of Leaflet List Markers Plugin Control

leafletleaflet-pluginsmarkers

I'm reading shapefiles with the leaflet library. I print the list of markers on the left in a list via the Leaflet List Markers library. I should sort the list of map markers that are shown to me on the screen from the library. I tried to work on the leaflet-list-markers-js file but didn't find the way how to either sort the values into the array or how to sort the array once composed.

This piece of code I use to create the list, markersLayer is a LayerGroup:

var list = new L.Control.ListMarkers({layer: markersLayer, itemIcon: null, maxItems: 30, maxZoom: 25});

    list.on('item-mouseover', function (e) {
        e.layer.setIcon(redSelectMarker)
    }).on('item-mouseout', function (e) {
        e.layer.setIcon(transparentIcon)
    });


    myMap.addControl(list);

The following lines in the test to the methods that the library uses to update the page content list leaflet-list-markers.min.js, I have been working on this page. _updateList: adds the

  • html elements that are created with the _createItem method to the a._list list:

     _updateList: function () {
               var a = this, b = 0;
               this._list.innerHTML = "ELENCO PUNTI: ", this._layer.eachLayer(function (c) {
                   c instanceof L.Marker && a._map.getBounds().contains(c.getLatLng()) && ++b < a.options.maxItems && a._list.appendChild(a._createItem(c))
               });
           },
    
    
    _createItem: function (a) {
               var b = L.DomUtil.create("li", "list-markers-li"), c = L.DomUtil.create("a", "", b),
                   d = this.options.itemIcon ? '<img src="' + this.options.itemIcon + '" />' : "", e = this;
               return c.href = "#", L.DomEvent.disableClickPropagation(c).on(c, "click", L.DomEvent.stop, this).on(c, "click", function (b) {
                   this._moveTo(a.getLatLng())
               }, this).on(c, "mouseover", function (b) {
                   e.fire("item-mouseover", {layer: a})
               }, this).on(c, "mouseout", function (b) {
                   e.fire("item-mouseout", {layer: a})
               }, this), a.options.hasOwnProperty(this.options.label) ? c.innerHTML = d + '<span style="opacity: 1">' + a.options[this.options.label] + "</span> <b>" + this.options.itemArrow + "</b>" : console.log("propertyName '" + this.options.label + "' not found in marker"), b
           },
    
    
  • Best Answer

    You can use .include method to modify ._updateList method of L.Control.ListMarkers control by adding sort of items before displaying them in control.

    The modifying code could look like this (it has to be executed before control is used):

    L.Control.ListMarkers.include({
      _updateList: function() {
        var that = this;
        var n = 0;
        var markers = [];
    
        this._list.innerHTML = '';
        this._layer.eachLayer(function(layer) {
          if(layer instanceof L.Marker)
            if( that._map.getBounds().contains(layer.getLatLng()) )
              if(++n < that.options.maxItems) {
                markers.push(layer);
              }
        });
        markers.sort(function(a, b) {
          var diff;
          if (a.options[that.options.label] > b.options[that.options.label])
            diff = 1;
          else if (a.options[that.options.label] < b.options[that.options.label])
            diff = -1;
          else {
            diff = 0;
          }
          return diff;
        });
        markers.forEach(function(marker) {
          that._list.appendChild(that._createItem(marker));
        });
      }
    });
    

    For the above code to work, label option has to be explicitly used when defining control, even if it has the default value 'title':

    var list = new L.Control.ListMarkers({
      layer: markersLayer,
      label: 'title',
      itemIcon: null,
      maxItems: 30,
      maxZoom: 25
    });