olliekav
olliekav

Reputation: 165

Leaflet: Use dynamic filters in GeoJSON layer

I've got this pretty close but I'm struggling to understand how to pass multiple user submitted form checkbox values through to the Leaflet geoJSON filter function and only display those points.

user checkboxes

What I have so far...

$('#map-filters').on("submit", function(e){
    e.preventDefault();
    map.spin(true,spinOpts);
    submittedValues = $(this).serializeArray();
    var filteredLocations = L.markerClusterGroup({ chunkedLoading: true }),
        filteredLocationsAjax = new L.GeoJSON.AJAX(Routes.filtered_locations_path({format: 'json'}), {
          style: style,
          pointToLayer: pointToLayer,
          onEachFeature: onEachFeature,
          filter: function(feature, layer) {
            if(submittedValues.length <= 1) {
              return feature.properties[submittedValues[0].value];
            } else {
              How do I return multiple values?
            }
          }
        });
    filteredLocationsAjax.on('data:loaded', function () {
      map.removeLayer(allLocations);
      filteredLocations.addLayer(filteredLocationsAjax);
      map.addLayer(filteredLocations);
      map.spin(false);
    });
  });

And an example of my geoJSON...

{
  type: "Feature",
  geometry: {
  type: "Point",
  coordinates: [
    "-76.286955",
    "45.335969"
  ]
},
  properties: {
    id: 2,
    name: "Mississippi River",
    body_of_water: null,
    url: "http://0.0.0.0:5000/locations/2",
    observations_count: 1,
    ph: true,
    water_temperature: true,
    oxygen: true,
    phosphates_threshold: true,
    clarity: true,
    nitrites: true,
    nitrates: true,
    issues_count: 3,
    water_quality: true,
    algae: true
  }
}

This works fine if the user has only submitted one checkbox, the map filters exactly how I want. But how would I pass multiple values to this?

I've seen people suggest using...

return (feature.properties[value] && feature.properties[value])

But how would I pass multiple values into a return statement like that, as the user could select 1 or 20 checkboxes.

Upvotes: 3

Views: 4693

Answers (1)

ghybs
ghybs

Reputation: 53185

If I understand correctly, you should just loop through all your submittedValues array items and perform your test.

E.g. you could use submittedValues.every() to test that every checked box value is true for the given feature:

filter: function (feature, layer) {
  return submittedValues.every(function (element) {
    return feature.properties[element.value];
  });
}

Of course you could do exactly the same with a classic for loop:

filter: function (feature, layer) {
  for (var i = 0; i < submittedValues.length; i += 1) {
    if (!feature.properties[submittedValues[i].value]) {
        return false;
    }
  }
  return true;
}

Upvotes: 6

Related Questions