Select to view content in your preferred language

populate a dgrid with results of a querytask

1297
7
Jump to solution
09-26-2013 07:53 AM
TracySchloss
Honored Contributor
I am running a querytask against a school layer and I need to be able to present the data in a dgrid with a rowrenderer.  I'm getting stuck formatting the data to populate the dgrid.  I'm new to the AMD format, I might not be using arrayUtil.map properly.   I commented out most of this, just to verify that my queryTask is executing. It is, but restoring the entire function, it fails, just firing my errorHandler instead.  The error comes back 'undefined', which is no help at all!

I'm pretty sure the problem is in the lines that define the variable 'data'.
function createSchoolList (results) {     var resultsLength = results.featureSet.features.length;     var data = [];     var schoolFeatures = results.featureSet.features;      if (dGridStacked) {         dGridStacked.refresh();     }      if (dGridTable) {         dGridTable.refresh();     }      data = arrayUtil.map(results, function(schoolFeatures){     return {         'facility': schoolFeatures.attributes[Facility],         'address': schoolFeatures.attributes[Address],         'city': schoolFeatures.attributes[City],              };    });     dGridStacked = new dgrid.Grid({         renderRow: renderRowFunction,         showHeader: true    }, "searchResultsGrid");          dGridStacked.startup();     dGridStacked.renderArray(data);     dGridStacked.sort('facility');      dGridStacked.on('.dgrid-row:click', function(event){       highlightGridSelection(event, dGridStacked);      });   console.log(data);       } function renderRowFunction (obj,options) {    var template = '<div class="title">${0}</div><div class="details">Address: ${1}</div> <div class="details">City: ${2}</div>';     return dojo.create("div",{        innerHTML : dojo.string.substitute(template,[obj.facility,obj.address,obj.city])       }); }
0 Kudos
1 Solution

Accepted Solutions
TracySchloss
Honored Contributor
That was part of it.  The other part was invalid syntax getting each value on the attributes.  I'm not sure where I got the idea I needed square brackets.  Maybe in another scenario that's appropriate.  It should be:

    data = arrayUtil.map(results.featureSet.features, function(feature){     return {         'facility': feature.attributes.Facility,         'address': feature.attributes.Address,         'city': feature.attributes.City,              };

View solution in original post

0 Kudos
7 Replies
KenBuja
MVP Esteemed Contributor
Do you also need to set the columns property of the dgrid? I'm using the dgrid to hold the contents of an IdentifyTask. This will be for a variety of layers, so I'm not hard coding the column list, which will show all the fields except the Shape field. This also adds the dgrid to a ContentPane and sets up some events.

var columns = buildColumns(results[0].feature);  //builds the column list from the first feature
var features = [];

for (i = 0, len = results.length; i < len; i++) {
    features.push(results.feature);
}

var data = array.map(features, function (feature) {
    return lang.clone(feature.attributes);
});

var dataGrid = new (declare([Grid, Selection, DijitRegistry, ColumnHider]))({
    id: "dgrid_0",
    bufferRows: Infinity,
    columns: columns,
    selectionMode: "single",
    "class": "resultsGrid"
});


var gridWidth = "width: " + String(columns.length * 100) + "px";
dataGrid.addCssRule("#" + dataGrid.id, gridWidth); //this makes the dgrid large enough to show all the columns

dataGrid.on(".dgrid-row:click", gridSelect);  //this flashes the feature
dataGrid.on("show", function () {
    dataGrid.resize();
});
dataGrid.on(mouseUtil.enterRow, gridEnter); //this highlights the feature
dataGrid.on(mouseUtil.leaveRow, function () {
    map.graphics.clear();
});
var plural = "";
if (combineResults[result].length !== 1) { plural = "s"; }
var cp = new dijit.layout.ContentPane({
    id: result,
    content: "<strong>" + combineResults[result][0].layerName + "</strong> (" + combineResults[result].length + " feature" + plural + ")",
    title: combineResults[result][0].layerId,
    style: "overflow: auto"
}).placeAt(dijit.byId('tabs'));

cp.addChild(dataGrid);
cp.startup();

dataGrid.renderArray(data);



    function buildColumns(feature) {
        var attributes = feature.attributes;
        var columns = [];

        for (var attribute in attributes) {
            if (attributes.hasOwnProperty(attribute)) {
                var objects = {};
                objects.label = attribute;
                objects.field = attribute;
                if (attribute === "Shape") {
                    objects.hidden = true;
                }
                columns.push(objects);
            }
        }
        return columns;
    }


This is part of an application to show the results from different layers in a service in one Tab Container contain a dgrid for each layer. Here's a Fiddle that shows it in action.
0 Kudos
TracySchloss
Honored Contributor
I copied this from an existing project which processes results from a selectFeatures request on a featureLayer instead of from a queryTask.  There it works properly without the column definitions you're suggesting.  I really don't think that's the problem.
0 Kudos
JasonZou
Frequent Contributor
Results is an object, not the array itself.

Change:
    data = arrayUtil.map(results, function(schoolFeatures){
    return {
        'facility': schoolFeatures.attributes[Facility],
        'address': schoolFeatures.attributes[Address],
        'city': schoolFeatures.attributes[City],
        
    };
   });


To:
    data = arrayUtil.map(results.featureSet.features, function(schoolFeature){
    return {
        'facility': schoolFeature.attributes[Facility],
        'address': schoolFeature.attributes[Address],
        'city': schoolFeature.attributes[City],
        
    };
   });
0 Kudos
TracySchloss
Honored Contributor
That was part of it.  The other part was invalid syntax getting each value on the attributes.  I'm not sure where I got the idea I needed square brackets.  Maybe in another scenario that's appropriate.  It should be:

    data = arrayUtil.map(results.featureSet.features, function(feature){     return {         'facility': feature.attributes.Facility,         'address': feature.attributes.Address,         'city': feature.attributes.City,              };
0 Kudos
JasonZou
Frequent Contributor
It's ok to use square brackets, but need to quote the attribute name, like schoolFeatures.attributes["Facility"]. If using schoolFeatures.attributes[Facility], then Facility should be a string variable holding the field name. I did miss that part in my previous post.
0 Kudos
TracySchloss
Honored Contributor
This works fine in Firefox, but testing it in IE, which is still the state's standard browser gives an error on the line that is defining the data variable:

Expected identifier, string or Number.  I assume that data is an object and IE doesn't like it?
0 Kudos
TracySchloss
Honored Contributor
The problem looks to be with the difference between an array and an object.  I had data defined as an array and IE didn't like that.  I changed this to:

function createSchoolList (results) {
    var resultsLength = results.featureSet.features.length;
    var schoolList = {};

    if (dGridStacked) {
        dGridStacked.refresh();
    }
    if (dGridTable) {
        dGridTable.refresh();
    }
    schoolList.data = arrayUtils.map(results.featureSet.features, function(feature){

    return {
        "facility": feature.attributes["Facility"],
        "address": feature.attributes["Address"],
        "city": feature.attributes["City"]      
    };
   });

   dGridStacked = new dgrid.Grid({
        renderRow: renderRowFunction,
        showHeader: true
   }, "searchResultsGrid");
    
    dGridStacked.startup();
    dGridStacked.renderArray(schoolList.data);
    dGridStacked.sort('facility');
  

  dGridStacked.on('.dgrid-row:click', function(event){
      highlightGridSelection(event, dGridStacked);

    });
queryDistrict();
}


This works OK in IE.
0 Kudos