Using dojo FilteringSelect for text autocomplete

4643
8
Jump to solution
10-28-2013 08:52 AM
GeoffSchwitzgebel
New Contributor
I am trying to implement text autocompleting within a dijit.form.FilteringSelect.  I have set up my query to return the appropriate values.  I have created a new mem store that is being populated correctly.  The issue I am running into is that the available names are not populating when the application is loaded.  I am getting "TypeError: a[this.searchAttr] is undefined" thrown back in firebug when I click on the dropdown arrow.  I have removed the query task URL since it is internal only.  Any assistance is appreciated.

Thanks,
Geoff

Here is my code:
      var queryTaskName = new esri.tasks.QueryTask("");                 //create an array                                 var locNames = [];                 locNamesMemory = new Memory({ data: locNames, idProperty: "NAME" });                 //build query filter                 var queryName = new esri.tasks.Query();                 queryName.returnGeometry = false;                 queryName.outFields = ["OBJECTID","NAME"];                 queryName.where = "OBJECTID > 0";                 queryName.returnGeometry = false;                 queryTaskName.execute(query, function (results) {                     //parse results and add to autocomplete widget                     dojo.forEach(results.features, function (value, index) {                         locNames.push(value.attributes.NAME);                     });                 }, function (error) {                     alert("Error: " + error);                 });                  var filteringSelect = new FilteringSelect({                     id: "txtSearch",                     name: "state",                     value: "Enter Name Here",                     store: locNamesMemory,                     autoComplete: true,                     searchAttr: ["NAME"]                 }, "txtSearch");

[HTML]<input id="txtSearch" type="text"  placeholder="Enter Name Here" >[/HTML]
0 Kudos
1 Solution

Accepted Solutions
JasonZou
Occasional Contributor III
Tracy is correct. I overlooked one thing in my revision.

Change:
locNames.push(value.attributes.NAME);


To:
locNames.push({NAME: value.attributes.NAME});

View solution in original post

0 Kudos
8 Replies
SteveCole
Frequent Contributor
I've used a FilteringSelect successfully but my coding is a little different. The javaScript code:

     //Push the list of road names into the combo box
     query = new esri.tasks.Query();    
     query.where = "1=1";
     query.outFields = ["*"];
     query.returnGeometry = false;
 
     var queryTask = new esri.tasks.QueryTask(SERVERPATH);
     queryTask.execute(query,populateRdNameCbo);
     .
     .
     .
     function populateRdNameCbo(results) {
 //Populate the dropdown list box with unique values
 values = [];
        testVals = {};
 
 features = results.features;
 dojo.forEach (features, function(feature) {
  curName = feature.attributes.FULLNAME;
  if (!testVals[curName]) {
   testVals[curName] = true;
   values.push({"OBJECTID":feature.attributes.OBJECTID,"RDNAME":feature.attributes.FULLNAME});
  }
 });
 
 dataItems = {
     identifier: "OBJECTID",
     label: "RDNAME",
     items: values
 };
 
 theStore = new dojo.data.ItemFileReadStore({data:dataItems});

 dijit.byId("cboRdName").set("store", theStore);  
      }


My HTML for the combo box is:
[HTML]<input id="cboRdName" dojoType="dijit.form.FilteringSelect" searchAttr="RDNAME" name="WidgetName" pageSize="6" fetchProperties="{sort:[{attribute:'RDNAME', descending:false}]}" placeHolder="Select a road or start typing" onChange="updateCrossStreetList();closureProps['rdName'] = document.getElementById('cboRdName').value;closureProps['status'] ='CLOSED';zoomToRoad()"/>[/HTML]

This is using v3.4 of the API.

Steve
0 Kudos
JasonZou
Occasional Contributor III
filteringSelect needs to be created inside the callback function of the query. Try to change your code as shown below.
      var queryTaskName = new esri.tasks.QueryTask("");
                var filteringSelect;
                var locNames = [];

                //build query filter
                var queryName = new esri.tasks.Query();
                queryName.returnGeometry = false;
                queryName.outFields = ["OBJECTID","NAME"];
                queryName.where = "OBJECTID > 0";
                queryName.returnGeometry = false;
                queryTaskName.execute(queryName, function (results) {
                    //parse results and add to autocomplete widget
                    dojo.forEach(results.features, function (value, index) {
                        locNames.push(value.attributes.NAME);
                    });

                    // assume locNamesMemory is declared as a global variable.
                    locNamesMemory = new Memory({ data: locNames, idProperty: "NAME" });
                    filteringSelect = new FilteringSelect({
                        id: "txtSearch",
                        name: "state",
                        value: "Enter Name Here",
                        store: locNamesMemory,
                        autoComplete: true,
                        searchAttr: "NAME"
                    }, "txtSearch");
                }, function (error) {
                    alert("Error: " + error);
                });
0 Kudos
GeoffSchwitzgebel
New Contributor
Jason,
I tried making your changes as suggested but I am still having the same issue.

Geoff
0 Kudos
JasonZou
Occasional Contributor III
Set a breakpoint right after filteringSelect is instantiated, and check filteringSelect.store to see if the data is populated. If yes, then something else in your code is wrong. From the original error:  "TypeError: a[this.searchAttr] is undefined", it's something to do with an array named "a". Can you post the code that relates to how "a" array is populated and being used?
0 Kudos
TracySchloss
Frequent Contributor
I don't see how Memory knows that NAME exists to serve as the idProperty.  If all you have is an array of names, where does it pick out anything called NAME?

I have a function that populates a filteriingSelect.  Maybe something in this will help you?
function populateResultsHandler(results){
    var select = registry.byId("pickSelect");//my filteringSelect dijit
    pickList.length = 0;
    var numResults = results.featureSet.features.length;
      for (var j = 0; j < numResults; j++) {
          var pickCode = results.featureSet.features.attributes[pickAttr];
        pickList.push({id: pickCode, label: pickCode});
      }
      pickList.sort(function(item1, item2) {
        var label1 = item1.label.toLowerCase(),
        label2 = item2.label.toLowerCase();      
        return (label1 > label2) ? 1 : (label1 < label2) ? -1 : 0;
    });

   var dataStore = new Memory({data:pickList, idProperty:"id"});
    select.set ("searchAttr", "id");
    select.set("labelAttr", "id");
    select.set("store", dataStore);
}


Here's the HTML
         <select id="pickSelect" data-dojo-type="dijit/form/FilteringSelect"  placeHolder="Select a township"
         data-dojo-props="title:'Find points in selected township/range',maxHeight:200, size: 30, queryExpr:'${0}*', ignoreCase:true">       
     </select>
0 Kudos
JasonZou
Occasional Contributor III
Tracy is correct. I overlooked one thing in my revision.

Change:
locNames.push(value.attributes.NAME);


To:
locNames.push({NAME: value.attributes.NAME});
0 Kudos
GeoffSchwitzgebel
New Contributor
Thanks everyone for your help!  I made Tracy's change to Jason's post and it's good to go. Steve, I did try yours out but I wasn't able to get it configured correctly.

Geoff
0 Kudos
SteveCole
Frequent Contributor
No worries! I had a little wonkty tidbit in my code since it's also trying to create a unique list for my filteringSelect. Glad you got it squared away!
0 Kudos