From 840460afe7116ae8c9cde6e76c69987c5b4e4697 Mon Sep 17 00:00:00 2001 From: johnnyq Date: Wed, 26 Nov 2025 16:12:19 -0500 Subject: [PATCH] Update Bulk Action JS to accept and pass multiple custom name selector arrays but default to selected_ids if data-bulk-names is not specified --- js/bulk_actions.js | 70 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/js/bulk_actions.js b/js/bulk_actions.js index 39399c2e..05db1340 100644 --- a/js/bulk_actions.js +++ b/js/bulk_actions.js @@ -43,7 +43,6 @@ if (selectAllCheckbox) { } // --- Per-row Checkbox Handling --- -// Use event delegation so it still works if table rows are re-rendered document.addEventListener('click', function (e) { const cb = e.target.closest('input[type="checkbox"].bulk-select'); if (!cb) return; @@ -52,3 +51,72 @@ document.addEventListener('click', function (e) { // --- Initialize count on page load --- document.addEventListener('DOMContentLoaded', updateSelectedCount); + +// ------------------------------------------------------ +// Generic bulk handler driven by data-bulk / data-bulk-names +// ------------------------------------------------------ +// Behavior: +// +// 1) If NO data-bulk-names: +// - all checked .bulk-select => ?selected_ids[]=1&selected_ids[]=2... +// +// 2) If data-bulk-names="file_ids[],document_ids[]": +// - checked name="file_ids[]" => ?file_ids[]=1&file_ids[]=2... +// - checked name="document_ids[]" => ?document_ids[]=5... +// +// Works with either data-modal-url or href. +// Does NOT open modal or prevent default; it just rewrites the URL. +document.addEventListener('click', function (e) { + const trigger = e.target.closest('[data-bulk="true"]'); + if (!trigger) return; + + // Base URL: prefer data-modal-url (ajax-modal style), fallback to href + const baseUrl = trigger.getAttribute('data-modal-url') || trigger.getAttribute('href'); + if (!baseUrl || baseUrl === '#') { + return; + } + + const url = new URL(baseUrl, window.location.origin); + const params = url.searchParams; + + const bulkNamesAttr = trigger.getAttribute('data-bulk-names'); + const checkboxes = getCheckboxes().filter(cb => cb.checked); + + // Clear previous ids (in case link is reused) + params.delete('selected_ids[]'); + + if (bulkNamesAttr && bulkNamesAttr.trim() !== '') { + // New behavior: group by checkbox name + const bulkNames = bulkNamesAttr + .split(',') + .map(s => s.trim()) + .filter(Boolean); + + // Clear specific names first + bulkNames.forEach(name => params.delete(name)); + + // Append values by name + bulkNames.forEach(name => { + checkboxes.forEach(cb => { + if (cb.name === name) { + params.append(name, cb.value); + } + }); + }); + } else { + // Old behavior: everything as selected_ids[] + checkboxes.forEach(cb => { + params.append('selected_ids[]', cb.value); + }); + } + + const finalUrl = url.pathname + '?' + params.toString(); + + // Write back to data-modal-url if present, else to href + if (trigger.hasAttribute('data-modal-url')) { + trigger.setAttribute('data-modal-url', finalUrl); + } else { + trigger.setAttribute('href', finalUrl); + } + // NOTE: we do NOT call preventDefault(), we do NOT open modals here. +}, true); // use capture so this runs before other click handlers