Get Feature Layer Attributes for variable

3490
9
Jump to solution
09-12-2014 07:19 AM
DamienRobinson
New Contributor III

Hi,

I am working on a system by where a user can click a point on a map and this passes several variables to a form for submission. I have successfully pulled the XY coordinates from the click event into the form, using the following lines of code:

  x = evt.geometry.x.toFixed(3);
  y = evt.geometry.y.toFixed(3);

However a new requirement means I have to pull an ID (an attribute in a feature layer) on click. I've been searching through the JS API but none of the examples seem to cover this topic. There is plenty covering popups, queries, identify tasks etc., for displaying the infromation, however I want to simply pass it as a variable, similar to the the x and y variables above.

I intially looked at the infotemplate function, as a simple substitution variable seems to populate the correct information.

e.g.

var content = "<br><b>Test ID</b>: ${Test_ID}"
var infotemplate = new esri.InfoTemplate(); 
infotemplate.setContent(content); 

I don't know if it's possible to utilise the substitution variable (${Test_ID}) to pass the attribute to a form?

I've looked at the query and identify tasks however these return objects that I can't seem to pass the results of as a variable.

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Damien,

  Here is a sample using your test service. It write the attribute to the console.

<!DOCTYPE html>

<html>

  <head>

    <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>Shapes and Symbols</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">

    <style>

      #info {

        top: 20px;

        color: #444;

        height: auto;

        font-family: arial;

        right: 20px;

        margin: 5px;

        padding: 10px;

        position: absolute;

        width: 115px;

        z-index: 40;

        border: solid 2px #666;

        border-radius: 4px;

        background-color: #fff;

      }

      html, body, #mapDiv {

        padding:0;

        margin:0;

        height:100%;

      }

      button {

        display: block;

      }

    </style>

    <script src="http://js.arcgis.com/3.10/"></script>

    <script>

      var map, tb;

      require([

        "esri/map", "esri/toolbars/draw",

        "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol",

        "esri/symbols/PictureFillSymbol", "esri/symbols/CartographicLineSymbol",

        "esri/graphic", "esri/tasks/query", "esri/tasks/QueryTask",

        "esri/Color", "dojo/dom", "dojo/on", "dojo/domReady!"

      ], function(

        Map, Draw,

        SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol,

        PictureFillSymbol, CartographicLineSymbol,

        Graphic, Query, QueryTask,

        Color, dom, on

      ) {

        map = new Map("mapDiv", {

          basemap: "streets",

          center: [-25.312, 34.307],

          zoom: 3

        });

        map.on("load", initToolbar);

        // markerSymbol is used for point and multipoint, see http://raphaeljs.com/icons/#talkq for more examples

        var markerSymbol = new SimpleMarkerSymbol();

        markerSymbol.setPath("M16,4.938c-7.732,0-14,4.701-14,10.5c0,1.981,0.741,3.833,2.016,5.414L2,25.272l5.613-1.44c2.339,1.316,5.237,2.106,8.387,2.106c7.732,0,14-4.701,14-10.5S23.732,4.938,16,4.938zM16.868,21.375h-1.969v-1.889h1.969V21.375zM16.772,18.094h-1.777l-0.176-8.083h2.113L16.772,18.094z");

        markerSymbol.setColor(new Color("#00FFFF"));

        // lineSymbol used for freehand polyline, polyline and line.

        var lineSymbol = new CartographicLineSymbol(

          CartographicLineSymbol.STYLE_SOLID,

          new Color([255,0,0]), 10,

          CartographicLineSymbol.CAP_ROUND,

          CartographicLineSymbol.JOIN_MITER, 5

        );

        // fill symbol used for extent, polygon and freehand polygon

        var fillSymbol = new SimpleFillSymbol();

        function initToolbar() {

          tb = new Draw(map);

          tb.on("draw-end", addGraphic);

          // event delegation so a click handler is not

          // needed for each individual button

          on(dom.byId("info"), "click", function(evt) {

            if ( evt.target.id === "info" ) {

              return;

            }

            var tool = evt.target.id.toLowerCase();

            map.disableMapNavigation();

            tb.activate(tool);

          });

        }

        function addGraphic(evt) {

          //deactivate the toolbar and clear existing graphics

          tb.deactivate();

          map.enableMapNavigation();

          // figure out which symbol to use

          var symbol;

          if ( evt.geometry.type === "point" || evt.geometry.type === "multipoint") {

            symbol = markerSymbol;

          } else if ( evt.geometry.type === "line" || evt.geometry.type === "polyline") {

            symbol = lineSymbol;

          }

          else {

            symbol = fillSymbol;

          }

          map.graphics.add(new Graphic(evt.geometry, symbol));

          queryMapService(evt.geometry);

        }

       

        function queryMapService(Geom){

          var query = new Query();

          query.returnGeometry = false;  

          query.outFields = ["NIHE_AREA"];  

          query.geometry = Geom 

          var queryTask = new QueryTask("http://webservices.spatialni.gov.uk/arcgis/rest/services/NIHE/NIHEAreas/MapServer/1");  

          queryTask.on ("error", function (err) {  

            console.log("error in queryTask: " + err.message);  

          });  

          queryTask.execute(query, showResults);

        }

       

        function showResults(results) {

          var resultCount = results.features.length;

          var niheAreaName = "";

          for (var i = 0; i < resultCount; i++) {

            var featureAttributes = results.features.attributes;

            niheAreaName += featureAttributes["NIHE_AREA"] + ", ";

          }

          console.log(niheAreaName);

          map.graphics.clear();

        }

      });

    </script>

  </head>

 

  <body>

   

    <div id="info">

      <div>Select a shape then draw on map to add graphic</div>

      <button id="Point">Point</button>

      <button id="Multipoint">Multipoint</button>

      <button id="Line">Line</button>

      <button id="Polyline">Polyline</button>

      <button id="FreehandPolyline">Freehand Polyline</button>

      <button id="Triangle">Triangle</button>

      <button id="Extent">Rectangle</button>

      <button id="Circle">Circle</button>

      <button id="Ellipse">Ellipse</button>

      <button id="Polygon">Polygon</button>

      <button id="FreehandPolygon">Freehand Polygon</button>

    </div>

    <div id="mapDiv"></div>

  </body>

</html>

View solution in original post

9 Replies
RobertScheitlin__GISP
MVP Emeritus

Damien,

   You would have to use a QueryTask to get the attribute value of the desired feature and with the results of the QueryTask you would get the features attribute you are interested in and feed that value to whatever variable you define and pass it to the form just like you are doing for the X and Y variables.

0 Kudos
DamienRobinson
New Contributor III

Hi Robert,

Thanks for the quick reply! It greatly focusses my efforts. I haven't had to deal with query tasks in JS as of yet, so it's something i'm going to have to work on. I had jumped straight into the API for it without actually looking at the conceptual documentation. I found this article in the ESRI documentation that explains it well to a certain point. Using QueryTask, Query, and FeatureSet | Guide | ArcGIS API for JavaScript .

My knowledge/skills get patchy around the queryTask.execute and particularly how the results of the query task are returned from the showResults() function. I'm assuming I have to call executeQueryTask(dojo.byId().value); at some point in my script/form. Can i define the executeQueryTask(dojo.byId().value); as a variable, then pass the variable to my form like I do with the XY variables? 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Damien,

  Maybe you better outline your workflow and requirements better as you are loosing me with your line of questioning... I thought your requirement was to click on the map and query the feature that was clicked and get a certain attribute and send that attribute to a form? Is this right?

0 Kudos
DamienRobinson
New Contributor III

Hi Robert, My requirement is to click on the map, query the feature that was clicked and pass a certain attribute to a form. I was trying to describe that I can get as far as the actual execution of the query and then i hit a wall as to how I return the attribute from the executed query.

0 Kudos
JohnGrayson
Esri Regular Contributor

Damien,

     to get the attributes you'll first have to get to the Graphic itself.  Once you have the Graphic, you can use the 'attributes' property to get the necessary values.

graphic-amd | API Reference | ArcGIS API for JavaScript

     However, I would first ask, what is triggering the event?  There are several ways to get to the graphic you just clicked on.

Map: the map 'click' event will have a property called 'graphic' if you happen to click over a graphic. This can get slightly more complex if there are several GraphicsLayer or FeatureLayers in the map, as you'll have to make sure the graphic you just clicked on belongs to the layer your are interested in.  If you only have one GraphicsLayer or FeatureLayers in the map, this event could be all you need.

GraphicsLayer/FeatureLayer:  there are several events you can listen to, like 'click', that will be triggered only for the graphics in the layer.  These events will provide access to get the clicked graphic.

QueryTask: If you have, for example, an ArcGISDynamicMapServiceLayer, then you can use the QueryTask to go directly to the service endpoint to retrieve the features at the current location.

     Also, depending on functionality and needs, there are additional ways to get to the graphic and attributes; these are just the simplest ones.

0 Kudos
DamienRobinson
New Contributor III

Hi John,

Thanks for the info. I currently have only a single feature layer in this viewer and 2 x ArcGISTiledMapService layers.

In terms of triggering the event, the user clicks a button to activate the draw a point function, and on a single click that draws a point. I have to pull back XY (always) and additionally an ID (when the event falls within the feature layer). If the map click falls outside the feature layer the ID will be passed as null/empty.

0 Kudos
DamienRobinson
New Contributor III

At this stage I thought it would be better to post some code to remove some ambiguity!

The attachment test.html is a cut down version of my original. The original contains a feature layer that will be hosted on AGOL as a Feature Service and will query for a different attribute. The test.html version contains a public facing dynamic map service instead of a feature service.

I have managed to set up the query task, but I can't see how I can get the results of the query and pass it to the variable. Here is the code snippet:

   /*

  

    var queryTask = new QueryTask("http://webservices.spatialni.gov.uk/arcgis/rest/services/NIHE/NIHEAreas/MapServer/1");

    var query = new Query();

    query.returnGeometry = false;

    query.outFields = ["NIHE_AREA"];

   

    queryTask.execute(query);

   

    */

   

    // Get the result of query task and pass it to variable 

    niheAreaName = "";

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Damien,

  Here is a sample using your test service. It write the attribute to the console.

<!DOCTYPE html>

<html>

  <head>

    <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>Shapes and Symbols</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">

    <style>

      #info {

        top: 20px;

        color: #444;

        height: auto;

        font-family: arial;

        right: 20px;

        margin: 5px;

        padding: 10px;

        position: absolute;

        width: 115px;

        z-index: 40;

        border: solid 2px #666;

        border-radius: 4px;

        background-color: #fff;

      }

      html, body, #mapDiv {

        padding:0;

        margin:0;

        height:100%;

      }

      button {

        display: block;

      }

    </style>

    <script src="http://js.arcgis.com/3.10/"></script>

    <script>

      var map, tb;

      require([

        "esri/map", "esri/toolbars/draw",

        "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol",

        "esri/symbols/PictureFillSymbol", "esri/symbols/CartographicLineSymbol",

        "esri/graphic", "esri/tasks/query", "esri/tasks/QueryTask",

        "esri/Color", "dojo/dom", "dojo/on", "dojo/domReady!"

      ], function(

        Map, Draw,

        SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol,

        PictureFillSymbol, CartographicLineSymbol,

        Graphic, Query, QueryTask,

        Color, dom, on

      ) {

        map = new Map("mapDiv", {

          basemap: "streets",

          center: [-25.312, 34.307],

          zoom: 3

        });

        map.on("load", initToolbar);

        // markerSymbol is used for point and multipoint, see http://raphaeljs.com/icons/#talkq for more examples

        var markerSymbol = new SimpleMarkerSymbol();

        markerSymbol.setPath("M16,4.938c-7.732,0-14,4.701-14,10.5c0,1.981,0.741,3.833,2.016,5.414L2,25.272l5.613-1.44c2.339,1.316,5.237,2.106,8.387,2.106c7.732,0,14-4.701,14-10.5S23.732,4.938,16,4.938zM16.868,21.375h-1.969v-1.889h1.969V21.375zM16.772,18.094h-1.777l-0.176-8.083h2.113L16.772,18.094z");

        markerSymbol.setColor(new Color("#00FFFF"));

        // lineSymbol used for freehand polyline, polyline and line.

        var lineSymbol = new CartographicLineSymbol(

          CartographicLineSymbol.STYLE_SOLID,

          new Color([255,0,0]), 10,

          CartographicLineSymbol.CAP_ROUND,

          CartographicLineSymbol.JOIN_MITER, 5

        );

        // fill symbol used for extent, polygon and freehand polygon

        var fillSymbol = new SimpleFillSymbol();

        function initToolbar() {

          tb = new Draw(map);

          tb.on("draw-end", addGraphic);

          // event delegation so a click handler is not

          // needed for each individual button

          on(dom.byId("info"), "click", function(evt) {

            if ( evt.target.id === "info" ) {

              return;

            }

            var tool = evt.target.id.toLowerCase();

            map.disableMapNavigation();

            tb.activate(tool);

          });

        }

        function addGraphic(evt) {

          //deactivate the toolbar and clear existing graphics

          tb.deactivate();

          map.enableMapNavigation();

          // figure out which symbol to use

          var symbol;

          if ( evt.geometry.type === "point" || evt.geometry.type === "multipoint") {

            symbol = markerSymbol;

          } else if ( evt.geometry.type === "line" || evt.geometry.type === "polyline") {

            symbol = lineSymbol;

          }

          else {

            symbol = fillSymbol;

          }

          map.graphics.add(new Graphic(evt.geometry, symbol));

          queryMapService(evt.geometry);

        }

       

        function queryMapService(Geom){

          var query = new Query();

          query.returnGeometry = false;  

          query.outFields = ["NIHE_AREA"];  

          query.geometry = Geom 

          var queryTask = new QueryTask("http://webservices.spatialni.gov.uk/arcgis/rest/services/NIHE/NIHEAreas/MapServer/1");  

          queryTask.on ("error", function (err) {  

            console.log("error in queryTask: " + err.message);  

          });  

          queryTask.execute(query, showResults);

        }

       

        function showResults(results) {

          var resultCount = results.features.length;

          var niheAreaName = "";

          for (var i = 0; i < resultCount; i++) {

            var featureAttributes = results.features.attributes;

            niheAreaName += featureAttributes["NIHE_AREA"] + ", ";

          }

          console.log(niheAreaName);

          map.graphics.clear();

        }

      });

    </script>

  </head>

 

  <body>

   

    <div id="info">

      <div>Select a shape then draw on map to add graphic</div>

      <button id="Point">Point</button>

      <button id="Multipoint">Multipoint</button>

      <button id="Line">Line</button>

      <button id="Polyline">Polyline</button>

      <button id="FreehandPolyline">Freehand Polyline</button>

      <button id="Triangle">Triangle</button>

      <button id="Extent">Rectangle</button>

      <button id="Circle">Circle</button>

      <button id="Ellipse">Ellipse</button>

      <button id="Polygon">Polygon</button>

      <button id="FreehandPolygon">Freehand Polygon</button>

    </div>

    <div id="mapDiv"></div>

  </body>

</html>

DamienRobinson
New Contributor III

Hi Robert,

Thanks for this, it is exactly what I was looking for! It's a brilliant code sample! I was struggling conceptually to get the ESRI examples of the query task.

I was also trying to populate the variable outside of the showResults() function, however i now see that it is much easier to create the pop-up form within the showResults() function and populate the variable that way!

Thanks again!

0 Kudos