Filter Feature Layer by Multiple Button Clicks

2745
4
Jump to solution
11-08-2013 04:38 AM
GeoffSchwitzgebel
New Contributor
In my application I have a few filters (as buttons) that are currently applying a definition query to a feature layer.  Currently you can only select one button at a time and add one definition query.  Is there a preferred method to incorporating multiple button clicks into a single feature layer query? I feel like this may need to be done with a graphics layer and not against a feature layer.

Each button click has the following callback but I need to apply both of these clicks/queries to the resulting map features :
                function executeHandicapQuery(handicapBtn) {                     map.graphics.clear();                     map.infoWindow.hide();                     elm = dojo.byId('handicapBtn');                     str = "Yes";                     query.where = "HANDICAPACCESS = '" + str + "'";                     queryTask.execute(query, showResults);                     populateGrid(Memory, query.where);//populate dgrid with results                     fl.setDefinitionExpression(query.where);                 }                 function executeRestroomQuery(restroomBtn) {                     map.graphics.clear();                     map.infoWindow.hide();                     elm = dojo.byId('restroomBtn');                     str = "Yes";                     query.where = "RESTROOMS = '" + str + "'";                     queryTask.execute(query, showResults);                     populateGrid(Memory, query.where);//populate dgrid with results                     fl.setDefinitionExpression(query.where);                 }


These functions are then passed to the showResults function and zoom to the result extent:
                function showResults(featureSet) {                     //map.graphics.clear();//clear graphics from map                     map.infoWindow.hide();//hide infowindow                                    var resultFeatures = featureSet.features;//Performance enhancer - assign featureSet array to a single variable.                     for (var i = 0, il = resultFeatures.length; i < il; i++) {//loop through all features                         if (resultFeatures.length == 1) {                             var graphic = resultFeatures;                             graphic.setSymbol(symbol);                             //Set the infoTemplate.                             //graphic.setInfoTemplate(infoTemplate);                             //Add graphic to the map graphics layer.                             nameGraphic = map.graphics.add(graphic);                             var thePoint = resultFeatures[0].geometry;                             map.centerAndZoom(thePoint, 5);                         }                         else if (resultFeatures.length > 1) {                             graphic = resultFeatures                             var extent = esri.graphicsExtent(graphic);                             map.setExtent(extent); //use to get whole extent//map.setExtent(extent.expand(3));                          }                         else {                             var myFeatureExtent = esri.graphicsExtent(resultFeatures);                             map.setExtent(myFeatureExtent);                         }                         //msg = "Selected Features:" + "\n" + resultFeatures.length                         //document.getElementById('rightPane').innerHTML = msg;                     }                    }


Thanks,
Geoff
0 Kudos
1 Solution

Accepted Solutions
JasonZou
Occasional Contributor III
Geoff, it's not hard to incorporate multiple filter options. Here is the sample code just showing the idea.

var filter = "";  function executeHandicapQuery(handicapBtn) {     map.graphics.clear();     map.infoWindow.hide();     elm = dojo.byId('handicapBtn');     str = "Yes";      var where = "HANDICAPACCESS = '" + str + "'";     filter = filter ? filter + " AND " + where : where;     query.where = filter;     queryTask.execute(query, showResults);     populateGrid(Memory, query.where); //populate dgrid with results     fl.setDefinitionExpression(query.where); }  function executeRestroomQuery(restroomBtn) {     map.graphics.clear();     map.infoWindow.hide();     elm = dojo.byId('restroomBtn');     str = "Yes";      var where = "RESTROOMS = '" + str + "'";     filter = filter ? filter + " AND " + where : where;     query.where = filter;     queryTask.execute(query, showResults);     populateGrid(Memory, query.where); //populate dgrid with results     fl.setDefinitionExpression(query.where); }


But quickly you will ask another question: I don't want to keep adding the filters. I want to have the freedom to decide how to form the filter freely. In that case, I'd suggest you using checkbox group instead of buttons. The user can build the filter by checking/unchecking each filter option. Here is just the general idea, not a working code.

HTML:
<div class="filterOptionContainer">     <input type="checkbox" id="filter1" class="clsFilter" />     <input type="checkbox" id="filter2" class="clsFilter" />     <button type="button" onclick="onFilterClick">Filter</button> </div>


JS:
var filter = ""; var whereClause = {   filter1: "HANDICAPACCESS = 'Yes'",   filter2: "RESTROOMS = 'Yes'" };  function onFilterClick() {     map.graphics.clear();     map.infoWindow.hide();     filter = "";      // dojoQuery is the alias of module dojo/query     dojoQuery(".clsFilter").forEach(function(aFilterNode) {         if (aFilterNode.checked) {             filter += filter ? " AND " + whereClause[aFilterNode.id] : whereClause[aFilterNode.id];         }     }));      query.where = filter;     queryTask.execute(query, showResults);     populateGrid(Memory, filter); //populate dgrid with results     fl.setDefinitionExpression(filter); }

View solution in original post

4 Replies
JasonZou
Occasional Contributor III
Geoff, it's not hard to incorporate multiple filter options. Here is the sample code just showing the idea.

var filter = "";  function executeHandicapQuery(handicapBtn) {     map.graphics.clear();     map.infoWindow.hide();     elm = dojo.byId('handicapBtn');     str = "Yes";      var where = "HANDICAPACCESS = '" + str + "'";     filter = filter ? filter + " AND " + where : where;     query.where = filter;     queryTask.execute(query, showResults);     populateGrid(Memory, query.where); //populate dgrid with results     fl.setDefinitionExpression(query.where); }  function executeRestroomQuery(restroomBtn) {     map.graphics.clear();     map.infoWindow.hide();     elm = dojo.byId('restroomBtn');     str = "Yes";      var where = "RESTROOMS = '" + str + "'";     filter = filter ? filter + " AND " + where : where;     query.where = filter;     queryTask.execute(query, showResults);     populateGrid(Memory, query.where); //populate dgrid with results     fl.setDefinitionExpression(query.where); }


But quickly you will ask another question: I don't want to keep adding the filters. I want to have the freedom to decide how to form the filter freely. In that case, I'd suggest you using checkbox group instead of buttons. The user can build the filter by checking/unchecking each filter option. Here is just the general idea, not a working code.

HTML:
<div class="filterOptionContainer">     <input type="checkbox" id="filter1" class="clsFilter" />     <input type="checkbox" id="filter2" class="clsFilter" />     <button type="button" onclick="onFilterClick">Filter</button> </div>


JS:
var filter = ""; var whereClause = {   filter1: "HANDICAPACCESS = 'Yes'",   filter2: "RESTROOMS = 'Yes'" };  function onFilterClick() {     map.graphics.clear();     map.infoWindow.hide();     filter = "";      // dojoQuery is the alias of module dojo/query     dojoQuery(".clsFilter").forEach(function(aFilterNode) {         if (aFilterNode.checked) {             filter += filter ? " AND " + whereClause[aFilterNode.id] : whereClause[aFilterNode.id];         }     }));      query.where = filter;     queryTask.execute(query, showResults);     populateGrid(Memory, filter); //populate dgrid with results     fl.setDefinitionExpression(filter); }
GeoffSchwitzgebel
New Contributor
Thanks Jason.  I'll start incorporating the check boxes as a starting point to get things functioning.  I know this will be helpful.  However the final product for this application will have to use buttons that will be "pressed" as the user chooses each filter.  I'll then add in a button to reset all of the filters.  See the screenshot below.  Right now only one can be selected at a time.

Thanks,
Geoff
0 Kudos
JasonZou
Occasional Contributor III
If you like to use button, then try to use dijit/form/ToggleButton. It has the button's look-n-feel, and function like a checkbox.
0 Kudos
GeoffSchwitzgebel
New Contributor
Thanks for the link to the ToggleButton.  I'm going to try and use this.  Meanwhile I was able to get the checkoxes working properly.  Here is the working javascript function.  I wasn't sure how to remove the first "and" out of the where clause so I just stripped out the unnecessary string.
                function onFilterClick() {
                    map.graphics.clear();
                    map.infoWindow.hide();
                    filter = [];

                    // dojoQuery is the alias of module dojo/query
                    dojo.query(".clsFilter").forEach(function (aFilterNode) {
                        if (aFilterNode.checked) {
                            //filter += " AND " + whereClause[aFilterNode.id]
                            filter += filter ? " AND " + whereClause[aFilterNode.id] : whereClause[aFilterNode.id];
                        }              
                    });
                    
                    query.where = filter.substr(5);
                    queryTask.execute(query, showResults);
                    //lstrip(s, chars)
                    populateGrid(Memory, query.where); //populate dgrid with results
                    fl.setDefinitionExpression(query.where);
                };


Thanks again,
Geoff
0 Kudos