itflow/js/bulk_actions.js

123 lines
3.8 KiB
JavaScript

// bulk_actions.js
// Shared bulk helper: selection count + simple URL enrichment for bulk actions
// --- Helpers ---
function getBulkCheckboxes() {
// Always query fresh in case rows are re-rendered
return Array.from(document.querySelectorAll('input[type="checkbox"].bulk-select'));
}
function getSelectedCount() {
return getBulkCheckboxes().filter(cb => cb.checked).length;
}
function updateSelectedCount() {
const count = getSelectedCount();
const selectedCountEl = document.getElementById('selectedCount');
if (selectedCountEl) {
selectedCountEl.textContent = count;
}
const bulkBtn = document.getElementById('bulkActionButton');
if (bulkBtn) {
bulkBtn.hidden = count === 0;
}
}
// --- Select All Handling ---
function checkAll(source) {
getBulkCheckboxes().forEach(cb => {
cb.checked = source.checked;
});
updateSelectedCount();
}
// --- Wire up once DOM is ready ---
document.addEventListener('DOMContentLoaded', function () {
// Initialize count
updateSelectedCount();
// Wire select-all checkbox if present
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
if (selectAllCheckbox) {
selectAllCheckbox.addEventListener('click', function () {
checkAll(this);
});
}
// Per-row checkbox handling
document.addEventListener('click', function (e) {
const cb = e.target.closest('input[type="checkbox"].bulk-select');
if (!cb) return;
updateSelectedCount();
});
// ------------------------------------------------------
// Generic bulk handler
//
// For ANY element with data-bulk="true":
// - Reads base URL from data-modal-url or href
// - Collects ALL checked .bulk-select checkboxes
// - Appends:
// <cb.name> = cb.value
// e.g. file_ids[]=12, document_ids[]=27, client_ids[]=3, etc.
// - Writes URL back to data-modal-url or href
// - DOES NOT prevent default, so ajax-modal / normal links still work
// ------------------------------------------------------
document.addEventListener('click', function (e) {
const trigger = e.target.closest('[data-bulk="true"]');
if (!trigger) return;
const base = trigger.getAttribute('data-modal-url') || trigger.getAttribute('href');
if (!base || base === '#') return;
let url;
try {
url = new URL(base, window.location.href);
} catch (err) {
// Invalid URL, bail
return;
}
const params = url.searchParams;
const checked = getBulkCheckboxes().filter(cb => cb.checked);
if (!checked.length) {
// Nothing selected; do nothing (no ids appended)
return;
}
// Collect all unique names (file_ids[], document_ids[], client_ids[], etc.)
const namesToClear = new Set();
checked.forEach(cb => {
if (cb.name) {
namesToClear.add(cb.name);
}
});
// Clear any existing values for those names
namesToClear.forEach(name => params.delete(name));
// Append each checked checkbox as name=value
checked.forEach(cb => {
if (!cb.name) return;
params.append(cb.name, cb.value);
});
const finalUrl = url.pathname + '?' + params.toString();
if (trigger.hasAttribute('data-modal-url')) {
trigger.setAttribute('data-modal-url', finalUrl);
} else {
trigger.setAttribute('href', finalUrl);
}
// IMPORTANT:
// We do NOT call preventDefault().
// Your existing ajax-modal handler / normal link click will continue normally,
// now using the updated URL.
}, true); // capture so we run before other click handlers
});