0

I am creating a Mapbox map in which I want multiple checkboxes to create an 'and' filter on one layer.

Here's the checkbox parts of my code so far:

<input type="checkbox" id="srBox" name="srBox" value="SustainableRecreation">
<label for="srBox"> Sustainable Recreation</label><br>

<input type="checkbox" id="hlBox" name="hlBox" value="HealthyLandscapes">
<label for="hlBox"> Healthy Landscapes</label><br>

<input type="checkbox" id="ovBox" name="ovBox" value="Overnight">
<label for="ovBox"> Overnight</label><br>



var checkbox = document.getElementById('srBox');
checkbox.addEventListener('change', function() {
  if (this.checked) {
    map.setFilter('rfovProjects', ['==', ['get', 'SR'], 'Y']);
  } else {
    map.setFilter('rfovProjects', null);
  }
});

var checkbox = document.getElementById('hlBox');
checkbox.addEventListener('change', function() {
  if (this.checked) {
    map.setFilter('rfovProjects', ['==', ['get', 'HL'], 'Y']);
  } else {
    map.setFilter('rfovProjects', null);
  }
});

var checkbox = document.getElementById('ovBox');
checkbox.addEventListener('change', function() {
  if (this.checked) {
    map.setFilter('rfovProjects', ['==', ['get', 'OV'], 'Y']);
  } else {
    map.setFilter('rfovProjects', null);
  }
});

If you look at the full map example (https://codepen.io/flyinginsect2/pen/oNoQvNQ), you'll see that if you click Healthy Landscapes and then Overnight, there are a few projects that show up. However, there are no projects that are in both of these categories.

How can I combine these filters?

I have a few more that I need to add in as well.

1 Answer 1

2

To achieve combined effect of selected filters you have to create a combined filter each time one of the individual filters change.

One way to do this is to have some filters object where you set key with individual filter name to true or false, depending on it's checked state.

Then on each individual filter change you iterate over filters keys and create and set Mapbox map filter accordingly. Relevant part of the code could then look something like this:

var filters = {};

function updateFilters() {
  var compositeFilter = ['all'];
  for (let filterValue in filters) {
    if (filters[filterValue]) {
      compositeFilter.push(['==', ['get', filterValue], 'Y']);
    }
  }
  if (compositeFilter.length > 1)
    map.setFilter('rfovProjects', compositeFilter);
  else {
    map.setFilter('rfovProjects', null);
  }
}

var checkbox = document.getElementById('srBox');
checkbox.addEventListener('change', function() {
  filters['SR'] = this.checked;
  updateFilters();
});

var checkbox = document.getElementById('hlBox');
checkbox.addEventListener('change', function() {
  filters['HL'] = this.checked;
  updateFilters();
});

var checkbox = document.getElementById('ovBox');
checkbox.addEventListener('change', function() {
  filters['OV'] = this.checked;
  updateFilters();
});

If you want to have OR filter, just substitute composite filter 'all' condition with 'any'.

2
  • This worked perfectly! Thank you! I have a follow up question... When I move these checkboxes to a new div, they stop working (codepen.io/flyinginsect2/pen/QWOJqRq). Do you have any thoughts on why that might be? Thanks!
    – Melissa
    Commented Mar 1, 2022 at 17:51
  • Check you browser debugger console to find out why it's not working.
    – TomazicM
    Commented Mar 1, 2022 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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