Unable to obtain datagrid object in javascript

4496
9
Jump to solution
08-05-2015 12:41 PM
TylerJones3
New Contributor III

I am attempting to write the results of a map search to a datagrid in a widget for ESRI's Web App Builder. I'm following an example from ESRI that comes from here: Show find task results in a DataGrid | ArcGIS API for JavaScript

The problem I am having is that I cannot obtain the datagrid object. On line 124 I receive this error message:

"resultsgrid.setStore is not a function"

It is apparent from the debug code that I am not actually obtaining the "real" datagrid object, but I cannot discern how to get it.

HTML:

<div>
     <div data-dojo-attach-point="SearchDiv" style="width:100%; height: 200px; background-color: #d9dde0";>
       <select class="select-type" id="SelectType" data-dojo-attach-point="selecttype">
          <option value="PoleNumber">Pole</option>
          <option value="TransformerNumber">Transformer</option>
          <option value="SWNO">SWNO</option>
       </select> 
      <input type="text" class="tb-searchvalue" id="SearchValue" maxlength="10" data-dojo-attach-point="tbsearchvalue">
      <button type="button" class="btn-search" data-dojo-attach-point="btnSearch" data-dojo-attach-event="onclick:_onPointBtnClicked">Search</button>
     
    </div>
    <div data-dojo-type="dijit/layout/BorderContainer" id="ResultsContainer" data-dojo-props="design:'headline'"  style="width:100%;height:100%;margin:0;">
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom'" style="height:150px;">
     <table data-dojo-type="dojox/grid/DataGrid" data-dojo-attach-point="TestGrid" class="results-datagrid" data-dojo-id="gridresults" id="grid" data-dojo-props="rowsPerPage:'10', rowSelector:'20px'" style="width:100%; height: 200px; background-color: #8080c0;">
      <thead>
        <tr>
          <th field="POLE_NO">PoleNumber</th>
          <th field="PNO">PNO</th>
        </tr>
      </thead>
    </table>
    </div>
  </div>

     
</div>

JS:


define([
    'dojo/parser',
    'dojo/_base/declare',
    'dojo/_base/lang',
    'dojo/_base/query',
    'dojo/_base/html',
    'dojo/_base/array',
    'dojo/_base/fx',
    'dojo/promise/all',
    'dojo/Deferred',
    'esri/map',
    'esri/graphic',
    'esri/graphicsUtils',
    'dojo/on',
    'jimu/BaseWidget',
    'dojo/dom',
    'dijit/registry',
    'dojo/_base/connect',
    'dojo/_base/array',
    'dojo/data/ItemFileReadStore',
    'esri/tasks/query',
    'esri/tasks/QueryTask',
    'esri/layers/FeatureLayer',
    'jimu/MapManager',
    
    'esri/geometry/Extent',
    'esri/Color',
    'esri/symbols/SimpleMarkerSymbol',
    'esri/symbols/SimpleLineSymbol',
    'esri/symbols/SimpleFillSymbol'
       
  ],
function(parser, declare, lang, query, html, array, fx, all, Deferred, Map, Graphic, graphicsUtils, on,  BaseWidget, dom, registry, connect, arrayUtils, ItemFileReadStore, Query, QueryTask,  FeatureLayer, MapManager,  Extent, Color, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol) { //a
  
  parser.parse();
  //To create a widget, you need to derive from BaseWidget.
  return declare([BaseWidget], { //b
    // Custom widget code goes here
   
    baseClass: 'jimu-widget-nessearch',
    name: 'Search',
    //this property is set by the framework when widget is loaded.
     //name: 'CustomWidget',
   //methods to communication with app container:

      
     postMixInProperties: function(){
        this.inherited(arguments);
        this.operationalLayers = [];
        var strClearResults = this.nls.clearResults;
//        var tip = esriLang.substitute({clearResults:strClearResults},this.nls.operationalTip);
//        this.nls.operationalTip = tip;
//        if(this.config){
//          this._updateConfig();
//        }
      },

   startup: function() { //c
    
//       this.mapIdNode.innerHTML = 'map id:' + this.map.id;
      console.log('startup');
   }, //c

  
   _onPointBtnClicked: function(){ //d
   
    
    var query = new Query();
    query.outSpatialReference = this.map.spatialReference; //The basemap's spatial reference does not match the other layers. Set the query to match.
    query.returnGeometry = true;
    
    
    this.map.graphics.clear();  
    switch (dom.byId("SelectType").selectedIndex) { //e
      case 0:  //First
         queryTask = new esri.tasks.QueryTask(<Layer 0);
      
        query.outFields = ["POLE_NO", "PNO", "NODE_ID"];
        query.where = "UPPER(POLE_NO) LIKE UPPER('%" + dom.byId("SearchValue").value + "%')";
        infoTemplate = new esri.InfoTemplate("${POLE_NO}", "Pole Number : ${POLE_NO}<br/> PNO : ${PNO}<br/> NODE_ID : ${NODE_ID}");
    

        break;
    
       
    } //e
    var markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 15, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([0, 0, 204]), 1.5),        new Color([0, 0, 255, 0.5]));
      
      
      
     
      queryTask.execute(query, lang.hitch(this, showResults))
    
      function showResults(featureSet) {
     
        //remove all graphics on the maps graphics layer
        
        //QueryTask returns a featureSet.  Loop through features in the featureSet and add them to the map.
        //Performance enhancer - assign featureSet array to a single variable.
        
           //New Datagrid code***********************************************
        //create array of attributes
          var items = arrayUtils.map(featureSet, function (result) {
           return result.feature.attributes;
          });

          //Create data object to be used in store
          var data = {
            identifier : "POLE_NO", //This field needs to have unique values
            label : "PoleNumber", //Name field for display. Not pertinent to a grid but may be used elsewhere.
            items : items
          };

          //Create data store and bind to grid.
          store = new ItemFileReadStore({
            data : data
          });
          
          
          var resultsgrid = registry.byId("grid");
          //var resultsgrid = dom.byId("grid");
          resultsgrid.setStore(store);
          resultsgrid.on("rowclick", onRowClickHandler);

            var myFeatureExtent = esri.graphicsExtent(resultFeatures);
            this.map.setExtent(myFeatureExtent.expand(2.5));
        //****************************************************************
                 var resultFeatures = featureSet.features;
        if (resultFeatures.length > 0) {
          
        
          for (var i = 0, il = resultFeatures.length; i < il; i++) {
            //Get the current feature from the featureSet.
            //Feature is a graphic
            var graphic = resultFeatures;
            graphic.setSymbol(markerSymbol);
            
            //Set the infoTemplate.
            graphic.setInfoTemplate(infoTemplate);
            
            //Add graphic to the map graphics layer.
            this.map.graphics.add(graphic);
            
            var myFeatureExtent = esri.graphicsExtent(resultFeatures);
            this.map.setExtent(myFeatureExtent.expand(2.5));
            
          }
        }else{
        //alert("No features were found using the provided search string.");
        }
      }
    
    return;
    
  } //d
    

  
  }); //b
}); //a
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Tyler,

  I did not take time initially to check your code. Well you have several issues in your code. Here is your Widegt.js and Widget.html Updated with comments

View solution in original post

9 Replies
RobertScheitlin__GISP
MVP Emeritus

Tyler,

  When you are working with templated widgets you access html components using the data-dojo-attach-point.

So your code should be:

          //var resultsgrid = registry.byId("grid"); 
          //var resultsgrid = dom.byId("grid"); 
          TestGrid.setStore(store); 
          TestGrid.on("rowclick", onRowClickHandler);
TylerJones3
New Contributor III

I have made the change to my code. I now receive this error:

ReferenceError: TestGrid is not defined.

The error occurs on the TestGrid.setStore(store); line.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Tyler,

  Sorry I forgot to include this dot

          //var resultsgrid = registry.byId("grid");   
          //var resultsgrid = dom.byId("grid");   
          this.TestGrid.setStore(store);   
          this.TestGrid.on("rowclick", onRowClickHandler);
TylerJones3
New Contributor III

I added "this."; now a new error:

TypeError: this.TestGrid.setStore is not a function

When stepping through the code in the debugger, it shows TestGrid as this (I do not know if this of any help or not):

  1. TestGrid: table#grid.results-datagrid
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Tyler,

  I did not take time initially to check your code. Well you have several issues in your code. Here is your Widegt.js and Widget.html Updated with comments

TylerJones3
New Contributor III

I'll owe you a beverage or three at the next dev conference. I'm new to javascript and the web app developer and your help is much appreciated. That cleanup of my code is much appreciated.

I'll be posting a more complete version of the script code once I've gotten a few more pieces working.

0 Kudos
RyanSellman
Occasional Contributor II

Hello All,

I too am having a similar issue populating a DataGrid from a query, within a Web AppBuilder widget.  I looked at the corrected code that Robert posted, but can't figure out why my implementation will not work.  Below is pertinent widget code.  I am getting an error on the grid's setStore method.  Console says, "this.dGrid.setStore is not a function".

define(['dojo/_base/declare', 'jimu/BaseWidget', 'esri/tasks/query', 'dojo/keys', 'esri/geometry/Extent', 'dojo/data/ItemFileReadStore', 'esri/graphicsUtils', 'esri/symbols/SimpleFillSymbol', 'esri/symbols/SimpleLineSymbol','esri/layers/FeatureLayer', 'dojo/_base/array','dojox/grid/DataGrid', 'dojo/_base/lang', 'dojo/dom'],
   function(declare, BaseWidget, Query, keys, Extent, ItemFileReadStore, graphicsUtils, SimpleFillSymbol, SimpleLineSymbol, FeatureLayer, array, DataGrid, lang, dom) {

  var clickEvent, featureLayerParcel;

    return declare([BaseWidget], {
   
  baseClass: 'jimu-widget-mywidget',
  name: 'My Widget',

  postCreate: function() {
  console.log('onPostCreate');
  },


        startup: function() {
  this.inherited(arguments);

  var layout = [
   {'name': 'PARID', 'field': 'PARID', 'width': 'auto'},
   {'name': 'Address', 'field': 'ADDR', 'width': 'auto'},
   {'name': 'Owner', 'field': 'OWN1', 'width': 'auto'},
  ];

  var grid = new DataGrid({
  structure: layout
  }, this.dGrid);


  grid.startup();
  console.log('startup, creating grid');

        },


       onOpen: function(){
        console.log('onOpen');
       },


       onClose: function(){
         console.log('onClose');
       },


       onMinimize: function(){
         console.log('onMinimize');
       },


       onMaximize: function(){
         console.log('onMaximize');
       },


       onPositionChange: function(){
         console.log('onPositionChange');
       },
    

    
  _queryParcels: function(){

  console.log(event);

  if (event.keyCode === keys.ENTER || event.type === "click") {

  var value = this.parcelText.value;

  var parcelsUrl = "http://summitmaps.summitoh.net/arcgis/rest/services/ParcelQuery/MapServer/1";
   
  featureLayerParcel = new esri.layers.FeatureLayer(parcelsUrl, {
  mode: esri.layers.FeatureLayer.MODE_SELECTION,
  visible: true,
  outFields: ["*"]
  });
   
  var symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_NULL, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new dojo.Color([0, 255, 255]), 2), new dojo.Color([0, 0, 255, 0.20]));
  featureLayerParcel.setSelectionSymbol(symbol);
  this.map.addLayer(featureLayerParcel);
   
  var queryParcels, store;
   
  queryParcels = new esri.tasks.Query();
  queryParcels.where = "PARID LIKE '" + "%" + value + "'";
  featureLayerParcel.selectFeatures(queryParcels, esri.layers.FeatureLayer.SELECTION_NEW, lang.hitch(this, function(features, selectionMethod) {

  console.log(features.length);
  this.map.setExtent(graphicsUtils.graphicsExtent(featureLayerParcel.getSelectedFeatures()).expand(3), true);

  var parcelItems = array.map(features, function(feature) {
                         return feature.attributes;
                     });
   
  store = new ItemFileReadStore({
  data: {
  idenitifer: "OBJECTID",
  items: parcelItems
  }
  });

  this.dGrid.setStore(store);

  }));
   
  } 

     }
    
    });
  });
<div>
    <div>This is my widget.  Hello world!</div>
  <input type="number" style="width:99%" class="jimu-input" data-dojo-attach-point="parcelText" data-dojo-props="placeholder: 'Parcel Number'" data-dojo-attach-event="onKeyDown:_queryParcels"/>
  <hr>
  <input type="button" value="Search" class="jimu-btn" data-dojo-attach-point="queryParcelButton" data-dojo-attach-event="onclick:_queryParcels">
  <hr>
  <div data-dojo-attach-point="dGrid"></div>
</div>

Any help is much appreciated!

Ryan

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Ryan,

   Just took a quick glance at your code and the var "this.dgrid" is the dom div not the actual grid object. "grid" is the var name to the actual grid object so you should use:

grid.setStore(store);

RyanSellman
Occasional Contributor II

Robert,

That was it.  I knew it was something simple.  Thank you so much!

Ryan