Sunday, 12 June 2016

Using the ArcGIS API for JavaScript AttributeInspector widget without a map

Though I am not currently working as a GIS developer, I am frequently called upon to make custom applications using the ArcGIS API for JavaScript. Recently a colleague of mine and I were faced with the task of creating a form from which to make updates to a Feature Layer without actually loading a map on the interface. Usually, people use the Edit Widget to edit attributes and geometry of features from a Feature Layer but as the linked sample above shows, it is mostly done within the confines of a map container.
The clients we were working for did not want a map container but instead needed a form on a blank page where they could make changes to features without having to see them on a map - choosing instead to reference them on the basis of IDs which are part of their attributes. The following is what we implemented.

JS Bin on jsbin.com

Though you can have an idea of how we tackled the situation through the JSBin above, let's go through a bit of the JavaScript code:

  • After referencing the FeatureLayer as shown below, we initialized a variable to simulate the first loading of the attribute inspector:
       
//Feature Layer representing Capital Projects around Nairobi
var teamsFL = new FeatureLayer("http://services.arcgis.com/CmINIEzurW7Tagtl/arcgis/rest/services/Infrastructural_Alerts/FeatureServer/4", {
      outFields: ["*"]
    });

//Initialize i to show that this is the first time the script is being run
i = 0;
 
 
  • We then set up the process that would allow for querying of a feature from the layer based on the Work ID attribute provided from the dropdown menu. This was bound to the select-change event of the menu:
       
//Initialize query based on the selected value
var selectQuery = new Query();
selectQuery.where = "WORKID = " + evt.target.value;

teamsFL.selectFeatures(selectQuery, FeatureLayer.SELECTION_NEW, function(features) {
if (features.length > 0) {
   //store the current feature
   updateFeature = features[0];
}
else {}
}); 
 
 
  • A definition of the feature attributes that would be available for changing was then specified, along with the type of data field that they were:
       
       //Define the details that will be dislayed in the Attribute Inspector element
      var layerInfos = [
        {
          'featureLayer': teamsFL,
          'showAttachments': false,
          'showDeleteButton': false,
          'isEditable': true,
          'fieldInfos': [
            {'fieldName': 'PROJTYPE', 'isEditable': true},
            {'fieldName': 'WORKSTATUS', 'isEditable': true,"stringFieldOption": AttributeInspector.STRING_FIELD_OPTION_TEXTAREA},
            {'fieldName': 'CHARGECODE', 'isEditable': true,"stringFieldOption": AttributeInspector.STRING_FIELD_OPTION_TEXTAREA},
            {'fieldName': 'ACTSTART', 'isEditable': true},
            {'fieldName': 'LOCATION', 'isEditable': true,"stringFieldOption": AttributeInspector.STRING_FIELD_OPTION_TEXTAREA}
          ]
        }
      ];

 
  • Finally, the Attribute Inspector widget was initialized and its functionality applied i.e. the possibility to post edits to a Feature Service using the applyEdits method. The main posting happens within the on click function of the Save button as shown in the code below:
       
if(i == 0){
   i++;
   //Initialize Attribute Inspector
   attInspector = new AttributeInspector({
    layerInfos: layerInfos
   }, "mapDiv");
   
   //Add the Save button
   var saveButton = new Button({ label: "Save", "class": "saveButton"},domConstruct.create("div"));
     domConstruct.place(saveButton.domNode, attInspector.deleteBtn.domNode, "after");
    
   //Add the functionality of the save button
     saveButton.on("click", function() {
    updateFeature.getLayer().applyEdits(null, [updateFeature], null, function (adds, updates, deletes) {
     
     alert("Updated feature successfully, OBJECTID: " + updates[0].objectId);
    }, function (err) {
     //when an error occurs
     alert("Apply Edits Failed: " + err.message);
    })
     });
     
     
     attInspector.on("attribute-change", function(evt) {
    //store the updates to apply when the save button is clicked
    updateFeature.attributes[evt.fieldName] = evt.fieldValue;
     });
   
   }else{
   console.log("already added attribute inspector");
   }

 

PS: Please note that this sample uses dropdown menus to get the parameter to be used for querying. It is not a generic sample either.  Therefore, you may need to learn the concept well (at least what happens on the save button click event) and apply it to your situation.

For more information on how to utilize the editing capabilities without using a map, check out this and this Stack Overflow Post as well as the ArcGIS API for JavaScript API reference.

Happy Coding!!

No comments:

Post a Comment