Mojolicious-Plugin-Fondation-Perm-UI-Bootstrap
view release on metacpan or search on metacpan
share/public/js/DatatablePerm.js view on Meta::CPAN
var tableau;
$(function() {
if (!$('#panel-perm').length) return;
initialiseTabPerm();
$('#menuAddPerm').on('click', function(event) {
addPerm();
});
// ââââââââââââââââââââââââââââââââââââââââââââââââ
// Form validation using validators.js
// ââââââââââââââââââââââââââââââââââââââââââââââââ
async function validatePermForm() {
const form = document.getElementById('perm-form');
if (!form) {
console.error("Form #perm-form not found");
return { valid: false, errors: [{ field: null, message: l("Form not found") }], data: {} };
}
const formDataObj = Object.fromEntries(new FormData(form).entries());
// Cleanup (trim all strings)
Object.keys(formDataObj).forEach(key => {
if (typeof formDataObj[key] === 'string') {
formDataObj[key] = formDataObj[key].trim();
}
});
// Validate via FondationValidators
if (typeof window.FondationValidators === 'undefined' || typeof FondationValidators.validate !== 'function') {
console.error("FondationValidators not loaded or invalid");
return { valid: false, errors: [{ field: null, message: l("Validator not available") }], data: {} };
}
const schemaName = 'Perm';
const result = FondationValidators.validate(schemaName, formDataObj);
return {
valid: result.valid,
errors: result.errors.map(msg => ({
field: null,
message: msg
})),
data: formDataObj
};
}
// Display errors (Bootstrap 5 style)
function displayValidationErrors(errors) {
$('.is-invalid').removeClass('is-invalid');
$('.invalid-feedback').remove();
errors.forEach(err => {
let input = err.field ? document.getElementById(err.field) : null;
if (!input) {
const alert = $(`<div class="alert alert-danger mt-3">${err.message}</div>`);
$('#perm-form').prepend(alert);
setTimeout(() => alert.fadeOut(3000), 8000);
return;
}
input.classList.add('is-invalid');
const feedback = document.createElement('div');
feedback.className = 'invalid-feedback';
feedback.textContent = err.message;
input.parentNode.appendChild(feedback);
});
}
// ââââââââââââââââââââââââââââââââââââââââââââââââ
// "Save" button
// ââââââââââââââââââââââââââââââââââââââââââââââââ
$('#saveObject').on('click', async function() {
const button = $(this);
button.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> ' + l("Saving..."));
try {
const validation = await validatePermForm();
if (!validation.valid) {
displayValidationErrors(validation.errors);
return;
}
const id = validation.data.id;
const method = id ? 'PUT' : 'POST';
const url = id ? `/api/perm/${id}` : '/api/perm';
// id is in the URL path, not the request body
delete validation.data.id;
const response = await fetch(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(validation.data)
});
if (!response.ok) {
const body = await response.json();
const msg = body?.errors?.map(e => e.message).join('; ')
|| body?.message
|| response.statusText;
throw new Error(msg);
}
successBox(l("Permission saved successfully"));
$('#perm-form')[0].reset();
$('#perm-modal').modal('hide');
$('#table-perm').DataTable().ajax.reload(null, false);
} catch (err) {
console.error("Error saving permission:", err);
alert(l("Error: ") + (err.message || l("Unknown error")));
} finally {
button.prop('disabled', false).text(l("Save"));
}
});
});
/**
* Initialize the permission table
*/
function initialiseTabPerm() {
if (!$('#table-perm').length) return;
$("#loading-icon").hide();
$("#panel-perm").show();
tableau = $('#table-perm').DataTable({
"dom": "<'row'<'col-sm-4'l><'col-sm-4'B><'col-sm-4'f>>" + "<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>",
"buttons": ['copy', 'csv', 'excel'],
"aLengthMenu": [[10,50,100,200,500,1000,-1], [10,50, 100, 200, 500, 1000, l("All")]],
"iDisplayLength": 10,
mark: true,
"search": {
"regex": true,
},
"bPaginate": true,
"bLengthChange": false,
"bInfo": true,
"ajax": {
( run in 0.337 second using v1.01-cache-2.11-cpan-ad19def0cd9 )