Select to view content in your preferred language

Add simple editing capabilities to existing app

1942
8
Jump to solution
04-12-2013 06:31 AM
JamesTrier
Occasional Contributor
Good morning,

I am working with a large Javascript-based app using the 3.2 JS API and ArcGIS 10 map services.  We need to add editing capabilities to the app.  The editor will be kicked off with a button click, and the user can add points or edit existing points. 

Where I'm getting stuck, however, is how to implement the editor.  My Google-Fu failed to answer my question, and I've reviewed all the editing samples in the documentation. It appears that each sample relies on a large on-screen panel to select graphics types. 

All I want users to do is click the map to add a point, and then get the infoWindow pop-up form where they can input data.  I do not want any other widgets, toolbars, or templatepickers on-screen.

Basically, I want the point editing capabilities in this sample without the sidebar on the left:  http://developers.arcgis.com/en/javascript/jssamples/ed_default_editingwidget.html

Can anyone point me in a direction (existing apps, blogs, etc) to help me implement this type of editor, or at least to get started?

Thanks!
0 Kudos
1 Solution

Accepted Solutions
JakeSkinner
Esri Esteemed Contributor
The service you are posting to may have REST configured to restrict access.  While additional server side configuration is required to use CORS with a  9.3 or 10.0 ArcGIS Server instance, 10.1 instances of ArcGIS Server  will support CORS out of the box.

Try using the following service:

http://sampleserver6.arcgisonline.com/arcgis/rest/services/PhoneIncidents/FeatureServer/0

View solution in original post

0 Kudos
8 Replies
JakeSkinner
Esri Esteemed Contributor
Hi James,

After you click the button to begin editing, you could have an onClick event send a post through REST to add a point feature where the user clicked.  You will need to encode the syntax for REST.  Ex:

function addFeature(evt){
          var X = evt.mapPoint.x
          var Y = evt.mapPoint.y
          featureService = "http://sever/ArcGIS/rest/services/HSEC/FeatureServer/0/addFeatures?features=";
          addPoint = '[{"geometry":{"x":' + X + ',"y":' + Y + '}}]';
          
          addFeaturesEncode();
}
      
function addFeaturesEncode() {
    var unencoded = addPoint;
        var obj = encodeURIComponent(unencoded);
        
        var theUrl = featureService + obj;
        
        var xmlHttp = null;
    
        xmlHttp = new XMLHttpRequest();
        xmlHttp.open( "POST", theUrl, false );
        xmlHttp.send( null );
}


Take a look at calling the attribute inspector after the point is created to update the attributes.
0 Kudos
JamesTrier
Occasional Contributor
@Jake,

Thanks for the idea and the code sample.  I'll give it a test after lunch and let you know how it works out.

Just curious, any thoughts or ideas on why that functionality doesn't have an out-of-the-box solution in the API?

Jim
0 Kudos
JamesTrier
Occasional Contributor
I tried using the sample code above, as well as dojo.xhrPost and dojo.xhrGet.  I cannot get the feature layer to accept a point this way.  I get two errors - one says 405 (Method not allowed) and the other says my address "is not allowed by Access-Control-Allow-Origin". 

Not sure why I'd get a CORS error with a POST, as I don't get this error when POSTing to other internal servers. 

Any thoughts?
0 Kudos
JakeSkinner
Esri Esteemed Contributor
The service you are posting to may have REST configured to restrict access.  While additional server side configuration is required to use CORS with a  9.3 or 10.0 ArcGIS Server instance, 10.1 instances of ArcGIS Server  will support CORS out of the box.

Try using the following service:

http://sampleserver6.arcgisonline.com/arcgis/rest/services/PhoneIncidents/FeatureServer/0
0 Kudos
JamesTrier
Occasional Contributor
I marked the last answer as the solution because it looks like changing the CORS settings would get the code above working just fine. 

Ultimately, we decided to not fight the API and will work with the Editor widget after all.  I already have the widget configured with our map services.  We'll use it to vary the types of points a user can add to the service.

Thanks for your help!
0 Kudos
KellyHutchins
Esri Notable Contributor
James

You can do this with the api you just need to handle many of the update events yourself. The feature layer has an applyEdits method that can be used to add, update and delete features. Here's code for a simple use case where we are editing a point feature layer with only one feature template. In this app just click the 'Add Note' button and you'll see a new note added to the map and the attribute inspector will appear.

<!DOCTYPE html>
<html>
<head>
  <title>Simple Editing</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.4/js/dojo/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.4/js/dojo/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.4/js/esri/css/esri.css">
  <style>
    html,body,#mapDiv,.map.container{
      padding:0;
      margin:0;
      height:100%;
    }
    #point{
      z-index: 40;
      position: absolute;
      top:30px;
      right:40px;
    }
  </style>
  
  <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.4/"></script>
  <script>
    dojo.require("esri.map");
    dojo.require("esri.layers.FeatureLayer");
    dojo.require("esri.dijit.AttributeInspector-all");
    dojo.require("esri.toolbars.draw");
    
    var drawToolbar, map;
    var notesLayer;
    var attributeInspector;

    function init(){

     dojo.connect(dojo.byId("point"), "onclick", function(){
      //activate the draw toolbar so a new point can be added to the map 
      drawToolbar.activate(esri.toolbars.Draw.POINT);
     });

     esri.config.defaults.io.proxyUrl = "http://localhost/~kell3008/proxy/proxy.php";

     map = new esri.Map("mapDiv", {
        center: [-56.049, 38.485],
        zoom: 3,
        basemap: "streets"
      });
     notesLayer  = new esri.layers.FeatureLayer("http://sampleserver5.arcgisonline.com/ArcGIS/rest/services/Notes/FeatureServer/0",{
      outFields: ["*"]
     });

     //select features and show attribute inspector when clicking on note feature
     dojo.connect(notesLayer,"onClick", showAttributes);

     dojo.connect(map, "onLayersAddResult", setupEditor);
     map.addLayers([notesLayer]);




    }
    function showAttributes(event){ 
      hideAttributes();

      var query  = new esri.tasks.Query();
      query.objectIds = [event.graphic.attributes.objectid];
      notesLayer.selectFeatures(query, esri.layers.FeatureLayer.SELECTION_NEW, function(features){
        //attributeInspector.refresh();
        map.infoWindow.show(event.screenPoint);
      });

    }
    function hideAttributes(){
      if(map.infoWindow.isShowing){
        map.infoWindow.hide();
      }

    }

    function setupEditor(results){
     //setup the draw toolbar and an event that will fire after the point has been drawn.
     drawToolbar = new esri.toolbars.Draw(map);
     dojo.connect(drawToolbar, "onDrawEnd",addNote);

     //Create the attribute inspector so we can update attributes
     //first lets get the feature layers to associate with the attribute inspector
      var layerInfos = dojo.map(results, function(result) {
       return {
        'featureLayer':result.layer,
        'showAttachments': false
       };
      });
      attributeInspector = new esri.dijit.AttributeInspector({
        layerInfos: layerInfos,
      },dojo.create("div"));
      //display the attribute inspector in the popup 
      map.infoWindow.setTitle("Edit Features");
      map.infoWindow.setContent(attributeInspector.domNode);
      
      dojo.connect(attributeInspector, "onAttributeChange", updateAttributes);
      dojo.connect(attributeInspector, "onDelete", deleteFeature);



    }
    function updateAttributes(feature, fieldName, newFieldValue){
      //update attributes for feature
      feature.attributes[fieldName] = newFieldValue;

      notesLayer.applyEdits(null, [feature]); 

    }
    function deleteFeature(feature){
      //remove the feature from the feature layer
      notesLayer.applyEdits(null, null, [feature]);
      hideAttributes();
    }
    function addNote(geometry){
      //add a new feature to the feature layer 
      drawToolbar.deactivate();

      //only one feature template in this feature layer so let's get that one and use it
      //the template gets us access to things like the attribute info so we can populate
      //the new feature with the default attributes. 
      var template = notesLayer.templates[0];
      //lets setup the attributes for the new feature
      var attributes = dojo.mixin({},template.prototype.attributes);
      //now create the feature and add it to the layer
      var feature = new esri.Graphic(geometry ,null, attributes);
      notesLayer.applyEdits([feature]);

      map.infoWindow.show(map.toScreen(geometry));

    }
    dojo.ready(init);
  </script>

</head>
<body class="claro">
  <div id="mapDiv">
      <input id="point" type="button" value="Add Note"/>
  </div>
</body>
</html>


0 Kudos
JamesTrier
Occasional Contributor
James

You can do this with the api you just need to handle many of the update events yourself. The feature layer has an applyEdits method that can be used to add, update and delete features. Here's code for a simple use case where we are editing a point feature layer with only one feature template. In this app just click the 'Add Note' button and you'll see a new note added to the map and the attribute inspector will appear.

<snip>



Kelly,

This is also very helpful, I think this will come in handy!  Thank you both for your assistance!  Enjoy the weekend!
0 Kudos
DerekMiller
Deactivated User

You can do this with the api you just need to handle many of the update events yourself. The feature layer has an applyEdits method that can be used to add, update and delete features. Here's code for a simple use case where we are editing a point feature layer with only one feature template. In this app just click the 'Add Note' button and you'll see a new note added to the map and the attribute inspector will appear.


Hey Kelly,

Couldn't seem to get your code example to work in JSFiddle. Could update an existing point, but not add a new point and update it's attributes.

I have a similar need for an ongoing project. Thoughts? Thanks!

Fidde http://jsfiddle.net/dmiller/YNb4y/
0 Kudos