Issues in generating a ComboBox within WAB Widget

4673
15
Jump to solution
10-07-2015 05:06 AM
BenHahn
New Contributor II

Hi everyone,

I am pretty new to WAB and Javacript development with Dojo. My plan is to generate a dynamic Combobox out of feature-layer attributes. On click the widget should add that specific feature-layer with the chosen layerexpression. e.g. Country selection ComboBox: "USA" -> Zoom on USA.

I got this to work in a standalone Javascript api, but now i'd like to include this into my WAB1.2 functionality set as a widget and I ran into several Dojo issues which I am not familiar with.

Basically I started a new widget from scratch:

Widget.js

define([
    'dojo/_base/declare', 
    'jimu/BaseWidget', 
    'jimu/ConfigManager', 
    "jimu/WidgetManager",    
    'esri/layers/FeatureLayer',  
    "dijit/form/Select",
    "dojo/query", 
    "dojo/ready", 
    "dijit/form/ComboBox", 
    "dojo/data/ItemFileReadStore", 
    "dojo/_base/array", 
    "dojo/on"
    ],
    
function(
    declare, 
    BaseWidget,
    ConfigManager,  
    WidgetManager,
    FeatureLayer, 
    Select,
    query, 
    ready,
    ComboBox, 
    ItemFileReadStore, 
    array, 
    on
    
) {
  return declare([BaseWidget], {
        baseClass: 'definition_query',  
        onOpen: function () {  

            function init() {
               queryTask = new esri.tasks.QueryTask
                        ("https://.../MapServer/0");

               query = new esri.tasks.Query();
               query.returnGeometry = false;
               query.outFields = ["NAME"];
               query.where = "NAME<> ''";
               queryTask.execute(query,populateList);
            }

            function populateList(results) {
                //Populate the ComboBox with unique values
                var zone;
                var values = [];
                var testVals={};

                //Add option to display all zoning types to the ComboBox
                values.push({name:"ALL"})

                //Loop through the QueryTask results and populate an array
                //with the unique values
                var features = results.features;
                dojo.forEach (features, function(feature) {
                  zone = feature.attributes.NAME;
                  if (!testVals[zone]) {
                    testVals[zone] = true;
                    values.push({name:zone});
                  }
                });
                //Create a ItemFileReadStore and use it for the
                //ComboBox's data source
                var dataItems = {
                       identifier: 'name',
                       label: 'name',
                       items: values
                };
            
                var store = new dojo.store.Memory({data:dataItems});//tried to work with ItemFileReadStore before, but couldn't get it to work either 
                console.log(dataItems);
                console.log(store);
                dijit.byId("mySelect").set('store', store);    
            }

        dojo.addOnLoad(init);    

         },  
  });
});

TypeError: dijit.byId(...) is undefined

dijit.byId("mySelect").set('store', store);

My Issue is dijit.byId won't be interpreted. What kind of modules am I missing? I am unsure how to figure out which of the modules are necessary for this job.

As mentioned, pretty much the same code works on plain javascript api. There are several working examples on JS but I couldn't manage to convert them into WAB. Maybe there is already a widget that has similar functionality?

HTML:

<select id="mySelect" dojoType="dijit.form.ComboBox" style="width:300px;font-size:18px;" value="Select Zoning Type"></select>

Thanks for advice

15 Replies
BenHahn
New Contributor II

sure, but its basically a blank widget filled with Widget.js and Widget.html only

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

That's OK. There just has to be something off for you not to be able to reference mySelect

RobertScheitlin__GISP
MVP Emeritus

Ben,

  I can't believe that I missed it earlier. But here it is working:

  1. There were a couple of issues but the main one was line 35. You have to have _WidgetsInTemplateMixin in the declare when using widgets in a template.
  2. Line 51. Adding lang.hitch so that the function was in scope and knew what "this" was.
  3. Line 89. You use this.mySelect.set not this.mySelect.setData

define([
  "dojo/_base/declare",
  "jimu/BaseWidget",
  "dijit/_WidgetsInTemplateMixin",
  "dojo/aspect",
  "jimu/ConfigManager",
  "jimu/WidgetManager",
  "esri/layers/FeatureLayer",
  "dojo/query",
  "esri/tasks/query",
  "esri/tasks/QueryTask",
  "dojo/store/Memory",
  "dojo/_base/array",
  "dojo/on",
  "dojo/_base/lang",
  "dijit/form/ComboBox"
  ],

  function (
    declare,
    BaseWidget,
    _WidgetsInTemplateMixin,
    aspect,
    ConfigManager,
    WidgetManager,
    FeatureLayer,
    dojoQuery,
    Query,
    QueryTask,
    Memory,
    array,
    on,
    lang
  ) {
    return declare([BaseWidget, _WidgetsInTemplateMixin], {

      baseClass: "definition_query",

      queryTask: null,
      query: null,

      postCreate: function () {
        this.queryTask = new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayer...");
        this.query = new Query();
        this.query.returnGeometry = false;
        this.query.outFields = ["FDNAME"];
        this.query.where = "FDNAME <> ''";
      },

      onOpen: function () {
        this.queryTask.execute(this.query, lang.hitch(this, this.populateList));
      },

      populateList: function (results) {
        //Populate the ComboBox with unique values
        var zone;
        var values = [];
        var testVals = {};

        //Add option to display all zoning types to the ComboBox
        values.push({
          name: "ALL"
        });

        //Loop through the QueryTask results and populate an array
        //with the unique values
        var features = results.features;
        array.forEach(features, function (feature) {
          zone = feature.attributes.FDNAME;
          if (!testVals[zone]) {
            testVals[zone] = true;
            values.push({
              name: zone
            });
          }
        });
        //Create a ItemFileReadStore and use it for the
        //ComboBox's data source
        var dataItems = {
          identifier: "name",
          label: "name",
          items: values
        };
        //console.log(dataItems);
        var store = new Memory({
          data: dataItems
        });
        //console.log(store);
        this.mySelect.set("store", store);
      }
    });
  });
BenHahn
New Contributor II

Thanks alot Robert, never thought about using lang.hitch cause of legacy...

this was alot of work for these basics...now I know where to follow up.

0 Kudos
NatashaManzuiga
Occasional Contributor

Robert, how can I call a JSON webservice and populate a combobox instead of using QueryTask?

I have to use ItemFileReadStore?

Thanks,

Naty

0 Kudos
NatashaManzuiga
Occasional Contributor

At least I found the way and I post it...Maybe someone needs it too...

Naty

postCreate: function() {

         var jsonStore= new JsonRest

         ({

          target: "lists.json",

          idProperty: "Code"

         });

        var restStore = new JsonRest({ target: "lists.json", idProperty: "Code" });

        var memoryStore = new Memory({ idProperty: "Code" });

        restStore.query().then(function(response) {

            memoryStore.setData(response.slice(0));

        });

        var combobox = new FilteringSelect( 

        { 

        id: "Code",

        name: "Name",

        value: "",

        searchAttr:"Name",

        store: memoryStore,

        style: "width: 200px;",

        queryExpr: "*${0}*",

        labelAttr: "Name",

        onChange: lang.hitch(this, '_onLoadWidgetBClick')

           }

        }, this.StoreItemSelect); 

        combobox.startup();  

      },