format datagrid question

1199
14
Jump to solution
06-29-2012 06:47 AM
TracySchloss
Frequent Contributor
I would like to be able to take the attributes from a featureSet and display them more like an mailing address in a pane along side my map.

Facility Name
Address
City, State

I see that I can easily put this information in a grid, but then the data is presented as columns and I really want a much smaller footprint on the screen.

I know how to do this in Flex using a datagrid renderer, but I don't see that there is such a thing in JavaScript.
0 Kudos
1 Solution

Accepted Solutions
KellyHutchins
Esri Frequent Contributor
That line of code is using dojo.string.substitute to add values into the middle of a text string. The values for 0,1,2,3 etc come from the order the info is provided to the substitute function. So in this example the value for 0 would be the id, 1 would be families etc....
dojo.string.substitute(template,[obj.id,obj.families,obj.vacant,obj.med_age])

Here's some additional info on substitute:

http://www.enterprisedojo.com/2011/10/14/coast-to-coast-with-dojo-string-substitute/



This helps so much, thanks! 


var template = '<div class="title">Record: ${0}</div><div class="subtitle"><div class="details">This block group has a median age of ${3} and a vacancy rate of ${2}. The percentage of families are ${1}</div>';


what do the numbers 0,1,2,3 relate to?  I would have thought this was the order of the attributes from the lines in the callback function, but that doesn't seem to be the case. Do they correspond to the order in the renderTable function?
return {                     'med_age': feature.attributes.MED_AGE,                     'vacant': feature.attributes.VACANT,                     'families': feature.attributes.FAMILIES,                     'id': feature.attributes.ObjectID                   }


innerHTML : dojo.string.substitute(template,[obj.id,obj.families,obj.vacant,obj.med_age])

View solution in original post

0 Kudos
14 Replies
KellyHutchins
Esri Frequent Contributor
You can do this using a Dojo dgrid. We have a sample in the help that specifies a custom renderer for a dgrid.

http://help.arcgis.com/en/webapi/javascript/arcgis/help/jssamples/portal_getgroup.html

In this sample the function below renders the contents that will appear in the grid.

function renderTable(obj, options) {

      var template = '<div class="thumbnail"><img src=${0} width="50" height="50"/></div><a target="_blank" class="title" href=${1}>${2}</a><span> <i> (${3} ) </i></span><div class="summary">${4} </div><div class="group=id">${5}</div>';
      var summary = obj.snippet || '';
      var url = portalUrl + '/home/group.html?groupid=id:' + obj.id;
      var thumbnail = obj.thumbnail || '';
      return div = dojo.create("div",{
        innerHTML : dojo.string.substitute(template,[thumbnail,url,obj.title,obj.owner,summary,obj.id])
      });

    }

0 Kudos
TracySchloss
Frequent Contributor
If I read this correctly, if I use dgrid, I should make sure I'm using version 3.0 of the API?
0 Kudos
KellyHutchins
Esri Frequent Contributor
If I read this correctly, if I use dgrid, I should make sure I'm using version 3.0 of the API?


Yes the dojo dgrid requires version 3.0.
0 Kudos
TracySchloss
Frequent Contributor
What I'm trying to do is pretty different from the example.  I have a featureset with a callback function from a queryTask.  To begin with, I'm not sure I'm formatting my data correctly for what the grid wants as input.
function queryFeatures_callback (featureSet) {
    var data = [];
     dojo.forEach(featureSet.features,function(feature){ 
           data.push({"facility":feature.attributes.FACILITY},{"address":feature.attributes.ADDRESS},{"city":feature.attributes.CITY} );
       });
       //create the grid
         grid = new dgrid.Grid({
           columns: {
             Facility: 'facility',
             Address: 'address',
             City: 'city'
              },
              renderRow: renderTable,
          //this function renders the table in a non-grid looking view
             showHeader: false
            }, "grid");
            
        grid.renderArray(data);
      }
function renderTable(obj, options) {

        var template = '<div class="facility">${FACILITY}</div><div class="address">${ADDRESS} </div><div class="city">${CITY}</div>';
        
        var facility = obj.facility;
        var address = obj.address;
        var city = obj.city;
        return div = dojo.create("div",{
          innerHTML : dojo.string.substitute(template,[obj.facility,obj.address,obj.city])
        });

    }
0 Kudos
KellyHutchins
Esri Frequent Contributor
Here's a quick code sample showing the dgrid that displays the results of a query task.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>Dgrid Demo</title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="https://community.esri.com//serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dgrid/css/dgrid.css">
    

    <style type="text/css">
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
      #mapDiv{padding:0;}
      .title{
        font-weight:bold;
        color:olive;
      }
      .details{
        padding:8px;
        color:olive;
      }
    </style>
    
    <script type="text/javascript">
      var dojoConfig = {parseOnLoad: true};
    </script>
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.0"></script>
    <script type="text/javascript">
      dojo.require("esri.map");
      dojo.require("esri.tasks.query");
      dojo.require("esri.tasks.geometry");
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      dojo.require("dgrid.Grid");



      dojo.addOnLoad(pageReady);
      var map, queryTask, query;
      var grid;

      function pageReady() {
        
        var initExtent = new esri.geometry.Extent({"xmin":-13067753,"ymin":4026278,"xmax":-13037178,"ymax":4049209,"spatialReference":{"wkid":102100}});
        
        // Create map with options
        map = new esri.Map("mapDiv",{
          extent: initExtent
        });


        dojo.connect(map, "onLoad", mapReady);

       
        // Add layers
        var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
        map.addLayer(basemap);


        var censusLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer");
        map.addLayer(censusLayer);

      }

      function mapReady(map) {

        dojo.connect(map, "onClick", executeQueryTask);

        queryTask = new esri.tasks.QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/1");

        query = new esri.tasks.Query();
        query.returnGeometry = true;
        query.outFields = ["*"];
        query.outSpatialReference = map.spatialReference;
        query.spatialRelationship = esri.tasks.Query.SPATIAL_REL_INTERSECTS;

    

        //resize the map when the browser resizes
        dojo.connect(dijit.byId('mapDiv'), 'resize', map,map.resize);
      }

      function executeQueryTask(evt) {
        query.geometry = evt.mapPoint;
       
        var deferred = queryTask.execute(query);

        deferred.addCallback(function(response) {
          // populate datagrid with results of query task 
            //clear the grid of any existing features 
            var data = [];
            if(grid){
                grid.refresh();
            }
        if (response.features.length > 0) {
                //create an array of attributes for each group - we'll display these in a dojo dgrid
                data = dojo.map(response.features, function (feature) {
                  return {
                    'med_age': feature.attributes.MED_AGE,
                    'vacant': feature.attributes.VACANT,
                    'families': feature.attributes.FAMILIES,
                    'id': feature.attributes.ObjectID
                  }
                });
                //create the grid
                grid = new dgrid.Grid({
                  renderRow: renderTable,
                  showHeader: false
                }, "grid");
                grid.renderArray(data);
                
              } 

        });

       

      }
      
      function renderTable(obj,options){

        var template = '<div class="title">Record: ${0}</div><div class="subtitle"><div class="details">This block group has a median age of ${3} and a vacancy rate of ${2}. The percentage of families are ${1}</div>';

              return div = dojo.create("div",{
                innerHTML : dojo.string.substitute(template,[obj.id,obj.families,obj.vacant,obj.med_age])
              });
      }

    </script>
  </head>
  <body class="claro" >
    <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline',gutters:'false'" style="width: 100%; height: 100%;">
      <div  data-dojo-type='dijit.layout.ContentPane' data-dojo-props='region:"right"' style='width:400px;'>
        <div>Click on a feature to view details about the block group</div>
            <div id='grid'></div>
      </div>
      <div id="mapDiv" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'">
      </div>
    </div>
  </body>
</html>
0 Kudos
TracySchloss
Frequent Contributor
This helps so much, thanks! 

In the line
var template = '<div class="title">Record: ${0}</div><div class="subtitle"><div class="details">This block group has a median age of ${3} and a vacancy rate of ${2}. The percentage of families are ${1}</div>';


what do the numbers 0,1,2,3 relate to?  I would have thought this was the order of the attributes from the lines in the callback function, but that doesn't seem to be the case. Do they correspond to the order in the renderTable function?
return {
                    'med_age': feature.attributes.MED_AGE,
                    'vacant': feature.attributes.VACANT,
                    'families': feature.attributes.FAMILIES,
                    'id': feature.attributes.ObjectID
                  }


innerHTML : dojo.string.substitute(template,[obj.id,obj.families,obj.vacant,obj.med_age])
0 Kudos
KellyHutchins
Esri Frequent Contributor
That line of code is using dojo.string.substitute to add values into the middle of a text string. The values for 0,1,2,3 etc come from the order the info is provided to the substitute function. So in this example the value for 0 would be the id, 1 would be families etc....
dojo.string.substitute(template,[obj.id,obj.families,obj.vacant,obj.med_age])

Here's some additional info on substitute:

http://www.enterprisedojo.com/2011/10/14/coast-to-coast-with-dojo-string-substitute/



This helps so much, thanks! 


var template = '<div class="title">Record: ${0}</div><div class="subtitle"><div class="details">This block group has a median age of ${3} and a vacancy rate of ${2}. The percentage of families are ${1}</div>';


what do the numbers 0,1,2,3 relate to?  I would have thought this was the order of the attributes from the lines in the callback function, but that doesn't seem to be the case. Do they correspond to the order in the renderTable function?
return {                     'med_age': feature.attributes.MED_AGE,                     'vacant': feature.attributes.VACANT,                     'families': feature.attributes.FAMILIES,                     'id': feature.attributes.ObjectID                   }


innerHTML : dojo.string.substitute(template,[obj.id,obj.families,obj.vacant,obj.med_age])
0 Kudos
TracySchloss
Frequent Contributor
That was my guess and now it is working!  Thanks so much.

I'm creating a list of all features on the map, tying it to the map extent to limit just what is shown.   I really need the data to be sorted alphabetically, especially when the user is still zoomed out.  It looked like the dojox.datagrid had an option to set the sort index, but there doesn't seem to be such a thing in dgrid.

I'm thinking I'm going to have to do this on the data before I populate the grid?
0 Kudos
KellyHutchins
Esri Frequent Contributor
dgrid has a sort method. Just tested and it worked for me.

                //create an array of attributes for each group - we'll display these in a dojo dgrid
                data = dojo.map(response.features, function (feature) {
                  return {
                    'zone': feature.attributes.REGION,
                    'sqmi':feature.attributes.SQMI,
                    'id': feature.attributes.ObjectID
                  }
                });
                //create the grid
                grid = new dgrid.Grid({
                  renderRow: renderTable,
                  showHeader: false
                }, "grid");
                
                grid.renderArray(data);
                grid.sort('zone');


0 Kudos