1

I am trying to filter my geoJSON layer (school) based on those properties:

  1. Type ( primary - preparatory - high )
  2. Time ( day - night - alltime )
  3. Gender ( male - female )

What I need : After user choose the properties and click the filter button school appear depend on the the properties.

But that happens: Filter button works just with "Type ( primary - preparatory - high )" and if I uncheck other properties There is no effect

This photo for map and chekbox

enter image description here

All Code in

codepen : https://codepen.io/A_Abdelwahed/pen/BaKJEGy

jsfiddle : https://jsfiddle.net/Ahmed_Abdelwahed/0yxtoh8w/

HTML code for input

<label> School type</label><br>
<input type='checkbox' name='fltschooltype' value='primary' checked>primary<br>
<input type='checkbox' name='fltschooltype'  value='preparatory' checked>preparatory<br>
<input type='checkbox' name='fltschooltype'  value='high' checked>high<br><br>

<label> School time</label><br>
<input type='checkbox' name='fltschooltime' value='day' checked>day<br>
<input type='checkbox' name='fltschooltime'   value='night' checked>night<br>
<input type='checkbox' name='fltschooltime'   value='all-time' checked>all time<br><br>

<label> School gender</label><br>
<input type='checkbox' name='fltschoolgender'   value='male' checked>male<br>
<input type='checkbox' name='fltschoolgender'   value='female' checked>female<br>

<button id="btnProjectFilter" >Filter</button>

Script code is

var schoolLayer = L.geoJson(schoolGeoJson, {
    pointToLayer: schoolMarker,
    filter: filterhotels
}).addTo(map);

function filterhotels(json) {
    var schooltypeFilter = [];
    $("input[name=fltschooltype]").each(function () {
        if (this.checked) {
            schooltypeFilter.push(this.value);
        }
    });
    $("input[name=fltschooltime]").each(function () {
        if (this.checked) {
            schooltypeFilter.push(this.value);
        }
    });

    $("input[name=fltschoolgender]").each(function () {
        if (this.checked) {
            schooltypeFilter.push(this.value);
        }
    });

    var att = json.properties;
    switch (att.Type) {
        case "primary":
            return (schooltypeFilter.indexOf('primary') >= 0);
            break;
        case "preparatory":
            return (schooltypeFilter.indexOf('preparatory') >= 0);
            break;
        case "high":
            return (schooltypeFilter.indexOf('high') >= 0);
            break;
    }

    var att = json.properties;
    switch (att.Time) {
        case "day":
            return (schooltypeFilter.indexOf('day') >= 0);
            break;
        case "night":
            return (schooltypeFilter.indexOf('night') >= 0);
            break;
        case "all-time":
            return (schooltypeFilter.indexOf('all-time') >= 0);
            break;
    }

    var att = json.properties;
    switch (att.Gender) {
        case "male":
            return (schooltypeFilter.indexOf('male') >= 0);
            break;
        case "female":
            return (schooltypeFilter.indexOf('female') >= 0);
            break;
    }
}
$("#btnProjectFilter").click(function () {
    schoolLayer.clearLayers();
    schoolLayer.addData(schoolGeoJson);

});
2

This is not really a GIS question, but pure JS one, but anyway ...

In your filter logic you return true/false value immediately when first condition is satisfied, and so the other two conditions remain untested. You also don't need switch statement for attribute values, attribute value can be directly used in .indexOf(...) array method.

Your filter should then look something like this:

function filterhotels (json) {
  var schooltypeFilter = [];
  $("input[name=fltschooltype]").each(function(){
    if (this.checked) {
      schooltypeFilter.push(this.value);
    }
  }); 

  $("input[name=fltschooltime]").each(function(){
    if (this.checked) {
      schooltypeFilter.push(this.value);
    }
  }); 

  $("input[name=fltschoolgender]").each(function(){
    if (this.checked) {
      schooltypeFilter.push(this.value);
    }
  }); 

  var att = json.properties;
  var cond1 = (schooltypeFilter.indexOf(att.Type) >= 0);
  var cond2 = (schooltypeFilter.indexOf(att.Time) >= 0);
  var cond3 = (schooltypeFilter.indexOf(att.Gender) >= 0);
  
  return(cond1 & cond2 & cond3);
}
| improve this answer | |
  • I really appreciate your help. Many thanks for the clear explanation and your time – Ahmed Sep 8 at 5:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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