// actions.js
/**
* Reusable confirmation + AJAX action handler.
* Can be used for delete, restore, or any other bulk action.
*/
export function actionWithAjax({ajax_call, title, confirmText, successText, btnClass, onSuccess, onError, onComplete})
{
if (!ajax_call?.formData || !ajax_call?.endpoint) {
console.error('❌ actionWithAjax: Missing ajax_call.formData or ajax_call.endpoint');
return;
}
// SweetAlert confirmation dialog
Swal.fire({
html: `Are you sure you want to ${title} ?`,
icon: 'warning',
showCancelButton: true,
buttonsStyling: false,
confirmButtonText: confirmText,
cancelButtonText: 'No, cancel',
allowOutsideClick: false,
customClass: {
confirmButton: `btn fw-bold ${btnClass}`,
cancelButton: 'btn fw-bold btn-active-light-primary'
}
}).then(result => {
if (!result.value) return;
const csrfMeta = $('meta[name="csrf-token"]');
const csrfToken = csrfMeta.length ? csrfMeta.attr('content') : null;
// Perform AJAX
$.ajax({
url: ajax_call.endpoint,
type: 'POST',
data: ajax_call.formData,
cache: false,
contentType: false,
processData: false,
dataType: 'json',
headers: csrfToken ? { 'X-CSRF-TOKEN': csrfToken } : {},
beforeSend: () =>
{
Swal.fire({
title: `${capitalize(title)}...`,
html: `Please wait while we ${title} the record(s).`,
allowOutsideClick: false,
allowEscapeKey: false,
didOpen: () => Swal.showLoading()
});
},
success: (res) =>
{
Swal.close();
if (res.status)
{
Swal.fire({
html: successText,
icon: 'success',
buttonsStyling: false,
showConfirmButton: false,
timer: 2000,
timerProgressBar: true
});
toastr.success(res.message);
if (typeof onSuccess === 'function') onSuccess(res);
} else {
toastr.error(res.message || 'Action failed.');
if (typeof onError === 'function') onError(res);
}
},
error: (xhr) =>
{
Swal.close();
if (xhr.responseJSON?.errors) {
Object.values(xhr.responseJSON.errors).forEach(msg => toastr.error(msg));
} else if (xhr.responseJSON?.message) {
toastr.error(xhr.responseJSON.message);
} else {
toastr.error('An unexpected error occurred.');
}
if (typeof onError === 'function') onError(xhr);
},
complete: (xhr, status) => {
if (typeof onComplete === 'function') onComplete(xhr, status);
},
statusCode:
{
404: function(xhr) {
// Get Response ==> xhr.responseJSON
// alert("page not found");
},
403: function(xhr) {
// alert("Forbidden");
},
419: function(xhr) {
// alert("CSRF Token Not Valid / Session Invalid");
},
422: function(xhr) {
// alert("Unprocessable Entity");
},
500: function(xhr) {
// alert("Internal Server Error");
}
}
});
});
}
/**
* Utility to refresh DataTable without full reload
* @param {string} tableId - The DataTable ID in window.LaravelDataTables
*/
export function refreshDataTable(tableId)
{
if (window.LaravelDataTables?.[tableId]) {
window.LaravelDataTables[tableId].draw(false);
} else {
// console.warn(`DataTable '${tableId}' not found`);
}
}
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}