Sfoglia il codice sorgente

Fixes #22531: Ensure Saved Filter selector has unique element ID (#22542)

Jeremy Stretch 1 settimana fa
parent
commit
9c73c7a8ae

File diff suppressed because it is too large
+ 0 - 0
netbox/project-static/dist/netbox.js


File diff suppressed because it is too large
+ 0 - 0
netbox/project-static/dist/netbox.js.map


+ 1 - 1
netbox/project-static/src/forms/savedFiltersSelect.ts

@@ -22,7 +22,7 @@ function handleSavedFilterChange(event: Event): void {
 export function initSavedFilterSelect(): void {
   const divResults = document.getElementById('results');
   if (isTruthy(divResults)) {
-    const savedFilterSelect = document.getElementById('id_filter_id');
+    const savedFilterSelect = document.getElementById('saved-filter-select');
     if (isTruthy(savedFilterSelect)) {
       savedFilterSelect.addEventListener('change', handleSavedFilterChange);
     }

+ 3 - 2
netbox/templates/inc/table_controls_htmx.html

@@ -1,3 +1,4 @@
+{% load form_helpers %}
 {% load helpers %}
 {% load i18n %}
 
@@ -20,11 +21,11 @@
   {% if filter_form %}
     <div class="col-auto d-print-none">
       <div class="input-group">
-        <label for="{{ filter_form.filter_id.id_for_label }}" class="input-group-text">
+        <label for="saved-filter-select" class="input-group-text">
           <i class="mdi mdi-filter" title="{% trans "Saved filter" %}" aria-hidden="true"></i>
           <span class="visually-hidden">{% trans "Saved filter" %}</span>
         </label>
-        {{ filter_form.filter_id }}
+        {% render_field_with_aria filter_form.filter_id element_id="saved-filter-select" %}
       </div>
     </div>
   {% endif %}

+ 10 - 2
netbox/utilities/templatetags/form_helpers.py

@@ -56,8 +56,14 @@ def widget_type(field):
 
 
 @register.simple_tag
-def render_field_with_aria(field, has_helptext=None):
-    """Render a bound form field with aria-describedby/aria-invalid/aria-label wired up."""
+def render_field_with_aria(field, has_helptext=None, element_id=None):
+    """Render a bound form field with aria-describedby/aria-invalid/aria-label wired up.
+
+    Pass ``element_id`` to override the widget's HTML ``id``. This is needed when the same
+    field is rendered more than once on a page (e.g. the saved-filter selector, which appears
+    both in the list controls and the filter drawer), to keep element IDs unique so that label
+    associations resolve correctly for assistive technology.
+    """
     if has_helptext is None:
         has_helptext = bool(field.help_text)
     widget_attrs = field.field.widget.attrs
@@ -67,6 +73,8 @@ def render_field_with_aria(field, has_helptext=None):
     if has_helptext:
         described_by.append(f'{field.auto_id}_helptext')
     extra_attrs = {}
+    if element_id:
+        extra_attrs['id'] = element_id
     if described_by:
         # Merge with any aria-describedby already set on the widget so we
         # append to (rather than clobber) descriptions defined elsewhere.

+ 10 - 0
netbox/utilities/tests/test_templatetags.py

@@ -266,6 +266,16 @@ class RenderFieldWithAriaTestCase(TestCase):
         self.assertIn('id_name_errors', html)
         self.assertIn('id_name_helptext', html)
 
+    def test_element_id_overrides_widget_id(self):
+        class TestForm(forms.Form):
+            name = forms.CharField()
+
+        form = TestForm()
+        html = render_field_with_aria(form['name'], element_id='custom-id')
+
+        self.assertIn('id="custom-id"', html)
+        self.assertNotIn('id="id_name"', html)
+
     @override_settings(DEBUG=True)
     def test_missing_label_emits_debug_warning(self):
         class TestForm(forms.Form):

Some files were not shown because too many files changed in this diff