Leaflet / Leaflet.draw

Vector drawing and editing plugin for Leaflet
https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html
MIT License
1.98k stars 995 forks source link

Can I enable edit mode programatically? #129

Closed stuporglue closed 11 years ago

stuporglue commented 11 years ago

Is there way to enable edit mode programatically? Right now I'm looping through the drawControl toolbars looking for one which has "edit" as an option, and saving it off for later use.

It seems like there should be an cleaner way to do this, but I couldn't find one.

for(var i in drawControl._toolbars){
    if(typeof drawControl._toolbars[i]._modes.edit != 'undefined'){
        editHandler = drawControl._toolbars[i]._modes.edit.handler;
    }   
}   

// Much later... editHandler.enable(); // Later still... editHandler.disable();

jacobtoye commented 11 years ago

There is no way at this stage I'm afraid.

What is your use case? Are you wanting to use a custom toolbar? If so I would suggest using the handlers directly.

stuporglue commented 11 years ago

I've got quite a few polygons that nearly overlap, and enabling edit mode for all of them at once gets too busy with all the node handles. I made each polygon have a pop-up with an "Edit me" button which moves the polygon to a separate edit layer and directly into edit mode.

Then outside the map I have "apply edits" and "discard edits" buttons which apply the changes via WFS-T and copy the shapes back to the non-editing layer.

Looping like I'm doing is working fine, it just seemed a little hackish.

jacobtoye commented 11 years ago

Yeah I debated the whole edit all at once functionality when building it. Specifically for your situation :|

You could make use of the Edit/Delete handlers directly (new L.EditToolbar.Edit(...);). Check out EditToolbar.js.

In your editMeClicked handler you could do as you say and copy the layer over to the edit layer group (pass this into the handlers when you create them), then enable the appropriate handler via myCustomEditHandler.enable().

See the _save() and disable() method to do the "apply edits" and "discard edits".

stuporglue commented 11 years ago

"You could make use of the Edit/Delete handlers directly"

That's a good idea. I'll look into that. Thank you!

olmoe commented 9 years ago

I would like to do this aswell.. Is it still not possible?

eaigner commented 8 years ago

The API seems kind of inflexible. Everything relies on the default toolbar. Would be greatly appreciated if everything could be done in code without any default UI.

perliedman commented 8 years ago

@eaigner you might want to check out Leaflet.Editable.

eaigner commented 8 years ago

Already skimmed the leaflet draw source. It seems after drawing a shape you can call layer.editable.enable() to begin editing the shape and the corresponding layer.editable.disable() call when you're done.

cduzan commented 8 years ago

Is there a call that will cancel the editing and revert the layer back to it's original state? Right now when I call layer.editing.disable( ) it just turns of the editing but the changes remain.

rawbeans commented 8 years ago

@cduzan I'm trying to do that as well.

I think the best approach is to save a copy the layer when editing starts, then revert back the old version when editing is disabled.

ghost commented 5 years ago

following this suggestion I got it working with leafet 1.4.0 and leaflet-draw 1.0.4 and:

// disable the original edit toolbar so that there aren't two ways to edit layers
drawControl = new L.Control.Draw({edit: false});

// manually create an edit toolbar (which won't be visible) when the page loads
toolbar = new L.EditToolbar({
  featureGroup: featureGroup
})

// and get its edit handler (this should probably be done with a loop like in the OP)
editHandler = toolbar.getModeHandlers()[0].handler

Now, to manually enable editing on a certain layer (eg. via an event like a custom button click) you can:

editHandler._enableLayerEdit(layer)

And if you want to disable edit in that layer and revert it back to its original pre-edit shape:

layer.editing.disable()
editHandler.revertLayers()

I hope this helps!

It would be nice to do this in a friendlier way, and tbh it doesn't look too hard to extract the functionality from the underlying code into easily accessible functions.

ghost commented 5 years ago

I had some problems with the solution from my last comment (regarding "undo'ing" edit changes) so I came up with another one (which also seems a bit nicer):

// disable the original edit toolbar so that there aren't two ways to edit layers
drawControl = new L.Control.Draw({edit: false});

// manually create an edit toolbar (which won't be visible) when the page loads
// use a new feature group to hold the layer that is being edited (and not the map's
// "real" feature group)
editFeatureGroup = L.featureGroup();
editToolbar = new L.EditToolbar({
  featureGroup: editFeatureGroup
})

// get toolbar edit handler (this should probably be done with a loop like in the OP)
editHandler = editToolbar.getModeHandlers()[0].handler

// this is hacky but needed otherwise enabling the edit mod will fail when the code
// attempts to fire map events for edit start etc
editHandler._map = map

To manually enable editing on a certain layer:

editFeatureGroup.addLayer(layer)
editHandler.enable()

And to disable it:

// revert layers (optional)
editHandler.revertLayers()

// disable layer editing
editHandler.disable()
editFeatureGroup.removeLayer(layer)
NebojsaStanic commented 5 years ago

@daniel-gomes-sociomantic Why did you use a new feature group to hold the layer that is being edited?

I have trouble with repeated editing of a polyline. First time, everything works fine, but if I enable editing again, if I hold "helper dot" between line's coordinates, they move detached from polyline (not dragging polyline as it supposed).

kulkarnipradnyas commented 4 years ago

I have quite similar requirement, whenever i am entering in map, my circle should be in edit mode and i can change the coordinate of that and send out through my onChange handler.can you please help me.. i was using react-leaflet-draw where i have to keep my edit btn hidden. <EditControl ref={(editControlRef: any) => _onEditControlReady(editControlRef)} position='bottomright' onEdited={_onEdited} onCreated={_onCreated} onDeleted={_onDeleted} onMounted={_onMounted} onEditStart={_onEditStart} onEditStop={_onEditStop} draw={{ rectangle: false, polyline: false, circle: false, marker: false, circlemarker: false, polygon: { allowIntersection: false, showArea: true } }} edit={{ remove: false, allowIntersection: false, edit: false, toolbar: false }} /> <Circle center={[51.51, -0.06]} radius={200} />

paveltretyakovru commented 1 year ago

The answer on stackowerflow can help изображение