How can I edit a feature in 4.x like I did with esri/toolbars/edit in 3.x?

1341
8
04-05-2022 09:43 AM
MattStayner
Occasional Contributor II

Hi,

I'm building a very custom application with 4.x and I'm struggling with duplicating functionality that I have in my current 3.x application.

Here's what I want to be able to do:

  1. Select a feature
  2. Enable "move mode" where I can move just that one feature
  3. Save changes

Watch this short screencast to see what I mean.

In 3.x that was super easy to do using the edit toolbar, like this:

editToolbar = new Edit(map);
//Once the feature is selected
editToolbar.activate(Edit.MOVE | Edit.SCALE | Edit.EDIT_VERTICES, feature);

 

 

How can I do the same thing in 4.x?

Thanks!

Matt

 

0 Kudos
8 Replies
BlakeTerhune
MVP Regular Contributor

Moving a single feature seems pretty straightforward with 4.x. Have you seen this demo of the Editor Widget? It got some major updates in the 4.23 release.

0 Kudos
MattStayner
Occasional Contributor II

Hi @BlakeTerhune ,

Thanks for the response, and thanks for pointing me back to the Editor widget demo! I saw it before, but I couldn't see how to move features. Now I see... you have to click Select under Edit Features. Once I do that, and select a feature, then it does exactly what I want.

If I go with that solution, I'm still stuck with using the Editor widget, which doesn't really fit into my flow. Is there a way I can use that tool, but hide the widget and pass in the feature before I start it?

Thanks,

Matt

0 Kudos
BlakeTerhune
MVP Regular Contributor

@MattStayner wrote:

If I go with that solution, I'm still stuck with using the Editor widget, which doesn't really fit into my flow. Is there a way I can use that tool, but hide the widget and pass in the feature before I start it?


Possibly, but I haven't worked with editing in 4.x yet so I really can't advise how to go about customizing that functionality. Hopefully someone else with more experience can contribute to this conversation.

0 Kudos
JoelBennett
MVP Regular Contributor

The key here is using the SketchViewModel module.  This is admittedly brief, but here's the basic flow:

  1. Get reference to graphic you want to edit.
  2. If you haven't already instantiated a GraphicsLayer for editing purposes, create one and add it to the view.
  3. If you haven't already instantiated a SketchViewModel, create one, assigning the layer and view properties in the constructor. (Set the GraphicsLayer in the previous step to the layer property.)  Also recommend setting the updateGraphicOnClick property in the constructor too.
  4. Clone the graphic and add it to your GraphicsLayer.
  5. Make the original graphic invisible by getting a reference to its associated layer's layerView, and calling layerView.setVisibility(graphic.getObjectID(), false).  Note: setVisibility is an undocumented function.
  6. Call SketchViewModel.update on the cloned graphic, with the appropriate updateOptions (2nd parameter) set.
  7. When the user has somehow signaled they are done editing, get the updated graphic from updateGraphics.
  8. Assign the cloned graphic's geometry to the original graphic reference (see step 1).
  9. Call applyEdits with the original graphic.
  10. After the layer has refreshed, cancel the SketchViewModel and clear the GraphicsLayer.
0 Kudos
MattStayner
Occasional Contributor II

@JoelBennett This looks like just what I need. It is a bit convoluted (coping graphics to other layer and back again), but if it works, that's OK. I will give it a go and report back here on my results. Thanks!

0 Kudos
JoelBennett
MVP Regular Contributor

Convoluted it is, but it's the nature of the way things work in 4.x now that FeatureLayer no longer exposes a graphics property.  This workflow is largely how the 4.x Editor widget works behind the scenes too.

0 Kudos
MattStayner
Occasional Contributor II

@JoelBennett ,

I can't seem to get sketchViewModel working. I do something like this:

const updateOptions = { tool: "move" };
const newGraphic = graphic.clone();
graphic.visible = false;
await sketchViewModel.update([newGraphic], updateOptions);
graphic.geometry = this.view.toMap(e);

But I keep getting this error:

SketchViewModel.js:51 Uncaught (in promise) TypeError: h.remove is not a function
at f.n._setupUpdateOperation (SketchViewModel.js:51:462)
at f.n.update (SketchViewModel.js:18:246)

Any thoughts/help on what I'm doing wrong?

0 Kudos
JoelBennett
MVP Regular Contributor

This would suggest that the layer property of the SketchViewModel has not been set.  Please see step 3 of the process given previously.

0 Kudos