change link and color table
This commit is contained in:
parent
7d0824d01f
commit
4c4c6e3153
BIN
public/photostrf/446-20250709084636-1.png
Normal file
BIN
public/photostrf/446-20250709084636-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 571 KiB |
BIN
public/photostrf/473-20250709125634-1.png
Normal file
BIN
public/photostrf/473-20250709125634-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 571 KiB |
BIN
public/photostrf/qrcodes/qrcode_446.png
Normal file
BIN
public/photostrf/qrcodes/qrcode_446.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 517 B |
BIN
public/photostrf/qrcodes/qrcode_473.png
Normal file
BIN
public/photostrf/qrcodes/qrcode_473.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 508 B |
@ -31,6 +31,6 @@ Content-Length: 51
|
||||
< strict-transport-security: max-age=2592000
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Wed, 09 Jul 2025 08:30:56 GMT
|
||||
< date: Wed, 09 Jul 2025 13:11:20 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
|
||||
@ -10,16 +10,16 @@
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/odata/CustomField(156)?$expand=CustomFieldsValues
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/odata/CustomField(1083)?$expand=CustomFieldsValues
|
||||
* [HTTP/2] [1] [:method: GET]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/odata/CustomField(156)?$expand=CustomFieldsValues]
|
||||
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1MjA1NzA1NiwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.EpN1LkxexY0yE3duBjXG6F8Ei5vnECYooARiHpG91_0]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/odata/CustomField(1083)?$expand=CustomFieldsValues]
|
||||
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1MjA3Mzg4MCwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.dSJQhKeFGyIvVAf06qc_KpuKvu1dslu58hXOBp4qU3Y]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
> GET /limsapi/api/odata/CustomField(156)?$expand=CustomFieldsValues HTTP/2
|
||||
> GET /limsapi/api/odata/CustomField(1083)?$expand=CustomFieldsValues HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1MjA1NzA1NiwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.EpN1LkxexY0yE3duBjXG6F8Ei5vnECYooARiHpG91_0
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1MjA3Mzg4MCwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.dSJQhKeFGyIvVAf06qc_KpuKvu1dslu58hXOBp4qU3Y
|
||||
Accept: application/json
|
||||
|
||||
< HTTP/2 200
|
||||
@ -30,6 +30,6 @@ Accept: application/json
|
||||
< odata-version: 4.0
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Wed, 09 Jul 2025 08:30:57 GMT
|
||||
< date: Wed, 09 Jul 2025 13:11:21 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -121,7 +121,7 @@
|
||||
if (template.button_size === "large") sizeClass = "btn-large";
|
||||
|
||||
let btn = document.createElement("a");
|
||||
btn.href = `import_xls.php?id=${template.id}`;
|
||||
btn.href = `import_xls2.php?id=${template.id}`;
|
||||
btn.className = `btn ${sizeClass}`;
|
||||
btn.style.backgroundColor = template.button_bg_color;
|
||||
btn.style.color = template.button_text_color;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -152,6 +152,44 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
<?php include('cssinclude.php'); ?>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2Lw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<style>
|
||||
/* Colori pastello per input/select */
|
||||
input.auto-input,
|
||||
select.auto-input {
|
||||
background-color: #d4edda;
|
||||
/* Verde pastello */
|
||||
}
|
||||
|
||||
input.manual-input,
|
||||
select.manual-input {
|
||||
background-color: #fff3cd;
|
||||
/* Giallino pastello */
|
||||
}
|
||||
|
||||
input.required-input,
|
||||
select.required-input {
|
||||
background-color: #f8d7da;
|
||||
/* Rossino chiaro */
|
||||
}
|
||||
|
||||
/* Stili base per input/select */
|
||||
input,
|
||||
select {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Mantieni leggibilità del testo */
|
||||
input,
|
||||
select {
|
||||
color: #333;
|
||||
/* Colore scuro per contrasto */
|
||||
}
|
||||
|
||||
/* Stili esistenti rimangono invariati */
|
||||
.grid-container {
|
||||
overflow-x: auto;
|
||||
max-width: 100%;
|
||||
@ -214,16 +252,6 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
flex: 0 0 500px !important;
|
||||
}
|
||||
|
||||
.grid-cell input,
|
||||
.grid-cell select {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.resizer {
|
||||
width: 5px;
|
||||
height: 100%;
|
||||
@ -379,7 +407,8 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
<?php include('include/topbar.php'); ?>
|
||||
<div class="page-wrapper">
|
||||
<div class="page-content">
|
||||
<?php include('top_stat_widget.php'); ?>
|
||||
<?php //include('top_stat_widget.php');
|
||||
?>
|
||||
<div class="card radius-10">
|
||||
<div class="card-header">
|
||||
<div class="d-flex align-items-center">
|
||||
@ -402,15 +431,26 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
foreach ($fixedColumns as $col) {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
||||
}
|
||||
// Campi automatici (is_manual = 0)
|
||||
// Campi automatici (is_manual = 0) - Solo SceltaMultipla ha campo e propagazione
|
||||
$autoIndex = 0;
|
||||
foreach ($allMappings as $mapping) {
|
||||
if (!$mapping['is_manual']) {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
||||
$inputClass = 'auto-input';
|
||||
if ($mapping['is_required']) $inputClass .= ' required-input';
|
||||
if ($mapping['data_type'] === 'SceltaMultipla') {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'>";
|
||||
echo "<select class='custom-field dropdown-select $inputClass' data-column='auto_$autoIndex' data-field-id='{$mapping['field_id']}' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
echo "</select>";
|
||||
echo "<button type='button' class='propagate-btn' data-column='auto_$autoIndex'><i class='fas fa-arrow-down'></i></button>";
|
||||
echo "</div>";
|
||||
} else {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>"; // Nessun input per altri tipi
|
||||
}
|
||||
$autoIndex++;
|
||||
}
|
||||
}
|
||||
// Campi manuali (is_manual = 1) con propagate-btn
|
||||
// Campi manuali (is_manual = 1) con propagate-btn - Rimane invariato
|
||||
$manualIndex = 0;
|
||||
foreach ($allMappings as $mapping) {
|
||||
if ($mapping['is_manual']) {
|
||||
@ -418,18 +458,20 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') {
|
||||
$fieldValue = date('Y-m-d');
|
||||
}
|
||||
$requiredAttr = $mapping['is_required'] ? 'required' : '';
|
||||
$inputClass = 'manual-input';
|
||||
if ($mapping['is_required']) $inputClass .= ' required-input';
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'>";
|
||||
if ($mapping['data_type'] === 'SceltaMultipla') {
|
||||
echo "<select class='custom-field dropdown-select' data-column='manual_$manualIndex' data-field-id='{$mapping['field_id']}' $requiredAttr>";
|
||||
echo "<select class='custom-field dropdown-select $inputClass' data-column='manual_$manualIndex' data-field-id='{$mapping['field_id']}' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
echo "</select>";
|
||||
echo "<button type='button' class='propagate-btn' data-column='manual_$manualIndex'><i class='fas fa-arrow-down'></i></button>";
|
||||
} elseif ($mapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' class='custom-field' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
||||
echo "<input type='date' class='custom-field $inputClass' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
} elseif ($mapping['data_type'] === 'INT') {
|
||||
echo "<input type='number' class='custom-field' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
||||
echo "<input type='number' class='custom-field $inputClass' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
} else {
|
||||
echo "<input type='text' class='custom-field' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
||||
echo "<input type='text' class='custom-field $inputClass' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
}
|
||||
echo "<button type='button' class='propagate-btn' data-column='manual_$manualIndex'><i class='fas fa-arrow-down'></i></button>";
|
||||
echo "</div>";
|
||||
@ -515,19 +557,19 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
$detail = reset($detail) ?: ['field_value' => $mapping['manual_default']];
|
||||
$fieldValue = $detail['field_value'] ?? $mapping['manual_default'] ?? '';
|
||||
$requiredClass = ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : '';
|
||||
$requiredAttr = $mapping['is_required'] ? 'required' : '';
|
||||
$inputClass = 'auto-input';
|
||||
if ($mapping['is_required']) $inputClass .= ' required-input';
|
||||
echo "<div class='grid-cell editable-cell $requiredClass' data-col='auto_$autoIndex' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
if ($mapping['data_type'] === 'SceltaMultipla') {
|
||||
echo "<select name='rows[$index][details][{$mapping['id']}][field_value]' class='cell-input dropdown-select' data-mapping-id='{$mapping['id']}' data-field-id='{$mapping['field_id']}' $requiredAttr>";
|
||||
echo "<select name='rows[$index][details][{$mapping['id']}][field_value]' class='cell-input dropdown-select $inputClass' data-mapping-id='{$mapping['id']}' data-field-id='{$mapping['field_id']}' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
// Placeholder, i valori saranno popolati via AJAX
|
||||
echo "</select>";
|
||||
} elseif ($mapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||
echo "<input type='date' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input $inputClass' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
} elseif ($mapping['data_type'] === 'INT') {
|
||||
echo "<input type='number' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||
echo "<input type='number' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input $inputClass' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
} else {
|
||||
echo "<input type='text' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||
echo "<input type='text' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input $inputClass' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
}
|
||||
echo "</div>";
|
||||
$cellIndex++;
|
||||
@ -544,19 +586,19 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
$fieldValue = date('Y-m-d');
|
||||
}
|
||||
$requiredClass = ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : '';
|
||||
$requiredAttr = $mapping['is_required'] ? 'required' : '';
|
||||
$inputClass = 'manual-input';
|
||||
if ($mapping['is_required']) $inputClass .= ' required-input';
|
||||
echo "<div class='grid-cell editable-cell $requiredClass' data-col='manual_$manualIndex' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
if ($mapping['data_type'] === 'SceltaMultipla') {
|
||||
echo "<select name='rows[$index][details][{$mapping['id']}][field_value]' class='cell-input dropdown-select' data-mapping-id='{$mapping['id']}' data-field-id='{$mapping['field_id']}' $requiredAttr>";
|
||||
echo "<select name='rows[$index][details][{$mapping['id']}][field_value]' class='cell-input dropdown-select $inputClass' data-mapping-id='{$mapping['id']}' data-field-id='{$mapping['field_id']}' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
// Placeholder, i valori saranno popolati via AJAX
|
||||
echo "</select>";
|
||||
} elseif ($mapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||
echo "<input type='date' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input $inputClass' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
} elseif ($mapping['data_type'] === 'INT') {
|
||||
echo "<input type='number' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||
echo "<input type='number' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input $inputClass' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
} else {
|
||||
echo "<input type='text' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||
echo "<input type='text' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input $inputClass' " . ($mapping['is_required'] ? 'required' : '') . ">";
|
||||
}
|
||||
echo "</div>";
|
||||
$cellIndex++;
|
||||
@ -714,41 +756,52 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<!-- script dropdonw senza overlay -->
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Oggetto per memorizzare i dati delle tendine recuperati
|
||||
const dropdownData = {};
|
||||
|
||||
async function populateDropdowns() {
|
||||
const dropdowns = document.querySelectorAll('.dropdown-select');
|
||||
for (const dropdown of dropdowns) {
|
||||
const fieldId = dropdown.getAttribute('data-field-id');
|
||||
if (!fieldId) {
|
||||
console.warn('Nessun field_id trovato per il dropdown:', dropdown);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const response = await fetch(`get_customfield_values.php?field_id=${fieldId}`);
|
||||
const data = await response.json();
|
||||
if (data.error) {
|
||||
console.error('Errore per field_id', fieldId, ':', data.error);
|
||||
dropdown.innerHTML = '<option value="">Errore nel caricamento</option>';
|
||||
continue;
|
||||
if (dropdowns.length === 0) return;
|
||||
|
||||
// Recupera i dati solo per i field_id univoci
|
||||
const uniqueFieldIds = [...new Set(Array.from(dropdowns).map(d => d.getAttribute('data-field-id')))].filter(fieldId => fieldId);
|
||||
for (const fieldId of uniqueFieldIds) {
|
||||
if (!dropdownData[fieldId]) {
|
||||
try {
|
||||
const response = await fetch(`get_customfield_values.php?field_id=${fieldId}`);
|
||||
const data = await response.json();
|
||||
if (data.error) {
|
||||
console.error('Errore per field_id', fieldId, ':', data.error);
|
||||
continue;
|
||||
}
|
||||
dropdownData[fieldId] = data.CustomFieldsValues || [];
|
||||
} catch (error) {
|
||||
console.error('Errore nel fetch per field_id', fieldId, ':', error);
|
||||
}
|
||||
// Pulisci opzioni esistenti
|
||||
dropdown.innerHTML = '<option value="">Seleziona...</option>';
|
||||
// Aggiungi opzioni dai dati ricevuti
|
||||
if (data.CustomFieldsValues) {
|
||||
data.CustomFieldsValues.forEach(value => {
|
||||
const option = document.createElement('option');
|
||||
option.value = value.IdCustomFieldsValue;
|
||||
option.textContent = value.Valore;
|
||||
if (dropdown.value === option.value) option.selected = true;
|
||||
dropdown.appendChild(option);
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Errore nel fetch per field_id', fieldId, ':', error);
|
||||
dropdown.innerHTML = '<option value="">Errore nel caricamento</option>';
|
||||
}
|
||||
}
|
||||
|
||||
// Popola tutti i dropdown con i dati recuperati
|
||||
dropdowns.forEach(dropdown => {
|
||||
const fieldId = dropdown.getAttribute('data-field-id');
|
||||
if (!fieldId || !dropdownData[fieldId]) {
|
||||
dropdown.innerHTML = '<option value="">Errore nel caricamento</option>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Pulisci opzioni esistenti
|
||||
dropdown.innerHTML = '<option value="">Seleziona...</option>';
|
||||
dropdownData[fieldId].forEach(value => {
|
||||
const option = document.createElement('option');
|
||||
option.value = value.IdCustomFieldsValue;
|
||||
option.textContent = value.Valore;
|
||||
if (dropdown.value === option.value) option.selected = true;
|
||||
dropdown.appendChild(option);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Esegui al caricamento della pagina
|
||||
@ -760,8 +813,167 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
setTimeout(populateDropdowns, 100); // Ritardo per garantire che il DOM sia aggiornato
|
||||
});
|
||||
});
|
||||
|
||||
// Gestione della propagazione per mantenere i valori sincronizzati
|
||||
const propagateButtons = document.querySelectorAll('.propagate-btn');
|
||||
propagateButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const columnIndex = this.getAttribute('data-column').replace('manual_', '');
|
||||
const input = this.previousElementSibling;
|
||||
const value = input.value;
|
||||
|
||||
const gridTopCells = document.querySelector('.grid-top').querySelectorAll('.grid-cell');
|
||||
const targetTopIndex = Array.from(gridTopCells).findIndex(cell =>
|
||||
cell.querySelector('.propagate-btn') === button
|
||||
);
|
||||
|
||||
if (targetTopIndex !== -1) {
|
||||
const rows = document.querySelectorAll('.grid-row');
|
||||
rows.forEach(row => {
|
||||
const cells = row.querySelectorAll('.grid-cell');
|
||||
if (cells.length > targetTopIndex) {
|
||||
const targetInput = cells[targetTopIndex].querySelector('select.dropdown-select');
|
||||
if (targetInput) {
|
||||
targetInput.value = value;
|
||||
// Aggiorna visivamente il dropdown
|
||||
const event = new Event('change');
|
||||
targetInput.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<!-- dropdown with overlay -->
|
||||
<!--
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Crea un overlay di caricamento
|
||||
const loadingOverlay = document.createElement('div');
|
||||
loadingOverlay.id = 'loading-overlay';
|
||||
loadingOverlay.style.cssText = `
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
z-index: 9999;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
`;
|
||||
const loadingMessage = document.createElement('div');
|
||||
loadingMessage.style.cssText = `
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
padding: 20px;
|
||||
background: #333;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||
`;
|
||||
loadingMessage.textContent = 'Loading Dropdown Options...';
|
||||
loadingOverlay.appendChild(loadingMessage);
|
||||
document.body.appendChild(loadingOverlay);
|
||||
|
||||
// Funzione originale populateDropdowns
|
||||
async function populateDropdowns() {
|
||||
const dropdowns = document.querySelectorAll('.dropdown-select');
|
||||
if (dropdowns.length === 0) return;
|
||||
|
||||
const dropdownData = {};
|
||||
|
||||
// Recupera i dati solo per i field_id univoci
|
||||
const uniqueFieldIds = [...new Set(Array.from(dropdowns).map(d => d.getAttribute('data-field-id')))].filter(fieldId => fieldId);
|
||||
for (const fieldId of uniqueFieldIds) {
|
||||
if (!dropdownData[fieldId]) {
|
||||
try {
|
||||
const response = await fetch(`get_customfield_values.php?field_id=${fieldId}`);
|
||||
const data = await response.json();
|
||||
if (data.error) {
|
||||
console.error('Errore per field_id', fieldId, ':', data.error);
|
||||
continue;
|
||||
}
|
||||
dropdownData[fieldId] = data.CustomFieldsValues || [];
|
||||
} catch (error) {
|
||||
console.error('Errore nel fetch per field_id', fieldId, ':', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Popola tutti i dropdown con i dati recuperati
|
||||
dropdowns.forEach(dropdown => {
|
||||
const fieldId = dropdown.getAttribute('data-field-id');
|
||||
if (!fieldId || !dropdownData[fieldId]) {
|
||||
dropdown.innerHTML = '<option value="">Errore nel caricamento</option>';
|
||||
return;
|
||||
}
|
||||
|
||||
dropdown.innerHTML = '<option value="">Seleziona...</option>';
|
||||
dropdownData[fieldId].forEach(value => {
|
||||
const option = document.createElement('option');
|
||||
option.value = value.IdCustomFieldsValue;
|
||||
option.textContent = value.Valore;
|
||||
if (dropdown.value === option.value) option.selected = true;
|
||||
dropdown.appendChild(option);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Esegui al caricamento della pagina con l'overlay
|
||||
async function loadDropdownsWithOverlay() {
|
||||
console.log('Inizio caricamento tendine');
|
||||
loadingOverlay.style.display = 'flex';
|
||||
await new Promise(resolve => setTimeout(resolve, 500)); // Minimo 500ms di visibilità
|
||||
await populateDropdowns();
|
||||
console.log('Caricamento tendine completato');
|
||||
loadingOverlay.style.display = 'none';
|
||||
}
|
||||
|
||||
// Esegui il caricamento iniziale
|
||||
loadDropdownsWithOverlay();
|
||||
|
||||
// Rielabora i dropdown quando si aggiunge una nuova riga
|
||||
document.querySelectorAll('.save-btn').forEach(btn => {
|
||||
btn.addEventListener('click', function() {
|
||||
setTimeout(loadDropdownsWithOverlay, 100);
|
||||
});
|
||||
});
|
||||
|
||||
// Gestione della propagazione
|
||||
const propagateButtons = document.querySelectorAll('.propagate-btn');
|
||||
propagateButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const columnIndex = this.getAttribute('data-column').replace('manual_', '');
|
||||
const input = this.previousElementSibling;
|
||||
const value = input.value;
|
||||
|
||||
const gridTopCells = document.querySelector('.grid-top').querySelectorAll('.grid-cell');
|
||||
const targetTopIndex = Array.from(gridTopCells).findIndex(cell =>
|
||||
cell.querySelector('.propagate-btn') === button
|
||||
);
|
||||
|
||||
if (targetTopIndex !== -1) {
|
||||
const rows = document.querySelectorAll('.grid-row');
|
||||
rows.forEach(row => {
|
||||
const cells = row.querySelectorAll('.grid-cell');
|
||||
if (cells.length > targetTopIndex) {
|
||||
const targetInput = cells[targetTopIndex].querySelector('select.dropdown-select');
|
||||
if (targetInput) {
|
||||
targetInput.value = value;
|
||||
const event = new Event('change');
|
||||
targetInput.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
-->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -67,3 +67,5 @@ https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
|
||||
@ -1,184 +1,207 @@
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Gestione del popup per le foto
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
// Funzione per caricare il contenuto del popup
|
||||
async function loadPopupContent(iddatadb) {
|
||||
const popupContent = document.getElementById('popupContent');
|
||||
const popupContent = document.getElementById("popupContent");
|
||||
if (!popupContent) {
|
||||
console.error("Elemento popupContent non trovato");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const response = await fetch(`photos_popup.php?iddatadb=${iddatadb}`);
|
||||
console.log("Caricamento contenuto per iddatadb:", iddatadb);
|
||||
const response = await fetch(
|
||||
`photos_popup.php?iddatadb=${iddatadb}`,
|
||||
);
|
||||
if (!response.ok)
|
||||
throw new Error("Errore nella risposta del server");
|
||||
popupContent.innerHTML = await response.text();
|
||||
|
||||
// Dopo aver caricato il contenuto, associa gli event listener
|
||||
attachPhotoEventListeners(iddatadb);
|
||||
} catch (error) {
|
||||
popupContent.innerHTML = `<p>Errore durante il caricamento: ${error.message}</p>`;
|
||||
console.error("Errore in loadPopupContent:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// Funzione per attaccare gli event listener al contenuto del popup
|
||||
function attachPhotoEventListeners(iddatadb) {
|
||||
const dropArea = document.getElementById('dropArea');
|
||||
const photoInput = document.getElementById('photoInput');
|
||||
const dropArea = document.getElementById("dropArea");
|
||||
const photoInput = document.getElementById("photoInput");
|
||||
const photosModal = document.getElementById("photosModal");
|
||||
|
||||
if (!dropArea || !photoInput) {
|
||||
console.error('Elementi dropArea o photoInput non trovati nel DOM');
|
||||
if (!dropArea || !photoInput || !photosModal) {
|
||||
console.error("Elementi mancanti:", {
|
||||
dropArea,
|
||||
photoInput,
|
||||
photosModal,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Associando event listener per drag-and-drop');
|
||||
console.log("Event listener associati per iddatadb:", iddatadb);
|
||||
|
||||
// Gestione drag-and-drop
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
const preventDefaults = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => {
|
||||
dropArea.addEventListener(eventName, preventDefaults, false);
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
['dragenter', 'dragover'].forEach(eventName => {
|
||||
dropArea.addEventListener(eventName, () => {
|
||||
console.log('Drag enter/over');
|
||||
dropArea.classList.add('highlight');
|
||||
}, false);
|
||||
["dragenter", "dragover"].forEach((eventName) => {
|
||||
dropArea.addEventListener(
|
||||
eventName,
|
||||
() => dropArea.classList.add("highlight"),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
['dragleave', 'drop'].forEach(eventName => {
|
||||
dropArea.addEventListener(eventName, () => {
|
||||
console.log('Drag leave/drop');
|
||||
dropArea.classList.remove('highlight');
|
||||
}, false);
|
||||
["dragleave", "drop"].forEach((eventName) => {
|
||||
dropArea.addEventListener(
|
||||
eventName,
|
||||
() => dropArea.classList.remove("highlight"),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
dropArea.addEventListener('drop', (e) => {
|
||||
console.log('File droppato');
|
||||
const files = e.dataTransfer.files;
|
||||
handleFiles(files, iddatadb);
|
||||
}, false);
|
||||
dropArea.addEventListener(
|
||||
"drop",
|
||||
(e) => {
|
||||
const files = e.dataTransfer.files;
|
||||
handleFiles(files, iddatadb);
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
dropArea.addEventListener('click', () => {
|
||||
console.log('Click su dropArea');
|
||||
photoInput.click();
|
||||
}, false);
|
||||
dropArea.addEventListener("click", () => photoInput.click(), false);
|
||||
|
||||
photoInput.addEventListener('change', () => {
|
||||
console.log('File selezionato tramite input');
|
||||
handleFiles(photoInput.files, iddatadb);
|
||||
}, false);
|
||||
photoInput.addEventListener(
|
||||
"change",
|
||||
() => handleFiles(photoInput.files, iddatadb),
|
||||
false,
|
||||
);
|
||||
|
||||
// Gestione della rimozione delle foto
|
||||
const deleteButtons = document.querySelectorAll('.delete-photo-btn');
|
||||
deleteButtons.forEach(button => {
|
||||
button.addEventListener('click', async function() {
|
||||
const photoId = this.getAttribute('data-photo-id');
|
||||
if (confirm('Sei sicuro di voler eliminare questa foto?')) {
|
||||
// Gestione rimozione foto
|
||||
document.querySelectorAll(".delete-photo-btn").forEach((button) => {
|
||||
button.addEventListener("click", async function () {
|
||||
const photoId = this.getAttribute("data-photo-id");
|
||||
if (confirm("Sei sicuro di voler eliminare questa foto?")) {
|
||||
try {
|
||||
const response = await fetch('delete_photo.php', {
|
||||
method: 'POST',
|
||||
const response = await fetch("delete_photo.php", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
"Content-Type":
|
||||
"application/x-www-form-urlencoded",
|
||||
},
|
||||
body: `photo_id=${photoId}`
|
||||
body: `photo_id=${photoId}`,
|
||||
});
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
// Ricarica il contenuto del popup
|
||||
loadPopupContent(iddatadb);
|
||||
} else {
|
||||
alert('Errore durante l\'eliminazione: ' + result.message);
|
||||
alert(
|
||||
"Errore durante l'eliminazione: " +
|
||||
result.message,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
alert('Errore durante l\'eliminazione: ' + error.message);
|
||||
alert(
|
||||
"Errore durante l'eliminazione: " + error.message,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Gestione del click sulle immagini per ingrandirle
|
||||
document.querySelectorAll('.thumbnail').forEach(img => {
|
||||
img.addEventListener('click', function() {
|
||||
const modal = document.getElementById('imageModal');
|
||||
const enlargedImage = document.getElementById('enlargedImage');
|
||||
// Gestione ingrandimento immagini
|
||||
document.querySelectorAll(".thumbnail").forEach((img) => {
|
||||
img.addEventListener("click", function () {
|
||||
const enlargedImage = document.getElementById("enlargedImage");
|
||||
enlargedImage.src = this.src;
|
||||
modal.style.display = 'block';
|
||||
document.getElementById("imageModal").style.display = "block";
|
||||
});
|
||||
});
|
||||
|
||||
// Gestione della chiusura del modal immagine
|
||||
const imageModal = document.getElementById('imageModal');
|
||||
const imageCloseBtn = document.querySelector('.image-modal-close');
|
||||
// Gestione chiusura modale immagine
|
||||
const imageCloseBtn = document.querySelector(".image-modal-close");
|
||||
if (imageCloseBtn) {
|
||||
imageCloseBtn.addEventListener('click', function() {
|
||||
imageModal.style.display = 'none';
|
||||
imageCloseBtn.addEventListener("click", () => {
|
||||
document.getElementById("imageModal").style.display = "none";
|
||||
});
|
||||
}
|
||||
if (imageModal) {
|
||||
imageModal.addEventListener('click', function(event) {
|
||||
if (event.target === imageModal) {
|
||||
imageModal.style.display = 'none';
|
||||
document
|
||||
.getElementById("imageModal")
|
||||
.addEventListener("click", function (event) {
|
||||
if (event.target === this) {
|
||||
this.style.display = "none";
|
||||
}
|
||||
});
|
||||
_
|
||||
}
|
||||
|
||||
async function handleFiles(files, iddatadb) {
|
||||
for (const file of files) {
|
||||
if (!file.type.startsWith('image/')) {
|
||||
alert('Per favore, carica solo immagini!');
|
||||
continue;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('photo', file);
|
||||
formData.append('iddatadb', iddatadb);
|
||||
|
||||
try {
|
||||
const response = await fetch('upload_photo.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
// Ricarica il contenuto del popup
|
||||
loadPopupContent(iddatadb);
|
||||
} else {
|
||||
alert('Errore durante il caricamento: ' + result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
alert('Errore durante il caricamento: ' + error.message);
|
||||
// Funzione per gestire il caricamento dei file
|
||||
async function handleFiles(files, iddatadb) {
|
||||
for (const file of files) {
|
||||
if (!file.type.startsWith("image/")) {
|
||||
alert("Per favore, carica solo immagini!");
|
||||
continue;
|
||||
}
|
||||
const formData = new FormData();
|
||||
formData.append("photo", file);
|
||||
formData.append("iddatadb", iddatadb);
|
||||
try {
|
||||
const response = await fetch("upload_photo.php", {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
loadPopupContent(iddatadb);
|
||||
} else {
|
||||
alert("Errore durante il caricamento: " + result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
alert("Errore durante il caricamento: " + error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gestione del popup per le foto
|
||||
const photosButtons = document.querySelectorAll('.photos-btn');
|
||||
const photosModal = document.getElementById('photosModal');
|
||||
const closeBtn = document.querySelector('.close-btn');
|
||||
// Gestione del pulsante Photos
|
||||
const photosButtons = document.querySelectorAll(".photos-btn");
|
||||
const photosModal = document.getElementById("photosModal");
|
||||
const closeBtn = document.querySelector(".close-btn");
|
||||
|
||||
photosButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const iddatadb = this.getAttribute('data-iddatadb');
|
||||
if (photosButtons.length && photosModal && closeBtn) {
|
||||
photosButtons.forEach((button) => {
|
||||
button.addEventListener("click", function () {
|
||||
console.log(
|
||||
"Pulsante Photos cliccato per iddatadb:",
|
||||
this.getAttribute("data-iddatadb"),
|
||||
);
|
||||
const iddatadb = this.getAttribute("data-iddatadb");
|
||||
loadPopupContent(iddatadb);
|
||||
photosModal.style.display = 'block';
|
||||
document.querySelector('.overlay').style.display = 'none'; // Nascondi overlay
|
||||
photosModal.style.display = "block";
|
||||
document.querySelector(".overlay").style.display = "none";
|
||||
});
|
||||
});
|
||||
|
||||
if (closeBtn) {
|
||||
closeBtn.addEventListener('click', function() {
|
||||
photosModal.style.display = 'none';
|
||||
document.querySelector('.overlay').style.display = 'none'; // Assicurati che l'overlay sia nascosto
|
||||
// Forza la riattivazione della pagina sottostante
|
||||
document.body.style.pointerEvents = 'auto';
|
||||
});
|
||||
}
|
||||
closeBtn.addEventListener("click", function () {
|
||||
photosModal.style.display = "none";
|
||||
document.querySelector(".overlay").style.display = "none";
|
||||
document.body.style.pointerEvents = "auto";
|
||||
});
|
||||
|
||||
if (photosModal) {
|
||||
window.addEventListener('click', function(event) {
|
||||
if (event.target === photosModal) {
|
||||
photosModal.style.display = 'none';
|
||||
document.querySelector('.overlay').style.display = 'none'; // Nascondi overlay
|
||||
document.body.style.pointerEvents = 'auto'; // Riattiva la pagina
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
window.addEventListener("click", function (event) {
|
||||
if (event.target === photosModal) {
|
||||
photosModal.style.display = "none";
|
||||
document.querySelector(".overlay").style.display = "none";
|
||||
document.body.style.pointerEvents = "auto";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error("Elementi mancanti:", {
|
||||
photosButtons,
|
||||
photosModal,
|
||||
closeBtn,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -202,7 +202,7 @@
|
||||
<a href="edit_template_xls.php?id=${data}" class="btn btn-sm btn-primary me-1">
|
||||
<i class="bx bx-edit-alt"></i>
|
||||
</a>
|
||||
<a href="mapping_template_xls.php?id=${data}" class="btn btn-sm btn-success me-1">
|
||||
<a href="mapping_template_xls_scheme2.php?id=${data}" class="btn btn-sm btn-success me-1">
|
||||
<i class="bx bx-link-alt"></i>
|
||||
</a>
|
||||
<button class="btn btn-sm btn-danger" onclick="confirmDelete(${data})">
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user