FeatureTable and Editing don't work well together

3079
2
Jump to solution
12-30-2015 12:28 PM
AndyWright
Occasional Contributor

I am developing an app where I display the FeatureTable for a feature class in a feature service and allow the user to edit information about features in that feature class.  I am not able to perform an edit operation on a feature if the feature table for that layer has been populated.  If I don't populate the feature table I can edit that feature just fine.  It seems to be related to things being selected in the feature table.  Click on any of the dots in the map and the first edit should work fine, then on the next one it breaks.  If I select any records in the feature table first then click on a dot on the map the edit will not work at all.

I've also found that selecting features from another feature class in the map causes the edit functionality of the original feature class to break as well.  All of this stuff seems very unstable, so hopefully I'm just missing something here.  If this is not buggy behavior then is there a valid workflow or workaround to do this sort of thing?

I've enclosed some code that you can throw into the Javascript API sandbox so you can see the behavior I am describing.  If you comment out the teamsTable.startup() line, the editing stuff will work fine.

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

<link rel="stylesheet" href="https://js.arcgis.com/3.15/dijit/themes/claro/claro.css">

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

<style>

  html, body, #mapDiv{

    height: 100%;

    width: 100%;

    margin: 0;

    padding: 0;

    overflow: hidden;

  }

  #detailPane{

    padding: 6px;

    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 .atiLayerName {display:none;}

</style>

<script src="https://js.arcgis.com/3.15/"></script>

<script>

  var map, updateFeature;

  require([

    "esri/map",

    "esri/layers/FeatureLayer",

    "esri/dijit/AttributeInspector",

    "esri/dijit/FeatureTable",

    "esri/symbols/SimpleLineSymbol",

    "esri/symbols/SimpleMarkerSymbol",

    "esri/Color",

    "esri/renderers/UniqueValueRenderer",

    "esri/config",

    "esri/tasks/query",

    "dojo/dom-construct",

    "dijit/form/Button",

    "dojo/on",

    "dojo/domReady!"

  ], function(

    Map, FeatureLayer, AttributeInspector, FeatureTable,

    SimpleLineSymbol, SimpleMarkerSymbol, Color, UniqueValueRenderer,

    esriConfig,

    Query, domConstruct, Button, on

  ) {

    // 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: "dark-gray",

      center: [-97.395, 37.537],

      zoom: 5

    });

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

    //Feature Layer representing 2015 men's NCAA basketball tournament teams

    var teamsFL = new FeatureLayer("http://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/NCAA_Tourney_2015/FeatureServer/1", {

      outFields: ["University", "WINPER", "Rd_64_Venue", "Rd_64_Result", "Rd_64_Margin"]

    });

    

    var selectionSymbol = new SimpleMarkerSymbol(

        SimpleMarkerSymbol.STYLE_CIRCLE, 6,

        new SimpleLineSymbol(

            "solid",

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

            4

        ),

        new Color("ED3939")

    );

    

    var defaultSymbol = new SimpleMarkerSymbol(

        SimpleMarkerSymbol.STYLE_CIRCLE, 7,

        null,

        new Color([255,255,255])

    );

    teamsFL.setSelectionSymbol(selectionSymbol);

    

    //Symbolize features by W/L record

    var recordRenderer = new UniqueValueRenderer(defaultSymbol, "Rd_64_Result");

    recordRenderer.addValue("W", new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 7, null, new Color([93,240,79])));

    recordRenderer.addValue("L", new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 7, null, new Color([240,146,79])));

    teamsFL.setRenderer(recordRenderer);

    map.addLayers([teamsFL]);

  

     var teamsTable = new FeatureTable({

          "featureLayer": teamsFL,

          //"dateOptions": {

          //  "timeEnabled" : true,

          //  "timePattern" : "HH:mm:ss",

          //  "datePattern" : "YYYY-MM-DD"

          //},

          //"hiddenFields": ["FID", "C_Seq", "Street"],  // field that end-user can show, but is hidden on startup

          "map": map,

          "enableLayerClick": true,

          "enableLayerSelection": true

      }, teamTableNode.id);

      //  Load event (must be before startup)

      on(teamsTable, "load", function (evt) {

          console.log("The load event - ", evt);

      });

      teamsTable.startup();

      on(teamsTable, "dgrid-refresh-complete", function (evt) {

          //  Check record count and enable filter button accordingly

          console.log("Team table dgrid-refresh-complete event - ", evt);

      });

      on(teamsTable, "dgrid-select", function (evt) {

          console.log("Team table dgrid-select event - ", evt);

      });

      on(teamsTable, "dgrid-deselect", function (evt) {

          console.log("Team table dgrid-deselect event - ", evt);

      });

      on(teamsFL, "selection-complete", function (evt) {

          console.log("TEAM SELECTION COUNT: " + evt.features.length);

      });

    function initSelectToolbar(evt) {

      var teamsFL = evt.layers[0].layer;

      var selectQuery = new Query();

      map.on("click", function(evt) {

        selectQuery.geometry = evt.mapPoint;

        selectQuery.distance = 50;

        selectQuery.units = "miles"

        selectQuery.returnGeometry = true;

        teamsFL.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() {

        teamsFL.clearSelection();

      });

      var layerInfos = [

        {

          'featureLayer': teamsFL,

          'showAttachments': false,

          'isEditable': true,

          'fieldInfos': [

            {'fieldName': 'University', 'isEditable': false, 'label': 'School:'},

            {'fieldName': 'WINPER', 'isEditable': true, 'tooltip': 'Win percentage', 'label': 'Win percentage:'},

            {'fieldName': 'Rd_64_Venue', 'isEditable': false, 'label': 'Rd 1 Venue:'},

            {'fieldName': 'Rd_64_Result', 'isEditable': true, 'tooltip': 'First round result (W/L)', 'label': 'Rd 1 Result:'},

            {'fieldName': 'Rd_64_Margin', 'isEditable': true, 'tooltip': 'First round margin of victory/loss', 'label': 'Rd 1 Margin:'}

          ]

        }

      ];

      //Initialize Attribute Inspector  

      var attInspector = new AttributeInspector({

        layerInfos: layerInfos

      }, domConstruct.create("div"));

      //add a save button next to the delete button

      var saveButton = new Button({ label: "Save", "class": "saveButton"},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 style="height:100%;width:100%;" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'">

        <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center', splitter:true" style="height:50%">

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

        </div>

        <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom',splitter:true" style="height:50%">

            <div style="height:100%;width:100%;" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'">

                <div data-dojo-type="dijit/layout/ContentPane" id="teamDiv" style="height:90%;width:100%" data-dojo-props="region:'center', splitter:true">

                    <div data-dojo-attach-point="teamTableNode" id="teamTableNode" style="height:100%;width:100%;"></div>

                </div>

            </div>

        </div>

    </div>

</body>

</html>

0 Kudos
1 Solution

Accepted Solutions
RickeyFight
MVP Regular Contributor

Andy,

I had the same issue.

Look here:

Default Editor with Dgrid

View solution in original post

0 Kudos
2 Replies
RickeyFight
MVP Regular Contributor

Andy,

I had the same issue.

Look here:

Default Editor with Dgrid

0 Kudos
AndyWright
Occasional Contributor

Rickey,

That looks like good stuff man.  Thanks for the heads up on this ...

0 Kudos