diff options
| author | Matthias Kestenholz <mk@feinheit.ch> | 2025-06-15 16:38:10 +0200 |
|---|---|---|
| committer | nessita <124304+nessita@users.noreply.github.com> | 2025-08-05 11:35:04 -0300 |
| commit | 0a262c8407a2f4e4971118ca435c6931c40b70ae (patch) | |
| tree | b922a295cb776eef0734211e95b7aa273865fb2d | |
| parent | 2013092b693be0ebdf36f41dc61615a2de1bbe31 (diff) | |
Fixed #36537 -- Ensured unique HTML IDs for geometry widget option scripts in the admin.
This work amends the code from f2f6046c0f92ff1faed057da0711ac478eef439c
where multiple geometry widgets rendered `<script>` elements in the
admin with the same HTML `id`, resulting in invalid HTML and fragile
JavaScript selectors. Refs #25706.
This change uses the widget's textarea ID to generate a unique `id` for
each JSON options `<script>`, ensuring valid and robust markup.
Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
| -rw-r--r-- | django/contrib/gis/static/gis/js/OLMapWidget.js | 6 | ||||
| -rw-r--r-- | django/contrib/gis/templates/gis/openlayers.html | 4 | ||||
| -rw-r--r-- | js_tests/gis/mapwidget.test.js | 4 | ||||
| -rw-r--r-- | tests/gis_tests/test_geoforms.py | 6 |
4 files changed, 12 insertions, 8 deletions
diff --git a/django/contrib/gis/static/gis/js/OLMapWidget.js b/django/contrib/gis/static/gis/js/OLMapWidget.js index bea4aab863..50860650f9 100644 --- a/django/contrib/gis/static/gis/js/OLMapWidget.js +++ b/django/contrib/gis/static/gis/js/OLMapWidget.js @@ -266,8 +266,10 @@ function initMapWidgetInSection(section) { if (wrapper.id.includes('__prefix__')) { return; } - const options = JSON.parse(wrapper.querySelector("#mapwidget-options").textContent); - options.id = wrapper.querySelector("textarea").id; + const textarea_id = wrapper.querySelector("textarea").id; + const options_script = wrapper.querySelector(`script#${textarea_id}_mapwidget_options`); + const options = JSON.parse(options_script.textContent); + options.id = textarea_id; options.map_id = wrapper.querySelector(".dj_map").id; maps.push(new MapWidget(options)); }); diff --git a/django/contrib/gis/templates/gis/openlayers.html b/django/contrib/gis/templates/gis/openlayers.html index 80fa57934b..ab52d3f11e 100644 --- a/django/contrib/gis/templates/gis/openlayers.html +++ b/django/contrib/gis/templates/gis/openlayers.html @@ -6,5 +6,7 @@ {% if widget.attrs.display_raw %}<p>{% translate "Debugging window (serialized value)" %}</p>{% endif %} <textarea id="{{ widget.attrs.id }}" class="vSerializedField required" cols="150" rows="10" name="{{ widget.name }}" {% if not widget.attrs.display_raw %} hidden{% endif %}>{{ serialized }}</textarea> - {{ widget.attrs|json_script:"mapwidget-options" }} + {% with script_id=widget.attrs.id|add:"_mapwidget_options" %} + {{ widget.attrs|json_script:script_id }} + {% endwith %} </div> diff --git a/js_tests/gis/mapwidget.test.js b/js_tests/gis/mapwidget.test.js index 723c63d22b..4f2f3bb91c 100644 --- a/js_tests/gis/mapwidget.test.js +++ b/js_tests/gis/mapwidget.test.js @@ -142,7 +142,7 @@ QUnit.test('initMapWidgetInSection initializes widgets and skips __prefix__', fu wrapper1.innerHTML = ` <textarea id="id_point"></textarea> <div class="dj_map" id="id_point_map"></div> - <script type="application/json" id="mapwidget-options"> + <script type="application/json" id="id_point_mapwidget_options"> { "geom_name": "Point" } </script> `; @@ -154,7 +154,7 @@ QUnit.test('initMapWidgetInSection initializes widgets and skips __prefix__', fu wrapper2.innerHTML = ` <textarea id="id_fake"></textarea> <div class="dj_map" id="id_fake_map"></div> - <script type="application/json" id="mapwidget-options"> + <script type="application/json" id="id_fake_mapwidget_options"> { "geom_name": "MultiPoint" } </script> `; diff --git a/tests/gis_tests/test_geoforms.py b/tests/gis_tests/test_geoforms.py index 2a1f585906..753505fc68 100644 --- a/tests/gis_tests/test_geoforms.py +++ b/tests/gis_tests/test_geoforms.py @@ -214,7 +214,7 @@ class GeometryFieldTest(SimpleTestCase): "id": "id_p", "geom_name": "Point", } - expected = json_script(attrs, "mapwidget-options") + expected = json_script(attrs, "id_p_mapwidget_options") self.assertInHTML(expected, rendered) @@ -305,7 +305,7 @@ class SpecializedFieldTest(SimpleTestCase): "id": map_field.id_for_label, "geom_name": geom_name, } - expected = json_script(attrs, "mapwidget-options") + expected = json_script(attrs, f"{map_field.id_for_label}_mapwidget_options") self.assertInHTML(expected, rendered) self.assertIn("gis/js/OLMapWidget.js", str(form_instance.media)) @@ -475,7 +475,7 @@ class OSMWidgetTest(SimpleTestCase): "id": "id_p", "geom_name": "Point", } - expected = json_script(attrs, "mapwidget-options") + expected = json_script(attrs, "id_p_mapwidget_options") self.assertInHTML(expected, rendered) |
