How to Add Two filter option

339
2
04-13-2021 03:48 PM
irmcintosh
New Contributor

I was curious if anyone can tell me why the Grade filter doesn't actually filter out the user-selected Grade? The

majorCommand workds fine. Lastly, would anyone know who to just add the grade to the major command so that a user could select 30 ABCT & E1
 

 

 

 

<!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>

 

 

 

0 Kudos
2 Replies
UndralBatsukh
Esri Regular Contributor

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

0 Kudos
irmcintosh
New Contributor

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?

0 Kudos