/* =================================== * NETGESCON FORM HANDLER * =================================== * Gestione form con UX migliorata: * - Modal di conferma * - Progress indicators * - No refresh pagina * - Feedback immediato * =================================== */ class NetGesConFormHandler { constructor() { this.init(); } init() { this.setupFormListeners(); this.createLoadingModal(); this.setupAjaxDefaults(); } setupAjaxDefaults() { // Setup CSRF token per tutte le richieste AJAX $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); } setupFormListeners() { // Intercetta tutti i form con classe 'netgescon-form' $(document).on('submit', '.netgescon-form', (e) => { e.preventDefault(); this.handleFormSubmit(e.target); }); // Intercetta i form di creazione/modifica stabili $(document).on('submit', 'form[action*="stabili"]', (e) => { if (!$(e.target).hasClass('netgescon-form')) { e.preventDefault(); this.handleFormSubmit(e.target); } }); } createLoadingModal() { const modalHtml = ` `; $('body').append(modalHtml); } showLoadingModal(message = 'Elaborazione in corso...') { $('#loading-message').text(message); $('#progress-bar').css('width', '20%'); $('#netgescon-loading-modal').removeClass('hidden'); // Simula progress setTimeout(() => $('#progress-bar').css('width', '60%'), 500); setTimeout(() => $('#progress-bar').css('width', '80%'), 1000); } hideLoadingModal() { $('#progress-bar').css('width', '100%'); setTimeout(() => { $('#netgescon-loading-modal').addClass('hidden'); $('#progress-bar').css('width', '0%'); }, 300); } handleFormSubmit(form) { const $form = $(form); const formData = new FormData(form); const action = $form.attr('action'); const method = $form.attr('method') || 'POST'; // Determina il messaggio di loading in base al form let loadingMessage = 'Salvataggio in corso...'; if (action.includes('create') || method.toUpperCase() === 'POST') { loadingMessage = 'Creazione in corso...'; } else if (action.includes('edit') || action.includes('update')) { loadingMessage = 'Aggiornamento in corso...'; } this.showLoadingModal(loadingMessage); // Se il form ha un metodo specificato tramite _method, usalo const actualMethod = formData.get('_method') || method; $.ajax({ url: action, type: method, data: formData, processData: false, contentType: false, success: (response) => { this.hideLoadingModal(); this.handleSuccess(response, $form); }, error: (xhr) => { this.hideLoadingModal(); this.handleError(xhr, $form); } }); } handleSuccess(response, $form) { // Mostra notifica di successo this.showNotification('Operazione completata con successo!', 'success'); // Reindirizza se specificato nella risposta if (response.redirect) { setTimeout(() => { window.location.href = response.redirect; }, 1500); } else { // Altrimenti ricarica la pagina dopo un delay setTimeout(() => { window.location.reload(); }, 1500); } } handleError(xhr, $form) { console.error('Form submission error:', xhr); let errorMessage = 'Si è verificato un errore. Riprova.'; if (xhr.status === 422 && xhr.responseJSON && xhr.responseJSON.errors) { // Errori di validazione errorMessage = 'Errori di validazione:'; const errors = xhr.responseJSON.errors; const errorList = Object.values(errors).flat(); this.showValidationErrors(errorList, $form); return; } else if (xhr.responseJSON && xhr.responseJSON.message) { errorMessage = xhr.responseJSON.message; } this.showNotification(errorMessage, 'error'); } showValidationErrors(errors, $form) { // Rimuovi errori precedenti $form.find('.error-message').remove(); $form.find('.border-red-500').removeClass('border-red-500'); // Mostra nuovo alert con errori const errorHtml = `

Errori di validazione:

    ${errors.map(error => `
  • • ${error}
  • `).join('')}
`; $form.prepend(errorHtml); // Scroll al primo errore $form[0].scrollIntoView({ behavior: 'smooth' }); } showNotification(message, type = 'info') { const bgColor = type === 'success' ? 'bg-green-500' : type === 'error' ? 'bg-red-500' : 'bg-blue-500'; const notification = $(`
${message}
`); $('body').append(notification); // Mostra notifica setTimeout(() => { notification.removeClass('translate-x-full'); }, 100); // Nascondi dopo 4 secondi setTimeout(() => { notification.addClass('translate-x-full'); setTimeout(() => notification.remove(), 300); }, 4000); } } // Inizializza quando il DOM è pronto $(document).ready(() => { // Verifica se jQuery è disponibile if (typeof $ === 'undefined') { console.warn('NetGesConFormHandler: jQuery non trovato, caricamento alternativo...'); // Carica jQuery se non presente const script = document.createElement('script'); script.src = 'https://code.jquery.com/jquery-3.6.0.min.js'; script.onload = () => { new NetGesConFormHandler(); }; document.head.appendChild(script); } else { new NetGesConFormHandler(); } }); // Esporta per uso globale window.NetGesConFormHandler = NetGesConFormHandler;