diff --git a/folium/plugins/draw.py b/folium/plugins/draw.py index 7d54f1805d..2de7733bbd 100644 --- a/folium/plugins/draw.py +++ b/folium/plugins/draw.py @@ -58,9 +58,8 @@ class Draw(JSCSSMixin, MacroElement): {% macro html(this, kwargs) %} {% if this.export %} - Export + Export {% endif %} {% endmacro %} @@ -123,14 +122,14 @@ class Draw(JSCSSMixin, MacroElement): }); {% if this.export %} - document.getElementById('export').onclick = function(e) { + document.getElementById('export_{{ this.get_name() }}').onclick = function(e) { var data = drawnItems_{{ this.get_name() }}.toGeoJSON(); var convertedData = 'text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(data)); - document.getElementById('export').setAttribute( + document.getElementById('export_{{ this.get_name() }}').setAttribute( 'href', 'data:' + convertedData ); - document.getElementById('export').setAttribute( + document.getElementById('export_{{ this.get_name() }}').setAttribute( 'download', {{ this.filename|tojson }} ); } diff --git a/tests/plugins/test_draw.py b/tests/plugins/test_draw.py new file mode 100644 index 0000000000..16889b1aea --- /dev/null +++ b/tests/plugins/test_draw.py @@ -0,0 +1,70 @@ +""" +Test Draw +--------- +""" + +import re + +import folium +from folium import plugins +from folium.template import Template +from folium.utilities import normalize + + +def test_draw(): + m = folium.Map([45.0, 3.0], zoom_start=4) + draw = plugins.Draw(export=True, filename="my_data.geojson") + m.add_child(draw) + + out = normalize(m._parent.render()) + + # Verify that the export button has been created with a unique id. + tmpl = Template("Export") + assert normalize(tmpl.render(this=draw)) in out + + # Verify that the style targets that same id. + assert normalize(f"#export_{draw.get_name()} {{") in out + + # Verify that the click handler is wired to that same id. + assert ( + normalize(f"document.getElementById('export_{draw.get_name()}').onclick") in out + ) + + +def test_draw_no_export(): + m = folium.Map([45.0, 3.0], zoom_start=4) + draw = plugins.Draw() + m.add_child(draw) + + out = normalize(m._parent.render()) + + assert "Export" not in out + assert f"export_{draw.get_name()}" not in out + + +def test_two_draw_controls_get_unique_export_ids(): + """Each Draw gets its own export button, wired to its own layers. + + A hard-coded ``id='export'`` made the second button dead and pointed the + first at the wrong FeatureGroup. + """ + m = folium.Map([45.0, 3.0], zoom_start=4) + first = plugins.Draw(export=True, filename="first.geojson") + second = plugins.Draw(export=True, filename="second.geojson") + m.add_child(first) + m.add_child(second) + + out = m._parent.render() + + ids = re.findall(r"id='(export_[^']+)'", out) + assert len(ids) == 2 + assert len(set(ids)) == 2, f"export button ids are not unique: {ids}" + + # Each handler must reference its own element, layers and filename. + for draw, filename in ((first, "first.geojson"), (second, "second.geojson")): + element_id = f"export_{draw.get_name()}" + assert f"id='{element_id}'" in out + start = out.index(f"document.getElementById('{element_id}').onclick") + handler = out[start : out.index("}", start) + 1] + assert f"drawnItems_{draw.get_name()}.toGeoJSON()" in handler + assert filename in handler