Home > Software design >  Custom leaflet control with an onchange event listener - do you pass the name of the layer or the le
Custom leaflet control with an onchange event listener - do you pass the name of the layer or the le

Time:03-02

While making a tabbed control menu for Leaflet I've set the ID of the checkbox to the name of the group, I then call that ID into a function which is part of the onclick for an input.

When I call it with me.id, as below, I get a

 leaflet.js:2361 Uncaught Error: The provided object is not a Layer.
at i.addLayer (leaflet.js:2361:28)
at i.addLayer (leaflet.markercluster.layersupport.js:6:6275)
at RgnCtrlChk (index.html:1217:7)
at HTMLInputElement.onclick (VM18957 -1.859:1224:25)

Or similarly Cannot create property '_leaflet_id' on string custom control depending on the method I use

When I call it with this._leaflet_id I get

 leaflet.markercluster.layersupport.js:6 Uncaught TypeError: Cannot read properties of undefined (reading '_mcgLayerSupportGroup')
at i.addLayer (leaflet.markercluster.layersupport.js:6:6203)
at RgnCtrlChk (index.html:1217:7)
at HTMLInputElement.onclick (VM18921 -2.090:1224:25)

I don't know if it is through me using the names of the layers which aren't how they are called in Leaflet or if I am completely missing it.

My code is as follows: For the if/else remove/add layer called in onclick

 function RgnCtrlChk(me) {
    if(map.hasLayer(me.id)){
    map.removeLayer(me.id);
    console.log(me.id)
    }else{
    map.addLayer(me.id);
    console.log(me.id);
    }};

and then this is created in a populated checkbox list from the names of the layers as defined previously, but maybe not using the names that Leaflet uses?

var cats = ["Development","Regeneration","Health and Equality","Strategy","Transport","MultipleDeliverables"];
        var catslayers = ["DevelopmentGrp","RegenerationGrp","HealthAndEqualityGrp","StrategyGrp","TransportGrp","MultipledeliverablesotherGrp"]

        for (var i = 0; i < cats.length; i  ) {
            var label = document.createElement('label');
                label.id = cats[i];
                tabCtrlPane2SectionDiv.appendChild(label);
                var div = document.createElement('div');
                label.appendChild(div);
                    var checkbox = document.createElement('input');
                    checkbox.id = catslayers[i];
                    checkbox.type = "checkbox";
                    checkbox.setAttribute("class","leaflet-control-layers-selector");
                    checkbox.setAttribute("onclick","return RgnCtrlChk(this)");
                    div.appendChild(checkbox);
                    var span = document.createElement('span');
                    div.appendChild(span);
                        span.appendChild(document.createTextNode(cats[i]));
                    }

Is there an easier way to do this without messing with the private _leaflet_id?

EDIT:

Then, when calling the layers variable first

var layer = map._layers.mcg[me.id];
        
        if(map.hasLayer(layer)){
        console.log(layer);
        map.removeLayer(layer);
        }else{
        map.addLayer(layer);
        console.log(layer);
        }};

throws up this error - which I presumed was because due to the presence of grouping from MarkerCluster/LayerSupport where it was called earlier?

leaflet.markercluster.layersupport.js:6 Uncaught TypeError: Cannot read properties of undefined (reading '_mcgLayerSupportGroup')
    at i.addLayer (leaflet.markercluster.layersupport.js:6:6203)
    at RgnCtrlChk (index.html:1220:7)
    at HTMLInputElement.onclick (VM20824 0.2204:1226:25)

The aforementioned code where the mcg group was created and the layers are checked

var mcg = L.markerClusterGroup.layerSupport().addTo(map),
            control2 = L.control.layers(null, null, {collapsed: false}),
            RegionCtrl = L.control.layers(null, null, {collapsed: false});

        mcg.checkIn([
            DevelopmentGrp,
            HealthAndEqualityGrp,
            RegenerationGrp,
            MultipledeliverablesotherGrp,
            TransportGrp,
            StrategyGrp
            ]);

Upon appending the subgroup to map._layers.mcg[me.id]; the group itself isn't defined making me think I'm not calling it correctly?

index.html:1214 Uncaught TypeError: Cannot read properties of undefined (reading 'DevelopmentGrp')
    at RgnCtrlChk (index.html:1214:31)
    at HTMLInputElement.onclick (VM20752 0.2135:1226:25)

CodePudding user response:

You need first to get the layer befor you can use hasLayer, addLayer and removeLayer:

var layer = map._layers[YOUR_LEAFLET_ID]

The function would look like:

function RgnCtrlChk(me) {
    var layer = map._layers[me.id];

    if(map.hasLayer(layer)){
        map.removeLayer(layer);
        console.log(layer)
    }else{
        map.addLayer(layer);
        console.log(layer);
    }
}

But what I not understand how you get the leafletId from the html element "return RgnCtrlChk(this)".

Is there an easier way to do this without messing with the private _leaflet_id?

The public function for the Leaflet id is L.stamp(object)

CodePudding user response:

Upon instead of sending the clicked checkbox via JavaScript taking a jQuery approach worked well.

$(".p2input").change(function(){
        var layerClicked = window[$(this).attr("id")];
            console.log(layerClicked);
        if(map.hasLayer(layerClicked)){
            map.removeLayer(layerClicked);
        }else{
            map.addLayer(layerClicked);
          }});
  • Related