AnsweredAssumed Answered

Interactive Filter Template - Replacing Default Dropdown with Dijit FilteringSelect

Question asked by mwalter2.optum on Oct 28, 2016
Latest reply on Oct 31, 2016 by rscheitlin

I am currently working off of the latest version of the Interactive Filter template. (GitHub - Esri/InteractiveFilter: Filter is a configurable application template that displays a map with an interactive f… )

 

And I need to replace the default drop down with a Dijit FilteringSelect from the Dojo Toolkit (dijit.form.FilteringSelect — The Dojo Toolkit - Reference Guide

 

This will allow the user to provide input in addition to the drop down, with autocomplete functionality when typing. I prefer the FilteringSelect as it will give an error if their search field isn't found in the layer. 

 

I have been trying to do this in a way that works with the overall template structure, as to not completely blow up the map filtering functionality. Currently, I have found a way to replace the drop down for layers with coded values, but the string type layers are not drawing the Dijit at all. 

 

Here is the _createFilterField function, where filter fields are created based on the layer type (coded values, integer, string): 

_createFilterField: function(param, filterLayer, fields) {

      var deferred = new Deferred();
      var field = null,
        paramInputs = null;
      param.inputId = filterLayer.id + "." + param.parameterId + ".value";

      array.some(fields, function(f) {
        if (f.name === param.fieldName) {
          field = f;
          return true;
        }
      });
      if (field && field.domain && field.domain.codedValues) {
        paramInputs = this._createDropdownList(param, field.domain.codedValues);
        deferred.resolve(paramInputs);
      } else if (field && field.type === "esriFieldTypeInteger") { //the pattern forces the numeric keyboard on iOS. The numeric type works on webkit browsers only
        paramInputs = lang.replace("<input class='param_inputs'  type='number'  id='{inputId}' pattern='[0-9]*'  value='{defaultValue}' />", param);
        deferred.resolve(paramInputs);
      } else { //string
        var capabilities = filterLayer.advancedQueryCapabilities;
        if (capabilities.supportsDistinct && this.uniqueVals) {
          var distinctQuery = new Query();
          distinctQuery.where = "1=1";
          distinctQuery.orderByFields = [field.name];
          distinctQuery.returnGeometry = false;
          distinctQuery.outFields = [field.name];
          distinctQuery.returnDistinctValues = true;

          var qt = new QueryTask(filterLayer.url);
          qt.execute(distinctQuery, lang.hitch(this, function(results) {
            var values = results.features.map(function(f, index) {
              return {
                name: f.attributes[field.name],
                code: f.attributes[field.name]
              };
            });
            var container = this._createDropdownList(param, values);
            deferred.resolve(container);
          }), function(error) {
            deferred.resolve(error);
          });
        } else {
          // string
          paramInputs = lang.replace("<input class='param_inputs'  type='text'  id='{inputId}' value='{defaultValue}' />", param);
          deferred.resolve(paramInputs);
        }
      }
      return deferred.promise;
    },

 

And here is my version of _createDropdownlist function, which sets up the drop down. 

_createDropdownList: function(param, values) {
     
      var container = domConstruct.create("div", {
       className: "styled-select small"
      });

      // Modify select to utilize Dojo - Dijit FilteringSelect Widget

      var select = domConstruct.create("select", {
        dojotype: "dijit/form/FilteringSelect",
        id: param.inputId
      }, container);

      array.forEach(values, function(val, index) {
        domConstruct.create("option", {
          value: val.code,
          innerHTML: val.name,
          selected: (val.name === param.defaultValue) ? true : false
        }, select);
      });
      var node = container.outerHTML ? container.outerHTML : container.innerHTML;
      console.log("node " + node);     
      return node;
    },

 

I have added line 10 above to manipulate the select element to become a FliteringSelect.

dojotype: "dijit/form/FilteringSelect",

 

To my surprise, this worked for the coded value layers. But not string type.

 

Here's a screenshot of the filterable layers:

The first (Admit by Diagnosis) is the Dijit with autocomplete.

The Second (Plan Name) is just a simple drop down. 

 

 

 

Anyone familiar with this template - any ideas why this might be happening? And how I can leverage the existing template code for string types?

Outcomes