Populate dropdown, specifying label and values coming from different attributes

7084
21
Jump to solution
09-25-2013 01:20 PM
TracySchloss
Frequent Contributor
I have a layer of school districts that contains both the school district name and a district ID number.  I have a layer of schools which contains just the district ID number.

I'm populating my dijit.form.Select from the attributes of the school district layer.  I need the list to appear as district names, but at the same time, it would be nice if the values were the district IDs.  Then I could fire off a query on the school layer using a where clause without having to do any other hoop jumping (I think).  This code works to populate my dropdown, I'd just like it to be a little more functional. 

function populateDropDownList(){     var queryTask = new QueryTask(educationLayer.url + "/3");     var query = new Query();     query.outFields = ["DIST_NAME"];     query.where = "1=1";     query.returnGeometry = false;       queryTask.on('complete', resultsHandler);     queryTask.on('error', errorHandler);     queryTask.execute(query); }  function resultsHandler(results){     select = registry.byId("distSelect");// a dijit.form.Select      districtList.length = 0;     var numResults = results.featureSet.features.length;     for (var j = 0; j < numResults; j++) {         var distName = results.featureSet.features.attributes.DIST_NAME; //note the attribute name for the district code is DIST_CODE         districtList.push(distName);     }     districtList.sort();     var testList = arrayUtil.map(districtList, function (item, index){     return {         label:item,         value:item         };     });     select.addOption(testList); }
0 Kudos
21 Replies
TracySchloss
Frequent Contributor
There must be something about the objects in the data store.  If I look at what's in districtList, it contains label and value.  So I thought maybe the issue was that idProperty should be value, not DIST_CODE.
   var dataStore = new Memory({data:districtList, idProperty:"value"})


Setting a breakpoint, I can see that select dijit goes from having just one entry in the 'store' value of "Pick a district" to a long list, starting with

Object { label="Adair Co. R-I", value="001090"}.

idProperty is defined as value.  Should I not have quoted it? It seems like it should be.  It looks to me like the store is getting set, but it's not the right format so it still doesn't work as a dropdown.
0 Kudos
TracySchloss
Frequent Contributor
When I look at the dojo example for using a datastore for a filteringselect, they are using  name and id, not label and value, so I thought maybe that was the problem. 
var stateStore = new Memory({
        data: [
            {name:"Alabama", id:"AL"},
            {name:"Alaska", id:"AK"},
            {name:"American Samoa", id:"AS"},
            {name:"Arizona", id:"AZ"},
            {name:"Arkansas", id:"AR"}
        ]
    });


So I change what I was pushing to my districtList:
districtList.push({name: distName, id: distCode});


But it didn't help ...
0 Kudos
GeorgeSimpson
Occasional Contributor
Are labelAttr and searchAttr defined for your select?  They should be set to "label" if they are not.
0 Kudos
TracySchloss
Frequent Contributor
They were not.  This started out as a simple Select and all I did was switch the type to FilteringSelect. 

         
<select id="distSelect" data-dojo-type="dijit/form/FilteringSelect" 
         data-dojo-props="title:'Find schools in selected district',maxHeight:200, size: 30, labelAttr:'label', searchAttr:'label'">
         <option>Pick a district</option>
     </select>


This must not be right.  I'm getting an error
TypeError: _32[this.searchAttr] is undefined

Like I mentioned, this is my first AMD, so I'm a little uncertain on syntax.
0 Kudos
TracySchloss
Frequent Contributor
On 2nd thought that's not going to work, because 'label' probably doesn't exist until it runs through my populateDropdownList function.

I changed it to this.  Still doesn't work, though.
function resultsHandler(results){
    var select = registry.byId("distSelect");
    districtList.length = 0;
    var numResults = results.featureSet.features.length;
    for (var j = 0; j < numResults; j++) {
        var distName = results.featureSet.features.attributes.DIST_NAME;
        var distCode = results.featureSet.features.attributes.DIST_CODE;
        districtList.push({label: distName, value: distCode});
    }
   districtList.sort(function(item1, item2) {
    var label1 = item1.name.toLowerCase(),
    label2 = item2.name.toLowerCase();        
  return (label1 > label2) ? 1 : (label1 < label2) ? -1 : 0;
   });
   var dataStore = new Memory({data:districtList, idProperty:"value"})
select.set ("store", dataStore);
select.set ("labelAttr", "label");
select.set ("searchAttr", "value");
 // select.addOption(districtList);
 console.log (districtList);

}
0 Kudos
GeorgeSimpson
Occasional Contributor
Try this:


<!DOCTYPE html>
<html>
    <head>        
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Select</title>
        <link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.7/js/dojo/dojo/resources/dojo.css" />
        <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/dojo/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/esri/css/esri.css">
        <link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.7/js/dojo/dijit/themes/claro/document.css" />

        <style>
            
        html, body, .dijitBorderContainer {
          width: 100%;
          height: 100%;
          margin: 0;
          overflow:hidden;          
        }
        
        </style>
    </head>
    
    <body class="claro">
       <select id="distSelect" data-dojo-type="dijit/form/FilteringSelect" 
         data-dojo-props="title:'Find schools in selected district',maxHeight:200, size: 30, labelAttr:'label', searchAttr:'label',autoComplete:false,queryExpr:'*${0}*',placeHolder:'Pick a District'">
         
     </select>
        
    </body>
    <script type="text/javascript">
        var dojoConfig = {
            async: true,
            parseOnLoad:true
        };
        </script>
        <script src="http://js.arcgis.com/3.7/"></script>
        <script type="text/javascript">
            require(["dojo/_base/declare", "dojo/ready", "dijit/registry", "dijit/form/Button", "dijit/form/FilteringSelect", "dojo/store/Memory"],
            function (declare, ready, registry, Button, FilteringSelect, Memory) {
                
                //fire when dojo is "ready"
                ready(function () {

                    //create a distric list
                    var districtList = [
                        { label: "District One", value: "Dist 1" },
                        { label: "District Two", value: "Dist 2" },
                        { label: "District Three", value: "Dist 3" },
                        { label: "District Four", value: "Dist 4" }
                    ];

                    //add a button
                    var button = new Button({ label: "Populate Select",
                        onClick: function () {
                        //get the filteringselect
                            var select = registry.byId("distSelect");

                            //set the select's store using the districtlist
                            select.set("store", new Memory({ data: districtList, idProperty: "value" }));
                        }
                    });

                    button.placeAt(document.body);

                });
            });
        </script>
</html>

0 Kudos
TracySchloss
Frequent Contributor
That example works.  Now I have to figure out how to do this more dynamically because I have to generate the list from a function.  There are hundreds of school district names. 

I don't have any "dojo/_base/declare" in my code.  I'm not sure what that does.  Maybe that's what I'm missing.
0 Kudos
TracySchloss
Frequent Contributor
I finally figured it out!  I finally noticed that my Memory was declared as the class ContentPane.  That wasn't right!  So I sorted out my requires etc and now it is working.  That is by far the most klunky aspect to using AMD.
0 Kudos
TracySchloss
Frequent Contributor
Not quite figured out after all.  When I try to entering a letter to move to that place in the list (the only reason I switched to FilteringSelect in the first place), it tells me the value entered isn't valid.  In the example, I saw the query filter set as
queryExpr:'*${0}*'



But when I looked at the variable, that was the property already, so I didn't explicitly set it again.  It seems redundant to do so.
0 Kudos
TracySchloss
Frequent Contributor
After all this, I'm not getting the behavior I really need.  I have district names for 'name' and for the values, I have a 6 digit numeric code, which is the common data element between my district polygons and school point layers.  When trying to use the 'filtering' aspect of the dijit, it is expecting the code.  My intent was for the user to end a "B" for example and skip to that section of the list.  Nobody is going to know the internal code!
0 Kudos