From bf7f88ac6e0a344cd6536687829f1b2cbc07e84f Mon Sep 17 00:00:00 2001 From: Ross Date: Wed, 25 Mar 2026 21:34:38 +0000 Subject: [PATCH] Render row selection controls server-side in SelectionTable for improved usability --- generic/tables.py | 8 ++++++++ templates/base.html | 40 ++-------------------------------------- 2 files changed, 10 insertions(+), 38 deletions(-) diff --git a/generic/tables.py b/generic/tables.py index d1f29a64..77b38d60 100644 --- a/generic/tables.py +++ b/generic/tables.py @@ -58,6 +58,14 @@ class SelectionTable(tables.Table): # Defensive: don't break table rendering if introspection fails pass + # By default render the row selection controls above the table so + # templates don't need to include `{{ table.row_selection_controls }}`. + try: + # `row_selection_controls` is already marked safe HTML. + self.caption = self.row_selection_controls + except Exception: + pass + @property def row_selection_controls(self): """Return HTML for the row-selection control bar. diff --git a/templates/base.html b/templates/base.html index a60421b3..c0993e34 100644 --- a/templates/base.html +++ b/templates/base.html @@ -351,44 +351,8 @@ return token ? idBase + '-' + token : idBase; } - // Ensure every selectable table has a row-selection control block. If the - // page author didn't render the controls, create them automatically and - // insert them before the table so the behavior is available out-of-the-box. - function ensureControlsForTable(table) { - if (!table) return; - // detect an existing nearby toggle button - var existing = table.previousElementSibling && table.previousElementSibling.querySelector && table.previousElementSibling.querySelector('[id^="toggle-row-selection"]'); - if (existing) return; // already present - - // generate a short token for unique IDs - var token = (Date.now().toString(16) + Math.floor(Math.random()*0xffff).toString(16)); - - var wrapper = document.createElement('div'); - wrapper.className = 'row-selection-controls-wrapper'; - wrapper.innerHTML = '
' - + '
' - + ' ' - + ' ' - + '
' - + '
' - + ' Selected: 0' - + '
' - + '
'; - - // Insert the controls immediately before the table (or its responsive wrapper) - var container = table.closest('.table-responsive') || table; - container.parentNode.insertBefore(wrapper, container); - } - - // Create controls for any table that looks selectable but lacks a control block - Array.from(document.querySelectorAll('table')).forEach(function(t){ - if (t.querySelector && (t.querySelector('input[name="selection"]') || t.querySelector('input[type="checkbox"]'))) { - ensureControlsForTable(t); - } - }); + // Injector removed: selection controls are rendered server-side + // by `SelectionTable.row_selection_controls` (now set as `caption`). // For every toggle button (supports both unsuffixed and suffixed IDs) document.querySelectorAll('button[id^="toggle-row-selection"]').forEach(function(toggleBtn) {