fixed fields
This commit is contained in:
@@ -25,6 +25,18 @@ $stmt = $pdo->prepare("SELECT id, field_id, excel_column, is_manual, manual_defa
|
||||
$stmt->execute([$id]);
|
||||
$mappings = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Recupera i fixed fields dalla tabella template_fixed_mapping
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT id, fixed_field_key, is_manual, data_type, is_required, default_value, is_visible_import
|
||||
FROM template_fixed_mapping
|
||||
WHERE template_id = ?
|
||||
ORDER BY id ASC
|
||||
");
|
||||
$stmt->execute([$id]);
|
||||
$fixedMappings = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$hasFixedMappings = !empty($fixedMappings);
|
||||
|
||||
// Recupera le colonne già associate nel database
|
||||
$usedColumnsFromDB = array_filter(array_column($mappings, 'excel_column'));
|
||||
|
||||
@@ -42,6 +54,8 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
<?php include('cssinclude.php'); ?>
|
||||
<title>Configure Template <?= htmlspecialchars($template['name'], ENT_QUOTES, 'UTF-8'); ?></title>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
||||
|
||||
<style>
|
||||
.dropdown-select {
|
||||
width: 100%;
|
||||
@@ -89,6 +103,11 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* fix bootstrap/select2 width */
|
||||
.select2-container {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -138,67 +157,215 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
<table id="schemaFieldsTable" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Main</th>
|
||||
<th>Visible on Import</th>
|
||||
<th style="width:100px; text-align:center;">Main</th>
|
||||
<th style="width:120px; text-align:center;">Visible on Import</th>
|
||||
<th>Title</th>
|
||||
<th>Type</th>
|
||||
<th style="width:140px;">Type</th>
|
||||
<th>Mapping</th>
|
||||
<th>Default Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
||||
|
||||
|
||||
<tbody id="schemaFieldsBody">
|
||||
<?php foreach ($mappings as $mapping): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="checkbox" class="main-field-checkbox" data-mapping-id="<?php echo $mapping['id']; ?>" <?php echo $mapping['main_field'] == 1 ? 'checked' : ''; ?>>
|
||||
<td class="text-center">
|
||||
<input type="checkbox"
|
||||
class="main-field-checkbox"
|
||||
data-mapping-id="<?php echo (int)$mapping['id']; ?>"
|
||||
<?php echo ((int)$mapping['main_field'] === 1) ? 'checked' : ''; ?>>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" class="visible-import-checkbox" data-mapping-id="<?php echo $mapping['id']; ?>" <?php echo (isset($mapping['is_visible_import']) ? $mapping['is_visible_import'] : 1) == 1 ? 'checked' : ''; ?>>
|
||||
|
||||
<td class="text-center">
|
||||
<input type="checkbox"
|
||||
class="visible-import-checkbox"
|
||||
data-mapping-id="<?php echo (int)$mapping['id']; ?>"
|
||||
<?php echo ((int)($mapping['is_visible_import'] ?? 1) === 1) ? 'checked' : ''; ?>>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<?php echo htmlspecialchars($mapping['field_label'] ?? 'N/A'); ?>
|
||||
<?php if ($mapping['is_required'] == 1): ?>
|
||||
<?php if ((int)$mapping['is_required'] === 1): ?>
|
||||
<span class="badge bg-danger ms-2">Required</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
|
||||
<td><?php echo htmlspecialchars($mapping['data_type'] ?? 'N/A'); ?></td>
|
||||
|
||||
<td>
|
||||
<?php
|
||||
$isSceltaMultipla = $mapping['data_type'] === 'SceltaMultipla';
|
||||
$mappingValue = $isSceltaMultipla ? 'manual' : ($mapping['excel_column'] ? 'xls' : ($mapping['is_manual'] ? 'manual' : ''));
|
||||
$isSceltaMultipla = ($mapping['data_type'] === 'SceltaMultipla');
|
||||
$mappingValue = $isSceltaMultipla
|
||||
? 'manual'
|
||||
: ($mapping['excel_column'] ? 'xls' : ((int)$mapping['is_manual'] === 1 ? 'manual' : ''));
|
||||
?>
|
||||
<select class="form-select mapping-select" data-id="<?php echo $mapping['id']; ?>" data-field-id="<?php echo $mapping['field_id']; ?>" <?php echo $isSceltaMultipla ? 'disabled' : ''; ?>>
|
||||
|
||||
<select class="form-select mapping-select"
|
||||
data-id="<?php echo (int)$mapping['id']; ?>"
|
||||
data-field-id="<?php echo (int)$mapping['field_id']; ?>"
|
||||
<?php echo $isSceltaMultipla ? 'disabled' : ''; ?>>
|
||||
|
||||
<?php if (!$isSceltaMultipla): ?>
|
||||
<option value="">Select Option</option>
|
||||
<option value="xls" <?php echo $mappingValue === 'xls' ? 'selected' : ''; ?>>Map to XLS Column</option>
|
||||
<option value="xls" <?php echo ($mappingValue === 'xls') ? 'selected' : ''; ?>>Map to XLS Column</option>
|
||||
<?php endif; ?>
|
||||
<option value="manual" <?php echo $mappingValue === 'manual' ? 'selected' : ''; ?>>Manual Entry</option>
|
||||
|
||||
<option value="manual" <?php echo ($mappingValue === 'manual') ? 'selected' : ''; ?>>Manual Entry</option>
|
||||
</select>
|
||||
<select class="form-select xls-columns" style="display:<?php echo $mappingValue === 'xls' ? 'block' : 'none'; ?>" data-id="<?php echo $mapping['id']; ?>" <?php echo $mapping['excel_column'] ? 'data-current-xls="' . htmlspecialchars($mapping['excel_column']) . '"' : ''; ?>></select>
|
||||
<?php if ($mapping['excel_column']): ?>
|
||||
<span class="mapped-column" style="margin-left: 5px;"><?php echo htmlspecialchars($mapping['excel_column']); ?></span>
|
||||
<button class="btn btn-danger btn-sm remove-xls" data-id="<?php echo $mapping['id']; ?>" style="margin-left: 5px;">X</button>
|
||||
|
||||
<select class="form-select xls-columns"
|
||||
style="display:<?php echo ($mappingValue === 'xls') ? 'block' : 'none'; ?>"
|
||||
data-id="<?php echo (int)$mapping['id']; ?>"
|
||||
<?php echo $mapping['excel_column'] ? 'data-current-xls="' . htmlspecialchars($mapping['excel_column']) . '"' : ''; ?>>
|
||||
</select>
|
||||
|
||||
<?php if (!empty($mapping['excel_column'])): ?>
|
||||
<span class="mapped-column" style="margin-left:5px;">
|
||||
(<?php echo htmlspecialchars($mapping['excel_column']); ?>)
|
||||
</span>
|
||||
<button class="btn btn-danger btn-sm remove-xls"
|
||||
data-id="<?php echo (int)$mapping['id']; ?>"
|
||||
style="margin-left:5px;">
|
||||
X
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<?php if ($mapping['data_type'] === 'SceltaMultipla'): ?>
|
||||
<select class="form-select dropdown-select manual-default" data-id="<?php echo $mapping['id']; ?>" data-field-id="<?php echo $mapping['field_id']; ?>" data-manual-default="<?php echo htmlspecialchars($mapping['manual_default'] ?? ''); ?>" style="display:block;">
|
||||
<select class="form-select dropdown-select manual-default"
|
||||
data-id="<?php echo (int)$mapping['id']; ?>"
|
||||
data-field-id="<?php echo (int)$mapping['field_id']; ?>"
|
||||
data-manual-default="<?php echo htmlspecialchars($mapping['manual_default'] ?? ''); ?>"
|
||||
style="display:block;">
|
||||
<option value="">Seleziona...</option>
|
||||
</select>
|
||||
<?php else: ?>
|
||||
<input type="text" class="form-control manual-default" placeholder="Default value" value="<?php echo htmlspecialchars($mapping['manual_default'] ?? ''); ?>" style="display:<?php echo $mapping['is_manual'] ? 'block' : 'none'; ?>" data-field-id="<?php echo $mapping['field_id']; ?>">
|
||||
<input type="text"
|
||||
class="form-control manual-default"
|
||||
placeholder="Default value"
|
||||
value="<?php echo htmlspecialchars($mapping['manual_default'] ?? ''); ?>"
|
||||
style="display:<?php echo ((int)$mapping['is_manual'] === 1) ? 'block' : 'none'; ?>"
|
||||
data-field-id="<?php echo (int)$mapping['field_id']; ?>">
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Defaults for fixed fields (not part of XLS mapping) -->
|
||||
<!-- Fixed fields defaults (saved in DB, autosave) -->
|
||||
<div class="row mt-4">
|
||||
<div class="col-12 d-flex align-items-center justify-content-between">
|
||||
<h5 class="mb-0">Fixed Fields Defaults</h5>
|
||||
|
||||
<?php if (!$hasFixedMappings): ?>
|
||||
<button id="btnAddFixedFields" class="btn btn-outline-primary">
|
||||
Add Fixed Fields
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<small class="text-muted">Defaults are saved automatically when changed</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-3" id="fixedFieldsSection" style="display: <?php echo $hasFixedMappings ? 'block' : 'none'; ?>;">
|
||||
<div class="col-12">
|
||||
<table class="table table-striped" id="fixedFieldsTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:120px; text-align:center;">Visible on Import</th>
|
||||
<th style="width:120px; text-align:center;">Required</th>
|
||||
<th>Field</th>
|
||||
<th style="width:140px;">Type</th>
|
||||
<th>Default Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<?php foreach ($fixedMappings as $fm): ?>
|
||||
<tr>
|
||||
|
||||
<td class="text-center">
|
||||
<input type="checkbox"
|
||||
class="fixed-visible-checkbox"
|
||||
data-fixed-id="<?php echo (int)$fm['id']; ?>"
|
||||
<?php echo ((int)$fm['is_visible_import'] === 1) ? 'checked' : ''; ?>>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<input type="checkbox"
|
||||
class="fixed-required-checkbox"
|
||||
data-fixed-id="<?php echo (int)$fm['id']; ?>"
|
||||
<?php echo ((int)$fm['is_required'] === 1) ? 'checked' : ''; ?>>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<strong><?php echo htmlspecialchars($fm['fixed_field_key']); ?></strong>
|
||||
</td>
|
||||
|
||||
|
||||
<td><?php echo htmlspecialchars($fm['data_type']); ?></td>
|
||||
|
||||
<td>
|
||||
|
||||
<?php if ($fm['data_type'] === 'DATE'): ?>
|
||||
|
||||
<input type="date"
|
||||
class="form-control fixed-default-input"
|
||||
data-fixed-id="<?php echo (int)$fm['id']; ?>"
|
||||
value="<?php echo htmlspecialchars($fm['default_value'] ?? ''); ?>">
|
||||
|
||||
<?php elseif (in_array($fm['fixed_field_key'], [
|
||||
'ClienteResponsabile',
|
||||
'MoltiplicatorePrezzo',
|
||||
'AnagraficaCertestObject',
|
||||
'AnagraficaCertestService'
|
||||
])): ?>
|
||||
|
||||
<select class="form-select fixed-default-select"
|
||||
data-fixed-id="<?php echo (int)$fm['id']; ?>"
|
||||
data-fixed-key="<?php echo htmlspecialchars($fm['fixed_field_key']); ?>"
|
||||
data-current-value="<?php echo htmlspecialchars($fm['default_value'] ?? ''); ?>">
|
||||
<option value="">Loading...</option>
|
||||
</select>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<input type="text"
|
||||
class="form-control fixed-default-input"
|
||||
data-fixed-id="<?php echo (int)$fm['id']; ?>"
|
||||
value="<?php echo htmlspecialchars($fm['default_value'] ?? ''); ?>">
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
<div id="fixedSaveStatus" class="small mt-2 text-muted"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="templates_dashboard.php" class="btn btn-primary">⬅ Back to Template Dashboard</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -209,7 +376,7 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
</div>
|
||||
|
||||
<?php include('jsinclude.php'); ?>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
<script>
|
||||
let availableXlsColumns = <?php echo json_encode($xlsHeaders); ?> || [];
|
||||
let usedColumnsFromDB = <?php echo json_encode($usedColumnsFromDB); ?> || [];
|
||||
@@ -316,6 +483,80 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
});
|
||||
}
|
||||
|
||||
function initSelect2ForSchemaDropdowns() {
|
||||
// dropdown-select = SceltaMultipla (manual default)
|
||||
if (window.jQuery && $.fn.select2) {
|
||||
$('.dropdown-select').each(function() {
|
||||
if ($(this).hasClass('select2-hidden-accessible')) return; // già inizializzato
|
||||
$(this).select2({
|
||||
width: '100%',
|
||||
placeholder: 'Seleziona...',
|
||||
allowClear: true
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initSelect2ForFixedDropdowns() {
|
||||
if (!(window.jQuery && $.fn.select2)) return;
|
||||
|
||||
$('.fixed-default-select').each(function() {
|
||||
const $el = $(this);
|
||||
|
||||
// se era già Select2, lo resettiamo (utile quando renderizzi righe nuove)
|
||||
if ($el.hasClass('select2-hidden-accessible')) {
|
||||
$el.select2('destroy');
|
||||
}
|
||||
|
||||
$el.select2({
|
||||
width: '100%',
|
||||
placeholder: 'Seleziona...',
|
||||
allowClear: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function saveFixedDefaultSelect(selectEl) {
|
||||
const id = selectEl.dataset.fixedId;
|
||||
const value = selectEl.value;
|
||||
|
||||
fetch('update_fixed_field.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id,
|
||||
field: 'default_value',
|
||||
value
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(d => {
|
||||
if (!d.success) throw new Error(d.message || 'Update failed');
|
||||
// aggiorno anche il dataset così rimane coerente
|
||||
selectEl.dataset.currentValue = value;
|
||||
fixedStatus('✅ Saved');
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
fixedStatus('❌ Save error', true);
|
||||
});
|
||||
}
|
||||
|
||||
// Eventi Select2 (jQuery)
|
||||
if (window.jQuery) {
|
||||
$(document).on('select2:select select2:clear', '.fixed-default-select', function() {
|
||||
saveFixedDefaultSelect(this);
|
||||
});
|
||||
|
||||
// fallback (nel caso cambi senza select2)
|
||||
$(document).on('change', '.fixed-default-select', function() {
|
||||
saveFixedDefaultSelect(this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
let templateId = <?php echo $id; ?>;
|
||||
let schemaId = <?php echo json_encode($template['idschema'] ?? 0); ?>;
|
||||
@@ -403,9 +644,13 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
dropdown.disabled = true;
|
||||
});
|
||||
} finally {
|
||||
// attiva Select2 dopo aver messo le options
|
||||
initSelect2ForSchemaDropdowns();
|
||||
|
||||
console.log('Nascondo overlay di caricamento.');
|
||||
loadingOverlay.style.display = 'none';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Carica i dropdown con overlay
|
||||
@@ -713,9 +958,352 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
.catch(error => console.error("❌ Fetch error:", error));
|
||||
}
|
||||
|
||||
// =======================
|
||||
// FIXED FIELDS (DB autosave)
|
||||
// =======================
|
||||
|
||||
function escapeHtml(str) {
|
||||
return String(str ?? '')
|
||||
.replaceAll('&', '&')
|
||||
.replaceAll('<', '<')
|
||||
.replaceAll('>', '>')
|
||||
.replaceAll('"', '"')
|
||||
.replaceAll("'", ''');
|
||||
}
|
||||
|
||||
function fixedStatus(msg, isError = false) {
|
||||
const el = document.getElementById('fixedSaveStatus');
|
||||
if (!el) return;
|
||||
el.textContent = msg;
|
||||
el.classList.toggle('text-danger', isError);
|
||||
el.classList.toggle('text-muted', !isError);
|
||||
setTimeout(() => {
|
||||
el.textContent = '';
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function renderFixedRows(rows) {
|
||||
const tbody = document.querySelector('#fixedFieldsTable tbody');
|
||||
if (!tbody) return;
|
||||
|
||||
const keysWithDropdown = [
|
||||
'ClienteResponsabile',
|
||||
'MoltiplicatorePrezzo',
|
||||
'AnagraficaCertestObject',
|
||||
'AnagraficaCertestService'
|
||||
];
|
||||
|
||||
tbody.innerHTML = rows.map(r => {
|
||||
const type = String(r.data_type || '').toUpperCase();
|
||||
const dv = r.default_value ?? '';
|
||||
const isDate = type === 'DATE';
|
||||
const isDropdown = keysWithDropdown.includes(String(r.fixed_field_key || ''));
|
||||
|
||||
return `
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<input type="checkbox"
|
||||
class="fixed-visible-checkbox"
|
||||
data-fixed-id="${r.id}"
|
||||
${parseInt(r.is_visible_import) === 1 ? 'checked' : ''}>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<input type="checkbox"
|
||||
class="fixed-required-checkbox"
|
||||
data-fixed-id="${r.id}"
|
||||
${parseInt(r.is_required) === 1 ? 'checked' : ''}>
|
||||
</td>
|
||||
|
||||
<td><strong>${escapeHtml(r.fixed_field_key)}</strong></td>
|
||||
|
||||
|
||||
<td>${escapeHtml(r.data_type || '')}</td>
|
||||
|
||||
<td>
|
||||
${
|
||||
isDate
|
||||
? `<input type="date"
|
||||
class="form-control fixed-default-input"
|
||||
data-fixed-id="${r.id}"
|
||||
value="${escapeHtml(dv)}">`
|
||||
: isDropdown
|
||||
? `<select class="form-select fixed-default-select"
|
||||
data-fixed-id="${r.id}"
|
||||
data-fixed-key="${escapeHtml(r.fixed_field_key)}"
|
||||
data-current-value="${escapeHtml(dv)}">
|
||||
<option value="">Loading...</option>
|
||||
</select>`
|
||||
: `<input type="text"
|
||||
class="form-control fixed-default-input"
|
||||
data-fixed-id="${r.id}"
|
||||
value="${escapeHtml(dv)}"
|
||||
placeholder="Default value">`
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Button: Add Fixed Fields
|
||||
const btnAddFixedFields = document.getElementById('btnAddFixedFields');
|
||||
if (btnAddFixedFields) {
|
||||
btnAddFixedFields.addEventListener('click', async () => {
|
||||
btnAddFixedFields.disabled = true;
|
||||
btnAddFixedFields.textContent = 'Creating...';
|
||||
|
||||
try {
|
||||
const res = await fetch('create_fixed_fields.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
template_id: templateId
|
||||
})
|
||||
});
|
||||
const data = await res.json();
|
||||
|
||||
if (!data.success) throw new Error(data.message || 'Create failed');
|
||||
|
||||
document.getElementById('fixedFieldsSection').style.display = 'block';
|
||||
btnAddFixedFields.style.display = 'none';
|
||||
|
||||
if (Array.isArray(data.rows)) {
|
||||
renderFixedRows(data.rows);
|
||||
await fillFixedDropdowns();
|
||||
initSelect2ForFixedDropdowns();
|
||||
|
||||
|
||||
}
|
||||
|
||||
fixedStatus('✅ Fixed fields created');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
fixedStatus('❌ ' + e.message, true);
|
||||
btnAddFixedFields.disabled = false;
|
||||
btnAddFixedFields.textContent = 'Add Fixed Fields';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Autosave: Visible on import
|
||||
document.addEventListener('change', (e) => {
|
||||
if (!e.target.classList.contains('fixed-visible-checkbox')) return;
|
||||
|
||||
const id = e.target.dataset.fixedId;
|
||||
const value = e.target.checked ? 1 : 0;
|
||||
|
||||
fetch('update_fixed_field.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id,
|
||||
field: 'is_visible_import',
|
||||
value
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(d => {
|
||||
if (!d.success) throw new Error(d.message || 'Update failed');
|
||||
fixedStatus('✅ Saved');
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
e.target.checked = !e.target.checked;
|
||||
fixedStatus('❌ Save error', true);
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('change', (e) => {
|
||||
if (!e.target.classList.contains('fixed-required-checkbox')) return;
|
||||
|
||||
const id = e.target.dataset.fixedId;
|
||||
const value = e.target.checked ? 1 : 0;
|
||||
|
||||
fetch('update_fixed_field.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id,
|
||||
field: 'is_required',
|
||||
value
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(d => {
|
||||
if (!d.success) throw new Error(d.message || 'Update failed');
|
||||
fixedStatus('✅ Saved');
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
e.target.checked = !e.target.checked;
|
||||
fixedStatus('❌ Save error', true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Autosave: manual_default (debounce)
|
||||
let fixedTimer = null;
|
||||
document.addEventListener('input', (e) => {
|
||||
if (!e.target.classList.contains('fixed-default-input')) return;
|
||||
|
||||
clearTimeout(fixedTimer);
|
||||
fixedTimer = setTimeout(() => {
|
||||
const id = e.target.dataset.fixedId;
|
||||
const value = e.target.value;
|
||||
|
||||
fetch('update_fixed_field.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id,
|
||||
field: 'default_value',
|
||||
value
|
||||
})
|
||||
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(d => {
|
||||
if (!d.success) throw new Error(d.message || 'Update failed');
|
||||
fixedStatus('✅ Saved');
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
fixedStatus('❌ Save error', true);
|
||||
});
|
||||
}, 350);
|
||||
});
|
||||
|
||||
|
||||
if (availableXlsColumns.length) updateXlsDropdowns();
|
||||
|
||||
fillFixedDropdowns().then(() => {
|
||||
initSelect2ForFixedDropdowns();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
async function fillFixedDropdowns() {
|
||||
const selects = document.querySelectorAll('.fixed-default-select');
|
||||
console.log('[fillFixedDropdowns] found selects:', selects.length);
|
||||
|
||||
if (!selects.length) return;
|
||||
|
||||
const clientId = <?php echo (int)($template['idclient'] ?? 0); ?>;
|
||||
|
||||
async function fetchJson(url) {
|
||||
const r = await fetch(url);
|
||||
const text = await r.text();
|
||||
if (!r.ok) throw new Error(`HTTP ${r.status} on ${url}: ${text.slice(0, 200)}`);
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch (e) {
|
||||
throw new Error(`Invalid JSON from ${url}: ${text.slice(0, 200)}`);
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeList(j, key) {
|
||||
// Accetta vari formati: {value:[]}, {Responsabili:[]}, {results:[]}, array diretto
|
||||
if (Array.isArray(j)) return j;
|
||||
if (j && Array.isArray(j.value)) return j.value;
|
||||
if (j && Array.isArray(j.Responsabili)) return j.Responsabili;
|
||||
if (j && Array.isArray(j.results)) return j.results;
|
||||
|
||||
console.warn('[fillFixedDropdowns] unknown JSON shape for', key, j);
|
||||
return [];
|
||||
}
|
||||
|
||||
async function loadData(key) {
|
||||
if (key === 'MoltiplicatorePrezzo') {
|
||||
const j = await fetchJson('get_moltiplicatoreprezzo.php');
|
||||
const list = normalizeList(j, key);
|
||||
return list.map(x => ({
|
||||
id: x.IdMoltiplicatorePrezzo,
|
||||
label: `${x.Descrizione} (x${x.Fattore})`
|
||||
}));
|
||||
}
|
||||
|
||||
if (key === 'AnagraficaCertestObject') {
|
||||
const j = await fetchJson('get_anagrafica_certest_object.php');
|
||||
const list = normalizeList(j, key);
|
||||
return list.map(x => ({
|
||||
id: x.IdAnagrafica,
|
||||
label: `${x.Codice} - ${x.NomeAnagrafica}`
|
||||
}));
|
||||
}
|
||||
|
||||
if (key === 'AnagraficaCertestService') {
|
||||
const j = await fetchJson('get_anagrafica_certest_service.php');
|
||||
const list = normalizeList(j, key);
|
||||
return list.map(x => ({
|
||||
id: x.IdAnagrafica,
|
||||
label: `${x.Codice} - ${x.NomeAnagrafica}`
|
||||
}));
|
||||
}
|
||||
|
||||
if (key === 'ClienteResponsabile') {
|
||||
if (!clientId) return [];
|
||||
const j = await fetchJson('get_cliente_responsabile.php?id_cliente=' + clientId);
|
||||
const list = normalizeList(j, key);
|
||||
|
||||
// supporto due possibili campi:
|
||||
// - {IdClienteResponsabile, Nominativo}
|
||||
// - {Id, Nome} o simili
|
||||
return list.map(x => ({
|
||||
id: x.IdClienteResponsabile ?? x.Id ?? x.id,
|
||||
label: x.Nominativo ?? x.Nome ?? x.name ?? ''
|
||||
})).filter(x => x.id != null && x.label);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
for (const select of selects) {
|
||||
const key = select.dataset.fixedKey;
|
||||
const current = select.dataset.currentValue;
|
||||
|
||||
// IMPORTANT: togli "Loading..." subito (così se crasha non resta bloccato)
|
||||
select.innerHTML = '<option value="">Loading...</option>';
|
||||
|
||||
try {
|
||||
console.log('[fillFixedDropdowns] loading', key);
|
||||
const items = await loadData(key);
|
||||
|
||||
if (!items.length) {
|
||||
select.innerHTML = '<option value="">No data</option>';
|
||||
continue;
|
||||
}
|
||||
|
||||
select.innerHTML = '<option value=""></option>';
|
||||
|
||||
for (const it of items) {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = it.id;
|
||||
opt.textContent = it.label;
|
||||
select.appendChild(opt);
|
||||
}
|
||||
|
||||
if (current) select.value = current;
|
||||
|
||||
} catch (err) {
|
||||
console.error('[fillFixedDropdowns] error for', key, err);
|
||||
select.innerHTML = '<option value="">Error loading data</option>';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user