Esri Leaflet

Editing feature layers

This sample uses the Leaflet Editable plugin to help users manipulate the geometry of features from a hosted feature service and pass the edits back to the server.

  <meta charset=utf-8 />
  <title>Editing feature layers</title>
  <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />

    <!-- Load Leaflet (not latest version due to dependencies) -->
    <link rel="stylesheet" href="" />
    <script src=""></script>

    <!-- Load Esri Leaflet from CDN -->
    <script src=""

    body { margin:0; padding:0; }
    #map { position: absolute; top:0; bottom:0; right:0; left:0; }

<script src=""></script>
<script src=""></script>

<div id='map'></div>

<script type="text/javascript">
    // make sure double clicking the map *only* triggers the editing workflow
    var map ='map', {
      editable: true,
      doubleClickZoom: false
    }).setView([45.512, -122.619], 12);

    var tilelayer = L.esri.basemapLayer("Topographic").addTo(map);

    // create a feature layer and add it to the map
    var pedestrianDistricts = L.esri.featureLayer({
      url: ''

    // create a generic control to invoke editing
    L.EditControl = L.Control.extend({
        options: {
            position: 'topleft',
            callback: null,
            kind: '',
            html: ''
        // when the control is added to the map, wire up its DOM dynamically and add a click listener
        onAdd: function (map) {
            var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar'),
                link = L.DomUtil.create('a', '', container);
            link.href = '#';
            link.title = 'Create a new ' + this.options.kind;
            link.innerHTML = this.options.html;
            L.DomEvent.on(link, 'click', L.DomEvent.stop)
                      .on(link, 'click', function () {
                        window.LAYER =;
                      }, this);
            return container;

    // extend the control to draw polygons
    L.NewPolygonControl = L.EditControl.extend({
        options: {
            position: 'topleft',
            callback: map.editTools.startPolygon,
            kind: 'polygon',
            html: '▰'

    // extend the control to draw rectangles
    L.NewRectangleControl = L.EditControl.extend({
        options: {
            position: 'topleft',
            callback: map.editTools.startRectangle,
            kind: 'rectangle',
            html: '⬛'

    // add the two new controls to the map
    map.addControl(new L.NewPolygonControl());
    map.addControl(new L.NewRectangleControl());

    // when users CMD/CTRL click an editable feature, remove it from the map and delete it from the service
    pedestrianDistricts.on('click', function (e) {
      if ((e.originalEvent.ctrlKey || e.originalEvent.metaKey) && e.layer.editEnabled()) {
        // delete expects an id, not the whole geojson object

    // when users double click a graphic toggle its editable status
    // when deselecting, pass the geometry update to the service
    pedestrianDistricts.on('dblclick', function (e) {
      if (!e.layer.editEnabled()) {

    // when a new feature is drawn using one of the custom controls, pass the edit to the service
    map.on('editable:drawing:commit', function (e) {