Hide Table of Contents
View Edit without editor widget sample in sandbox
Edit without editor widget

Description

The template picker is an out of the box widget that displays a gallery of templates from one or more feature layers. The template picker displays a symbol and label for each type in the feature layer. The editor widget uses the template picker to provide template based editing so in most cases you'll want to use the editor widget to take advantage of all the functionality the editor provides (attribute editing, automatic updates and editing tools). In this example, the template picker is used without the editor so the developer is responsible for updating features after they are modified.

To create new features, select the desired template from the TemplatePicker then draw a new feature on the map. This sample uses the Draw toolbar to sketch the new feature then in the toolbar's onDrawEnd event the edits are saved by calling FeatureLayer.applyEdits().

This sample also includes logic to delete features and edit vertices.The edit toolbar is activated when you double-click on a graphic. Double-clicking enables the edit toolbar with the EDIT_VERTICES constant and you'll see vertices and ghost vertices appear on the map. You can delete features by holding the CTRL key while clicking a graphic. The layer's click event checks to see if you've pressed the CTRL key, if so applyEdits is called and the selected graphic is added to the array of features to delete.

Code

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Landuse</title>

    <link rel="stylesheet" href="https://js.arcgis.com/3.21/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="https://js.arcgis.com/3.21/esri/css/esri.css">
    <style>
      html, body {
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
        overflow:hidden;
      }
      #header {
        border:solid 2px #462d44;
        background:#fff;
        color:#444;
        -moz-border-radius: 4px;
        border-radius: 4px;
        font-family: sans-serif;
        font-size: 1.1em
        padding-left:20px;
      }
      #map {
        padding:1px;
        border:solid 2px #444;
        -moz-border-radius: 4px;
        border-radius: 4px;
      }
      #rightPane {
        border:none;
        padding: 0;
        width:228px;
      }
      .templatePicker {
        border: solid 2px #444;
      }
    </style>

    <script src="https://js.arcgis.com/3.21/"></script>
    <script>
      var map;
      require([
        "esri/map",
        "esri/toolbars/draw",
        "esri/toolbars/edit",
        "esri/graphic",
        "esri/config",

        "esri/layers/FeatureLayer",

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

        "esri/dijit/editing/TemplatePicker",

        "dojo/_base/array",
        "dojo/_base/event",
        "dojo/_base/lang",
        "dojo/parser",
        "dijit/registry",

        "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
        "dijit/form/Button", "dojo/domReady!"
      ], function(
        Map, Draw, Edit, Graphic, esriConfig,
        FeatureLayer,
        SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol,
        TemplatePicker,
        arrayUtils, event, lang, parser, registry
      ) {
        parser.parse();

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

        // This service is for development and testing purposes only. We recommend that you create your own geometry service for use within your applications.
        esriConfig.defaults.geometryService = new esri.tasks.GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");

        map = new Map("map", {
          basemap: "streets",
          center: [-83.244, 42.581],
          zoom: 15
        });

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

        var landusePointLayer = new FeatureLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/FeatureServer/6", {
          mode: FeatureLayer.MODE_SNAPSHOT,
          outFields: ["*"]
        });
        var landuseLineLayer = new FeatureLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/FeatureServer/8", {
          mode: FeatureLayer.MODE_SNAPSHOT,
          outFields: ["*"]
        });
        var landusePolygonLayer = new FeatureLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/FeatureServer/9", {
          mode: FeatureLayer.MODE_SNAPSHOT,
          outFields: ["*"]
        });

        map.addLayers([landusePointLayer, landuseLineLayer, landusePolygonLayer]);

        function initEditing(evt) {
          console.log("initEditing", evt);
          // var map = this;
          var currentLayer = null;
          var layers = arrayUtils.map(evt.layers, function(result) {
            return result.layer;
          });
          console.log("layers", layers);

          var editToolbar = new Edit(map);
          editToolbar.on("deactivate", function(evt) {
            currentLayer.applyEdits(null, [evt.graphic], null);
          });

          arrayUtils.forEach(layers, function(layer) {
            var editingEnabled = false;
            layer.on("dbl-click", function(evt) {
              event.stop(evt);
              if (editingEnabled === false) {
                editingEnabled = true;
                editToolbar.activate(Edit.EDIT_VERTICES , evt.graphic);
              } else {
                currentLayer = this;
                editToolbar.deactivate();
                editingEnabled = false;
              }
            });

            layer.on("click", function(evt) {
              event.stop(evt);
              if (evt.ctrlKey === true || evt.metaKey === true) {  //delete feature if ctrl key is depressed
                layer.applyEdits(null,null,[evt.graphic]);
                currentLayer = this;
                editToolbar.deactivate();
                editingEnabled=false;
              }
            });
          });

          var templatePicker = new TemplatePicker({
            featureLayers: layers,
            rows: "auto",
            columns: 2,
            grouping: true,
            style: "height: auto; overflow: auto;"
          }, "templatePickerDiv");

          templatePicker.startup();

          var drawToolbar = new Draw(map);

          var selectedTemplate;
          templatePicker.on("selection-change", function() {
            if( templatePicker.getSelected() ) {
              selectedTemplate = templatePicker.getSelected();
            }
            switch (selectedTemplate.featureLayer.geometryType) {
              case "esriGeometryPoint":
                drawToolbar.activate(Draw.POINT);
                break;
              case "esriGeometryPolyline":
                drawToolbar.activate(Draw.POLYLINE);
                break;
              case "esriGeometryPolygon":
                drawToolbar.activate(Draw.POLYGON);
                break;
            }
          });

          drawToolbar.on("draw-end", function(evt) {
            drawToolbar.deactivate();
            editToolbar.deactivate();
            var newAttributes = lang.mixin({}, selectedTemplate.template.prototype.attributes);
            var newGraphic = new Graphic(evt.geometry, null, newAttributes);
            selectedTemplate.featureLayer.applyEdits([newGraphic], null, null);
          });
        }
      });
    </script>
  </head>
  <body class="claro">
    <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="gutters:true, design:'headline'" style="width:100%;height:100%;">
      <div data-dojo-type="dijit/layout/ContentPane"  id="header" data-dojo-props="region:'top'">Use ctrl or cmd + click on graphic to delete.  Double click on graphic to edit vertices. </div>
      <div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
      <div id="rightPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'right'">
        <div id="templatePickerDiv"></div>
      </div>
    </div>
  </body>
</html>