emilhe / dash-leaflet

MIT License
213 stars 37 forks source link

Changing EditControl property draw in Callback stopped working with > 1.0.0 #212

Open wibbico opened 11 months ago

wibbico commented 11 months ago

In version 0.1.23 we were able to dynamically enable EditControl/Draw in callback.

Versions > 0.1.23 ,< 1.0.0 do not work because "Error: No context provided: useLeafletContext() can only be used in a descendant of " is raised.

With dash-leaflet >= 1.0.0. drawing controls can only be set up in the constructor of EditControl. This works fine. If you set the draw property in the callback, there is no update for this property. Other properties still work

emilhe commented 11 months ago

Could you post a MWE?

etiennecelery commented 5 months ago

Yes! This happened to me too. I need to block the creation of new polygons after a user has already created one. I had this working previously.

Here is an MWE:

import dash
from dash import Output, Input, State, html, callback

app = dash.Dash(__name__)
app.layout = html.Div(
    [
        dl.Map(center=[56, 10], zoom=4, children=[
            dl.TileLayer(), dl.FeatureGroup([
                dl.EditControl(
                    id="edit_control",
                    draw=dict(
                        circlemarker=False,
                        line=False,
                        polygon=True,
                        rectangle=True,
                        circle=True,
                        marker=False,
                        polyline=False,                       
                    ),
                ),
                dl.Marker(position=[56, 10])]),
        ], style={'width': '100%', 'height': '50vh', 'margin': "auto", "display": "inline-block"},
               id="map"
        ),
        html.Button(children="Toggle edit mode", id="btn", n_clicks=0),
    ]
)

@callback(
    Output("edit_control", "draw"),
    Input("btn", "n_clicks"),
    State("edit_control", "draw"),
    prevent_initial_call=True
)
def sdf(n_clicks, draw):
    if n_clicks > 0:
        return dict(
            circlemarker=True,
            line=False,
            polygon=False,
            rectangle=False,
            circle=False,
            marker=False,
            polyline=False,
        )

if __name__ == '__main__':
    app.run_server(port=8850, debug=False)