Overview
You will learn: how to build an app to use client-side and server-side SQL and spatial expressions to limit data displayed.
Applications can perform server-side or client-side SQL and spatial filters to access and display data from feature layers. The source
data for a feature layer can be hosted on
Server-side Filters: To access a subset of the data from the server without adding the feature layer to a map, you can set the
definitionExpression
(SQL expression) on aFeatureLayer
object.Client-side Filters: To access a subset of data on the client, you have to add the feature layer to a map first, and then set the filter property on a FeatureLayerView object. The filter can be both a SQL and a spatial expression. Client-side filters execute very quickly.
One of the key differences between server-side and client-side filtering is that client-side filtering is only possible after the feature layer is added to a map and the attributes are present. To learn how to access and display data using a query, visit the Query a feature layer tutorial.
In this tutorial, you will apply server-side and client-side SQL filters to the Trails feature layer.
Click the options below to apply filters.
Steps
Create a starter app
Open the JavaScript Starter App on CodePen.
In CodePen, click Fork and save the pen as
ArcGIS JavaScript Tutorials: Filter a feature layer
.
Add a feature layer
Create a feature layer for the trails and add it to the map.
In the
require
statement, add a reference to the FeatureLayer module.require([ "esri/Map", "esri/views/MapView", "esri/layers/FeatureLayer" ],function(Map, MapView, FeatureLayer
At the end of the code in the main
function
, create a FeatureLayer and set theurl
to access the Trails (Styled) feature layer, theoutputFields
to return all fields and values, and thepopupTemplate
to show the trail name and the elevation gain value in the popup content. Add the layer to the map.var featureLayer = new FeatureLayer({ url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails_Styled/FeatureServer/0", outFields: ["*"], // Return all fields so it can be queried client-side popupTemplate: { // Enable a popup title: "{TRL_NAME}", // Show attribute value content: "The trail elevation gain is {ELEV_GAIN} ft." // Display in pop-up } }); map.add(featureLayer);
Create SQL expressions
Define a list of SQL expressions and use the list to generate a
Select
HTML element with an option for each expression. Add the element to thetop-right
of the view.var sqlExpressions = ["TRL_ID = 0", "TRL_ID > 0", "USE_BIKE = 'Yes'", "USE_BIKE = 'No'", "ELEV_GAIN < 1000", "ELEV_GAIN > 1000", "TRL_NAME = 'California Coastal Trail'"]; var selectFilter = document.createElement("select"); selectFilter.setAttribute("class", "esri-widget esri-select"); selectFilter.setAttribute("style", "width: 275px; font-family: Avenir Next W00; font-size: 1em;"); sqlExpressions.forEach(function(sql){ var option = document.createElement("option"); option.value = sql; option.innerHTML = sql; selectFilter.appendChild(option); }); view.ui.add(selectFilter, "top-right");
Run the code and test out the select element and the different query options.
NOTE: No filter has been applied so all of the data will be displayed.
Apply a server-side filter
You can apply a server-side filter to limit the features returned from a feature layer by setting the definitionExpression
.
Create a function that sets the
definitionExpression
for a feature layer.function setFeatureLayerFilter(expression) { featureLayer.definitionExpression = expression; }
Add an event handler to the
selectFilter
element to get the selected sql expression and call thesetFeatureLayerFilter
function.selectFilter.addEventListener('change', function (event) { setFeatureLayerFilter(event.target.value); });
Run the code and select the different query options to filter the features in the layer.
Apply a client-side filter
You can apply a client-side filter by filtering the FeatureLayerView after the features have been loaded and the FeatureLayerView is ready. This type of filtering allows you to apply both SQL expressions and spatial relationship operators, and is often faster than a server-side filter.
Create a function that gets a
FeatureLayerView
and applies afilter
with the SQL expression when the layer is ready.function setFeatureLayerViewFilter(expression) { view.whenLayerView(featureLayer).then(function(featureLayerView) { featureLayerView.filter = { where: expression }; }); }
Comment out the
setFeatureLayerFilter
function and call thesetFeatureLayerViewFilter
function passing it in the selected sql expression.selectFilter.addEventListener('change', function (event) { // setFeatureLayerFilter(event.target.value); setFeatureLayerViewFilter(event.target.value); });
Run the code and select the different query options to filter the layer features. Click on features to show the pop-up information.
Congratulations, you're done!
Your app should look something like this.
Challenge
Style the excluded features
When a feature layer is filtered, only the features that match the criteria will be displayed. If you want to show the "excluded" features for reference, you can set the effect
property on the FeatureLayerView
. This property requires a filter
and an excludedEffect
, which will be used to style and draw the excluded features.
Update the filter with the code below to show the excluded features with 50% opacity.
function setFeatureLayerViewFilter(expression) {
view.whenLayerView(featureLayer).then(function(featureLayerView) {
//*** UPDATE ***//
// featureLayerView.filter = {
// where: expression
// };
featureLayerView.effect = {
filter: {
where: expression
},
excludedEffect: "opacity(50%)"
}
});
}
Find and highlight features
Another form of filtering is to use the hitTest
method on the view
to find features at a given screen location. After the view
and FeatureLayerView
are ready, use hitTest
to find and highlight
features the cursor is over. hitTest
returns features for all visible layers, so it is necessary to filter the results for the layer of interest.
NOTE: Highlighting features does not add new graphics to the map, it simply highlights the feature as part of the FeatureLayerView
. The highlightOptions
property can be used to change the color used to highlight the feature.
Add the following code to highlight features as the cursor moves.
var highlight;
view.whenLayerView(featureLayer).then(function(featureLayerView) {
view.on("pointer-move", function(event){
view.hitTest(event).then(function(response){
// Only return features for the feature layer
var feature = response.results.filter(function (result) {
return result.graphic.layer === featureLayer;
})[0].graphic;
if (highlight) {
highlight.remove();
}
// Highlight feature
highlight = featureLayerView.highlight(feature);
});
});
});