I have an JS object where the 1st value of each key is the checkbox id, 2nd is the API where the data is and the 3rd is the color
var layers={childcares: ["#childcares",'http://127.0.0.1:8000/childcare_data/','orange'], childcare_buff: ["#childcaresbuff","http://127.0.0.1:8000/childcare_buff_data/","orange"],
religious: ["#religious","http://127.0.0.1:8000/religious_data/","blue"], religious_buff: ["#religiousbuff","http://127.0.0.1:8000/religious_buff_data/","blue"],
park: ["#parks","http://127.0.0.1:8000/park_data/","green"],park_buff: ["#parksbuff","http://127.0.0.1:8000/park_buff_data/","green"],
school: ["#schools","http://127.0.0.1:8000/school_data/","red"],school_buff: ["#schoolsbuff","http://127.0.0.1:8000/school_buff_data/","red"]
};
now I have these two functions
function color(feature, color_chosen, opacity){
return{
color: color_chosen,
fillOpacity: opacity}
};
this color one above is fairly simple and just sets the color
the legend_click one is where I am getting problems
function legend_click(id,layer_api,color_layer) {
$(id).click(function () {
var layer_add=new L.GeoJSON.AJAX(layer_api,{
style: color(layer_add,color_layer,0.8),
onEachFeature: function(feature,layer_add){
layer_add.bindPopup('<b>Buffer Type</b> = ' +feature.properties.buff+ '<br>'
+'<b>Address</b> = '+feature.properties.address+ '<br>' +'<b>Buffer Distance</b> = '+feature.properties.buff_dist)
}
}
);
if ($(id).prop('checked')==true) {
layer_add.addTo(map);
//map.fitBounds(layer_add.getBounds())
}
else if ($(id).prop('checked')==false) {
console.log('noury')
map.removeLayer(layer_add);
}
})
};
looping through the layers
like this
for (var key in layers){
console.log(layers[key])
legend_click(layers[key][0],layers[key][1],layers[key][2])
};
so in the map when I click on the checkbox the layer correctly gets added to the display but when I uncheck the checkbox is it throws NO error and prints out noury
to the console but it does not remove the layer...
2 Answers 2
As I suggested in my comment, this could be one way of doing it:
var idArray = [];
var layerArray = [];
function legend_click(id, layer_api, color_layer) {
$(id).click(function () {
var layer_add;
var i = idArray.indexOf(id);
if (i < 0) {
layer_add = new L.GeoJSON.AJAX(layer_api,{
style: color(layer_add, color_layer, 0.8),
onEachFeature: function(feature, layer_add){
layer_add.bindPopup('<b>Buffer Type</b> = ' + feature.properties.buff + '<br>'
+'<b>Address</b> = ' + feature.properties.address+ '<br>' + '<b>Buffer Distance</b> = ' +feature.properties.buff_dist)
}
}
);
layerArray.push(layer_add);
idArray.push(id);
}
else {
layer_add = layerArray[i];
};
if ($(id).prop('checked') == true) {
layer_add.addTo(map);
}
else if ($(id).prop('checked') == false) {
map.removeLayer(layer_add);
}
})
};
-
awesome this works! one thing is I don't understand why you did this
i = idArray.length - 1;
ziggy– ziggy2019年03月13日 12:39:57 +00:00Commented Mar 13, 2019 at 12:39 -
With
push
method new element is added to the end of array. Since indexes start at 0, it's index is number of array elements minus one.TomazicM– TomazicM2019年03月13日 13:16:03 +00:00Commented Mar 13, 2019 at 13:16 -
I know what its doing it just seems unnecessary because
i
is created in the scope of when the function is called...?ziggy– ziggy2019年03月13日 13:29:42 +00:00Commented Mar 13, 2019 at 13:29 -
Not when
id
is not found inidArray
andi
has conseqently negative value.TomazicM– TomazicM2019年03月13日 15:06:48 +00:00Commented Mar 13, 2019 at 15:06 -
1It looks like I need more (or less :) cofee. Of course it's not needed since it's not used after being calculated. I removed it. Thanks!TomazicM– TomazicM2019年03月13日 18:09:18 +00:00Commented Mar 13, 2019 at 18:09
This might help, it's a little different then your but works well. I use it in a sidebar or panel. Basically create a label and checkbox, in my case for the hospital layer called hosp. Note I used a "name" id.
The HTML checkbox:
<label class="container">Hospitals
<input type="checkbox" id="hosp" name="hosp" value="hosp" >
</label>
The JavaScript that adds and adds/removes the layer from the map as checked or not.
document.querySelector("input[name=hosp]").addEventListener('change', function() {
if(this.checked) map.addLayer(hosp)
else map.removeLayer(hosp)
})
remember to set the value to checked it you add it to the map on load, in my example, it's off.
Example: http://www.gistechsolutions.com/leaflet/DEMO/baseball/sports/sports.html
-
where would I initialize the geojson ajax? before this? and I set my checkbox to be unchecked when the page loadsziggy– ziggy2019年03月11日 18:35:50 +00:00Commented Mar 11, 2019 at 18:35
-
Like I said, I did it a little different than you. Here is an example and write up of what I normally do for points. gistechsolutions.com/leaflet/DEMO/Simple/indexMap1.html I define each as a separate layer, then the checkbox see's them as separate layers to turn on/off. BTW since all your data is coming from the same database, and has the same fields, you could make just one service, and use a filter to define each layer and a GetColor function to show each different colors. The extra JavaScript won't make that much difference in page display speed.Bill Chappell– Bill Chappell2019年03月11日 18:55:21 +00:00Commented Mar 11, 2019 at 18:55
-
I was originally adding them as separate layers and it worked fine -- but I was just repeating the same code over and over so that is why i wrote this function...I will have a look at your link. thanks for the suggestionsziggy– ziggy2019年03月11日 19:25:34 +00:00Commented Mar 11, 2019 at 19:25
-
Here is a 3000+ lines of code app. apps.health.ny.gov/statistics/cancer/environmental_facilities/… so you should be fine with what you are doing.Bill Chappell– Bill Chappell2019年03月11日 19:28:18 +00:00Commented Mar 11, 2019 at 19:28
map.removeLayer(layer_add);
is applied to the new layer and initial layer stays intact on the map.