I was curious if anyone can tell me why the Grade filter doesn't actually filter out the user-selected Grade? The
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>
MOS Status - Test
</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.18/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.18/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#grade-filter{
height: 315px;
width: 150%;
visibility: hidden;
}
.grade-item {
width: 100%;
padding: 12px;
text-align: center;
vertical-align: baseline;
cursor: pointer;
height: 40px;
}
.grade-item:focus {
background-color: dimgrey;
}
.grade-item:hover {
background-color: dimgrey;
}
#major-command-filter{
height: 315px;
width: 150%;
visibility: hidden;
}
.majorCommand-item {
width: 100%;
padding: 12px;
text-align: center;
vertical-align: baseline;
cursor: pointer;
height: 40px;
}
.majorCommand-item:focus {
background-color: dimgrey;
}
.majorCommand-item:hover {
background-color: dimgrey;
}
.esri-editor .esri-item-list__scroller {
max-height: 350px;
}
#info {
padding: 14px;
border-radius: 5px;
width: 25%;
}
</style>
<script>
require([
"esri/Map",
"esri/layers/FeatureLayer",
"esri/form/FormTemplate",
"esri/widgets/Editor",
"esri/views/MapView",
"esri/widgets/Expand",
"esri/popup/content/TextContent",
], function (
Map,
FeatureLayer,
FormTemplate,
Editor,
MapView,
Expand,
TextContent,
) {
const editThisAction = {
title: "Edit feature",
id: "edit-this",
className: "esri-icon-edit",
};
let editor, features, majorCommandView, gradeView;
// Create a popTemplate
const template = {
title: "MOS Vacancy: {mos}",
content:
"<ul><li>Grade: <b>{grade}</b></li>" +
"<li>Unit: <b>{unit}</b></li>" +
"<li>Major Command: <b>{macom}</b></li>" +
"<li>City: <b>{city}</b></li><ul>",
actions: [editThisAction],
};
// Create a map from the referenced webmap item id
const featureLayer = new FeatureLayer({
url:
"https://ncguardview.nc.gov/server/rest/services/Hosted/test/FeatureServer/0",
outFields: ["*"],
displayField: "mod",
popupTemplate: template,
formTemplate: {
title: "NCNG MOS Vacancy",
description: "Provide information for MOS Vacancy",
elements: [
{
// Autocasts to new GroupElement
type: "group",
label: "Military Occupation Specaility",
//description: "Field inspector information",
elements: [
{
// Autocasts to new FieldElement
type: "field",
fieldName: "mos",
label: "MOS",
},
{
type: "field",
fieldName: "series",
label: "MOS Branch",
},
{
type: "field",
fieldName: "jobtitle",
label: "MOS Job Title",
},
{
type: "field",
fieldName: "grade",
label: "MOS Grade",
},
],
}, // end of first group element
{
type: "group",
label: "Unit",
elements: [
{
type: "field",
fieldName: "unit",
label: "Unit",
},
{
type: "field",
fieldName: "battalion",
label: "Battalion",
},
{
type: "field",
fieldName: "macom",
label: "Major Command",
},
],
}, // End of Second Group
{
type: "group",
label: "Location",
elements: [
{
type: "field",
fieldName: "address",
label: "Unit Address",
},
{
type: "field",
fieldName: "city",
label: "Unit City",
},
{
type: "field",
fieldName: "county",
label: "Unit County",
},
],
}, // End of Second Group,
],
},
});
// Create the Map
const map = new Map({
basemap: "streets-night-vector",
layers: [featureLayer]
});
//map.add(featureLayer);
const view = new MapView({
container: "viewDiv",
map: map,
zoom: 6,
center: [-79, 35],
});
///////////////////////////////////////////////////////////////////
/* Grade Filter */
// Doesn't really filter out Grade. The filter still inlcudes
// whatever grades are at that location
/*
const gradeNode = document.querySelectorAll(`.grade-item`);
const gradeElement = document.getElementById("grade-filter");
gradeElement.addEventListener('click', filterByGrade); // handle user choice
// Handle selection for user filter
function filterByGrade(event) {
const selectedGrade = event.target.getAttribute("data-grade");
gradeView.filter = {
where: "grade = '"+ selectedGrade +"'",
};
};
view.whenLayerView(featureLayer).then(function (layerView) {
gradeView = layerView;
// set up UI items
gradeElement.style.visibility = 'visible';
const gradeExpand = new Expand({
view: view,
content: gradeElement,
expandIconClass: "esri-icon-filter",
group: "top-left",
});
// clear filters
gradeExpand.watch("expanded", function(){
if(!gradeExpand.expanded) {
gradeView.filter = null;
};
});
//view.ui.add(gradeExpand, 'top-left');
});
*/
///////////////////////////////////////////////////////////////////
const majComNode = document.querySelectorAll(`.majorCommand-item`);
const majComElement = document.getElementById("major-command-filter");
const gradeNode = document.querySelectorAll(`.grade-item`);
const gradeElement = document.getElementById("grade-filter");
// click event handler for seasons choices
majComElement.addEventListener("click", filterByCommand);
gradeElement.addEventListener("click", filterByGrade);
// User clicked on Major Commands 30th, 449th, 13th, and etc..
// set an attribute filter on major command layer view
function filterByCommand(event) {
const selectedCommand = event.target.getAttribute("data-command");
majorCommandView.filter = {
where: "macom = '" + selectedCommand + "'",
};
}
function filterByGrade(event) {
const selectedGrade = event.target.getAttribute("data-grade");
gradeView.filter = {
where: "grade = '"+ selectedGrade +"'",
};
};
view.whenLayerView(featureLayer).then(function (layerView) {
majorCommandView = layerView;
gradeView = layerView;
// set up UI items
majComElement.style.visibility = "visible";
gradeElement.style.visibility = "visible";
const majCommandExpand = new Expand({
view: view,
content: majComElement,
expandIconClass: "esri-icon-filter",
group: "top-left",
});
const gradeExpand = new Expand ({
view: view,
content: gradeElement,
expandIconClass: "esri-icon-filter",
group: "top-left",
})
// clear the filters
majCommandExpand.watch( "expanded", function() {
if(!majCommandExpand.expanded) {
majorCommandView.filter = null;
}
});
gradeExpand.watch('expanded', function(){
if(!gradeExpand.expanded) {
gradeView.filter = null;
};
});
view.ui.add([majCommandExpand, gradeExpand], 'top-left')
//////////////////////////////////////////
/* Stop with Filter and Begin with Editor */
/////////////////////////////////////////////////////
view.when(function () {
view.popup.position = 'top-right';
// Create the Editor
let editor = new Editor({
view: view,
container: document.createElement("div"),
layerInfos: [
{
layer: featureLayer,
deleteEnabled: true,
addEnabled: true,
},
],
});
// Add widget to top-right of the view
//view.ui.add(editor, "top-right");
// Execute each time the "Edit Feature" action is called
function editThis() {
// If the EditorViewModel's activeWorkflow is null, make the popup not visible
if (!editor.viewModel.activeWorkFlow) {
view.popup.visible =false;
editor.startUpdateWorkflowAtFeatureEdit(
view.popup.selectedFeature
);
view.ui.add(editor, "bottom-right");
view.popup.spinnerEnabled = true;
}
// We need to set a timeout to ensure the editor widget is fully rendered. We
// then grab it from the DOM stack
setTimeout(function () {
// Use the editor's back button as a way to cancel out of editing
let arrComp = editor.domNode.getElementsByClassName(
"esri-editor__back-button esri-interactive"
);
if (arrComp.length === 1) {
// Add a tooltip for the back button
arrComp[0].setAttribute(
"title",
"Cancel edits, return to popup"
);
// Add a listerner to listen for when the editor's back button is clicked
arrComp[0].addEventListener("click", function (evt) {
console.log(evt);
// Prevent the default behavior for the back button and instead remove the editor and reopen the popup
evt.preventDefault();
//view.ui.remove(editor);
view.popup.open({
features: features,
});
});
}
}, 150);
}
// Event handler that fires each time an action is clicked
view.popup.on("trigger-action", function (event) {
if (event.action.id === "edit-this") {
editThis();
}
});
// Watch when the popup is visible
view.popup.watch("visible", function (event) {
// Check the Editor's viewModel state, if it is currently open and editing existing features, disable popups
if (editor.viewModel.state === "editing-existing-feature") {
view.popup.close();
} else {
// Grab the features of the popup
features = view.popup.features;
}
});
featureLayer.on("apply-edits", function () {
// Once edits are applied to the layer, remove the Editor from the UI
//view.ui.remove(editor);
// Iterate through the features
features.forEach(function (feature) {
// Reset the template for the feature if it was edited
feature.popupTemplate = template;
});
// Open the popup again and reset its content after updates were made on the feature
if (features) {
view.popup.open({
features: features,
});
}
// Cancel the workflow so that once edits are applied, a new popup can be displayed
editor.viewModel.cancelWorkflow();
});
});
});
view.ui.add("info", {
position: "bottom-left",
index: 1,
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="major-command-filter" class="esri-widget">
<div class="majorCommand-item visible-command" data-command="30 ABCT">30 ABCT</div>
<div class="majorCommand-item visible-command" data-command="130 MEB">130 MEB</div>
<div class="majorCommand-item visible-command" data-command="113 SB">113 SB</div>
<div class="majorCommand-item visible-command" data-command="60 TC">60 TC</div>
<div class="majorCommand-item visible-command" data-command="449 TAB">449 TAB</div>
<div class="majorCommand-item visible-command" data-command="139 REG">139 REG</div>
<div class="majorCommand-item visible-command" data-command="JFHQ">JFHQ</div>
<div class="majorCommand-item visible-command" data-command="TEST">TEST</div>
</dvi>
<div id="grade-filter" class="esri-widget">
<div class="grade-item visible-grade" data-grade="E1">E1</div>
<div class="grade-item visible-grade" data-grade="E2">E2</div>
<div class="grade-item visible-grade" data-grade="E3">E3</div>
<div class="grade-item visible-grade" data-grade="E4">E4</div>
<div class="grade-item visible-grade" data-grade="E5">E5</div>
<div class="grade-item visible-grade" data-grade="E6">E6</div>
<div class="grade-item visible-grade" data-grade="E7">E7</div>
<div class="grade-item visible-grade" data-grade="E8">E8</div>
</dvi>
<div id="info" class="esri-widget">
<h3>Select a feature to display its popup</h3>
<h4>
Edit the feature by clicking on the "Edit feature" action within the
popup.
</h4>
</div>
</body>
</html>
Hi there,
From what I can see the grade filter is working as expected. For example, grade = 'E1' returns only one feature from the service as well. So the client-side filtering matches the server result in this case.
As for filtering features based both on grade and major values you can do the following were you can dynamically populate the values for the grade as you are doing in your app.
majorCommandView.filter = {
where: `macom = '${selectedCommand}' AND grade = 'E6'`,
};
-Undral
Hi Undral,
I understand that I'll have to do the where clause with the and statement, but I am unsure how to make it use two filters that the user applies to filter the attribute.
I was exploring the Expand and thought I could expand on another for example:
user selects major command which will then expand to Grade > user then is able to select grade along with major command.
My question would then be would I need to do an expression instead that gives the user a choice?