updated client payment, file upload and notes
This commit is contained in:
@@ -1,14 +1,21 @@
|
||||
$(document).ready(function() {
|
||||
|
||||
// Generic AJAX handler for standard forms (Shortcodes & Payments)
|
||||
function submitAjaxForm(formId, modalId) {
|
||||
$(formId).on('submit', function(e) {
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
if (typeof jQuery === 'undefined') {
|
||||
console.error('jQuery is required for client-modals.js to work.');
|
||||
return;
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
console.log('Client modals AJAX script loaded with SweetAlert.');
|
||||
|
||||
// Generic AJAX handler for standard forms (Shortcodes & Payments)
|
||||
$(document).on('submit', '#shortcodeForm, #paymentForm, #noteForm', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
let $form = $(this);
|
||||
let modalId = '#' + $form.closest('.modal').attr('id');
|
||||
let $submitBtn = $form.find('button[type="submit"]');
|
||||
let originalBtnText = $submitBtn.text();
|
||||
|
||||
// Disable button and show loading state
|
||||
$submitBtn.prop('disabled', true).text('Saving...');
|
||||
|
||||
$.ajax({
|
||||
@@ -19,12 +26,18 @@ $(document).ready(function() {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
},
|
||||
success: function(response) {
|
||||
// Hide modal
|
||||
$(modalId).modal('hide');
|
||||
// Reset form
|
||||
$form[0].reset();
|
||||
// Reload page to show fresh data (or dynamically append to table)
|
||||
location.reload();
|
||||
|
||||
// Success SweetAlert
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Success!',
|
||||
text: response.message || 'Record saved successfully.',
|
||||
confirmButtonColor: '#0d6efd'
|
||||
}).then(() => {
|
||||
location.reload();
|
||||
});
|
||||
},
|
||||
error: function(xhr) {
|
||||
let errors = xhr.responseJSON?.errors;
|
||||
@@ -32,39 +45,55 @@ $(document).ready(function() {
|
||||
if (errors) {
|
||||
errorMsg = Object.values(errors).flat().join('\n');
|
||||
}
|
||||
alert(errorMsg);
|
||||
},
|
||||
complete: function() {
|
||||
|
||||
// Error SweetAlert
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Validation Error',
|
||||
text: errorMsg,
|
||||
confirmButtonColor: '#dc3545'
|
||||
});
|
||||
|
||||
$submitBtn.prop('disabled', false).text(originalBtnText);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// AJAX handler for Document Upload (Requires FormData for files)
|
||||
function submitFileForm(formId, modalId) {
|
||||
$(formId).on('submit', function(e) {
|
||||
// AJAX handler for Document Upload (FormData)
|
||||
$(document).on('submit', '#documentForm', function(e) {
|
||||
e.preventDefault();
|
||||
let formElement = $(this)[0];
|
||||
|
||||
let formElement = this;
|
||||
let $form = $(this);
|
||||
let formData = new FormData(formElement);
|
||||
let $submitBtn = $(this).find('button[type="submit"]');
|
||||
let modalId = '#' + $form.closest('.modal').attr('id');
|
||||
let $submitBtn = $form.find('button[type="submit"]');
|
||||
let originalBtnText = $submitBtn.text();
|
||||
|
||||
$submitBtn.prop('disabled', true).text('Uploading...');
|
||||
|
||||
$.ajax({
|
||||
url: $(this).attr('action'),
|
||||
url: $form.attr('action'),
|
||||
type: 'POST',
|
||||
data: formData,
|
||||
processData: false, // Essential for file uploads
|
||||
contentType: false, // Essential for file uploads
|
||||
processData: false,
|
||||
contentType: false,
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
},
|
||||
success: function(response) {
|
||||
$(modalId).modal('hide');
|
||||
formElement.reset();
|
||||
location.reload();
|
||||
|
||||
// Success SweetAlert
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Uploaded!',
|
||||
text: response.message || 'Document uploaded successfully.',
|
||||
confirmButtonColor: '#0d6efd'
|
||||
}).then(() => {
|
||||
location.reload();
|
||||
});
|
||||
},
|
||||
error: function(xhr) {
|
||||
let errors = xhr.responseJSON?.errors;
|
||||
@@ -72,17 +101,119 @@ $(document).ready(function() {
|
||||
if (errors) {
|
||||
errorMsg = Object.values(errors).flat().join('\n');
|
||||
}
|
||||
alert(errorMsg);
|
||||
},
|
||||
complete: function() {
|
||||
|
||||
// Error SweetAlert
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Upload Failed',
|
||||
text: errorMsg,
|
||||
confirmButtonColor: '#dc3545'
|
||||
});
|
||||
|
||||
$submitBtn.prop('disabled', false).text(originalBtnText);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize the handlers
|
||||
submitAjaxForm('#shortcodeForm', '#addShortcodeModal');
|
||||
submitAjaxForm('#paymentForm', '#addPaymentModal');
|
||||
submitFileForm('#documentForm', '#uploadDocumentModal');
|
||||
// Initialize Select2 for Payment Services when modal opens
|
||||
$('#addPaymentModal').on('shown.bs.modal', function () {
|
||||
let $select = $('#paymentServicesSelect');
|
||||
|
||||
// Only fetch if options haven't been loaded yet
|
||||
if ($select.children('option').length === 0) {
|
||||
$.ajax({
|
||||
url: base_url + '/api/services', // Update route if needed
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
$select.empty();
|
||||
data.forEach(function(service) {
|
||||
$select.append(new Option(service.name, service.name, false, false));
|
||||
});
|
||||
|
||||
// Initialize Select2 with Bootstrap 5 theme
|
||||
$select.select2({
|
||||
theme: 'bootstrap-5',
|
||||
dropdownParent: $('#addPaymentModal'),
|
||||
placeholder: 'Search and select services...'
|
||||
});
|
||||
},
|
||||
error: function() {
|
||||
console.error('Failed to load services for Select2.');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// If already loaded, just re-initialize if needed
|
||||
$select.select2({
|
||||
theme: 'bootstrap-5',
|
||||
dropdownParent: $('#addPaymentModal'),
|
||||
placeholder: 'Search and select services...'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Clear Select2 values when modal is closed
|
||||
$('#addPaymentModal').on('hidden.bs.modal', function () {
|
||||
$('#paymentServicesSelect').val(null).trigger('change');
|
||||
});
|
||||
|
||||
// --- DYNAMIC DOCUMENT ROW HANDLERS ---
|
||||
$('#addRowBtn').on('click', function() {
|
||||
let rowHtml = `
|
||||
<div class="file-row card border bg-light p-3 mb-3 position-relative">
|
||||
<div class="row g-2 align-items-center">
|
||||
<div class="col-md-5">
|
||||
<label class="form-label text-muted small fw-bold">Document Name / Title</label>
|
||||
<input type="text" name="names[]" class="form-control" placeholder="e.g. Tax Clearance" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-muted small fw-bold">Select File</label>
|
||||
<input type="file" name="files[]" class="form-control" required>
|
||||
</div>
|
||||
<div class="col-md-1 text-end d-flex align-items-end">
|
||||
<button type="button" class="btn btn-outline-danger btn-sm remove-row-btn mt-4"><i class="bi bi-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
$('#fileRowsContainer').append(rowHtml);
|
||||
updateRemoveButtons();
|
||||
});
|
||||
|
||||
// Remove row click handler
|
||||
$(document).on('click', '.remove-row-btn', function() {
|
||||
$(this).closest('.file-row').remove();
|
||||
updateRemoveButtons();
|
||||
});
|
||||
|
||||
// Hide delete button if only 1 row remains
|
||||
function updateRemoveButtons() {
|
||||
let totalRows = $('.file-row').length;
|
||||
if (totalRows === 1) {
|
||||
$('.remove-row-btn').hide();
|
||||
} else {
|
||||
$('.remove-row-btn').show();
|
||||
}
|
||||
}
|
||||
|
||||
// Reset modal fields when closed
|
||||
$('#uploadDocumentModal').on('hidden.bs.modal', function() {
|
||||
$('#documentForm')[0].reset();
|
||||
$('#fileRowsContainer').html(`
|
||||
<div class="file-row card border bg-light p-3 mb-3 position-relative">
|
||||
<div class="row g-2 align-items-center">
|
||||
<div class="col-md-5">
|
||||
<label class="form-label text-muted small fw-bold">Document Name / Title</label>
|
||||
<input type="text" name="names[]" class="form-control" placeholder="e.g. Signed Service Agreement" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-muted small fw-bold">Select File</label>
|
||||
<input type="file" name="files[]" class="form-control" required>
|
||||
</div>
|
||||
<div class="col-md-1 text-end d-flex align-items-end">
|
||||
<button type="button" class="btn btn-outline-danger btn-sm remove-row-btn mt-4" style="display: none;"><i class="bi bi-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user