1
0
mirror of https://github.com/django/django.git synced 2025-08-21 01:09:13 +00:00

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>
This commit is contained in:
Matthias Kestenholz 2025-06-15 16:38:10 +02:00 committed by nessita
parent 2013092b69
commit 0a262c8407
4 changed files with 12 additions and 8 deletions

View File

@ -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));
});

View File

@ -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>

View File

@ -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>
`;

View File

@ -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)