Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions folium/plugins/draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ class Draw(JSCSSMixin, MacroElement):
{% macro html(this, kwargs) %}
{% if this.export %}
<style>
#export {
#export_{{ this.get_name() }} {
position: absolute;
top: 5px;
right: 10px;
z-index: 999;
background: white;
Expand All @@ -74,7 +73,7 @@ class Draw(JSCSSMixin, MacroElement):
top: 90px;
}
</style>
<a href='#' id='export'>Export</a>
<a href='#' id='export_{{ this.get_name() }}'>Export</a>
{% endif %}
{% endmacro %}

Expand Down Expand Up @@ -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 }}
);
}
Expand Down
70 changes: 70 additions & 0 deletions tests/plugins/test_draw.py
Original file line number Diff line number Diff line change
@@ -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("<a href='#' id='export_{{this.get_name()}}'>Export</a>")
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</a>" 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
Loading