How to add a ZoomTo button in my attributeInspector

2103
3
Jump to solution
01-27-2016 08:08 AM
TracySchloss
Frequent Contributor

I would like to have a ZoomTo button in my AttributeInspector dialog.  I see it in the actionPane, but hidden, I assume because the tool wouldn't actually work if I displayed that pane.  I'm working at a state-wide perspective and my users are used to being able to zoom in closer to a location from an information tag.

The attributeInspector is part of my Editor constructor, and not something I've defined by itself.

  initEditor: function (evt, geometryService, map) {
    var layers = [];
       var templatePicker = new TemplatePicker({
            featureLayers: [app.eusLayer],
            columns: 1,
            style: "height: 100%; width: 150px; border: 2px",
            showTooltip: true
          }, "templateDiv");
          templatePicker.startup();

        layers.push({featureLayer: app.eusLayer });
       var settings = {
            map: map,
            templatePicker: templatePicker,
            geometryService: geometryService,
            layerInfos: layers,
            toolbarVisible: false
          };

          var params = { settings: settings };
          app.myEditor = new Editor(params, 'editorDiv');

          app.myEditor.startup();
          var itmLbl = query('.itemLabel');
         itmLbl[0].innerHTML = 'Click to Add New Staff';
         esriBundle.widgets.attributeInspector.NLS_deleteFeature = "Delete Staff Location"; 
         
         on(templatePicker, 'selection-change', function (evt)  {
            app.editEnabled = true;
         });
         
        var attInspector = app.myEditor.attributeInspector;
        on (attInspector, 'attribute-change', function (evt) {
         app.editEnabled = false;

        });
      }  

I have a chunk of code I've used in the past to add a ZoomTo button to an infoTemplate, because when using bootstrap style, it doesn't include one for some reason.  This likely needs to be modified for this purpose.  I'm also not sure where this goes.

        var link = dom.byId('zoomLink');
           if (!link ) {
            link = domConstruct.create("a", {
             "class": "action zoomTo myZoom",
             "id": "zoomLink",
             "title": "Zoom in",
             "innerHTML": "Zoom To", //text that appears in the popup for the link
             "href": "javascript: void(0);"
             }, query(".sizer", app.map.infoWindow.domNode)[1]);         
           }
          on(link, "click", zoomTo);    

       function zoomTo(){
            var geom = currentGraphic.geometry;
            var lod = app.map.getLevel();
            app.map.centerAndZoom(geom, lod + 4);
            app.map.infoWindow.setFeatures(currentGraphic);
            app.map.infoWindow.show(geom);           
          }
0 Kudos
1 Solution

Accepted Solutions
TracySchloss
Frequent Contributor

My solution needed a little tweaking.  Here's the final:

    on (app.eusLayer, "click", function (evt) {
      app.feat = evt.graphic;
      if (!dom.byId('zoomLink')) {
        app.link = domConstruct.create("a", {
          "class": "action zoomTo myZoom",
          "id": "zoomLink",
          "title": "My Zoom",
          "innerHTML": "Zoom To",
          "href": "javascript: void(0);"
        }, query(".sizer", app.myEditor.attributeInspectordomNode)[1]);
          on (app.link,"click", function(){
              app.map.infoWindow.hide();
              var geom = app.feat.geometry;
              var lod = app.map.getLevel();
              if (geom.type === 'point') {
                app.map.centerAndZoom(geom, lod + 4);
              }  else {
                app.map.setExtent(geom.getExtent(), true);
              } 
            });
          }
        app.eusLayer.clearSelection();
    });

View solution in original post

0 Kudos
3 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Tracy,

  Here is a sample that adds a zoom to and save button to the attribute inspector:

<!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>Editable FeatureLayer in Selection Only Mode with Attribute Inspector</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.12/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.12/esri/css/esri.css">
    <style>
      html, body {
        height: 100%; width: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }
      #mapDiv{
        margin: 0;
        padding:0;
      }
      #detailPane{
        height:20px;
        color:#570026;
        font-size:12pt;
        font-weight:600;
        overflow:hidden;
      }
      .dj_ie .infowindow .window .top .right .user .content { position: relative; }
      .dj_ie .simpleInfoWindow .content {position: relative;}

      .esriAttributeInspector {height:100px;}
      .esriAttributeInspector .atiLayerName {display:none;}

      .esriAttributeInspector .atiButton{
        margin-top:1px;
        margin-right:45px;
       }
    </style>

    <script src="http://js.arcgis.com/3.12/"></script>
    <script>
      var map;
      var updateFeature;

      require([
        "esri/map",
        "esri/layers/FeatureLayer",
        "esri/dijit/AttributeInspector",

        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/SimpleFillSymbol",
        "esri/Color",

        "esri/layers/ArcGISDynamicMapServiceLayer",
        "esri/config",

        "esri/tasks/query",
        "dojo/query",
        "dojo/parser",
        "dojo/dom-construct",
        "dijit/form/Button",

        "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojo/domReady!"
      ], function(
        Map, FeatureLayer, AttributeInspector,
        SimpleLineSymbol, SimpleFillSymbol, Color,
        ArcGISDynamicMapServiceLayer, esriConfig,
        Query,dojoQuery,
        parser, domConstruct, Button
      ) {
        parser.parse();

        // refer to "Using the Proxy Page" for more information:  https://developers.arcgis.com/javascript/jshelp/ags_proxy.html
        esriConfig.defaults.io.proxyUrl = "/proxy/";

        map = new Map("mapDiv", {
          basemap: "streets",
          center: [-97.395, 37.537],
          zoom: 11
        });

        map.on("layers-add-result", initSelectToolbar);

        var petroFieldsMSL = new ArcGISDynamicMapServiceLayer("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Petroleum/KSFields/MapServer");
        petroFieldsMSL.setDisableClientCaching(true);
        map.addLayer(petroFieldsMSL);

        var petroFieldsFL = new FeatureLayer("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Petroleum/KSFields/FeatureServer/0", {
          mode: FeatureLayer.MODE_SELECTION,
          outFields: ["approxacre", "objectid", "field_name", "activeprod", "cumm_oil", "cumm_gas", "avgdepth"]
        });
        var selectionSymbol = new SimpleFillSymbol(
            SimpleFillSymbol.STYLE_NULL,
            new SimpleLineSymbol(
                "solid",
                new Color("yellow"),
                2
            ),
            null
        );
        petroFieldsFL.setSelectionSymbol(selectionSymbol);

        petroFieldsFL.on("edits-complete", function() {
          petroFieldsMSL.refresh();
        });

        map.addLayers([petroFieldsFL]);

        function initSelectToolbar(evt) {
          var petroFieldsFL = evt.layers[0].layer;
          var selectQuery = new Query();

          map.on("click", function(evt) {
            selectQuery.geometry = evt.mapPoint;
            petroFieldsFL.selectFeatures(selectQuery, FeatureLayer.SELECTION_NEW, function(features) {
              if (features.length > 0) {
                //store the current feature
                updateFeature = features[0];
                map.infoWindow.setTitle(features[0].getLayer().name);
                map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint));
              }
              else {
                map.infoWindow.hide();
              }
            });
          });

          map.infoWindow.on("hide", function() {
            petroFieldsFL.clearSelection();
          });

          var layerInfos = [
            {
              'featureLayer': petroFieldsFL,
              'showAttachments': false,
              'isEditable': true,
              'fieldInfos': [
                {'fieldName': 'activeprod', 'isEditable': true, 'tooltip': 'Current Status', 'label': 'Status:'},
                {'fieldName': 'field_name', 'isEditable': true, 'tooltip': 'The name of this oil field', 'label': 'Field Name:'},
                {'fieldName': 'approxacre', 'isEditable': false, 'label': 'Acreage:'},
                {'fieldName': 'avgdepth', 'isEditable': false, 'label': 'Average Depth:'},
                {'fieldName': 'cumm_oil', 'isEditable': false, 'label': 'Cummulative Oil:'},
                {'fieldName': 'cumm_gas', 'isEditable': false, 'label': 'Cummulative Gas:'}
              ]
            }
          ];

          var attInspector = new AttributeInspector({
            layerInfos: layerInfos
          }, domConstruct.create("div"));

          //add a zoom button next to the delete button
          var zoomButton = new Button({ label: "Zoom To", "class": "zoomButton atiButton"},domConstruct.create("div"));
          domConstruct.place(zoomButton.domNode, attInspector.deleteBtn.domNode, "after");

          zoomButton.on("click", function() {
            console.info(updateFeature);
            var geom = updateFeature.geometry;
            var lod = map.getLevel();
            if(geom.type === 'point'){
              map.centerAndZoom(geom, lod + 4);
            }else{
              map.setExtent(geom.getExtent(), true);
            }

          });

          //add a save button next to the delete button
          var saveButton = new Button({ label: "Save", "class": "saveButton atiButton"},domConstruct.create("div"));
          domConstruct.place(saveButton.domNode, attInspector.deleteBtn.domNode, "after");

          saveButton.on("click", function() {
            updateFeature.getLayer().applyEdits(null, [updateFeature], null);
          });

          attInspector.on("attribute-change", function(evt) {
            //store the updates to apply when the save button is clicked
            updateFeature.attributes[evt.fieldName] = evt.fieldValue;
          });

          attInspector.on("next", function(evt) {
            updateFeature = evt.feature;
            console.log("Next " + updateFeature.attributes.objectid);
          });

          attInspector.on("delete", function(evt) {
            evt.feature.getLayer().applyEdits(null, null, [evt.feature]);
            map.infoWindow.hide();
          });

          map.infoWindow.setContent(attInspector.domNode);
          map.infoWindow.resize(350, 240);
        }
      });
    </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 id="detailPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'">
        Click a field to display the attribute inspector with customized fields.
      </div>
      <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'" id="mapDiv"></div>
    </div>
  </body>
</html>
TracySchloss
Frequent Contributor

Thanks.  I was looking for something styled the same as the typical Zoom To at the bottom of an InfoWindow.  I'm not explicitly defining my attributeInspector, so there's not much from this example I thought I could use without extensive rewrite.

This seems to work, though. 

    on (myFeatureLayer, "click", function (evt) {

      if (!dom.byId('zoomLink')) {

        app.link = domConstruct.create("a", {

          "class": "action zoomTo myZoom",

          "id": "zoomLink",

          "title": "My Zoom",

          "innerHTML": "Zoom To", //text to appear in the popup for the link 

          "href": "javascript: void(0);"

        }, query(".sizer", app.myEditor.attributeInspectordomNode)[1]);

       on (app.link,"click", function(){

          app.map.infoWindow.hide();

          var geom = evt.graphic.geometry;

          var lod = app.map.getLevel();

          if (geom.type === 'point') {

            app.map.centerAndZoom(geom, lod + 4);

          }  else {

            app.map.setExtent(geom.getExtent(), true);

          }

        })

      }

    })

TracySchloss
Frequent Contributor

My solution needed a little tweaking.  Here's the final:

    on (app.eusLayer, "click", function (evt) {
      app.feat = evt.graphic;
      if (!dom.byId('zoomLink')) {
        app.link = domConstruct.create("a", {
          "class": "action zoomTo myZoom",
          "id": "zoomLink",
          "title": "My Zoom",
          "innerHTML": "Zoom To",
          "href": "javascript: void(0);"
        }, query(".sizer", app.myEditor.attributeInspectordomNode)[1]);
          on (app.link,"click", function(){
              app.map.infoWindow.hide();
              var geom = app.feat.geometry;
              var lod = app.map.getLevel();
              if (geom.type === 'point') {
                app.map.centerAndZoom(geom, lod + 4);
              }  else {
                app.map.setExtent(geom.getExtent(), true);
              } 
            });
          }
        app.eusLayer.clearSelection();
    });
0 Kudos