{% block export_modal_html %}
<!-- Export Application Modal -->
<div class="modal fade" id="exportApplicationModal" tabindex="-1" aria-labelledby="exportApplicationModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exportApplicationModalLabel">
<i data-lucide="download" style="width: 18px; height: 18px;" class="me-2"></i>
Export Applications
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
{{ form_start(exportForm, {'attr': {'id': 'exportApplicationForm'}}) }}
<div class="modal-body">
{% if form_errors(exportForm)|length > 0 %}
<div class="alert alert-danger">
{{ form_errors(exportForm) }}
</div>
{% endif %}
<div class="mb-3">
{{ form_label(exportForm.name, 'Export Name', {'label_attr': {'class': 'form-label small'}}) }}
<span class="text-danger">*</span>
{{ form_widget(exportForm.name, {'attr': {'class': 'form-control form-control-sm', 'placeholder': 'Enter export name...'}}) }}
{{ form_errors(exportForm.name) }}
</div>
{{ form_widget(exportForm.filters) }}
{{ form_widget(exportForm.columns) }}
{{ form_widget(exportForm.type) }}
{{ form_widget(exportForm.format) }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary btn-sm" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary btn-sm">
<i data-lucide="check" style="width: 14px; height: 14px;" class="me-1"></i>
Export
</button>
</div>
{{ form_end(exportForm) }}
</div>
</div>
</div>
{% endblock %}
{% block export_modal_js %}
<script>
$(document).ready(function() {
var $exportModal = $('#exportApplicationModal');
var $exportForm = $('#exportApplicationForm');
// Set filters and columns in export form when modal opens
$exportModal.on('show.bs.modal', function() {
var $filtersInput = $exportForm.find('input[name="export_application[filters]"]');
var $columnsInput = $exportForm.find('input[name="export_application[columns]"]');
if ($filtersInput.length) {
// Get filters from URL query parameters
var urlParams = new URLSearchParams(window.location.search);
var filters = {};
// Convert camelCase to snake_case
function toSnakeCase(str) {
return str.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase();
}
// Extract application_filter parameters from URL
urlParams.forEach(function(value, key) {
// Match pattern like "application_filter[fieldName]"
var match = key.match(/^application_filter\[([^\]]+)\]$/);
if (match) {
var filterKey = match[1];
// Skip CSRF token and empty values
if (filterKey !== '_token' && value !== null && value !== undefined && value !== '') {
// Skip '0' values for fields that should be null (productName, status)
// These fields use null as the placeholder value
if (value === '0' && (filterKey === 'productName' || filterKey === 'status')) {
return; // Skip this value
}
// Convert key to snake_case
filterKey = toSnakeCase(filterKey);
filters[filterKey] = value;
}
}
});
$filtersInput.val(JSON.stringify(filters));
}
});
// Handle export form submission
$exportForm.on('submit', function(e) {
e.preventDefault();
var $form = $(this);
var filtersValue = $form.find('input[name="export_application[filters]"]').val() || '{}';
var columnsValue = $form.find('input[name="export_application[columns]"]').val() || '{}';
var typeValue = $form.find('input[name="export_application[type]"]').val() || 'applications';
var formatValue = $form.find('input[name="export_application[format]"]').val() || 'xlsx';
var data = {
name: $form.find('input[name="export_application[name]"]').val(),
filters: JSON.parse(filtersValue),
columns: JSON.parse(columnsValue),
type: typeValue,
format: formatValue
};
$.ajax({
url: '{{ path('export') }}',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(data),
dataType: 'json',
success: function(response) {
// Reset form
$exportForm[0].reset();
// Close modal properly
var modalInstance = bootstrap.Modal.getInstance($exportModal[0]);
if (modalInstance) {
modalInstance.hide();
} else {
$exportModal.modal('hide');
}
// Clean up backdrop and reset form when modal is fully closed
$exportModal.one('hidden.bs.modal', function() {
// Remove any lingering backdrop
$('.modal-backdrop').remove();
$('body').removeClass('modal-open').css({
'overflow': '',
'padding-right': ''
});
// Reset form fields
$exportForm[0].reset();
$exportForm.find('.is-invalid').removeClass('is-invalid');
$exportForm.find('.invalid-feedback').remove();
});
// Show success message
if (response.token || response.message) {
if (typeof Swal !== 'undefined') {
Swal.fire({
title: response.message,
icon: 'success',
confirmButtonText: 'OK'
});
} else {
alert(response.message);
}
}
},
error: function(xhr, status, error) {
console.error('Error:', error);
var errorMessage = 'An error occurred while starting the export.';
if (xhr.responseJSON && xhr.responseJSON.message) {
errorMessage = xhr.responseJSON.message;
}
if (typeof Swal !== 'undefined') {
Swal.fire({
title: 'Error',
text: errorMessage,
icon: 'error',
confirmButtonText: 'OK'
});
} else {
alert(errorMessage);
}
}
});
});
});
</script>
{% endblock %}