Select to view content in your preferred language

DataGrid with zoom button...button doesn't show and won't zoom

2649
16
01-30-2014 05:23 AM
MichelleRogers1
Occasional Contributor
I am new at working with ArcGIS API for JavaScript and have come across the following problem:

I am working with the sample DataGrid with zoom button to get my data to zoom to a specific point, but not only is the data not zooming, the button isn't even showing inside the grid.  Instead it is showing the OBJECTID.  Any suggestions on how to fix this?

Here is part of the  JavaScript code I am working with:

policeUnits2 = new esri.layers.FeatureLayer
("http://GIS10204:6080/arcgis/rest/services/GeoEvent/gx440P/MapServer/0",{
mode:esri.layers.FeatureLayer.MODE_SELECTION,
outFields:["VehicleId", "Velocity", "OBJECTID"]
});
  
//define a selection symbol
var highlightSymbol = new esri.symbol.SimpleFillSymbol().setColor( new dojo.Color([50,205,50,.25]));
policeUnits2.setSelectionSymbol(highlightSymbol);

dojo.connect(policeUnits2,'onLoad',function(layer){
var query = new esri.tasks.Query();
query.where = "1=1";
layer.queryFeatures(query,function(featureSet){
  var items = dojo.map(featureSet.features,function(feature){
   return feature.attributes;
  });
  var data = {
   identifier:"OBJECTID",
   items:items};
  store = new dojo.data.ItemFileReadStore({data:data});
  grid.setStore(store);
  grid.setSortIndex(1,"true"); //sort on VehicleId
});
});
map.addLayer([policeUnits2]);

//modify the grid so only the VehicleId field is sortable
grid.canSort = function(col){ if(Math.abs(col) == 2) { return true; } else { return false; } };
  
function makeZoomButton(id){
var zBtn = "<div data-dojo-type='dijit/form/Button'><img src='images/zoom.png'";
zBtn = zBtn + " width='18' height='18'";
zBtn = zBtn + " onClick=\"zoomRow('"+id+"')\"></div>";
return zBtn;
}
function zoomRow(id){
policeUnits2.clearSelection();
var query = new esri.tasks.Query();
query.objectIds = [id];
policeUnits2.selectFeatures(query,esri.layers.FeatureLayer.SELECTION_NEW,function(features){
  //zoom to the selected feature
  var unitExtent = features[0].geometry.getExtent().expand(1.0);
  map.setExtent(unitExtent);
});
}


This is the html code:
<body class="claro">
<div data-dojo-type="dijit/layout/BorderContainer" style="width: 100%; height: 100%">
  <div data-dojo-type="dijit/layout/ContentPane"  id="header" data-dojo-props="region:'top'">City of Naples Police AVL
   <div id="locateContainer">
    <label>Address: </label>
    <input id='addressInput'></input>
   </div>
  </div>
  <div id="mapDiv" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">
   <div id="BasemapToggle" ></div>
   <div id="HomeButton"></div>
  </div>
  <div data-dojo-type="dijit/layout/ContentPane" id="leftPane" data-dojo-props="region:'leading'">
   <table data-dojo-type="dojox/grid/DataGrid" jsid="grid" id="grid" selectionMode="none">
    <thead>
     <tr>
      <th field="OBJECTID" formatter="makeZoomButton" width="25px">
      <img alt="+" src="images/zoom.png"/>
      </th>
      <th field="VehicleId" width="100px">Vehicle Id</th>
     </tr>
    </thead>
   </table>
  </div>
        </div>
</body>


Here is a picture of what my viewer looks like
[ATTACH=CONFIG]30965[/ATTACH]

Any help would be very much appreciated!
Michelle
0 Kudos
16 Replies
JakeSkinner
Esri Esteemed Contributor
Hi Michelle,

I'm not sure why the zoom.png is not showing in your datagrid, but I think I know why it is not zooming to your data.  Since you are using point data, you will need to define an extent.  Point data will only have an X & Y coordinate value.  Here is function you can add to do this:

function pointToExtent(map, pointX, pointY, tolerance){
    var xmin = pointX - tolerance;
    var ymin = pointY - tolerance;
    var xmax = pointX + tolerance;
    var ymax = pointY + tolerance;
    
    return new esri.geometry.Extent(xmin, ymin, xmax, ymax, map.spatialReference)
}


You can then update the zoomRow function to use this:

function zoomRow(id){
    policeUnits2.clearSelection();
    var query = new esri.tasks.Query();
    query.objectIds = [id];
    policeUnits2.selectFeatures(query,esri.layers.FeatureLayer.SELECTION_NEW,function(features){
      extent = pointToExtent(map, features[0].geometry.x, features[0].geometry.y, 6)
      map.setExtent(extent);
    });
}


Also, I believe you will need to update the higlightSymbol since you are using point data.  Try using the SimpleMarkSymbol.  Ex:

var highlightSymbol = new esri.symbol.SimpleMarkerSymbol({
      "color": [255,255,255,64],
      "size": 12,
      "angle": -30,
      "xoffset": 0,
      "yoffset": 0,
      "type": "esriSMS",
      "style": "esriSMSCircle",
      "outline": {
        "color": [0,0,0,255],
        "width": 1,
        "type": "esriSLS",
        "style": "esriSLSSolid"
      }
    });
policeUnits2.setSelectionSymbol(highlightSymbol);
0 Kudos
MichelleRogers1
Occasional Contributor
I added the code that you suggested, but it still doesn't work.  I am going to copy and paste the entire code here, so you can see if there is a conflict with something else that I am doing.

<!DOCTYPE html>
<html>
 <head>
  <meta http-equiv="cache-control" content="max-age=0" />
  <meta http-equiv="cache-control" content="no-cache" />
  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
  <META HTTP-EQUIV="Expires" CONTENT="-1">
 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <!--The viewport meta tag is used to improve the presentation and behavior of the samples on iOS devices-->
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">    
  <title>Police AVL</title>
  <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/dojo/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css">
  <style type="text/css">
  .dj_ie .infowindow .window .top .right .user .content { position: relative; }
  .dj_ie .simpleInfoWindow .content {position: relative;}
  </style>
  <style> 
   html, body, #main { height: 100%; width: 100%; margin: 0; padding: 0; overflow:hidden; }
   #leftPane{
    height:100%;
    width:25%;
    font-family:"Roboto Condensed", sans-serif;
    font-size: 0.90em;
   }
   #mapDiv {
    height:100%;
    width:75%;
    margin:0;
    padding:0;
   }
   #header{
    font-weight:600;
    font-size:14pt;
    color:#666666;
    padding-left:20px;
   }
   #HomeButton {
    position: absolute;
    top: 90px;
    left: 20px;
    z-index: 50;
   }
   #BasemapToggle {
    position: absolute;
    top: 10px;
    right: 20px;
    z-index: 50;
   }
   #locateContainer{
    position:absolute;
    right:10px;
    top:5px;
    border-radius:5px;
   }
   
  </style>
  <script src="http://js.arcgis.com/3.8/"></script>
  <script>
   var map;
   require([
    "esri/map", "esri/InfoTemplate", "esri/layers/FeatureLayer",
    "dojo/parser", "esri/dijit/HomeButton", "esri/dijit/BasemapToggle",
    "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
    "dijit/form/Button", "dijit/form/TextBox", "dojox/grid/DataGrid",
    "dojo/data/ItemFileReadStore", "dojo/domReady!"
   ], function(
    Map, InfoTemplate, FeatureLayer,
    parser, HomeButton, BasemapToggle
   ) {
    parser.parse();
    map = new Map("mapDiv", {
     basemap: "topo",
     center: [-81.797, 26.153],
     zoom: 12
    });
    //Address Locator
    dojo.connect(dojo.byId("addressInput"), 'onkeyup',function(event){
     if(event.keyCode == 13 && this.value.length>0){
     locateAddress(this.value);
     }
    });

    //Create Home Button
    var home = new HomeButton({
     map:map
    }, "HomeButton");
    home.startup();
    //Create Basemap Toggle
    var toggle = new BasemapToggle ({
     map:map,
     basemap: "hybrid"
    }, "BasemapToggle");
    toggle.startup();

    map.on("load", initOperationalLayer);
    

    function initOperationalLayer() {
     var infoTemplate = new InfoTemplate("${VehicleId}", "Speed: ${Velocity:NumberFormat} MPH");
     var policeUnits = new FeatureLayer("http://GIS10204:6080/arcgis/rest/services/GeoEvent/gx440P/MapServer/0",{
      mode: FeatureLayer.MODE_ONDEMAND,
      outFields: ["*"],
      infoTemplate: infoTemplate
     });

                    map.addLayer(policeUnits);
     policeUnits.setRefreshInterval(0.083);
     map.infoWindow.resize(155,75);
     
    }

    function locateAddress(atText){
     var l = esri.tasks.Locator('http://gis.naplesgov.com/naplesgis/rest/services/Locators/Naples_Address_Locator/GeocodeServer');
     l.outSpatialReference = map.spatialReference;
     var params = {address : {'Single Line Input': atText}};
     l.addressToLocations(params, function(c){
     if(c.length == 0){
      alert("No location found at this address");
     }
     var currentLoc = c[0].location;
    var g = new esri.Graphic(currentLoc);
    map.graphics.clear();
    map.graphics.add(g);
     map.centerAndZoom(currentLoc,19);
     },
    function(){
     console.log("No location found at this address");
     })
    }
    
    policeUnits2 = new esri.layers.FeatureLayer
    ("http://GIS10204:6080/arcgis/rest/services/GeoEvent/gx440P/MapServer/0",{
    mode:esri.layers.FeatureLayer.MODE_SELECTION,
    outFields:["VehicleId", "Velocity", "OBJECTID"]
    });
   
    //define a selection symbol
    var highlightSymbol = new esri.symbol.SimpleMarkerSymbol({
     "color":[255,255,255,64],
     "size":12,
     "angle":-30,
     "xoffset":0,
     "yoffset":0,
     "type":"esriSMS",
     "style":"esriSMSCircle",
     "outline":{
     "color":[0,0,0,255],
     "width":1,
     "type":"esriSLS",
     "style":"esriSLSSolid"
     }
    });
    policeUnits2.setSelectionSymbol(highlightSymbol);

    dojo.connect(policeUnits2,'onLoad',function(layer){
     var query = new esri.tasks.Query();
     query.where = "1=1";
     layer.queryFeatures(query,function(featureSet){
      var items = dojo.map(featureSet.features,function(feature){
       return feature.attributes;
      });
      var data = {
       identifier:"OBJECTID",
       items:items};
      store = new dojo.data.ItemFileReadStore({data:data});
      grid.setStore(store);
      grid.setSortIndex(1,"true"); //sort on VehicleId
     });
    });
    map.addLayer([policeUnits2]);

    //modify the grid so only the VehicleId field is sortable
    grid.canSort = function(col){ if(Math.abs(col) == 2) { return true; } else { return false; } };
   
    function makeZoomButton(id){
     var zBtn = "<div data-dojo-type='dijit/form/Button'><img src='images/zoom.png'";
     zBtn = zBtn + " width='18' height='18'";
     zBtn = zBtn + " onClick=\"zoomRow('"+id+"')\"></div>";
     return zBtn;
    }
    
    function pointToExtent(map, pointX, pointY, tolerance){
     var xmin = pointX - 100;
     var ymin = pointY - 100;
     var xmax = pointX + 100;
     var ymax = pointY + 100;
      return new esri.geometry.Extent(xmin, ymin, xmax, ymax, map.spatialReference)
    }
    
    function zoomRow(id){
     policeUnits2.clearSelection();
     var query = new esri.tasks.Query();
     query.objectIds = [id];
     policeUnits2.selectFeatures(query,esri.layers.FeatureLayer.SELECTION_NEW,function(features){
      extent = pointToExtent(map, features[0].geometry.x, features[0].geometry.y, 6)
      map.setExtent(extent);
      //zoom to the selected feature
      //var unitExtent = features[0].geometry.getExtent().expand(1.0);
      //map.setExtent(unitExtent);
     });
    }
    
    
    var cityLimits = new esri.layers.ArcGISDynamicMapServiceLayer("http://gis.naplesgov.com/naplesgis/rest/services/City/CityLimits/MapServer");
    map.addLayer(cityLimits);
    
    var addressPoints = new esri.layers.ArcGISDynamicMapServiceLayer("http://gis.naplesgov.com/naplesgis/rest/services/City/AddressPointSlbl/MapServer");
    map.addLayer(addressPoints);  
    
   });
  </script>
 </head>
 <body class="claro">
  <div data-dojo-type="dijit/layout/BorderContainer" style="width: 100%; height: 100%">
   <div data-dojo-type="dijit/layout/ContentPane"  id="header" data-dojo-props="region:'top'">City of Naples Police AVL
    <div id="locateContainer">
     <label>Address: </label>
     <input id='addressInput'></input>
    </div>
   </div>
   <div id="mapDiv" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">
    <div id="BasemapToggle" ></div>
    <div id="HomeButton"></div>
   </div>
   <div data-dojo-type="dijit/layout/ContentPane" id="leftPane" data-dojo-props="region:'leading'">
    <table data-dojo-type="dojox/grid/DataGrid" jsid="grid" id="grid" selectionMode="none">
     <thead>
      <tr>
       <th field="OBJECTID" formatter="makeZoomButton" width="25px">
       <img alt="+" src="images/zoom.png"/>
       </th>
       <th field="VehicleId" width="100px">Vehicle Id</th>
      </tr>
     </thead>
    </table>
   </div>
        </div>
 </body>
</html>
0 Kudos
JakeSkinner
Esri Esteemed Contributor
With the AMD model, it's not as easy to call a function from HTML.  It's recommended to call the dom/dijit, and then execute the event.  In the code you provided, you are calling the 'makeZoomButton' from the DataGrid.  I couldn't figure out how to execute this function by calling the DataGrid dijit, however, I have a workaround that you can use.  Add the following to your code:

var grid1 = dijit.byId("grid");
on(grid1,"rowClick", onRowClickHandler)
                              
function onRowClickHandler(evt){
             policeUnits2.clearSelection();
                    
             var id= grid1.getItem(evt.rowIndex).OBJECTID;                    
             var query = new esri.tasks.Query();
             query.objectIds = [id];
             policeUnits2.selectFeatures(query,esri.layers.FeatureLayer.SELECTION_NEW,function(features){
             extent = pointToExtent(map, features[0].geometry.x, features[0].geometry.y)
             map.setExtent(extent);                      
             });
}
0 Kudos
MichelleRogers1
Occasional Contributor
Jake,

Would I just add this code under the code that I already have for function zoomRow, or do I need to replace code that is there already?

Thanks!

With the AMD model, it's not as easy to call a function from HTML.  It's recommended to call the dom/dijit, and then execute the event.  In the code you provided, you are calling the 'makeZoomButton' from the DataGrid.  I couldn't figure out how to execute this function by calling the DataGrid dijit, however, I have a workaround that you can use.  Add the following to your code:

var grid1 = dijit.byId("grid");
on(grid1,"rowClick", onRowClickHandler)
                              
function onRowClickHandler(evt){
             policeUnits2.clearSelection();
                    
             var id= grid1.getItem(evt.rowIndex).OBJECTID;                    
             var query = new esri.tasks.Query();
             query.objectIds = [id];
             policeUnits2.selectFeatures(query,esri.layers.FeatureLayer.SELECTION_NEW,function(features){
             extent = pointToExtent(map, features[0].geometry.x, features[0].geometry.y)
             map.setExtent(extent);                      
             });
}
0 Kudos
JakeSkinner
Esri Esteemed Contributor
You can delete the 'zoomRow' function and add this code.
0 Kudos
MichelleRogers1
Occasional Contributor
Jake,

I just tried it, and it's still not zooming.  Would I change the code in makeZoomButton below, that shows the zoomRow, since it is no longer there, and what would I replace it with?

Sorry, I am new to this kind of coding, and I have just been taking code snippets out of ESRI samples and putting them together, so any help is appreciated.


zBtn = zBtn + " onClick=\"zoomRow('"+id+"')\"></div>";
0 Kudos
MichelleRogers1
Occasional Contributor
Also, when I use the Debugger tools in Internet Explorer, it is telling me that 'on' is undefined in
on(grid1, "rowClick", onRowClickHandler)


Jake,

I just tried it, and it's still not zooming.  Would I change the code in makeZoomButton below, that shows the zoomRow, since it is no longer there, and what would I replace it with?

Sorry, I am new to this kind of coding, and I have just been taking code snippets out of ESRI samples and putting them together, so any help is appreciated.


zBtn = zBtn + " onClick=\"zoomRow('"+id+"')\"></div>";
0 Kudos
JakeSkinner
Esri Esteemed Contributor
That was my mistake.  I forgot to mention that you will need to import the dojo/dom and dojo/on modules.  Try the attached.
0 Kudos
MichelleRogers1
Occasional Contributor
I tried literally copying and pasting your exact code that you gave me, still no luck with the zoom function.  Now it is giving me the error:

dojo.io.script error Error: Failed to execute query.

This is when I click on the OBJECTID.  The map is not showing once I click either.  This is the screenshot:

[ATTACH=CONFIG]31024[/ATTACH]

We have another ESRI person on it from talking on the phone with him yesterday, so I think we have something that has stumped two of you.:)

That was my mistake.  I forgot to mention that you will need to import the dojo/dom and dojo/on modules.  Try the attached.
0 Kudos