Editor attribute inspector default values

6510
3
12-12-2011 11:57 AM
DavidHollema
New Contributor III
I'm curious what some approaches are to providing default values for fields by means of the out-of-the-box attribute inspector.  Ideally, I'd like to display the value to the end user in an editable or non-editable text box.

I've tried 3 approaches.


  1. Intercept on layer's BeforeApplyEdits event and provide value based on advice here by Kelly Hutchins -> http://forums.arcgis.com/threads/32271-Default-date-of-1970-for-date-field-at-2.3?highlight=default+...

  2. Use customField based on my own custom dijit for fieldInfo - never successfully completed this.  I can see the value in the attribute inspector but it doesn't get transmitted across the wire to ArcGIS Server.

  3. Use customField based on my dijit.form.TextBox - never successfully completed this.  I can't see the value in the attribute inspector. I tried setting the 'value' of the textbox in the constructor and later using .set("value").


  4. My own custom dijit attempt is described here
    var userIDdijit = new nrss.overflights.dijit.SimpleBehavioralDijit({ "value": user }); //user variable has a value, I double-checked

    //and in fieldInfos
    { 'fieldName': 'USERID', 'label': 'User ID', 'customField': userIDdijit, 'isEditable':true}

    SampleBehavioralDijit

    dojo.provide("nrss.overflights.dijit.SimpleBehavioralDijit");
    dojo.require("dijit._Widget");


    //this class is used to provide default values for a field in the editor dijit
    dojo.declare("nrss.overflights.dijit.SimpleBehavioralDijit", [dijit._Widget], {

        // put methods, attributes, etc. here
        value: 'No content defined',
        _disabled: true,
        _execute: function () {
            if (typeof this.value === 'function') {
                return this.value();
            }
            else {
                return this.value;
            }
        },

        buildRendering: function () {
            // create the DOM for this widget    
            var textBox = new dijit.form.TextBox({ 'value': this._execute() });
            this.domNode = textBox.domNode;
        }
    });


The issue, I suspect, is in how the attribute inspector pulls the values from the form to send off to the post request.  Since I'm creating a new dom node, my guess is the attribute inspector doesn't see this value.  I prefer this custom dijit approach...can anyone offer assistance?
3 Replies
KellyHutchins
Esri Frequent Contributor
Setting a value on a custom widget probably won't work because when the attribute editor is displayed it will overwrite your value with the value (perhaps null) for the currently edited feature.

Here's an example that uses the 'onBeforeApplyEdits' approach. Is there a reason you didn't want to use this approach?

<html lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9" />
    <!--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>Validate Attributes</title>

    <!-- include dojo theme -->

    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.6/js/dojo/dijit/themes/claro/claro.css">
    <style type="text/css">
      .dj_ie .infowindow .window .top .right .user .content { position: relative; }
      .dj_ie .simpleInfoWindow .content {position: relative;}
    </style>
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; overflow:hidden; }
      #leftPane{
        overflow:hidden;
        border:none;
        color:#5C832F;
      }
      #map{
        border: solid medium #382513;
        padding:0;
      }

      .esriAttributeInspector{
          atiLayerName:'Building Details'
      }
      .templatePicker{
        border:none !important;
      }
      .templatePicker .grid .groupLabel{
        display:none;
      }
    </style>

    <!-- specify dojo configuration to parse dijits at load time -->
    <script type="text/javascript">
      dojoConfig = {
        parseOnLoad:true
      };
    </script>

    <!-- reference ArcGIS JavaScript API -->

    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.6"></script>
    <script type="text/javascript">
      //require selection dijit
      dojo.require("esri.map");
      dojo.require("esri.dijit.editing.Editor-all");
      dojo.require("dijit.layout.ContentPane");
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.form.DateTextBox");
      dojo.require("dijit.form.TextBox");
  

      var map;
      
      function init() {
        //This sample requires a proxy page to handle communications with the ArcGIS Server services. You will need to  
        //replace the url below with the location of a proxy on your machine. See the 'Using the proxy page' help topic 
        //for details on setting up a proxy page.
        esri.config.defaults.io.proxyUrl = "http://autumn/proxy/proxy.ashx";
        
        //This service is for development and testing purposes only. We recommend that you create your own geometry service for use within your applications. 
        esri.config.defaults.geometryService = new esri.tasks.GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
        
        
        var initialExtent = new esri.geometry.Extent({"xmin":-13062820,"ymin":4063755,"xmax":-13048794,"ymax":4071609,"spatialReference":{"wkid":102100}});
        map = new esri.Map("map", { extent:initialExtent, slider: false, nav: true });
        
        dojo.connect(map, "onLoad", function() {
         //resize the map when the browser resizes
         dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
        });
        
        dojo.connect(map, "onLayersAddResult", initEditor);
        

        var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");
        map.addLayer(basemap);
 
       //Add the editable feature layer to the map
        var pointsOfInterest = new esri.layers.FeatureLayer("http://sampleserver5.arcgisonline.com/ArcGIS/rest/services/Notes/FeatureServer/0",{
          mode: esri.layers.FeatureLayer.MODE_ONDEMAND, 
          outFields: ['*']
        });
        
        
        map.addLayers([pointsOfInterest]);
      }

      function initEditor(results) {

        //only one layer 
        var featureLayer = results[0].layer;
  
        //add a default value for newly added features 
        dojo.connect(featureLayer,'onBeforeApplyEdits',function(adds,deletes,updates){
          dojo.forEach(adds,function(add){
            if(add.attributes['name'] === null){
              add.attributes['name'] = 'Sam Wrangler';
            }
          });
        });
        var templatePicker = new esri.dijit.editing.TemplatePicker({
          featureLayers: [featureLayer],
          rows: 'auto',
          groupingEnabled:false,
          columns: 1
        },'editorDiv');
        

        templatePicker.startup();
        
        
       
         var textDijit = new dijit.form.TextBox({
          id:"nameField",
          placeHolder:'Enter your name here' //do they need placeholder or value
         });
    

    
       var layerInfos = [{
          'featureLayer':featureLayer,
          'showAttachments':false,
          'showDeleteButton':false,
          'fieldInfos':[
            {'fieldName':'name','label':'Name','customField':textDijit},
            {'fieldName':'email','label':'Email'}
          ]
        }];   
        
        //define the editor settings
        var settings = {
          map: map,
          templatePicker:templatePicker,
          layerInfos:layerInfos
        };
        
        var params = {settings: settings};

        //Create the editor widget 
        var editorWidget = new esri.dijit.editing.Editor(params);
        editorWidget.startup();
        
        //resize the info window (attribute inspector)
        map.infoWindow.resize(295,245);
      }
      
      dojo.addOnLoad(init);
    </script>
  </head>
  <body class="claro">    
    <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'sidebar'" style="width:100%;height:100%;">
      <div id="map" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"></div>
      <div id="leftPane" data-dojo-type="dijit.layout.ContentPane" style="width:100px;"  data-dojo-props="region:'left'">
        <div>Click the Notes icon - then click location on map to add new map note. When a new phone number is 
          entered dojo's ValidationTextBox is used to make sure a properly formatted phone number is entered.</div>

        <div id="editorDiv"></div>
        <div></div>
      </div>
    </div>
  </body>
</html>

DavidHollema
New Contributor III
I wanted to ensure that both approaches worked.  I tested your code below, paying specific attention to the TextBox you assign to the customField.  I ran this against v2.5 CDN and neither the TextBox's placeholder or value was visible in the attribute inspector.  I switched to newly released v2.6 CDN and the behavior for the same code is definitely different.  I read the bug fixes for 2.6 what's new and see no mention of this.

However, now I'm getting another error upon destroy the editor widget and recreating:

Tried to register widget with id==templateDiv but that id is already registered
http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.6
Line 48


This is a new error with v2.6.  I saw it at 2.5 but had it fixed.  It's back at 2.6.
Setting a value on a custom widget probably won't work because when the attribute editor is displayed it will overwrite your value with the value (perhaps null) for the currently edited feature.

Here's an example that uses the 'onBeforeApplyEdits' approach. Is there a reason you didn't want to use this approach?

<html lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9" />
    <!--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>Validate Attributes</title>

    <!-- include dojo theme -->

    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.6/js/dojo/dijit/themes/claro/claro.css">
    <style type="text/css">
      .dj_ie .infowindow .window .top .right .user .content { position: relative; }
      .dj_ie .simpleInfoWindow .content {position: relative;}
    </style>
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; overflow:hidden; }
      #leftPane{
        overflow:hidden;
        border:none;
        color:#5C832F;
      }
      #map{
        border: solid medium #382513;
        padding:0;
      }

      .esriAttributeInspector{
          atiLayerName:'Building Details'
      }
      .templatePicker{
        border:none !important;
      }
      .templatePicker .grid .groupLabel{
        display:none;
      }
    </style>

    <!-- specify dojo configuration to parse dijits at load time -->
    <script type="text/javascript">
      dojoConfig = {
        parseOnLoad:true
      };
    </script>

    <!-- reference ArcGIS JavaScript API -->

    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.6"></script>
    <script type="text/javascript">
      //require selection dijit
      dojo.require("esri.map");
      dojo.require("esri.dijit.editing.Editor-all");
      dojo.require("dijit.layout.ContentPane");
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.form.DateTextBox");
      dojo.require("dijit.form.TextBox");
  

      var map;
      
      function init() {
        //This sample requires a proxy page to handle communications with the ArcGIS Server services. You will need to  
        //replace the url below with the location of a proxy on your machine. See the 'Using the proxy page' help topic 
        //for details on setting up a proxy page.
        esri.config.defaults.io.proxyUrl = "http://autumn/proxy/proxy.ashx";
        
        //This service is for development and testing purposes only. We recommend that you create your own geometry service for use within your applications. 
        esri.config.defaults.geometryService = new esri.tasks.GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
        
        
        var initialExtent = new esri.geometry.Extent({"xmin":-13062820,"ymin":4063755,"xmax":-13048794,"ymax":4071609,"spatialReference":{"wkid":102100}});
        map = new esri.Map("map", { extent:initialExtent, slider: false, nav: true });
        
        dojo.connect(map, "onLoad", function() {
         //resize the map when the browser resizes
         dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
        });
        
        dojo.connect(map, "onLayersAddResult", initEditor);
        

        var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");
        map.addLayer(basemap);
 
       //Add the editable feature layer to the map
        var pointsOfInterest = new esri.layers.FeatureLayer("http://sampleserver5.arcgisonline.com/ArcGIS/rest/services/Notes/FeatureServer/0",{
          mode: esri.layers.FeatureLayer.MODE_ONDEMAND, 
          outFields: ['*']
        });
        
        
        map.addLayers([pointsOfInterest]);
      }

      function initEditor(results) {

        //only one layer 
        var featureLayer = results[0].layer;
  
        //add a default value for newly added features 
        dojo.connect(featureLayer,'onBeforeApplyEdits',function(adds,deletes,updates){
          dojo.forEach(adds,function(add){
            if(add.attributes['name'] === null){
              add.attributes['name'] = 'Sam Wrangler';
            }
          });
        });
        var templatePicker = new esri.dijit.editing.TemplatePicker({
          featureLayers: [featureLayer],
          rows: 'auto',
          groupingEnabled:false,
          columns: 1
        },'editorDiv');
        

        templatePicker.startup();
        
        
       
         var textDijit = new dijit.form.TextBox({
          id:"nameField",
          placeHolder:'Enter your name here' //do they need placeholder or value
         });
    

    
       var layerInfos = [{
          'featureLayer':featureLayer,
          'showAttachments':false,
          'showDeleteButton':false,
          'fieldInfos':[
            {'fieldName':'name','label':'Name','customField':textDijit},
            {'fieldName':'email','label':'Email'}
          ]
        }];   
        
        //define the editor settings
        var settings = {
          map: map,
          templatePicker:templatePicker,
          layerInfos:layerInfos
        };
        
        var params = {settings: settings};

        //Create the editor widget 
        var editorWidget = new esri.dijit.editing.Editor(params);
        editorWidget.startup();
        
        //resize the info window (attribute inspector)
        map.infoWindow.resize(295,245);
      }
      
      dojo.addOnLoad(init);
    </script>
  </head>
  <body class="claro">    
    <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'sidebar'" style="width:100%;height:100%;">
      <div id="map" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"></div>
      <div id="leftPane" data-dojo-type="dijit.layout.ContentPane" style="width:100px;"  data-dojo-props="region:'left'">
        <div>Click the Notes icon - then click location on map to add new map note. When a new phone number is 
          entered dojo's ValidationTextBox is used to make sure a properly formatted phone number is entered.</div>

        <div id="editorDiv"></div>
        <div></div>
      </div>
    </div>
  </body>
</html>

0 Kudos
DavidHollema
New Contributor III
That approach is fine.  I was just curious if I can make use of a custom widget or dojo-provided widget to do the same.  However, if I were to use a custom dijit to collect special data from the user, it would be nice to set any default value simultaneously in that widget instantiation instead of using the event handling method separately.  1 thing to maintain instead of 2. 

Upon creating a new feature with the editor, wouldn't it make sense to omit attempting to read any set field values in the attribute inspector since a feature doesn't yet exist and alternatively read values set in the customField widget?  Or, another means altogether to provide a default value, possibly as an addition fieldInfo property?
0 Kudos