How do I update this code for Dojo AMD?

3643
5
05-06-2015 02:28 PM
ChrisSergent
Regular Contributor III

I was looking at this post by Kelly Hutchins​ a programmatic way to populate a combo box. I have this web service: Layer: Sign (ID: 0)  and I want to populate the items from the MUTCD field; there are over 257 items in the list. How would I change this code to work as AMD and what required statements do I need; I also want the first value to be "" and display as Select One :

function init() {
  queryTask = new esri.tasks.QueryTask
  ("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Louisville/LOJIC_LandRecords_Louisville/M...");

  query = new esri.tasks.Query();
  query.returnGeometry = false;
  query.outFields = ["ZONING_TYPE"];
  query.where = "ZONING_TYPE<> ''";
  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.ZONING_TYPE;
  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.data.ItemFileReadStore({data:dataItems});
  dijit.byId("mySelect").store = store;
  }
  dojo.addOnLoad(init);
5 Replies
KellyHutchins
Esri Frequent Contributor

That's a really old blog post and there are new options for getting distinct values from a service.  Take a look at returnDistinctValues on Query for one option.

Here's a code sample that uses it:

        var query = new Query();
        query.where = "SUB_REGION IS NOT NULL";
        query.returnGeometry = false;
        query.outFields = ["SUB_REGION"]
        query.returnDistinctValues = true;
        layer.queryFeatures(query, function(results){
          array.forEach(results.features, function(feature){
            console.log(feature.attributes["SUB_REGION"]);
          });
        });
ChrisSergent
Regular Contributor III

Just to be sure, does this return the values that the user selects or the entered values?

0 Kudos
ChrisSergent
Regular Contributor III

I ended up entering the following:

/* Query Begin */
            
            var query = new esriQuery("http://maps.decaturil.gov/arcgis/rest/services/test/StreetSignTest/FeatureServer/0");
            query.where = "CONDITION_ IS NOT NULL";
            query.returnGeometry = false;
            query.outFields = ["CONDITION_"]
            query.returnDistinctValues = true;
            layer.queryFeatures(query, function (results) {
                array.forEach(results.features, function (feature) {
                    console.log(feature.attributes["CONDITION_"]);
                });
            });
            /* Query End */

I used esriQuery because dojo/query was in the require statement and already used a variable name query

and here is the latest code: csergent45/streetSigns · GitHub

0 Kudos
ChrisSergent
Regular Contributor III

Kelly Hutchins​ I updated my code to the following. Your code was working but it was providing me with a unique list of values entered. I wanted the coded values that were available for entry for the web service: I was using this page: FeatureLayer | API Reference | ArcGIS API for JavaScript

/* Query Begin */
            var query = new esriQuery();
            var queryBacking = new queryTask("http://maps.decaturil.gov/arcgis/rest/services/test/StreetSignTest/FeatureServer/0");
            query.where = "1=1";
            query.returnGeometry = false;
            query.outFields = ["BACKING"];
            query.returnDistinctValues = true;
            queryBacking.execute(query, function (results) {
                array.forEach(results.features.getDomain("BACKING"), function (feature) {
                    console.log(feature.getDomain["BACKING"]);
                    });
               
                //for (var i = 0; i < results.CodedValues.length; i++) {
                //    console.log(results.CodedValues);
                //}
            });
            /* Query End */

I'm getting this error:

TypeError: results.features.getDomain is not a function {stack: (...), message: "results.features.getDomain is not a function"}

  1. message: "results.features.getDomain is not a function"
  2. stack: (...)
  3. get stack: function () { [native code] }
  4. set stack: function () { [native code] }
  5. __proto__: Error

"TypeError: results.features.getDomain is not a function

I also tried this, but it was undefined: console.log(app.signLayer.getDomain("BACKING").value);

How should I use getDomain to get the list of values?

ChrisSergent
Regular Contributor III

This question was answered through Esri support. To obtain the coded values to populate a dropdown list, you enter the following code. I included an additional line so that no option would appear to be selected when a dropdown first appears.

//get the domain value
            var domain = app.signLayer.getDomain("BACKING");


            //get the html select by ID
            var select = document.getElementById("backing");


            //clear the current options in select
            for (var option in select) {
                select.remove(option);
            }


            var opt = document.createElement('option');
            opt.innerHTML = "";
            select.appendChild(opt);
            //loop through the domain value to fill the drop down
            for (var i = 0; i < domain.codedValues.length; i++) {
                console.log(domain.codedValues.name);
                ;var opt = document.createElement('option');
                opt.innerHTML = domain.codedValues.name;
                opt.value = domain.codedValues.name;
                select.appendChild(opt);
            }

To go a little further with this, you could create a function with arguments like so:

function populateSelect(x, y) {
        //get the domain value 
        var domain = app.signLayer.getDomain(x);


        //get the html select by ID
        var select = document.getElementById(y);


        //clear the current options in select
        for (var option in select) {
            select.remove(option);
        }


        var opt = document.createElement('option');
        opt.innerHTML = "";
        select.appendChild(opt);
        //loop through the domain value to fill the drop down
        for (var i = 0; i < domain.codedValues.length; i++) {
            console.log(domain.codedValues.name);
            ; var opt = document.createElement('option');
            opt.innerHTML = domain.codedValues.name;
            opt.value = domain.codedValues.name;
            select.appendChild(opt);
        }


    }

And then for each dropdown that you want to populate, you could enter this line of code and replace the values for each line.

 populateSelect("BACKING", "backing");

This will save you around 15 lines of code for each dropdown list that you want to populate.