Updated bulk action js to pass the checkboxe names into the get array this allows the use of multiple checkbox name arrays to be passed at once instead of just selected_ids had to update each bulk model from selected_ids to to the array that was passed. This was important so we could mix files and documents together

This commit is contained in:
johnnyq 2025-11-27 12:48:59 -05:00
parent 0347382a34
commit 53178b8d20
45 changed files with 431 additions and 356 deletions

View File

@ -286,7 +286,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<tr>
<td class="pr-0 bg-light">
<div class="form-check">
<input class="form-check-input bulk-select" type="checkbox" name="selected_ids[]" value="<?= $expense_id ?>">
<input class="form-check-input bulk-select" type="checkbox" name="expense_ids[]" value="<?= $expense_id ?>">
</div>
</td>
<td>

View File

@ -447,24 +447,15 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num'])
</button>
<div class="dropdown-menu">
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/file/file_bulk_move.php?client_id=<?= $client_id ?>"
data-modal-url="modals/file/file_bulk_move.php?client_id=<?= $client_id ?>&current_folder_id=<?= $get_folder_id ?>"
data-bulk="true">
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move Files
</a>
<a class="dropdown-item ajax-modal" href="#"
data-modal-url="modals/document/document_bulk_move.php?client_id=<?= $client_id ?>"
data-bulk="true">
<i class="fas fa-fw fa-exchange-alt mr-2"></i>Move Documents
</a>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_files">
<i class="fas fa-fw fa-trash mr-2"></i>Delete Files
</button>
<button class="dropdown-item text-danger text-bold"
type="submit" form="bulkActions" name="bulk_delete_documents">
<i class="fas fa-fw fa-trash mr-2"></i>Delete Documents
</button>
</div>
</div>

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$asset_ids = array_map('intval', $_GET['asset_ids'] ?? []);
$count = count($selected_ids);
$count = count($asset_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="asset_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($asset_ids as $asset_id) { ?><input type="hidden" name="asset_ids[]" value="<?= $asset_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -3,9 +3,9 @@
require_once '../../../includes/modal_header.php';
$client_id = intval($_GET['client_id']);
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$asset_ids = array_map('intval', $_GET['asset_ids'] ?? []);
$count = count($selected_ids);
$count = count($asset_ids);
ob_start();
@ -20,7 +20,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="asset_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($asset_ids as $asset_id) { ?><input type="hidden" name="asset_ids[]" value="<?= $asset_id ?>"><?php } ?>
<div class="modal-body">
<div class="form-group">

View File

@ -3,9 +3,9 @@
require_once '../../../includes/modal_header.php';
$client_id = intval($_GET['client_id']);
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$asset_ids = array_map('intval', $_GET['asset_ids'] ?? []);
$count = count($selected_ids);
$count = count($asset_ids);
ob_start();
@ -20,7 +20,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="asset_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($asset_ids as $asset_id) { ?><input type="hidden" name="asset_ids[]" value="<?= $asset_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$asset_ids = array_map('intval', $_GET['asset_ids'] ?? []);
$count = count($selected_ids);
$count = count($asset_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="asset_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($asset_ids as $asset_id) { ?><input type="hidden" name="asset_ids[]" value="<?= $asset_id ?>"><?php } ?>
<div class="modal-body">
<div class="form-group">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$asset_ids = array_map('intval', $_GET['asset_ids'] ?? []);
$count = count($selected_ids);
$count = count($asset_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="asset_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($asset_ids as $asset_id) { ?><input type="hidden" name="asset_ids[]" value="<?= $asset_id ?>"><?php } ?>
<div class="modal-body">
<input type="hidden" name="remove_tags" value="0">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$asset_ids = array_map('intval', $_GET['asset_ids'] ?? []);
$count = count($selected_ids);
$count = count($asset_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="asset_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($asset_ids as $asset_id) { ?><input type="hidden" name="asset_ids[]" value="<?= $asset_id ?>"><?php } ?>
<div class="modal-body">
<div class="form-group">

View File

@ -2,8 +2,8 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$count = count($selected_ids);
$asset_ids = array_map('intval', $_GET['asset_ids'] ?? []);
$count = count($asset_ids);
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
@ -25,7 +25,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="asset_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($asset_ids as $asset_id) { ?><input type="hidden" name="asset_ids[]" value="<?= $asset_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$client_ids = array_map('intval', $_GET['client_ids'] ?? []);
$count = count($selected_ids);
$count = count($client_ids);
// Generate the HTML form content using output buffering.
ob_start();
@ -20,7 +20,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="client_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($client_ids as $client_id) { ?><input type="hidden" name="client_ids[]" value="<?= $client_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$client_ids = array_map('intval', $_GET['client_ids'] ?? []);
$count = count($selected_ids);
$count = count($client_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="client_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($client_ids as $client_id) { ?><input type="hidden" name="client_ids[]" value="<?= $client_id ?>"><?php } ?>
<input type="hidden" name="bulk_remove_tags" value="0">
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$client_ids = array_map('intval', $_GET['client_ids'] ?? []);
$count = count($selected_ids);
$count = count($client_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="client_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($client_ids as $client_id) { ?><input type="hidden" name="client_ids[]" value="<?= $client_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$client_ids = array_map('intval', $_GET['client_ids'] ?? []);
$count = count($selected_ids);
$count = count($client_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="client_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($client_ids as $client_id) { ?><input type="hidden" name="client_ids[]" value="<?= $client_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$client_ids = array_map('intval', $_GET['client_ids'] ?? []);
$count = count($selected_ids);
$count = count($client_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="client_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($client_ids as $client_id) { ?><input type="hidden" name="client_ids[]" value="<?= $client_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$client_ids = array_map('intval', $_GET['client_ids'] ?? []);
$count = count($selected_ids);
$count = count($client_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="client_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($client_ids as $client_id) { ?><input type="hidden" name="client_ids[]" value="<?= $client_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -3,9 +3,9 @@
require_once '../../../includes/modal_header.php';
$client_id = intval($_GET['client_id']);
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$contact_ids = array_map('intval', $_GET['contact_ids'] ?? []);
$count = count($selected_ids);
$count = count($contact_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="contact_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($contact_ids as $contact_id) { ?><input type="hidden" name="contact_ids[]" value="<?= $contact_id ?>"><?php } ?>
<div class="modal-body">
<div class="form-group">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$contact_ids = array_map('intval', $_GET['contact_ids'] ?? []);
$count = count($selected_ids);
$count = count($contact_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="contact_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($contact_ids as $contact_id) { ?><input type="hidden" name="contact_ids[]" value="<?= $contact_id ?>"><?php } ?>
<div class="modal-body">
<input type="hidden" name="bulk_remove_tags" value="0">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$contact_ids = array_map('intval', $_GET['contact_ids'] ?? []);
$count = count($selected_ids);
$count = count($contact_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="contact_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($contact_ids as $contact_id) { ?><input type="hidden" name="contact_ids[]" value="<?= $contact_id ?>"><?php } ?>
<div class="modal-body">
<label>Department / Group</label>

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$contact_ids = array_map('intval', $_GET['contact_ids'] ?? []);
$count = count($selected_ids);
$count = count($contact_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="contact_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($contact_ids as $contact_id) { ?><input type="hidden" name="contact_ids[]" value="<?= $contact_id ?>"><?php } ?>
<div class="modal-body">
<label>Phone</label>

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$contact_ids = array_map('intval', $_GET['contact_ids'] ?? []);
$count = count($selected_ids);
$count = count($contact_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="contact_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($contact_ids as $contact_id) { ?><input type="hidden" name="contact_ids[]" value="<?= $contact_id ?>"><?php } ?>
<input type="hidden" name="bulk_contact_important" value="0">
<input type="hidden" name="bulk_contact_billing" value="0">
<input type="hidden" name="bulk_contact_technical" value="0">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$contact_ids = array_map('intval', $_GET['contact_ids'] ?? []);
$count = count($selected_ids);
$count = count($contact_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="contact_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($contact_ids as $contact_id) { ?><input type="hidden" name="contact_ids[]" value="<?= $contact_id ?>"><?php } ?>
<div class="modal-body">
<label>From Email / Display Name</label>

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$credential_ids = array_map('intval', $_GET['credential_ids'] ?? []);
$count = count($selected_ids);
$count = count($credential_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="credential_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($credential_ids as $credential_id) { ?><input type="hidden" name="credential_ids[]" value="<?= $credential_id ?>"><?php } ?>
<div class="modal-body">
<input type="hidden" name="bulk_remove_tags" value="0">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$expense_ids = array_map('intval', $_GET['expense_ids'] ?? []);
$count = count($selected_ids);
$count = count($expense_ids);
// Generate the HTML form content using output buffering.
ob_start();
@ -13,7 +13,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?> <input type="hidden" name="expense_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($expense_ids as $expense_id) { ?> <input type="hidden" name="expense_ids[]" value="<?= $expense_id ?>"><?php } ?>
<div class="modal-body text-center">
<div class="mb-4" style="text-align: center;">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$expense_ids = array_map('intval', $_GET['expense_ids'] ?? []);
$count = count($selected_ids);
$count = count($expense_ids);
// Generate the HTML form content using output buffering.
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?> <input type="hidden" name="expense_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($expense_ids as $expense_id) { ?> <input type="hidden" name="expense_ids[]" value="<?= $expense_id ?>"><?php } ?>
<div class="modal-body">
<div class="form-group">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$expense_ids = array_map('intval', $_GET['expense_ids'] ?? []);
$count = count($selected_ids);
$count = count($expense_ids);
// Generate the HTML form content using output buffering.
ob_start();
@ -21,8 +21,8 @@ ob_start();
<div class="modal-body">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php
foreach ($selected_ids as $id) { ?>
<input type="hidden" name="expense_ids[]" value="<?= $id ?>">
foreach ($expense_ids as $expense_id) { ?>
<input type="hidden" name="expense_ids[]" value="<?= $expense_id ?>">
<?php
}
?>

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$expense_ids = array_map('intval', $_GET['expense_ids'] ?? []);
$count = count($selected_ids);
$count = count($expense_ids);
// Generate the HTML form content using output buffering.
ob_start();
@ -21,7 +21,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?> <input type="hidden" name="expense_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($expense_ids as $expense_id) { ?> <input type="hidden" name="expense_ids[]" value="<?= $expense_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,17 +2,26 @@
require_once '../../../includes/modal_header.php';
$client_id = intval($_GET['client_id']);
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$client_id = intval($_GET['client_id'] ?? 0);
$current_folder_id = intval($_GET['current_folder_id'] ?? 0);
$count = count($selected_ids);
// Selected IDs from JS (may be empty arrays)
$file_ids = array_map('intval', $_GET['file_ids'] ?? []);
$document_ids = array_map('intval', $_GET['document_ids'] ?? []);
$count_files = count($file_ids);
$count_docs = count($document_ids);
$total = $count_files + $count_docs;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fa fa-fw fa-exchange-alt mr-2"></i>Move <strong><?= $count ?></strong> Files</h5>
<h5 class="modal-title">
<i class="fa fa-fw fa-exchange-alt mr-2"></i>
Move <strong><?= $total ?></strong> Item<?= $total === 1 ? '' : 's' ?>
</h5>
<button type="button" class="close text-white" data-dismiss="modal">
<span>&times;</span>
</button>
@ -20,10 +29,22 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="file_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($file_ids as $id): ?>
<input type="hidden" name="file_ids[]" value="<?= $id ?>">
<?php endforeach; ?>
<?php foreach ($document_ids as $id): ?>
<input type="hidden" name="document_ids[]" value="<?= $id ?>">
<?php endforeach; ?>
<div class="modal-body">
<p>
Files: <strong><?= $count_files ?></strong><br>
Documents: <strong><?= $count_docs ?></strong>
</p>
<div class="form-group">
<label>Target Folder</label>
<div class="input-group">
@ -33,40 +54,47 @@ ob_start();
<select class="form-control select2" name="bulk_folder_id">
<option value="0">/</option>
<?php
// Fetch all folders for the client
$sql_all_folders = mysqli_query($mysqli, "SELECT folder_id, folder_name, parent_folder FROM folders WHERE folder_location = 1 AND folder_client_id = $client_id ORDER BY folder_name ASC");
$folders = array();
// Build an associative array of folders indexed by folder_id
while ($row = mysqli_fetch_assoc($sql_all_folders)) {
$folders[$row['folder_id']] = array(
'folder_id' => intval($row['folder_id']),
'folder_name' => nullable_htmlentities($row['folder_name']),
'parent_folder' => intval($row['parent_folder']),
'children' => array()
// NOTE: folder_location is gone now, so just use folder_client_id
$sql_all_folders = mysqli_query(
$mysqli,
"SELECT folder_id, folder_name, parent_folder
FROM folders
WHERE folder_client_id = $client_id
ORDER BY folder_name ASC"
);
$folders = [];
while ($row = mysqli_fetch_assoc($sql_all_folders)) {
$folders[$row['folder_id']] = [
'folder_id' => (int)$row['folder_id'],
'folder_name' => nullable_htmlentities($row['folder_name']),
'parent_folder'=> (int)$row['parent_folder'],
'children' => []
];
}
// Build the folder hierarchy
// Build hierarchy
foreach ($folders as $id => &$folder) {
if ($folder['parent_folder'] != 0 && isset($folders[$folder['parent_folder']])) {
$folders[$folder['parent_folder']]['children'][] = &$folder;
}
}
unset($folder); // Break the reference
unset($folder);
// Prepare a list of root folders
$root_folders = array();
$root_folders = [];
foreach ($folders as $id => $folder) {
if ($folder['parent_folder'] == 0) {
$root_folders[] = $folder;
}
}
// Display the folder options iteratively
$stack = array();
// Optional: if you want to default-select current folder, pass it in GET
$current_folder_id = intval($_GET['current_folder_id'] ?? 0);
$stack = [];
foreach (array_reverse($root_folders) as $folder) {
$stack[] = array('folder' => $folder, 'level' => 0);
$stack[] = ['folder' => $folder, 'level' => 0];
}
while (!empty($stack)) {
@ -74,21 +102,15 @@ ob_start();
$folder = $node['folder'];
$level = $node['level'];
// Indentation for subfolders
$indentation = str_repeat('&nbsp;', $level * 4);
// Check if this folder is selected
$selected = '';
if ($folder['folder_id'] == $get_folder_id) {
$selected = 'selected';
}
$selected = ($folder['folder_id'] === $current_folder_id) ? 'selected' : '';
echo "<option value=\"{$folder['folder_id']}\" $selected>$indentation{$folder['folder_name']}</option>";
// Add children to the stack
if (!empty($folder['children'])) {
foreach (array_reverse($folder['children']) as $child_folder) {
$stack[] = array('folder' => $child_folder, 'level' => $level + 1);
foreach (array_reverse($folder['children']) as $child) {
$stack[] = ['folder' => $child, 'level' => $level + 1];
}
}
}
@ -98,9 +120,14 @@ ob_start();
</div>
</div>
<div class="modal-footer">
<button type="submit" name="bulk_move_files" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Move Files</button>
<button type="button" class="btn btn-light" data-dismiss="modal"><i class="fa fa-times mr-2"></i>Cancel</button>
<button type="submit" name="bulk_move_files" class="btn btn-primary text-bold">
<i class="fa fa-check mr-2"></i>Move Files
</button>
<button type="button" class="btn btn-light" data-dismiss="modal">
<i class="fa fa-times mr-2"></i>Cancel
</button>
</div>
</form>

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$invoice_ids = array_map('intval', $_GET['invoice_ids'] ?? []);
$count = count($selected_ids);
$count = count($invoice_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="invoice_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($invoice_ids as $invoice_id) { ?><input type="hidden" name="invoice_ids[]" value="<?= $invoice_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$location_ids = array_map('intval', $_GET['location_ids'] ?? []);
$count = count($selected_ids);
$count = count($location_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="location_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($location_ids as $location_id) { ?><input type="hidden" name="location_ids[]" value="<?= $location_id ?>"><?php } ?>
<input type="hidden" name="bulk_remove_tags" value="0">
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$recurring_ticket_ids = array_map('intval', $_GET['recurring_ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($recurring_ticket_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="recurring_ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($recurring_ticket_ids as $recurring_ticket_id) { ?><input type="hidden" name="recurring_ticket_ids[]" value="<?= $recurring_ticket_id ?>"><?php } ?>
<div class="modal-body">
<div class="form-group">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$recurring_ticket_ids = array_map('intval', $_GET['recurring_ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($recurring_ticket_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="recurring_ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($recurring_ticket_ids as $recurring_ticket_id) { ?><input type="hidden" name="recurring_ticket_ids[]" value="<?= $recurring_ticket_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$recurring_ticket_ids = array_map('intval', $_GET['recurring_ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($recurring_ticket_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="recurring_ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($recurring_ticket_ids as $recurring_ticket_id) { ?><input type="hidden" name="recurring_ticket_ids[]" value="<?= $recurring_ticket_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$recurring_ticket_ids = array_map('intval', $_GET['recurring_ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($recurring_ticket_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="recurring_ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($recurring_ticket_ids as $recurring_ticket_id) { ?><input type="hidden" name="recurring_ticket_ids[]" value="<?= $recurring_ticket_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$recurring_ticket_ids = array_map('intval', $_GET['recurring_ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($recurring_ticket_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="recurring_ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($recurring_ticket_ids as $recurring_ticket_id) { ?><input type="hidden" name="recurring_ticket_ids[]" value="<?= $recurring_ticket_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$ticket_ids = array_map('intval', $_GET['ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($ticket_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($ticket_ids as $ticket_id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $ticket_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$ticket_ids = array_map('intval', $_GET['ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($ticket_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($ticket_ids as $ticket_id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $ticket_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$ticket_ids = array_map('intval', $_GET['ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($ticket_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($ticket_ids as $ticket_id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $ticket_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$ticket_ids = array_map('intval', $_GET['ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($ticket_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($ticket_ids as $ticket_id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $ticket_id ?>"><?php } ?>
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$ticket_ids = array_map('intval', $_GET['ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($ticket_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($ticket_ids as $ticket_id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $ticket_id ?>"><?php } ?>
<input type="hidden" id="current_ticket_id" value="0"> <!-- Can't currently bulk check this -->
<input type="hidden" name="merge_move_replies" value="0"> <!-- Default 0 -->
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$ticket_ids = array_map('intval', $_GET['ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($ticket_ids);
ob_start();
@ -19,7 +19,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($ticket_ids as $ticket_id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $ticket_id ?>"><?php } ?>
<input type="hidden" name="bulk_private_reply" value="0">
<div class="modal-body">

View File

@ -2,9 +2,9 @@
require_once '../../../includes/modal_header.php';
$selected_ids = array_map('intval', $_GET['selected_ids'] ?? []);
$ticket_ids = array_map('intval', $_GET['ticket_ids'] ?? []);
$count = count($selected_ids);
$count = count($ticket_ids);
ob_start();
@ -18,7 +18,7 @@ ob_start();
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<?php foreach ($selected_ids as $id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $id ?>"><?php } ?>
<?php foreach ($ticket_ids as $ticket_id) { ?><input type="hidden" name="ticket_ids[]" value="<?= $ticket_id ?>"><?php } ?>
<input type="hidden" name="bulk_private_note" value="0">
<div class="modal-body">

View File

@ -255,47 +255,117 @@ if (isset($_POST['bulk_delete_files'])) {
}
// Unified bulk move for Files + Documents
if (isset($_POST['bulk_move_files'])) {
validateCSRFToken($_POST['csrf_token']);
enforceUserPermission('module_support', 2);
$folder_id = intval($_POST['bulk_folder_id']);
// Get folder name for logging and Notification
// Default values (for root or missing folder)
$folder_name = "/";
$log_client_id = 0;
// If moving into a real folder, get folder name + client for logging
if ($folder_id > 0) {
$sql = mysqli_query($mysqli,"SELECT folder_name, folder_client_id FROM folders WHERE folder_id = $folder_id");
$row = mysqli_fetch_array($sql);
if ($row = mysqli_fetch_array($sql)) {
$folder_name = sanitizeInput($row['folder_name']);
$client_id = intval($row['folder_client_id']);
$log_client_id = intval($row['folder_client_id']);
}
}
// Check array for data
if (isset($_POST['file_ids'])) {
// Get Selected file Count
$file_count = count($_POST['file_ids']);
$file_count = 0;
$document_count = 0;
// Move Documents to Folder Loop
foreach($_POST['file_ids'] as $file_id) {
$file_id = intval($file_id);
// -------------------------
// Move FILES (if any)
// -------------------------
if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
$file_ids = array_map('intval', $_POST['file_ids']);
$file_count = count($file_ids);
foreach ($file_ids as $file_id) {
// Get file name for logging
$file_name = sanitizeInput(getFieldById('files', $file_id, 'file_name'));
// file move query
// Move file
mysqli_query($mysqli,"UPDATE files SET file_folder_id = $folder_id WHERE file_id = $file_id");
logAction("File", "Move", "$session_name moved file $file_name to folder $folder_name", $client_id, $file_id);
// Per-file log
logAction(
"File",
"Move",
"$session_name moved file $file_name to folder $folder_name",
$log_client_id,
$file_id
);
}
logAction("File", "Bulk Move", "$session_name moved $file_count file(s) to folder $folder_name", $client_id);
// Bulk summary log for files
logAction(
"File",
"Bulk Move",
"$session_name moved $file_count file(s) to folder $folder_name",
$log_client_id
);
}
flash_alert("Moved <strong>$file_count</strong> files to the folder <strong>$folder_name</strong>");
// -------------------------
// Move DOCUMENTS (if any)
// -------------------------
if (!empty($_POST['document_ids']) && is_array($_POST['document_ids'])) {
$document_ids = array_map('intval', $_POST['document_ids']);
$document_count = count($document_ids);
foreach ($document_ids as $document_id) {
// Get document name for logging
$document_name = sanitizeInput(getFieldById('documents', $document_id, 'document_name'));
// Move document
mysqli_query($mysqli,"UPDATE documents SET document_folder_id = $folder_id WHERE document_id = $document_id");
// Per-document log
logAction(
"Document",
"Move",
"$session_name moved document $document_name to folder $folder_name",
$log_client_id,
$document_id
);
}
// Bulk summary log for documents
logAction(
"Document",
"Bulk Move",
"$session_name moved $document_count document(s) to folder $folder_name",
$log_client_id
);
}
// -------------------------
// Flash message
// -------------------------
if ($file_count && $document_count) {
flash_alert("Moved <strong>$file_count</strong> file(s) and <strong>$document_count</strong> document(s) to the folder <strong>$folder_name</strong>");
} elseif ($file_count) {
flash_alert("Moved <strong>$file_count</strong> file(s) to the folder <strong>$folder_name</strong>");
} elseif ($document_count) {
flash_alert("Moved <strong>$document_count</strong> document(s) to the folder <strong>$folder_name</strong>");
} else {
flash_alert("No items were moved.");
}
redirect();
}
if (isset($_POST['link_asset_to_file'])) {
enforceUserPermission('module_support', 2);

View File

@ -3,31 +3,18 @@ $(document).on('click', '.ajax-modal', function (e) {
e.preventDefault();
const $trigger = $(this);
let modalUrl = $trigger.data('modal-url');
// Prefer data-modal-url, fallback to href
let modalUrl = $trigger.data('modal-url') || $trigger.attr('href') || '#';
const modalSize = $trigger.data('modal-size') || 'md';
const modalId = 'ajaxModal_' + new Date().getTime();
const modalId = 'ajaxModal_' + Date.now();
// -------- Optional bulk mode (activated via data-bulk="true") --------
if ($trigger.data('bulk') === true || $trigger.data('bulk') === 'true') {
const selector = $trigger.data('bulk-selector') || '.bulk-select:checked';
const param = $trigger.data('bulk-param') || 'selected_ids[]';
const ids = Array.from(document.querySelectorAll(selector)).map(cb => cb.value);
if (!ids.length) {
alert('Please select at least one item.');
return; // abort opening modal
// If no usable URL, bail
if (!modalUrl || modalUrl === '#') {
console.warn('ajax-modal: No modal URL found on trigger:', this);
return;
}
// Merge ids into existing query string safely
const urlObj = new URL(modalUrl, window.location.href);
ids.forEach(id => urlObj.searchParams.append(param, id));
// Preserve path + updated query (avoid absolute origin for relative AJAX)
modalUrl = urlObj.pathname + (urlObj.search ? '?' + urlObj.searchParams.toString() : '');
}
// --------------------------------------------------------------------
// Show loading spinner while fetching content
const loadingSpinner = `
<div id="modal-loading-spinner" class="text-center p-5">

View File

@ -1,20 +1,19 @@
// bulk_actions.js
// Allow selecting and editing multiple records at once (no <form> dependency)
// Shared bulk helper: selection count + simple URL enrichment for bulk actions
// --- Helpers ---
function getCheckboxes() {
function getBulkCheckboxes() {
// Always query fresh in case rows are re-rendered
return Array.from(document.querySelectorAll('input[type="checkbox"].bulk-select'));
}
function getSelectedIds() {
return getCheckboxes()
.filter(cb => cb.checked)
.map(cb => cb.value);
function getSelectedCount() {
return getBulkCheckboxes().filter(cb => cb.checked).length;
}
function updateSelectedCount() {
const count = getSelectedIds().length;
const count = getSelectedCount();
const selectedCountEl = document.getElementById('selectedCount');
if (selectedCountEl) {
selectedCountEl.textContent = count;
@ -28,95 +27,96 @@ function updateSelectedCount() {
// --- Select All Handling ---
function checkAll(source) {
getCheckboxes().forEach(cb => {
getBulkCheckboxes().forEach(cb => {
cb.checked = source.checked;
});
updateSelectedCount();
}
// Wire select-all checkbox if present
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
if (selectAllCheckbox) {
// --- 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) {
// Per-row checkbox handling
document.addEventListener('click', function (e) {
const cb = e.target.closest('input[type="checkbox"].bulk-select');
if (!cb) return;
updateSelectedCount();
});
});
// --- 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) {
// ------------------------------------------------------
// 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;
// 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 === '#') {
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 url = new URL(baseUrl, window.location.origin);
const params = url.searchParams;
const checked = getBulkCheckboxes().filter(cb => cb.checked);
const bulkNamesAttr = trigger.getAttribute('data-bulk-names');
const checkboxes = getCheckboxes().filter(cb => cb.checked);
if (!checked.length) {
// Nothing selected; do nothing (no ids appended)
return;
}
// 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);
// 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);
});
} 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
// 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
});