Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
eliot
/
import_export
:
table_0016_debug008_change_001.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<script> function getWorkingDays(startDate, endDate, holidays = []) { const workingDays = []; const start = new Date(startDate); const end = new Date(endDate); // Ajouter un jour à la date de fin pour inclure le dernier jour end.setDate(end.getDate() + 1); for (let currentDate = new Date(start); currentDate < end; currentDate.setDate(currentDate.getDate() + 1)) { const dayOfWeek = currentDate.getDay(); // 0 (dimanche) à 6 (samedi) const dateStr = currentDate.toISOString().split('T')[0]; if (dayOfWeek !== 0 && dayOfWeek !== 6 && !holidays.includes(dateStr)) { workingDays.push({ day: currentDate.getDate(), day_of_week_initial: getDayInitial(currentDate), week_number: getWeekNumber(currentDate), full_date: dateStr }); } } console.log(" Erreur : le dernier jour n'est pas inclus dans la plage ???. ") return workingDays; } function getFrenchHolidays(year) { const holidays = []; const easterDate = calculateEaster(year); // Jours fériés fixes holidays.push(`${year}-01-01`); // Jour de l'An holidays.push(`${year}-05-01`); // Fête du Travail holidays.push(`${year}-05-08`); // Victoire 1945 holidays.push(`${year}-07-14`); // Fête Nationale holidays.push(`${year}-08-15`); // Assomption holidays.push(`${year}-11-01`); // Toussaint holidays.push(`${year}-11-11`); // Armistice holidays.push(`${year}-12-25`); // Noël // Jours fériés variables (calculés à partir de Pâques) const easter = new Date(easterDate); holidays.push(formatDate(easter)); // Pâques (non férié officiellement mais utile) holidays.push(formatDate(new Date(easter.setDate(easter.getDate() + 1)))); // Lundi de Pâques holidays.push(formatDate(new Date(easter.setDate(easter.getDate() + 38)))); // Ascension holidays.push(formatDate(new Date(easter.setDate(easter.getDate() + 11)))); // Lundi de Pentecôte return holidays; } function calculateEaster(year) { const a = year % 19; const b = Math.floor(year / 100); const c = year % 100; const d = Math.floor(b / 4); const e = b % 4; const f = Math.floor((b + 8) / 25); const g = Math.floor((b - f + 1) / 3); const h = (19 * a + b - d - g + 15) % 30; const i = Math.floor(c / 4); const k = c % 4; const l = (32 + 2 * e + 2 * i - h - k) % 7; const m = Math.floor((a + 11 * h + 22 * l) / 451); const month = Math.floor((h + l - 7 * m + 114) / 31); const day = ((h + l - 7 * m + 114) % 31) + 1; return new Date(year, month - 1, day); } function formatDate(date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } function getDayInitial(date) { const days = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi']; return days[date.getDay()][0]; } function getWeekNumber(date) { const firstDayOfYear = new Date(date.getFullYear(), 0, 1); const pastDaysOfYear = (date - firstDayOfYear) / 86400000; return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7); } // Exemple d'utilisation const year = 2025; const holidays = getFrenchHolidays(year); const startDate = "2025-01-10"; const endDate = "2026-02-14"; let workingDays = getWorkingDays(startDate, endDate, holidays); console.log(workingDays); </script> <?php function getWorkingDays($startDate, $endDate, $holidays = []) { $start = strtotime($startDate); $end = strtotime($endDate); $workingDays = []; setlocale(LC_TIME, 'fr_FR.UTF-8'); for ($currentDate = $start; $currentDate <= $end; $currentDate = strtotime("+1 day", $currentDate)) { $dayOfWeek = date("N", $currentDate); if ($dayOfWeek < 6 && !in_array(date("Y-m-d", $currentDate), $holidays)) { $workingDays[] = [ 'day' => date("d", $currentDate), 'day_of_week_initial' => strtoupper(strftime("%A", $currentDate)[0]), 'week_number' => date("W", $currentDate), 'full_date' => date("Y-m-d", $currentDate) // Ajout de la date complète ]; } } return $workingDays; } function getFrenchHolidays($year) { $easterDate = easter_date($year); $holidays = []; // Jours fériés fixes $holidays[] = "$year-01-01"; // Jour de l'An $holidays[] = "$year-05-01"; // Fête du Travail $holidays[] = "$year-05-08"; // Victoire 1945 $holidays[] = "$year-07-14"; // Fête Nationale $holidays[] = "$year-08-15"; // Assomption $holidays[] = "$year-11-01"; // Toussaint $holidays[] = "$year-11-11"; // Armistice $holidays[] = "$year-12-25"; // Noël // Jours fériés variables (calculés à partir de Pâques) $easter = new DateTime("@$easterDate"); $easter->setTimezone(new DateTimeZone(date_default_timezone_get())); $holidays[] = $easter->format("Y-m-d"); // Pâques (non férié officiellement mais utile) $holidays[] = $easter->modify('+1 day')->format("Y-m-d"); // Lundi de Pâques $holidays[] = $easter->modify('+38 days')->format("Y-m-d"); // Ascension $holidays[] = $easter->modify('+11 days')->format("Y-m-d"); // Lundi de Pentecôte return $holidays; } $year = 2025; $holidays = []; $holidays = getFrenchHolidays($year); // Liste des jours fériés et fêtes religieuses à exclure (exemple pour la France, à compléter avec d'autres fêtes) $old_holidays = [ "2025-01-01", // Jour de l'An "2025-04-14", // Lundi de Pâques "2025-05-01", // Fête du Travail "2025-05-08", // Victoire 1945 "2025-07-14", // Bastille "2025-08-15", // Assomption "2025-11-01", // Toussaint "2025-12-25", // Noël "2026-01-01", // Jour de l'An "2026-04-06", // Lundi de Pâques // Ajouter d'autres jours fériés ici... ]; // Définir la période de début et de fin $startDate = "2025-01-10"; $endDate = "2026-02-14"; // Appeler la fonction pour obtenir les jours ouvrés entre les deux dates $workingDays = getWorkingDays($startDate, $endDate, $holidays); // Convertir le tableau en JSON $workingDaysJson = json_encode($workingDays); ?> <!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tableau Sticky - 3 Lignes Fixes</title> <style> .table-wrapper { width: 100%; height: calc(100vh - 100px); overflow: auto; border: 1px solid #ccc; position: relative; } table { border-collapse: collapse; width: max-content; table-layout: fixed; } th, td { padding: 3px; text-align: center; height: 40px; border: 1px solid #ccc; white-space: nowrap; min-width: 120px; position: relative; background-color: white; box-sizing: border-box; } th { background-color: #f2f2f2; position: sticky; top: 0; z-index: 100; } th:first-child, td:first-child { position: sticky; left: 0; z-index: 101; background-color: white; } th:nth-child(2), td:nth-child(2) { position: sticky; left: 120px; z-index: 100; background-color: white; } th:nth-child(3), td:nth-child(3) { position: sticky; left: 240px; z-index: 99; background-color: white; } th:first-child::after, td:first-child::after, th:nth-child(2)::after, td:nth-child(2)::after, th:nth-child(3)::after, td:nth-child(3)::after { content: ""; position: absolute; right: 0; top: 0; width: 2px; height: 100%; background-color: #ccc; z-index: 102; } tbody tr:nth-child(odd) { background-color: #f9f9f9; } th:nth-child(n+4), td:nth-child(n+4) { min-width: 40px; max-width: 40px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .second-header th { background-color: #f2f2f2; position: sticky; top: 40px; z-index: 99; } .third-header th { background-color: #f2f2f2; position: sticky; top: 80px; z-index: 98; } .second-header th:first-child, .third-header th:first-child { left: 0; z-index: 101; background-color: white; } .second-header th:nth-child(2), .third-header th:nth-child(2) { left: 120px; z-index: 100; background-color: white; } .second-header th:nth-child(3), .third-header th:nth-child(3) { left: 240px; z-index: 99; background-color: white; } thead tr:first-child th:first-child, thead tr:first-child th:nth-child(2), thead tr:first-child th:nth-child(3) { z-index: 105; background-color: #ddd; } .second-header th:first-child, .second-header th:nth-child(2), .second-header th:nth-child(3) { z-index: 104; } .third-header th:first-child, .third-header th:nth-child(2), .third-header th:nth-child(3) { z-index: 103; } thead tr:first-child th, .second-header th, .third-header th { box-shadow: inset 0 -2px #aaa; background-clip: padding-box; padding-bottom: 2px; margin-bottom: -2px; z-index: 100; } .second-header th { top: calc(40px + 2px); margin-top: 2px; } .third-header th { top: calc(80px + 2px); margin-top: 2px; } .even-week { background-color: #ffcc99 !important; } .odd-week { background-color: #e6b3ff !important; } .fourth-header th { background-color: #f2f2f2; position: sticky; top: 120px; z-index: 97; } .fourth-header th:first-child { left: 0; z-index: 101; background-color: white; } .fourth-header th:nth-child(2) { left: 120px; z-index: 100; background-color: white; } .fourth-header th:nth-child(3) { left: 240px; z-index: 99; background-color: white; } .fourth-header th:first-child, .fourth-header th:nth-child(2), .fourth-header th:nth-child(3) { z-index: 102; } .fourth-header th { top: calc(120px + 2px); margin-top: 2px; } .fourth-header th { box-shadow: inset 0 -2px #aaa; background-clip: padding-box; padding-bottom: 2px; margin-bottom: -2px; z-index: 97; } .month-even { background-color: #99ccff !important; } .month-odd { background-color: #ff9999 !important; } .btn { margin-bottom: 20px; padding: 10px; background-color: #4CAF50; color: white; border: none; cursor: pointer; font-size: 16px; border-radius: 5px; transition: background-color 0.3s ease; } .btn:hover { background-color: #45a049; } .btn-special { background-color: #2196F3; } .btn-special:hover { background-color: #1e88e5; } .btn-special:hover { background-color: #1e88e5; } #contextMenu { position: absolute; display: none; flex-direction: column; background: white; border: 1px solid #ccc; box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); border-radius: 5px; z-index: 1000; min-width: 180px; } #contextMenu .dropdown-item { display: block; width: 100%; padding: 8px 12px; text-align: left; color: #333; cursor: pointer; } #contextMenu .dropdown-item:hover { background: #f8f9fa; } #specialContextMenu { position: absolute; display: none; flex-direction: column; background: white; border: 1px solid #ccc; box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); border-radius: 5px; z-index: 1000; min-width: 180px; } #specialContextMenu .dropdown-item { display: block; width: 100%; padding: 8px 12px; text-align: left; color: #333; cursor: pointer; } #specialContextMenu .dropdown-item:hover { background: #f8f9fa; } #colorContextMenu { position: absolute; display: none; flex-direction: column; background: white; border: 1px solid #ccc; box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); border-radius: 5px; z-index: 1000; min-width: 180px; } #colorContextMenu .dropdown-item { display: block; width: 100%; padding: 8px 12px; text-align: left; color: #333; cursor: pointer; } #colorContextMenu .dropdown-item:hover { background: #f8f9fa; } .add-button { background-color: orange; color: white; border: none; padding: 5px 10px; cursor: pointer; margin-left: 5px; } .editable-input { width: 65px; box-sizing: border-box; } .collapsed { display: none; } #jsonOutput { margin-top: 20px; padding: 10px; border: 1px solid #ccc; background-color: #f9f9f9; white-space: pre-wrap; word-wrap: break-word; } #logOutput { margin-top: 20px; padding: 10px; border: 1px solid #ccc; background-color: #f9f9f9; white-space: pre-wrap; word-wrap: break-word; } .no-click { pointer-events: none; } #debugOutput { margin-top: 20px; padding: 10px; border: 1px solid #ccc; background-color: #f9f9f9; white-space: pre-wrap; word-wrap: break-word; } .dropdown-item.disabled { pointer-events: none; color: #6c757d; font-style: italic; } .no-select { pointer-events: none; } </style> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> </head> <body> <div class="modal fade" id="confirmationModal" tabindex="-1" aria-labelledby="confirmationModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="confirmationModalLabel">Confirmation</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> Voulez-vous vraiment supprimer cette ligne ? </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" id="cancelDelete">Annuler</button> <button type="button" class="btn btn-danger" id="confirmDelete">OK</button> </div> </div> </div> </div> <div class="modal fade" id="successModal" tabindex="-1" aria-labelledby="successModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="successModalLabel">Succès</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> Données sauvegardées avec succès ! </div> <div class="modal-footer"> <button type="button" class="btn btn-primary" id="closeSuccessModal">OK</button> </div> </div> </div> </div> <div class="modal fade" id="messageModal" tabindex="-1" aria-labelledby="messageModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="messageModalLabel">Message</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body" id="messageModalBody"> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary" data-dismiss="modal">OK</button> </div> </div> </div> </div> <!-- Modal de confirmation de sauvegarde --> <div class="modal fade" id="confirmSaveModal" tabindex="-1" aria-labelledby="confirmSaveModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="confirmSaveModalLabel">Confirmation</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> Voulez-vous vraiment sauvegarder les données ? </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" id="cancelSave">Annuler</button> <button type="button" class="btn btn-primary" id="confirmSave">OK</button> </div> </div> </div> </div> <div id="colorContextMenu" class="dropdown-menu" style="display: none;"> <button class="dropdown-item" style="background-color: green;" data-color="green">Vert</button> <button class="dropdown-item" style="background-color: blue;" data-color="blue">Bleu</button> <button class="dropdown-item" style="background-color: red;" data-color="red">Rouge</button> <button class="dropdown-item" style="background-color: yellow;" data-color="yellow">Jaune</button> <button class="dropdown-item" style="background-color: orange;" data-color="orange">Orange</button> <button class="dropdown-item" style="background-color: purple;" data-color="purple">Violet</button> <button class="dropdown-item" style="background-color: pink;" data-color="pink">Rose</button> <button class="dropdown-item" style="background-color: brown;" data-color="brown">Marron</button> <button class="dropdown-item" style="background-color: cyan;" data-color="cyan">Cyan</button> <button class="dropdown-item" style="background-color: gray;" data-color="gray">Gris</button> </div> <div class="modal fade" id="rangeSelectionModal" tabindex="-1" aria-labelledby="rangeSelectionModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="rangeSelectionModalLabel">Sélection de Plage</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <div class="form-group"> <label for="startCellId">Cellule de Départ</label> <input type="text" class="form-control" id="startCellId" disabled> </div> <div class="form-group"> <label for="endCellId">Cellule de Fin</label> <input type="text" class="form-control" id="endCellId"> </div> <div class="form-group"> <label for="rangeComboBox">Sélectionnez une valeur</label> <select class="form-control" id="rangeComboBox"> </select> </div> <div id="rangeResult" class="form-group"> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" id="cancelRangeSelection">Annuler</button> <button type="button" class="btn btn-primary" id="confirmRangeSelection">Valider</button> </div> </div> </div> </div> <div class="table-wrapper"> <table> <thead> <tr> <th></th> <th>plouf</th> <th>cretin</th> <?php foreach ($workingDays as $dateData): ?> <th> <?php echo $dateData['day']; ?> <br> </th> <?php endforeach; ?> </tr> <tr class="second-header"> <th></th> <th>Valeur 1</th> <th>Valeur 2</th> <?php $currentWeek = null; $weekClass = ""; foreach ($workingDays as $dateData): if ($currentWeek !== $dateData['week_number']) { $currentWeek = $dateData['week_number']; $weekClass = ($currentWeek % 2 === 0) ? 'even-week' : 'odd-week'; } ?> <th class="<?= $weekClass; ?>"><?php echo $dateData['day_of_week_initial']; ?></th> <?php endforeach; ?> </tr> <tr class="third-header"> <th></th> <th>Info 1</th> <th>Info 2</th> <?php $currentWeek = null; $colspan = 0; foreach ($workingDays as $index => $dateData): if ($currentWeek !== $dateData['week_number']) { if ($currentWeek !== null) { $weekClass = $currentWeek % 2 === 0 ? 'even-week' : 'odd-week'; echo '<th class="' . $weekClass . '" colspan="' . $colspan . '">' . $currentWeek . '</th>'; } $currentWeek = $dateData['week_number']; $colspan = 1; } else { $colspan++; } endforeach; if ($currentWeek !== null) { $weekClass = $currentWeek % 2 === 0 ? 'even-week' : 'odd-week'; echo '<th class="' . $weekClass . '" colspan="' . $colspan . '">' . $currentWeek . '</th>'; } ?> </tr> <tr class="fourth-header"> <th></th> <th>Label 1</th> <th>Label 2</th> <?php $currentMonthYear = null; $colspan = 0; $monthClass = ""; $colorIndex = 0; $colors = ['month-even', 'month-odd']; foreach ($workingDays as $index => $dateData): $monthYear = ucfirst(strftime("%B %Y", strtotime($dateData['full_date']))); if ($currentMonthYear !== $monthYear) { if ($currentMonthYear !== null) { echo '<th class="' . $monthClass . '" colspan="' . $colspan . '">' . $currentMonthYear . '</th>'; } $currentMonthYear = $monthYear; $colspan = 1; $monthClass = $colors[$colorIndex % 2]; $colorIndex++; } else { $colspan++; } endforeach; if ($currentMonthYear !== null) { echo '<th class="' . $monthClass . '" colspan="' . $colspan . '">' . $currentMonthYear . '</th>'; } ?> </tr> </thead> <tbody> </tbody> </table> </div> <button id="addRowButton" class="btn">Ajouter une ligne</button> <button id="addSpecialRowButton" class="btn btn-special">Ajouter une ligne spéciale</button> <button id="SauveButton" class="btn">Sauver</button> <input type="file" id="fileInput" accept=".json" style="display: none;"> <button id="loadJsonButton" class="btn">Charger</button> <!-- <button id="ChargeButton" class="btn">Charger</button> --> <button id="GraphiqueButton" class="btn">Graphique</button> <!-- <button id="logButton" class="btn">Log</button> --> <button id="queryButton" class="btn">Query</button> <!-- <div id="jsonOutput"></div> --> <!-- <div id="debugOutput"></div> --> <script> // Intégrer le JSON PHP dans une variable JavaScript workingDays = <?php echo $workingDaysJson; ?>; // Fonction pour afficher les données dans la console function displayWorkingDays() { console.log(workingDays); } // Appeler la fonction pour afficher les données //displayWorkingDays(); //const value = workingDays[27].full_date; //console.log(value); // Déclarez le tableau list_lignes en dehors des fonctions pour qu'il soit accessible globalement let list_lignes = []; document.addEventListener("DOMContentLoaded", function () { const tableBody = document.querySelector("tbody"); let specialRowCounter = 1; let rowCounter = 1; let linkageCounter = 1; let standardRowsData = []; let estimationRowsData = []; let specialRowsData = []; // Tableau dédié pour stocker les objets des lignes spéciales let linkages = []; const specialRowStates = {}; const associations = {}; let currentCell = null; let keydownHandled = false; let alertShown = false; let selectedRow = null; // Variable to keep track of the selected row const contextMenu = document.createElement("div"); contextMenu.id = "contextMenu"; contextMenu.classList.add("dropdown-menu"); contextMenu.style.display = "none"; document.body.appendChild(contextMenu); const specialContextMenu = document.createElement("div"); specialContextMenu.id = "specialContextMenu"; specialContextMenu.classList.add("dropdown-menu"); specialContextMenu.style.display = "none"; document.body.appendChild(specialContextMenu); const colorContextMenu = document.getElementById("colorContextMenu"); const colorButtons = colorContextMenu.querySelectorAll(".dropdown-item"); colorButtons.forEach(button => { button.addEventListener("click", function () { const color = this.getAttribute("data-color"); const cell = document.querySelector(".selected-cell"); if (cell) { cell.style.backgroundColor = color; cell.dataset.cellColor = color; hideColorContextMenu(); updateRowData(cell); } }); }); // Déclarez la variable selection_origine en dehors de la fonction pour qu'elle soit accessible globalement let selection_origine = null; // Déclarez l'objet objet_up en dehors de la fonction pour qu'il soit accessible globalement let objet_up = []; // Changez objet_up pour qu'il soit un tableau // Déclarez le tableau objet_selection en dehors de la fonction pour qu'il soit accessible globalement let objet_selection = []; function generateRandomId(length = 8) { const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; for (let i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * characters.length)); } return result; } function addRow(afterRow = null) { const rowNumber = tableBody.rows.length + 1; const newRow = document.createElement("tr"); newRow.setAttribute("draggable", "true"); newRow.dataset.rowId = `standard-${generateRandomId()}`; newRow.title = newRow.dataset.rowId; // Ajoutez cette ligne const rowData = { id: newRow.dataset.rowId, name: `Row ${rowNumber}`, selectValue: "1", count: "0", cells: [], selection: "OFF" // TAG : SELECTION }; // Ajoutez l'identifiant de la ligne dans le tableau list_lignes list_lignes.push(newRow.dataset.rowId); const firstCells = [`Row ${rowNumber}`, "", "0"]; firstCells.forEach((text, index) => { const td = document.createElement("td"); td.dataset.cellId = `cell-${rowData.id}-${index}`; if (index === 0) { const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = rowData.name; input.addEventListener("click", function (event) { event.stopPropagation(); input.focus(); input.style.width = "130px"; }); input.addEventListener("blur", function () { if (!keydownHandled && !alertShown) { alertShown = true; input.classList.remove("editing"); input.blur(); input.style.width = "65px"; console.clear; updateRowData(input); } keydownHandled = false; alertShown = false; }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { keydownHandled = true; if (!alertShown) { alertShown = true; input.classList.remove("editing"); input.blur(); input.style.width = "65px"; console.clear; updateRowData(input); } } }); td.appendChild(input); } else if (index === 1) { const select = document.createElement("select"); for (let i = 1; i <= 10; i++) { const option = document.createElement("option"); option.value = i; option.textContent = `Option ${i}`; select.appendChild(option); } select.value = rowData.selectValue; select.addEventListener("change", function () { updateRowData(select); }); td.appendChild(select); } else { td.textContent = text; } if (index === 0) { td.classList.add("row-header"); td.addEventListener("click", function () { handleRowClick(newRow, td); // TAG : SELECTION }); td.addEventListener("contextmenu", function (event) { event.preventDefault(); showContextMenu(event, newRow); }); } newRow.appendChild(td); }); const headerCells = document.querySelectorAll("thead tr:nth-child(2) th:not(.weekend):not(.holiday)"); const workingDaysCount = headerCells.length; for (let i = 0; i < workingDaysCount - 3; i++) { const td = document.createElement("td"); td.dataset.cellId = `cell-${rowData.id}-${i}`; td.dataset.cellValue = "0"; td.dataset.cellColor = "white"; td.textContent = "0"; td.style.backgroundColor = "white"; td.addEventListener("click", function () { const newValue = td.dataset.cellValue === "0" ? "1" : "0"; td.dataset.cellValue = newValue; td.textContent = newValue; td.style.backgroundColor = newValue === "1" ? "green" : "white"; td.dataset.cellColor = newValue === "1" ? "green" : "white"; updateCountCell(newRow); updateRowData(td); }); td.addEventListener("click", function (event) { const fullDate = event.target.dataset.fullDate; console.log("Date complète :", fullDate); //alert(fullDate); // maintenant utiliser fullDate pour d'autres opérations }); td.addEventListener("contextmenu", function (event) { event.preventDefault(); if (td.dataset.cellValue === "1") { showColorContextMenu(event, td); } }); td.title = `ID: ${td.dataset.cellId}`; newRow.appendChild(td); // $workingDays 555 const value = workingDays[i].full_date; // Ajouter la clé full_date td.dataset.fullDate = workingDays[i].full_date; rowData.cells.push({ value: "0", color: "white", full_date: workingDays[i].full_date // Ajouter la clé full_date }); } if (afterRow) { tableBody.insertBefore(newRow, afterRow.nextSibling); } else { tableBody.appendChild(newRow); } newRow.addEventListener("dragstart", dragStart); newRow.addEventListener("dragover", dragOver); newRow.addEventListener("drop", drop); rowCounter++; standardRowsData.push(rowData); const estimationRow = document.createElement("tr"); estimationRow.setAttribute("draggable", "true"); estimationRow.dataset.rowId = `estimation-${generateRandomId()}`; estimationRow.classList.add("estimation-row"); estimationRow.title = estimationRow.dataset.rowId; // Ajoutez cette ligne const estimationRowData = { id: estimationRow.dataset.rowId, name: `Estimation ${rowNumber}`, selectValue: "1", estimationValue: "0", selection: "OFF" // TAG : SELECTION }; // Ajoutez l'identifiant de la ligne d'estimation dans le tableau list_lignes list_lignes.push(estimationRow.dataset.rowId); const estimationFirstCells = [`Estimation ${rowNumber}`, "", "0"]; estimationFirstCells.forEach((text, index) => { const td = document.createElement("td"); td.dataset.cellId = `cell-${estimationRowData.id}-${index}`; if (index === 0) { const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = estimationRowData.name; input.addEventListener("click", function (event) { event.stopPropagation(); input.focus(); input.style.width = "130px"; }); input.addEventListener("blur", function () { if (!keydownHandled && !alertShown) { alertShown = true; input.classList.remove("editing"); input.blur(); input.style.width = "65px"; console.clear; updateRowData(input); } keydownHandled = false; alertShown = false; }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { keydownHandled = true; if (!alertShown) { alertShown = true; input.classList.remove("editing"); input.blur(); input.style.width = "65px"; console.clear; updateRowData(input); } } }); td.appendChild(input); } else if (index === 1) { const select = document.createElement("select"); for (let i = 1; i <= 10; i++) { const option = document.createElement("option"); option.value = i; option.textContent = `Option ${i}`; select.appendChild(option); } select.value = estimationRowData.selectValue; select.addEventListener("change", function () { updateRowData(select); }); td.appendChild(select); } else { const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = "1"; input.addEventListener("click", function (event) { event.stopPropagation(); input.focus(); input.style.width = "130px"; }); input.addEventListener("blur", function () { if (!keydownHandled && !alertShown) { alertShown = true; input.classList.remove("editing"); input.blur(); input.style.width = "65px"; console.clear; const value = parseInt(input.value, 10); if (isNaN(value) || value < 1 || value > 365) { input.value = "1"; showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365."); } else { updateRowData(input); } } keydownHandled = false; alertShown = false; }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { keydownHandled = true; if (!alertShown) { alertShown = true; input.classList.remove("editing"); input.blur(); input.style.width = "65px"; console.clear; const value = parseInt(input.value, 10); if (isNaN(value) || value < 1 || value > 365) { input.value = "1"; showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365."); } else { updateRowData(input); } } } }); td.appendChild(input); } if (index === 0) { td.classList.add("row-header"); td.addEventListener("click", function () { handleRowClick(estimationRow, td); // TAG : SELECTION }); td.addEventListener("contextmenu", function (event) { event.preventDefault(); showContextMenu(event, estimationRow); }); } estimationRow.appendChild(td); }); const mergedCell = document.createElement("td"); mergedCell.colSpan = workingDaysCount - 3; mergedCell.textContent = ""; mergedCell.classList.add("no-click"); estimationRow.appendChild(mergedCell); if (afterRow) { tableBody.insertBefore(estimationRow, newRow.nextSibling); } else { tableBody.appendChild(estimationRow); } estimationRow.addEventListener("dragstart", dragStart); estimationRow.addEventListener("dragover", dragOver); estimationRow.addEventListener("drop", drop); const linkage = { id: `linkage-${generateRandomId()}`, // Remplacez linkageId par id standardRowId: newRow.dataset.rowId, estimationRowId: estimationRow.dataset.rowId }; linkages.push(linkage); //displayLinkages(); rowCounter++; estimationRowsData.push(estimationRowData); } function handleRowClick(row, td) { const rowId = row.dataset.rowId; selection_origine = rowId; // Mémorisez l'ID de la ligne cliquée console.log("Selection_origine :", selection_origine); // Affichez la valeur de selection_origine dans la console const tableBody = document.querySelector("tbody"); const rowIds = []; /*if (objet_selection.length > 0 ) { // Afficher une fenêtre modale indiquant qu'une seule sélection est possible à la fois showMessageModal("Une seule sélection est possible à la fois."); return; // Empêcher la couleur de fond de changer }*/ // Parcourir chaque ligne du tableau tableBody.querySelectorAll("tr").forEach(row => { const rowId = row.dataset.rowId; if (rowId) { rowIds.push(rowId); } }); console.log(rowIds); let linkedRowId = null; let linkedRow = null; if (rowId.startsWith("standard-")) { const linkage = linkages.find(link => link.standardRowId === rowId); if (linkage) { linkedRowId = linkage.estimationRowId; linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`); } } else if (rowId.startsWith("estimation-")) { const linkage = linkages.find(link => link.estimationRowId === rowId); if (linkage) { linkedRowId = linkage.standardRowId; linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`); } } // Vérifiez si l'identifiant de la ligne cliquée fait déjà partie de objet_selection if (objet_selection.includes(rowId)) { const standardRowData = standardRowsData.find(data => data.id === rowId) || standardRowsData.find(data => data.id === linkedRowId); const estimationRowData = estimationRowsData.find(data => data.id === rowId) || estimationRowsData.find(data => data.id === linkedRowId); if (standardRowData && estimationRowData) { standardRowData.selection = "OFF"; estimationRowData.selection = "OFF"; td.style.backgroundColor = "white"; linkedRow.cells[0].style.backgroundColor = "white"; // Supprimez les identifiants du tableau objet_selection objet_selection = objet_selection.filter(id => id !== standardRowData.id && id !== estimationRowData.id); // Réinitialisez les variables selection_origine = null; selectedRow = null; console.log(" UNSELECT "); } return; // Empêcher la couleur de fond de changer } // Vérifiez si objet_selection contient déjà les identifiants d'une ligne standard et d'une ligne d'estimation if (objet_selection.length > 0) //if (objet_selection.length === 2) { showMessageModal("Une seule sélection est possible."); return; // Empêcher la couleur de fond de changer } if (linkedRow) { const standardRowData = standardRowsData.find(data => data.id === rowId) || standardRowsData.find(data => data.id === linkedRowId); const estimationRowData = estimationRowsData.find(data => data.id === rowId) || estimationRowsData.find(data => data.id === linkedRowId); if (standardRowData.selection === "OFF" && estimationRowData.selection === "OFF") { console.log(`ID standard : ${standardRowData.id}`); console.log(`ID estimation : ${estimationRowData.id}`); standardRowData.selection = "ON"; estimationRowData.selection = "ON"; td.style.backgroundColor = "red"; linkedRow.cells[0].style.backgroundColor = "red"; // Ajoutez les identifiants dans le tableau objet_selection objet_selection.push(standardRowData.id, estimationRowData.id); selectedRow = row; // Mettez à jour la ligne sélectionnée console.log(`SELECT ${standardRowData.id} ${estimationRowData.id}`); console.log(" ---- " + objet_selection); } } } function moveRowsUp() { console.log(" Move UP "); // Vider le tableau list_lignes.length = 0; const allRows = Array.from(tableBody.querySelectorAll("tr")); allRows.forEach(row => { list_lignes.push(row.dataset.rowId); }); displayListLignes(); const id_ligne_standard = objet_selection[0]; const id_ligne_estimation = objet_selection[1]; let position_ligne_standard = list_lignes.indexOf(id_ligne_standard); let position_ligne_estimation = list_lignes.indexOf(id_ligne_estimation); console.log(" ------ position_ligne_standard " + position_ligne_standard); console.log(" ------ position_ligne_estimation" + position_ligne_estimation); // Vérifiez si la ligne au-dessus de la ligne standard est une ligne spéciale let is_speciale = position_ligne_standard > 0 && list_lignes[position_ligne_standard - 1].startsWith("special-"); // Vérifiez si la ligne au-dessus de la ligne d'estimation est une ligne spéciale let is_standard = position_ligne_standard > 0 && list_lignes[position_ligne_standard - 1].startsWith("estimation-"); if( is_speciale === true ) { console.log("Saut speciale " ); let save_identifiant_speciale = list_lignes[position_ligne_standard - 1]; console.log(" TRACE identifiant " + save_identifiant_speciale); let index = list_lignes.indexOf(save_identifiant_speciale); list_lignes.splice(index, 1); // Supprime élément à cet index console.log(" TRACE suppimer " + list_lignes); // recherche l'index de let new_position_speciale= list_lignes.indexOf(id_ligne_estimation); // on l'insére juste aprés list_lignes.splice( new_position_speciale + 1, 0, save_identifiant_speciale); console.log(" TRACE " + new_position_speciale + list_lignes); console.log("<<<<<<< Nouvel ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); // Réorganiser les lignes du tableau en fonction de biduleArr reorderTableRows(list_lignes); } if( is_standard === true ) { console.log(" Saut de la liaison " ); // saut : standard <-> standard-2 if (position_ligne_standard - 2 >= 0) { let temp = list_lignes[position_ligne_standard]; list_lignes[position_ligne_standard] = list_lignes[position_ligne_standard - 2]; list_lignes[position_ligne_standard - 2] = temp; } // saut : estimation <-> estimation-2 if (position_ligne_estimation - 2 >= 0) { let temp = list_lignes[position_ligne_estimation]; list_lignes[position_ligne_estimation] = list_lignes[position_ligne_estimation - 2]; list_lignes[position_ligne_estimation - 2] = temp; } console.log("<<<<<<< Nouvel ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); // Réorganiser les lignes du tableau en fonction de biduleArr reorderTableRows(list_lignes); } } function moveRowsDown() { console.log(" Move Down "); // Vider le tableau list_lignes.length = 0; const allRows = Array.from(tableBody.querySelectorAll("tr")); allRows.forEach(row => { list_lignes.push(row.dataset.rowId); }); displayListLignes(); const id_ligne_standard = objet_selection[0]; const id_ligne_estimation = objet_selection[1]; let position_ligne_standard = list_lignes.indexOf(id_ligne_standard); let position_ligne_estimation = list_lignes.indexOf(id_ligne_estimation); console.log(" ------ position_ligne_standard " + position_ligne_standard); console.log(" ------ position_ligne_estimation" + position_ligne_estimation); // Vérifiez si une ligne existe sous la ligne estimation if (position_ligne_estimation + 1 < list_lignes.length) { console.log("yes"); } // Arrêtez la fonction si aucune ligne n'existe sous position_ligne_estimation else { console.log("stop"); return; } // Vérifiez si la ligne en dessous de la ligne estimation est une ligne spéciale let is_speciale = position_ligne_estimation > 0 && list_lignes[position_ligne_estimation + 1].startsWith("special-"); // Vérifiez si la ligne en dessous de la ligne d'estimation est une ligne standard let is_estimation = position_ligne_estimation > 0 && list_lignes[position_ligne_estimation + 1].startsWith("standard-"); if( is_speciale === true ) { // cette ligne speciale se trouve aprés la ligne estimation , c'est à dire +1 console.log("Saut speciale " + list_lignes[position_ligne_estimation + 1]); // Étape 2 : Vérifier que e1 est juste avant v if (list_lignes[position_ligne_estimation + 1].startsWith("special-") ) { let save_identifiant_speciale = list_lignes[position_ligne_estimation + 1]; console.log(" save_identifiant_speciale " + save_identifiant_speciale); let position_special = list_lignes.indexOf(save_identifiant_speciale); console.log(" position_special " + position_special); // supprime l'élément qui se trouve à cette position list_lignes.splice(list_lignes.indexOf(save_identifiant_speciale), 1); // retourne l'index qui correspond à la valeur de l'id let new_position_speciale = list_lignes.indexOf(id_ligne_standard); console.log(" new_position_speciale " + new_position_speciale); // Insérer save_identifiant_speciale à l’indice new_position_speciale list_lignes.splice( new_position_speciale, 0, save_identifiant_speciale); console.log("<<<<<<< Nouvel ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); // Réorganiser les lignes du tableau en fonction de biduleArr reorderTableRows(list_lignes); } } if( is_estimation === true ) { console.log(" Saut de la liaison "); // saut : standard <-> standard+2 if (position_ligne_standard + 2 >= 0) { let temp = list_lignes[position_ligne_standard]; list_lignes[position_ligne_standard] = list_lignes[position_ligne_standard + 2]; list_lignes[position_ligne_standard + 2] = temp; } // saut estimation <-> estimation+2 if (position_ligne_estimation + 2 >= 0) { let temp = list_lignes[position_ligne_estimation]; list_lignes[position_ligne_estimation] = list_lignes[position_ligne_estimation + 2]; list_lignes[position_ligne_estimation + 2] = temp; } console.log("<<<<<<< Nouvel ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); // Réorganiser les lignes du tableau en fonction de biduleArr reorderTableRows(list_lignes); } } function moveSpecialRowUp(row) { console.log("UP special"); const rowId = row.dataset.rowId; const currentIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(row); if (currentIndex > 0) { const previousRow = tableBody.querySelectorAll("tr")[currentIndex - 1]; const previousRowId = previousRow.dataset.rowId; if (previousRowId.startsWith("special-")) { console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); let position_ligne_speciale = list_lignes.indexOf(previousRowId); console.log(" TRACE position speciale " + position_ligne_speciale); console.log(" TRACE identifiant speciale " + previousRowId); // element à déplacer console.log(" TRACE deplacer position current " + currentIndex); console.log(" TRACE deplaced identifiant current " + rowId); let save_identifiant_speciale = list_lignes[currentIndex]; console.log(" TRACE save identifiant " + save_identifiant_speciale); // Supprime élément à cet index list_lignes.splice(currentIndex, 1); console.log("<<<<<<< Nouvel ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); list_lignes.splice( position_ligne_speciale , -1, save_identifiant_speciale); console.log("<<<<<<< Nouvel ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); // Réorganiser les lignes du tableau en fonction de biduleArr reorderTableRows(list_lignes); return; } else if (previousRowId.startsWith("estimation-")) { console.log(" Saut de la liaison " ); //alert("La ligne au-dessus est une ligne d'estimation."); console.log(" +++ estimation " + rowId); console.log(" +++ estimation " + previousRowId); // Trouver l'objet de liaison qui contient previousRowId const linkage = linkages.find(link => link.estimationRowId === previousRowId); if (linkage) { // Afficher les valeurs de l'objet de liaison dans la console console.log("Objet de liaison trouvé :", linkage); console.log("Identifiant de la ligne standard :", linkage.standardRowId); console.log("Identifiant de la ligne d'estimation :", linkage.estimationRowId); let position_ligne_speciale_selection = list_lignes.indexOf(rowId); console.log("Position selection:", position_ligne_speciale_selection); //aaa list_lignes.splice(position_ligne_speciale_selection, 1); // Supprime élément à cet index console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); let position_ligne_standard = list_lignes.indexOf(linkage.standardRowId); console.log("Position pour insertion:", position_ligne_standard); // insérer rowId a list_lignes.splice( position_ligne_standard , 0, rowId); console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); // Réorganiser les lignes du tableau en fonction de biduleArr reorderTableRows(list_lignes); } else { console.log("Aucun objet de liaison trouvé pour l'identifiant :", previousRowId); } // return; } // Si la ligne au-dessus n'est ni spéciale ni d'estimation, procédez au déplacement //tableBody.insertBefore(row, previousRow); //reorderTableRows(list_lignes); } else { alert("Aucune ligne au-dessus pour effectuer le déplacement."); } } function moveSpecialRowDown(row) { console.log("DOWN"); const rowId = row.dataset.rowId; const currentIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(row); if (currentIndex >= 0 && currentIndex < tableBody.querySelectorAll("tr").length - 1) { const previousRow = tableBody.querySelectorAll("tr")[currentIndex + 1]; const previousRowId = previousRow.dataset.rowId; console.log(" ------ " + rowId + " " + previousRowId); if (previousRowId.startsWith("special-")) { console.log("Special detection"); // supprimer l'identifiant let index_ligne_speciale = list_lignes.indexOf(rowId); list_lignes.splice(index_ligne_speciale, 1); // Supprime élément à cet index console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); // rechrcher position de previousRowId let bidule = list_lignes.indexOf(previousRowId); // insérer rowId aprés le position de previousRowId list_lignes.splice( bidule + 1 , 0, rowId); console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); // Réorganiser les lignes du tableau en fonction de biduleArr reorderTableRows(list_lignes); } else if (previousRowId.startsWith("standard-")) { console.log("Saut de la liaison"); // Trouver l'objet de liaison qui contient previousRowId const linkage = linkages.find(link => link.standardRowId === previousRowId); if (linkage) { // Afficher les valeurs de l'objet de liaison dans la console console.log("Objet de liaison trouvé :", linkage); console.log("Identifiant de la ligne standard :", linkage.standardRowId); console.log("Identifiant de la ligne d'estimation :", linkage.estimationRowId); // sauvegarder l'identifiant de la ligne speciale let save_identifiant_speciale = list_lignes[currentIndex]; console.log(" TRACE sauve identifiant speciale " + save_identifiant_speciale); // supprimer l'identifiant let index_ligne_speciale = list_lignes.indexOf(save_identifiant_speciale); list_lignes.splice(index_ligne_speciale, 1); // Supprime élément à cet index console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); // rechercher la position de linkage.estimationRowId let index_ligne_estimation = list_lignes.indexOf(linkage.estimationRowId); // insérer sous la ligne estimation list_lignes.splice( index_ligne_estimation + 1 , 0, save_identifiant_speciale); console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>"); console.log(list_lignes); console.log("<<<<<<<>>>>>>>>"); // Réorganiser les lignes du tableau en fonction de biduleArr reorderTableRows(list_lignes); } } else { console.log("Aucun objet de liaison trouvé pour l'identifiant :", previousRowId); } } } function reorderTableRows(biduleArr) { // Récupérer toutes les lignes du tableau const allRows = Array.from(tableBody.querySelectorAll("tr")); // Créer un mapping des lignes par leur identifiant const rowMap = new Map(allRows.map(row => [row.dataset.rowId, row])); // Réorganiser les lignes en fonction de biduleArr const orderedRows = biduleArr.map(id => rowMap.get(id)).filter(row => row !== undefined); // Vider le tableau actuel tableBody.innerHTML = ""; // Ajouter les lignes réorganisées au tableau orderedRows.forEach(row => { tableBody.appendChild(row); }); // Réattacher les événements de drag-and-drop aux lignes orderedRows.forEach(row => { row.addEventListener("dragstart", dragStart); row.addEventListener("dragover", dragOver); row.addEventListener("drop", drop); }); } function updateRowData(element) { const row = element.closest("tr"); const rowId = row.dataset.rowId; if (rowId.startsWith("standard-")) { let standardRowData = standardRowsData.find(data => data.id === rowId); if (!standardRowData) { standardRowData = { id: rowId, name: "", selectValue: "", count: "", cells: [], selection: "OFF" // TAG : SELECTION }; standardRowsData.push(standardRowData); } const cells = row.querySelectorAll("td"); standardRowData.name = cells[0].querySelector("input").value; standardRowData.selectValue = cells[1].querySelector("select").value; standardRowData.count = cells[2].textContent.trim(); standardRowData.cells = []; cells.forEach((cell, index) => { if (index > 2) { standardRowData.cells.push({ value: cell.dataset.cellValue, color: cell.dataset.cellColor, full_date: cell.dataset.fullDate // Ajouter la clé full_date }); } }); console.log(`Mise à jour de la ligne standard : ${rowId}`); } else if (rowId.startsWith("estimation-")) { let estimationRowData = estimationRowsData.find(data => data.id === rowId); if (!estimationRowData) { estimationRowData = { id: rowId, name: "", selectValue: "", estimationValue: "", selection: "OFF" // TAG : SELECTION }; estimationRowsData.push(estimationRowData); } const cells = row.querySelectorAll("td"); estimationRowData.name = cells[0].querySelector("input").value; estimationRowData.selectValue = cells[1].querySelector("select").value; estimationRowData.estimationValue = cells[2].querySelector("input").value; console.log(`Mise à jour de la ligne d'estimation : ${rowId}`); } else if (rowId.startsWith("special-")) { let specialRowData = specialRowsData.find(data => data.id === rowId); if (!specialRowData) { specialRowData = { id: rowId, name: "", selection: "OFF" // TAG : SELECTION }; specialRowsData.push(specialRowData); } specialRowData.name = row.querySelector("input").value; console.log(`Mise à jour de la ligne spéciale : ${rowId}`); } } function updateCountCell(row) { const countCell = row.cells[2]; const count = Array.from(row.cells).slice(3).filter(cell => cell.dataset.cellValue === "1").length; countCell.textContent = count; } function displayListLignes() { // Fonction pour afficher le contenu de list_lignes dans la console console.log("Contenu de list_lignes :", list_lignes); } function displaySpecialRowsData() { console.log("Contenu de specialRowsData :"); specialRowsData.forEach((rowData, index) => { console.log(`Ligne spéciale ${index + 1} :`, rowData); }); } function addSpecialRow(afterRow = null) { const newRow = document.createElement("tr"); newRow.classList.add("special-row"); newRow.setAttribute("draggable", "true"); newRow.dataset.rowId = `special-${generateRandomId()}`; newRow.title = newRow.dataset.rowId; // Ajoutez cette ligne const specialRowData = { id: newRow.dataset.rowId, name: `Ligne spéciale ${specialRowCounter}`, selection: "OFF" // Ajouter la variable selection }; // Ajoutez l'identifiant de la ligne spéciale dans le tableau list_lignes list_lignes.push(newRow.dataset.rowId); const firstCell = document.createElement("td"); firstCell.classList.add("row-header"); const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = specialRowData.name; input.addEventListener("click", function (event) { event.stopPropagation(); input.focus(); input.style.width = "130px"; }); input.addEventListener("blur", function () { input.classList.remove("editing"); input.style.width = "65px"; updateRowData(input); }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { input.classList.remove("editing"); input.blur(); input.style.width = "65px"; updateRowData(input); } }); input.addEventListener("input", function () { updateRowData(input); }); const addButton = document.createElement("button"); addButton.classList.add("add-button"); addButton.textContent = "+"; addButton.addEventListener("click", function () { toggleCollapse(newRow); }); firstCell.appendChild(input); firstCell.appendChild(addButton); firstCell.addEventListener("contextmenu", function (event) { event.preventDefault(); showSpecialContextMenu(event, newRow); }); // Ajouter un gestionnaire de clic pour changer la couleur de fond firstCell.addEventListener("click", function () { handleSpecialRowClick(newRow, firstCell); }); newRow.appendChild(firstCell); const mergedCell = document.createElement("td"); mergedCell.colSpan = 2; mergedCell.textContent = ""; newRow.appendChild(mergedCell); const td = document.createElement("td"); td.textContent = `Ligne spéciale ${specialRowCounter} - Détails`; td.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3; newRow.appendChild(td); if (afterRow) { tableBody.insertBefore(newRow, afterRow.nextSibling); } else { tableBody.appendChild(newRow); } newRow.addEventListener("dragstart", dragStart); newRow.addEventListener("dragover", dragOver); newRow.addEventListener("drop", drop); specialRowsData.push(specialRowData); // Ajouter l'objet dans le tableau dédié specialRowCounter++; // Afficher le contenu du tableau specialRowsData après l'ajout displaySpecialRowsData(); } function handleSpecialRowClick(row, td) { const rowId = row.dataset.rowId; const specialRowData = specialRowsData.find(data => data.id === rowId); if (specialRowData) { // Vérifiez si le clic est sur le bouton "+" if (event.target.classList.contains('add-button')) { return; // Ignorer le clic sur le bouton "+" } if (objet_selection.length > 0 && !objet_selection.includes(rowId)) { // Afficher une fenêtre modale indiquant qu'une seule sélection est possible à la fois showMessageModal("Une seule sélection est possible à la fois."); return; // Empêcher la couleur de fond de changer } if (specialRowData.selection === "OFF") { specialRowData.selection = "ON"; td.style.backgroundColor = "blue"; // Ajoutez l'identifiant à objet_selection if (!objet_selection.includes(rowId)) { objet_selection.push(rowId); } } else { specialRowData.selection = "OFF"; td.style.backgroundColor = "white"; // Supprimer l'identifiant de objet_selection objet_selection = objet_selection.filter(id => id !== rowId); } } // Afficher les identifiants dans objet_selection pour vérification console.log("objet_selection:", objet_selection); } function toggleCollapse(specialRow) { const nextSpecialRow = getNextSpecialRow(specialRow); const rowsToToggle = []; let currentRow = specialRow.nextElementSibling; while (currentRow && currentRow !== nextSpecialRow) { if (!currentRow.classList.contains("special-row")) { rowsToToggle.push(currentRow); } currentRow = currentRow.nextElementSibling; } rowsToToggle.forEach(row => { row.classList.toggle("collapsed"); }); } function getNextSpecialRow(specialRow) { let currentRow = specialRow.nextElementSibling; while (currentRow) { if (currentRow.classList.contains("special-row")) { return currentRow; } currentRow = currentRow.nextElementSibling; } return null; } function showContextMenu(event, row) { contextMenu.innerHTML = ` <button class="dropdown-item" id="add-row">Ajouter une ligne</button> <button class="dropdown-item" id="delete-row">Supprimer cette ligne</button> <!-- <button class="dropdown-item" id="show-linkage">Afficher la liaison</button> --> <button class="dropdown-item" id="up-elements">UP</button> <button class="dropdown-item" id="down-elements">DOWN</button> `; contextMenu.style.top = `${event.clientY}px`; contextMenu.style.left = `${event.clientX}px`; contextMenu.style.display = "flex"; contextMenu.style.flexDirection = "column"; // Vérifier si la ligne est une ligne standard ou une ligne d'estimation const rowId = row.dataset.rowId; const isEstimationRow = rowId.startsWith("estimation-"); // Afficher ou masquer l'option "Ajouter une ligne" en fonction du type de ligne const addRowButton = document.getElementById("add-row"); if (isEstimationRow) { addRowButton.style.display = "block"; } else { addRowButton.style.display = "none"; } let linkedRowId = null; let linkedRow = null; // Vérifier si les options UP et DOWN doivent être désactivées if (rowId.startsWith("standard-")) { const linkage = linkages.find(link => link.standardRowId === rowId); if (linkage) { linkedRowId = linkage.estimationRowId; linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`); } } else if (rowId.startsWith("estimation-")) { const linkage = linkages.find(link => link.estimationRowId === rowId); if (linkage) { linkedRowId = linkage.standardRowId; linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`); } } let disableUpDown = true; if (linkedRow) { const standardRowData = standardRowsData.find(data => data.id === rowId) || standardRowsData.find(data => data.id === linkedRowId); const estimationRowData = estimationRowsData.find(data => data.id === rowId) || estimationRowsData.find(data => data.id === linkedRowId); if (standardRowData.selection === "ON" && estimationRowData.selection === "ON") { disableUpDown = false; } } const upButton = document.getElementById("up-elements"); const downButton = document.getElementById("down-elements"); if (disableUpDown) { upButton.classList.add("disabled"); downButton.classList.add("disabled"); } else { upButton.classList.remove("disabled"); downButton.classList.remove("disabled"); } document.getElementById("add-row").addEventListener("click", function () { addRow(row); hideContextMenu(); }); document.getElementById("delete-row").addEventListener("click", function () { showConfirmationModal(row); hideContextMenu(); }); upButton.addEventListener("click", function () { if (!disableUpDown) { moveRowsUp(); hideContextMenu(); } }); downButton.addEventListener("click", function () { if (!disableUpDown) { moveRowsDown(); hideContextMenu(); } }); } function insertSpecialRow(direction, row) { const newSpecialRow = document.createElement("tr"); newSpecialRow.classList.add("special-row"); newSpecialRow.setAttribute("draggable", "true"); newSpecialRow.dataset.rowId = `special-${generateRandomId()}`; newSpecialRow.title = newSpecialRow.dataset.rowId; const firstCell = document.createElement("td"); firstCell.classList.add("row-header"); const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = `Ligne spéciale`; input.addEventListener("click", function (event) { event.stopPropagation(); input.focus(); input.style.width = "130px"; }); input.addEventListener("blur", function () { input.classList.remove("editing"); input.style.width = "65px"; updateRowData(input); }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { input.classList.remove("editing"); input.blur(); input.style.width = "65px"; updateRowData(input); } }); input.addEventListener("input", function () { updateRowData(input); }); const addButton = document.createElement("button"); addButton.classList.add("add-button"); addButton.textContent = "+"; addButton.addEventListener("click", function () { toggleCollapse(newSpecialRow); }); firstCell.appendChild(input); firstCell.appendChild(addButton); firstCell.addEventListener("contextmenu", function (event) { event.preventDefault(); showSpecialContextMenu(event, newSpecialRow); }); newSpecialRow.appendChild(firstCell); const mergedCell = document.createElement("td"); mergedCell.colSpan = 2; mergedCell.textContent = ""; newSpecialRow.appendChild(mergedCell); const td = document.createElement("td"); td.textContent = `Ligne spéciale - Détails`; td.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3; newSpecialRow.appendChild(td); if (direction === "up") { tableBody.insertBefore(newSpecialRow, row); } else if (direction === "down") { tableBody.insertBefore(newSpecialRow, row.nextSibling); } newSpecialRow.addEventListener("dragstart", dragStart); newSpecialRow.addEventListener("dragover", dragOver); newSpecialRow.addEventListener("drop", drop); specialRowsData.push({ id: newSpecialRow.dataset.rowId, name: input.value }); // Afficher le contenu du tableau specialRowsData après l'ajout displaySpecialRowsData(); } function showSpecialContextMenu(event, row) { specialContextMenu.innerHTML = ` <button class="dropdown-item" id="add-special-row">Ajouter une ligne spéciale</button> <button class="dropdown-item" id="delete-special-row">Supprimer cette ligne</button> <!-- <button class="dropdown-item text-danger" id="delete-special-row">Supprimer cette ligne</button> --> <!-- <label class="dropdown-item"> <input type="checkbox" id="special-checkbox"> Attacher </label> --> <button class="dropdown-item" id="up-special-row">UP</button> <button class="dropdown-item" id="down-special-row">DOWN</button> `; specialContextMenu.style.top = `${event.clientY}px`; specialContextMenu.style.left = `${event.clientX}px`; specialContextMenu.style.display = "flex"; specialContextMenu.style.flexDirection = "column"; // inactif attacher const checkbox = document.getElementById("special-checkbox"); const rowId = row.dataset.rowId; // inactif attacher let hasStandardRowsBelow = false; // inactif attacher let currentRow = row.nextElementSibling; // inactif attacher const standardRows = []; // inactif attacher while (currentRow && !currentRow.classList.contains("special-row")) { // inactif attacher if (!currentRow.classList.contains("special-row")) { // inactif attacher hasStandardRowsBelow = true; // inactif attacher standardRows.push(currentRow); // inactif attacher } // inactif attacher currentRow = currentRow.nextElementSibling; // inactif attacher } // inactif attacher if (hasStandardRowsBelow) { // inactif attacher checkbox.disabled = false; // inactif attacher } else { // inactif attacher checkbox.disabled = true; // inactif attacher checkbox.checked = false; // inactif attacher } // inactif attacher if (specialRowStates[rowId]) { // inactif attacher checkbox.checked = specialRowStates[rowId].checked; // inactif attacher } // inactif attacher checkbox.addEventListener("change", function () { // inactif attacher specialRowStates[rowId] = { // inactif attacher checked: checkbox.checked, // inactif attacher rows: standardRows // inactif attacher }; // inactif attacher standardRows.forEach(standardRow => { // inactif attacher const firstCell = standardRow.querySelector("td:first-child"); // inactif attacher if (checkbox.checked) { // inactif attacher firstCell.style.backgroundColor = "yellow"; // inactif attacher standardRow.classList.add("no-drag"); // inactif attacher } else { // inactif attacher firstCell.style.backgroundColor = ""; // inactif attacher standardRow.classList.remove("no-drag"); // inactif attacher } // inactif attacher }); // inactif attacher if (checkbox.checked) { // inactif attacher associations[rowId] = standardRows.map(row => row.dataset.rowId); // inactif attacher } else { // inactif attacher delete associations[rowId]; // inactif attacher } // inactif attacher console.log(`Lignes standards concernées : ${standardRows.map(row => row.rowIndex).join(", ")}`); // inactif attacher }); // Vérifier si les options UP et DOWN doivent être désactivées const specialRowData = specialRowsData.find(data => data.id === rowId); let disableUpDown = true; if (specialRowData && specialRowData.selection === "ON") { disableUpDown = false; } const upButton = document.getElementById("up-special-row"); const downButton = document.getElementById("down-special-row"); if (disableUpDown) { upButton.classList.add("disabled"); downButton.classList.add("disabled"); } else { upButton.classList.remove("disabled"); downButton.classList.remove("disabled"); } document.getElementById("add-special-row").addEventListener("click", function () { addSpecialRow(row); hideSpecialContextMenu(); }); document.getElementById("delete-special-row").addEventListener("click", function () { showConfirmationModal(row); hideSpecialContextMenu(); }); upButton.addEventListener("click", function () { if (!disableUpDown) { moveSpecialRowUp(row); hideSpecialContextMenu(); } }); downButton.addEventListener("click", function () { if (!disableUpDown) { moveSpecialRowDown(row); hideSpecialContextMenu(); } }); } function showColorContextMenu(event, cell) { colorContextMenu.style.top = `${event.clientY}px`; colorContextMenu.style.left = `${event.clientX}px`; colorContextMenu.style.display = "flex"; colorContextMenu.style.flexDirection = "column"; document.querySelectorAll(".selected-cell").forEach(c => c.classList.remove("selected-cell")); cell.classList.add("selected-cell"); } function showMessageModal(message) { const modal = new bootstrap.Modal(document.getElementById('messageModal')); const modalBody = document.getElementById('messageModalBody'); modalBody.textContent = message; modal.show(); } document.addEventListener("click", function (event) { if (!contextMenu.contains(event.target)) { hideContextMenu(); } if (!specialContextMenu.contains(event.target)) { hideSpecialContextMenu(); } if (!colorContextMenu.contains(event.target)) { hideColorContextMenu(); } const inputs = document.querySelectorAll(".editable-input"); inputs.forEach(input => { if (!input.contains(event.target)) { input.classList.remove("editing"); } }); }); document.addEventListener("keydown", function (event) { if (event.key === "Escape") { hideContextMenu(); hideSpecialContextMenu(); hideColorContextMenu(); } }); function hideContextMenu() { contextMenu.style.display = "none"; } function hideSpecialContextMenu() { specialContextMenu.style.display = "none"; } function hideColorContextMenu() { colorContextMenu.style.display = "none"; } document.getElementById("addRowButton").addEventListener("click", addRow); document.getElementById("addSpecialRowButton").addEventListener("click", addSpecialRow); document.querySelectorAll("tbody tr td:first-child").forEach(td => { td.addEventListener("contextmenu", function (event) { event.preventDefault(); showContextMenu(event, td.parentElement); }); }); let draggedRowId = null; function dragStart(event) { const row = event.target.closest("tr"); if (!row) return; const rowId = row.dataset.rowId; // Vérifiez si la ligne est une ligne d'estimation if (rowId.startsWith("standard-") || rowId.startsWith("estimation-")) { event.preventDefault(); return; } draggedRowId = row.dataset.rowId; event.dataTransfer.setData("text/plain", row.rowIndex); row.classList.add("dragging"); } function dragOver(event) { event.preventDefault(); const draggingRow = document.querySelector(".dragging"); const targetRow = event.target.closest("tr"); if (targetRow && draggingRow !== targetRow && !targetRow.classList.contains("no-drag")) { const rect = targetRow.getBoundingClientRect(); const offset = rect.top + (rect.height / 2); if (event.clientY - offset > 0) { tableBody.insertBefore(draggingRow, targetRow.nextSibling); } else { tableBody.insertBefore(draggingRow, targetRow); } const targetRowId = targetRow.dataset.rowId; let linkage = null; if (targetRowId.startsWith("standard-")) { linkage = linkages.find(link => link.standardRowId === targetRowId); } else if (targetRowId.startsWith("estimation-")) { linkage = linkages.find(link => link.estimationRowId === targetRowId); } if (linkage) { const draggedRowIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow); console.log("++++ " + linkage.standardRowId + " + " + linkage.estimationRowId + " at index " + draggedRowIndex); } } } function drop(event) { event.preventDefault(); const draggingRow = document.querySelector(".dragging"); draggingRow.classList.remove("dragging"); const draggingRowId = draggingRow.dataset.rowId; let linkage = null; console.log(" Element " + draggingRowId); if (draggingRowId.startsWith("standard-")) { linkage = linkages.find(link => link.standardRowId === draggingRowId); console.log("Standard " + draggingRowId + " " + linkage.estimationRowId + " " + linkage.id ); // sauvegarde l'identifiant qui correspond à la ligne estimation let save_identifiant_estimation = linkage.estimationRowId; console.log(" TRACE sauve identifiant estimation " + save_identifiant_estimation); const draggedRowIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow); console.log("Position ligne drag standard " + draggedRowIndex); // Sélectionnez la ligne avec l'identifiant donné const estimationRow = document.querySelector(`tr[data-row-id="${linkage.estimationRowId}"]`); if (estimationRow) { // Obtenez toutes les lignes du tbody const rows = Array.from(tableBody.querySelectorAll("tr")); // Trouvez l'index de la ligne estimation const estimationRowIndex = rows.indexOf(estimationRow); console.log("Position ligne estimation yes" + estimationRowIndex); moveEstimationRow(estimationRowIndex, draggedRowIndex + 1); } else { console.log(`Aucune ligne trouvée avec l'identifiant ${save_identifiant_estimation}.`); } } else if (draggingRowId.startsWith("estimation-")) { linkage = linkages.find(link => link.estimationRowId === draggingRowId); console.log("Estimation " ); } if (linkage) { const draggedRowIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow); console.log("++++ " + linkage.standardRowId + " + " + linkage.estimationRowId + " at index " + draggedRowIndex); console.log("Linkage " ); } if (draggingRowId.startsWith("special-")) { console.log("Speciale "); // donne moi la position de la ligne speciale const index = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow); console.log("Position ligne speciale " + index + " " + draggingRowId); // donne moi le nom de la ligne placée au dessus // donne moi le nom de la ligne placée en dessous // Donne moi le nom de la ligne placée au-dessus const previousRow = tableBody.querySelectorAll("tr")[index - 1]; const nextRow = tableBody.querySelectorAll("tr")[index + 1]; if (previousRow) { const previousRowId = previousRow.dataset.rowId; console.log("Identifiant de la ligne précédente :", previousRowId); } if (nextRow) { const nextRowId = nextRow.dataset.rowId; console.log("Identifiant de la ligne suivante :", nextRowId); } } if (draggingRowId.startsWith("special-")) { console.log("Speciale "); const specialRowId = draggingRow.dataset.rowId; const newIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow); // Vérifiez si la nouvelle position est entre une ligne standard et une ligne d'estimation liées const previousRow = tableBody.querySelectorAll("tr")[newIndex - 1]; const nextRow = tableBody.querySelectorAll("tr")[newIndex + 1]; if (previousRow && nextRow) { const previousRowId = previousRow.dataset.rowId; const nextRowId = nextRow.dataset.rowId; const linkage = linkages.find(link => (link.standardRowId === previousRowId && link.estimationRowId === nextRowId) || (link.standardRowId === nextRowId && link.estimationRowId === previousRowId) ); if (linkage) { // Ajustez la position en fonction de la direction du drag const direction = draggingRow.rowIndex < newIndex ? 1 : -1; tableBody.insertBefore(draggingRow, tableBody.querySelectorAll("tr")[newIndex + direction]); } } if (associations[specialRowId]) { const associatedRowIds = associations[specialRowId]; associatedRowIds.forEach(rowId => { const associatedRow = document.querySelector(`tr[data-row-id="${rowId}"]`); if (associatedRow) { tableBody.insertBefore(associatedRow, draggingRow.nextSibling); } }); } } } let deletedEstimationRowData = null; function deleteRowById(rowId) { const row = document.querySelector(`tr[data-row-id="${rowId}"]`); if (row) { // Conservez les données de la ligne avant de la supprimer deletedEstimationRowData = { id: row.dataset.rowId, name: row.cells[0].querySelector("input").value, selectValue: row.cells[1].querySelector("select").value, estimationValue: row.cells[2].querySelector("input").value, selection: row.cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION }; // Supprimez la ligne du DOM row.remove(); console.log(`Ligne avec l'identifiant ${rowId} supprimée.`); } else { console.log(`Aucune ligne trouvée avec l'identifiant ${rowId}.`); } } function reinsertEstimationRowAtPosition(position) { if (deletedEstimationRowData) { const tableBody = document.querySelector("tbody"); const newRow = document.createElement("tr"); newRow.setAttribute("draggable", "true"); newRow.dataset.rowId = deletedEstimationRowData.id; newRow.classList.add("estimation-row"); newRow.title = newRow.dataset.rowId; // Créez les cellules de la nouvelle ligne const firstCells = [deletedEstimationRowData.name, "", deletedEstimationRowData.estimationValue]; firstCells.forEach((text, index) => { const td = document.createElement("td"); td.dataset.cellId = `cell-${deletedEstimationRowData.id}-${index}`; if (index === 0) { const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = deletedEstimationRowData.name; input.addEventListener("click", function (event) { event.stopPropagation(); input.focus(); input.style.width = "130px"; }); input.addEventListener("blur", function () { input.classList.remove("editing"); input.style.width = "65px"; updateRowData(input); }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { input.classList.remove("editing"); input.blur(); input.style.width = "65px"; updateRowData(input); } }); td.appendChild(input); } else if (index === 1) { const select = document.createElement("select"); for (let i = 1; i <= 10; i++) { const option = document.createElement("option"); option.value = i; option.textContent = `Option ${i}`; select.appendChild(option); } select.value = deletedEstimationRowData.selectValue; select.addEventListener("change", function () { updateRowData(select); }); td.appendChild(select); } else { const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = deletedEstimationRowData.estimationValue; input.addEventListener("blur", function () { const value = parseInt(input.value, 10); if (isNaN(value) || value < 1 || value > 365) { input.value = "1"; showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365."); } else { updateRowData(input); } input.classList.remove("editing"); input.style.width = "65px"; }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { const value = parseInt(input.value, 10); if (isNaN(value) || value < 1 || value > 365) { input.value = "1"; showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365."); } else { updateRowData(input); } input.classList.remove("editing"); input.blur(); input.style.width = "65px"; } }); td.appendChild(input); } if (index === 0) { td.classList.add("row-header"); td.addEventListener("click", function (event) { event.preventDefault(); handleRowClick(newRow, td); // TAG : SELECTION }); td.addEventListener("contextmenu", function (event) { event.preventDefault(); showContextMenu(event, newRow); }); } newRow.appendChild(td); }); // Créez une cellule fusionnée pour les colonnes restantes const mergedCell = document.createElement("td"); mergedCell.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3; mergedCell.textContent = ""; mergedCell.classList.add("no-click"); newRow.appendChild(mergedCell); // Insérez la nouvelle ligne à la position souhaitée if (position >= 0 && position <= tableBody.children.length) { tableBody.insertBefore(newRow, tableBody.children[position]); } else { tableBody.appendChild(newRow); } // Ajoutez les événements de drag-and-drop à la nouvelle ligne newRow.addEventListener("dragstart", dragStart); newRow.addEventListener("dragover", dragOver); newRow.addEventListener("drop", drop); // Ajoutez l'objet de la nouvelle ligne dans le tableau estimationRowsData estimationRowsData.push(deletedEstimationRowData); // Réinitialisez les données conservées deletedEstimationRowData = null; } else { console.log("Aucune donnée de ligne d'estimation supprimée à réinsérer."); } } function moveEstimationRow(fromPosition, toPosition) { const tableBody = document.querySelector("tbody"); const rows = tableBody.querySelectorAll("tr"); // Sélectionnez la ligne à déplacer const rowToMove = rows[fromPosition]; // Vérifiez si la ligne est une ligne d'estimation if (rowToMove.dataset.rowId.startsWith("estimation-")) { // Retirez la ligne de sa position actuelle tableBody.removeChild(rowToMove); // Réinsérez la ligne à la nouvelle position if (toPosition >= rows.length) { // Si la nouvelle position est à la fin, ajoutez la ligne à la fin tableBody.appendChild(rowToMove); } else { // Sinon, insérez la ligne avant la ligne à la nouvelle position tableBody.insertBefore(rowToMove, rows[toPosition]); } console.log(`Ligne d'estimation déplacée de la position ${fromPosition} à la position ${toPosition}.`); } else { console.error("La ligne sélectionnée n'est pas une ligne d'estimation."); } } function getRowPositionById(rowId) { // Sélectionnez le tbody du tableau const tableBody = document.querySelector("tbody"); // Sélectionnez la ligne avec l'identifiant donné const row = tableBody.querySelector(`tr[data-row-id="${rowId}"]`); // Vérifiez si la ligne existe if (row) { // Obtenez toutes les lignes du tbody const rows = Array.from(tableBody.querySelectorAll("tr")); // Trouvez l'index de la ligne const rowIndex = rows.indexOf(row); // Retournez la position de la ligne return rowIndex; } else { console.log(`Aucune ligne trouvée avec l'identifiant ${rowId}.`); return -1; // Retournez -1 si la ligne n'est pas trouvée } } function showConfirmationModal(row) { const modal = new bootstrap.Modal(document.getElementById('confirmationModal')); modal.show(); document.getElementById('confirmDelete').addEventListener('click', function () { let linkageIndex = -1; const rowId = row.dataset.rowId; const isStandardRow = rowId.startsWith("standard-"); const isEstimationRow = rowId.startsWith("estimation-"); const isSpecialRow = rowId.startsWith("special-"); console.log(" +++++++ " + rowId + " " + isSpecialRow) if (isStandardRow) { linkageIndex = linkages.findIndex(link => link.standardRowId === rowId); } else if (isEstimationRow) { linkageIndex = linkages.findIndex(link => link.estimationRowId === rowId); } else if (isSpecialRow) { //linkageIndex = linkages.findIndex(link => link.specialRowId === rowId); //console.log(" TRACE : " + linkageIndex); const specialRowIndex = specialRowsData.findIndex(data => data.id === rowId); console.log(" TRACE : " + specialRowIndex); ///12345 //const tableData = traceTable(); //console.log("Données retournées par traceTable():", JSON.stringify(tableData, null, 2)); if (specialRowIndex !== -1) { //console.log(" TRACE : " + linkageIndex); specialRowsData.splice(specialRowIndex, 1); } // Vérifiez si l'identifiant de la ligne spéciale est dans objet_selection if (objet_selection.includes(rowId)) { // Purgez objet_selection objet_selection = objet_selection.filter(id => id !== rowId); console.log("objet_selection purgé :", objet_selection); } row.remove(); // Remove the special row from the DOM modal.hide(); return; } if (linkageIndex !== -1) { const linkage = linkages[linkageIndex]; console.log("Liaison trouvée :"); console.log("Index de la liaison :", linkageIndex); // Afficher l'indice de la liaison console.log("ID de la liaison :", linkage.id); console.log("ID de la ligne standard :", linkage.standardRowId); console.log("ID de la ligne d'estimation :", linkage.estimationRowId); // Vérifiez si les identifiants de la ligne standard et de la ligne d'estimation sont dans objet_selection if (objet_selection.includes(linkage.standardRowId) && objet_selection.includes(linkage.estimationRowId)) { // Purgez objet_selection objet_selection = objet_selection.filter(id => id !== linkage.standardRowId && id !== linkage.estimationRowId); console.log("objet_selection purgé :", objet_selection); } } let standardRowId = null; let estimationRowId = null; let linkageId = null; if (isStandardRow) { standardRowId = rowId; const linkage = linkages.find(link => link.standardRowId === standardRowId); if (linkage) { estimationRowId = linkage.estimationRowId; linkageId = linkage.id; } } else if (isEstimationRow) { estimationRowId = rowId; const linkage = linkages.find(link => link.estimationRowId === estimationRowId); if (linkage) { standardRowId = linkage.standardRowId; linkageId = linkage.id; } } else if (isSpecialRow) { // Handle special row deletion if needed } if (standardRowId && estimationRowId && linkageId) { // Remove the corresponding sub-arrays in tableData const tableData = traceTable(); const standardIndex = tableData.findIndex(item => item.id === standardRowId); const estimationIndex = tableData.findIndex(item => item.id === estimationRowId); const linkageIndex = tableData.findIndex(item => item.id === linkageId); if (standardIndex !== -1) { tableData.splice(standardIndex, 1); } if (estimationIndex !== -1) { tableData.splice(estimationIndex, 1); } if (linkageIndex !== -1) { tableData.splice(linkageIndex, 1); } // Remove the rows from the DOM const standardRow = document.querySelector(`tr[data-row-id="${standardRowId}"]`); const estimationRow = document.querySelector(`tr[data-row-id="${estimationRowId}"]`); if (standardRow) { standardRow.remove(); } if (estimationRow) { estimationRow.remove(); } // Update the linkages array const linkageIndexInLinkages = linkages.findIndex(link => link.id === linkageId); if (linkageIndexInLinkages !== -1) { linkages.splice(linkageIndexInLinkages, 1); } // Display the updated tableData //displayJSONData(tableData); } modal.hide(); }); document.getElementById('cancelDelete').addEventListener('click', function () { modal.hide(); }); } function showMessageModal(message) { const modal = new bootstrap.Modal(document.getElementById('messageModal')); const modalBody = document.getElementById('messageModalBody'); modalBody.textContent = message; modal.show(); } function query() { const tableData = []; const rows = tableBody.querySelectorAll("tr"); rows.forEach(row => { const rowData = {}; const cells = row.querySelectorAll("td"); if (row.dataset.rowId.startsWith("special-")) { const inputCell = cells[0]; const inputValue = inputCell.querySelector("input").value; rowData.id = row.dataset.rowId; rowData.name = inputValue; rowData.selection = inputCell.style.backgroundColor === "blue" ? "ON" : "OFF"; // Ajouter la variable selection } else if (row.dataset.rowId.startsWith("estimation-")) { const inputCell = cells[0]; const inputValue = inputCell.querySelector("input").value; rowData.id = row.dataset.rowId; rowData.name = inputValue; rowData.estimationValue = cells[2].querySelector("input").value; rowData.selectValue = cells[1].querySelector("select").value; rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION } else { rowData.id = row.dataset.rowId; rowData.name = cells[0].querySelector("input").value; rowData.selectValue = cells[1].querySelector("select").value; rowData.count = cells[2].textContent.trim(); rowData.cells = []; rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION cells.forEach((cell, index) => { if (index > 2) { rowData.cells.push({ value: cell.dataset.cellValue, color: cell.dataset.cellColor, full_date: cell.dataset.fullDate // Ajouter la clé full_date }); } }); } tableData.push(rowData); }); // Ajouter les objets linkage au tableau de données linkages.forEach(linkage => { tableData.push({ id: linkage.id, standardRowId: linkage.standardRowId, estimationRowId: linkage.estimationRowId }); }); //return tableData; //const tableData = traceTable(); console.log("Données retournées par traceTable():", JSON.stringify(tableData, null, 2)); } function traceTable() { const tableData = []; const rows = tableBody.querySelectorAll("tr"); // Parcourir chaque ligne du tableau et récupérer les données des cellules rows.forEach(row => { const rowData = {}; const cells = row.querySelectorAll("td"); if (row.dataset.rowId.startsWith("special-")) { const inputCell = cells[0]; const inputValue = inputCell.querySelector("input").value; rowData.id = row.dataset.rowId; rowData.name = inputValue; rowData.selection = inputCell.style.backgroundColor === "blue" ? "ON" : "OFF"; // Ajouter la variable selection } else if (row.dataset.rowId.startsWith("estimation-")) { const inputCell = cells[0]; const inputValue = inputCell.querySelector("input").value; rowData.id = row.dataset.rowId; rowData.name = inputValue; rowData.estimationValue = cells[2].querySelector("input").value; rowData.selectValue = cells[1].querySelector("select").value; rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION } else { rowData.id = row.dataset.rowId; rowData.name = cells[0].querySelector("input").value; rowData.selectValue = cells[1].querySelector("select").value; rowData.count = cells[2].textContent.trim(); rowData.cells = []; rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION cells.forEach((cell, index) => { if (index > 2) { rowData.cells.push({ value: cell.dataset.cellValue, color: cell.dataset.cellColor, full_date: cell.dataset.fullDate // Ajouter la clé full_date }); } }); } tableData.push(rowData); }); // Ajouter les objets linkage au tableau de données linkages.forEach(linkage => { tableData.push({ id: linkage.id, standardRowId: linkage.standardRowId, estimationRowId: linkage.estimationRowId }); }); console.log("TRACE"); return tableData; } function openRangeSelectionModal(cell) { const modal = new bootstrap.Modal(document.getElementById('rangeSelectionModal')); const startCellIdInput = document.getElementById('startCellId'); const endCellIdInput = document.getElementById('endCellId'); const rangeResult = document.getElementById('rangeResult'); const rangeComboBox = document.getElementById('rangeComboBox'); rangeComboBox.innerHTML = ""; for (let i = 1; i <= 50; i++) { const option = document.createElement("option"); option.value = i; option.textContent = i; rangeComboBox.appendChild(option); } rangeComboBox.addEventListener("change", function () { const startCellId = startCellIdInput.value; const startParts = startCellId.split('-'); const startNumber = parseInt(startParts[2], 10); const comboValue = parseInt(rangeComboBox.value, 10); const totalDays = startNumber + comboValue; const endCellId = `${startParts[0]}-${startParts[1]}-${totalDays}`; console.log("Valeur sélectionnée :", comboValue); console.log("Nb jours :", totalDays); rangeResult.textContent = `Nb jours : ${totalDays}`; endCellIdInput.value = endCellId; }); startCellIdInput.value = cell.dataset.cellId; endCellIdInput.value = ""; rangeResult.textContent = "Nb jours : 0"; modal.show(); document.getElementById('confirmRangeSelection').addEventListener('click', function () { const startCellId = startCellIdInput.value; const endCellId = endCellIdInput.value; const comboValue = rangeComboBox.value; alert(startCellId + " " + endCellId); updateCellRange(startCellId, endCellId, comboValue); modal.hide(); }); document.getElementById('cancelRangeSelection').addEventListener('click', function () { modal.hide(); }); const modalHeader = modal._dialog.querySelector('.modal-header'); let isDragging = false; let offsetX, offsetY; modalHeader.addEventListener('mousedown', function (event) { isDragging = true; offsetX = event.clientX - modal._dialog.offsetLeft; offsetY = event.clientY - modal._dialog.offsetTop; modal._dialog.style.pointerEvents = 'none'; }); document.addEventListener('mousemove', function (event) { if (isDragging) { modal._dialog.style.left = `${event.clientX - offsetX}px`; modal._dialog.style.top = `${event.clientY - offsetY}px`; } }); document.addEventListener('mouseup', function () { isDragging = false; modal._dialog.style.pointerEvents = 'all'; }); endCellIdInput.addEventListener('input', function () { const startParts = startCellIdInput.value.split('-'); const endParts = endCellIdInput.value.split('-'); if (startParts.length === 3 && endParts.length === 3 && startParts[0] === endParts[0] && startParts[1] === endParts[1]) { const startValue = parseInt(startParts[2], 10); const endValue = parseInt(endParts[2], 10); console.log(" ++ " + startValue + " " + endValue); const result = endValue - startValue; rangeResult.textContent = `Nb jours : ${result} jours`; if (result > 0) { alert(`Nb jours : ${result} jours`); } } else { rangeResult.textContent = "Nb jours : 0"; } }); } function updateCellRange(startCellId, endCellId) { const startCell = document.querySelector(`td[data-cell-id="${startCellId}"]`); const endCell = document.querySelector(`td[data-cell-id="${endCellId}"]`); if (startCell && endCell && startCell.parentElement === endCell.parentElement) { const startIndex = Array.from(startCell.parentElement.cells).indexOf(startCell); const endIndex = Array.from(endCell.parentElement.cells).indexOf(endCell); for (let i = startIndex; i <= endIndex; i++) { const cell = startCell.parentElement.cells[i]; cell.dataset.cellValue = "1"; cell.textContent = "1"; cell.style.backgroundColor = "green"; cell.dataset.cellColor = "green"; updateRowData(cell); } updateCountCell(startCell.parentElement); } else { showMessageModal("Les cellules doivent être sur la même ligne."); } } tableBody.addEventListener("mouseover", function (event) { const cell = event.target.closest("td"); if (cell) { currentCell = cell; } }); document.addEventListener("keydown", function (event) { if (event.key === "p" && currentCell) { openRangeSelectionModal(currentCell); } }); document.getElementById("SauveButton").addEventListener("click", function () { const rows = tableBody.querySelectorAll("tr"); if (rows.length === 0) { showMessageModal("Aucune ligne à sauvegarder. Veuillez ajouter des lignes avant de sauvegarder."); } else { const modal = new bootstrap.Modal(document.getElementById('confirmSaveModal')); modal.show(); document.getElementById('confirmSave').addEventListener('click', function () { Jsondata(); modal.hide(); }); document.getElementById('cancelSave').addEventListener('click', function () { modal.hide(); }); } }); /* function async Jsondata() { const jsonData = []; const rows = document.querySelectorAll("tbody tr"); rows.forEach(row => { const rowId = row.dataset.rowId; const cells = row.querySelectorAll("td"); if (rowId.startsWith("standard-")) { const standardRow = { id: rowId, name: cells[0].querySelector("input").value, selectValue: cells[1].querySelector("select").value, count: cells[2].textContent.trim(), cells: [], selection: cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION }; cells.forEach((cell, index) => { if (index > 2) { standardRow.cells.push({ value: cell.dataset.cellValue, color: cell.dataset.cellColor, full_date: cell.dataset.fullDate // Ajouter la clé full_date }); } }); jsonData.push(standardRow); } else if (rowId.startsWith("estimation-")) { const estimationRow = { id: rowId, name: cells[0].querySelector("input").value, selectValue: cells[1].querySelector("select").value, estimationValue: cells[2].querySelector("input").value, selection: cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION }; jsonData.push(estimationRow); } else if (rowId.startsWith("special-")) { const specialRow = { id: rowId, name: cells[0].querySelector("input").value, selection: cells[0].style.backgroundColor === "blue" ? "ON" : "OFF" // TAG : SELECTION }; jsonData.push(specialRow); } }); // Ajouter les objets linkage linkages.forEach(linkage => { jsonData.push({ id: linkage.id, standardRowId: linkage.standardRowId, estimationRowId: linkage.estimationRowId }); }); console.log(JSON.stringify(jsonData, null, 2)); // Générer et télécharger le fichier JSON //generateAndDownloadJSON(jsonData); // Demander à l'utilisateur de choisir un nom de fichier try { const fileHandle = await window.showSaveFilePicker({ suggestedName: 'table_data.json', types: [{ description: 'JSON Files', accept: { 'application/json': ['.json'], }, }], }); // Écrire les données dans le fichier const writableStream = await fileHandle.createWritable(); await writableStream.write(jsonDataStr); await writableStream.close(); console.log('Fichier sauvegardé avec succès.'); } catch (error) { console.error('Erreur lors de la sauvegarde du fichier :', error); showMessageModal('Une erreur est survenue lors de la sauvegarde du fichier.'); } } */ async function Jsondata() { const jsonData = []; const rows = document.querySelectorAll("tbody tr"); rows.forEach(row => { const rowId = row.dataset.rowId; const cells = row.querySelectorAll("td"); if (rowId.startsWith("standard-")) { const standardRow = { id: rowId, name: cells[0].querySelector("input").value, selectValue: cells[1].querySelector("select").value, count: cells[2].textContent.trim(), cells: [], selection: cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION }; cells.forEach((cell, index) => { if (index > 2) { standardRow.cells.push({ value: cell.dataset.cellValue, color: cell.dataset.cellColor, full_date: cell.dataset.fullDate // Ajouter la clé full_date }); } }); jsonData.push(standardRow); } else if (rowId.startsWith("estimation-")) { const estimationRow = { id: rowId, name: cells[0].querySelector("input").value, selectValue: cells[1].querySelector("select").value, estimationValue: cells[2].querySelector("input").value, selection: cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION }; jsonData.push(estimationRow); } else if (rowId.startsWith("special-")) { const specialRow = { id: rowId, name: cells[0].querySelector("input").value, selection: cells[0].style.backgroundColor === "blue" ? "ON" : "OFF" // TAG : SELECTION }; jsonData.push(specialRow); } }); // Ajouter les objets linkage linkages.forEach(linkage => { jsonData.push({ id: linkage.id, standardRowId: linkage.standardRowId, estimationRowId: linkage.estimationRowId }); }); console.log(JSON.stringify(jsonData, null, 2)); // Convertir les données en chaîne JSON const jsonDataStr = JSON.stringify(jsonData, null, 2); // Demander à l'utilisateur de choisir un nom de fichier try { const fileHandle = await window.showSaveFilePicker({ suggestedName: 'table_data.json', types: [{ description: 'JSON Files', accept: { 'application/json': ['.json'], }, }], }); // Écrire les données dans le fichier const writableStream = await fileHandle.createWritable(); await writableStream.write(jsonDataStr); await writableStream.close(); console.log('Fichier sauvegardé avec succès.'); } catch (error) { console.error('Erreur lors de la sauvegarde du fichier :', error); showMessageModal('Une erreur est survenue lors de la sauvegarde du fichier.'); } } function generateAndDownloadJSON(jsonData) { // Convertir les données en chaîne JSON const jsonDataStr = JSON.stringify(jsonData, null, 2); // Créer un blob avec les données JSON const blob = new Blob([jsonDataStr], { type: 'application/json' }); // Créer un lien de téléchargement const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'table_data.json'; // Ajouter le lien au DOM et déclencher le téléchargement document.body.appendChild(a); a.click(); // Nettoyer document.body.removeChild(a); URL.revokeObjectURL(url); } function logRowTypes() { console.log("TRACE Start"); const rowDataArray = []; const rows = tableBody.querySelectorAll("tr"); const rowTypes = { standard: 0, estimation: 0, special: 0 }; linkages.forEach((linkage, index) => { rowDataArray.push(linkage); }); rows.forEach(row => { const rowId = row.dataset.rowId; if (rowId.startsWith("standard-")) { rowTypes.standard++; } else if (rowId.startsWith("estimation-")) { rowTypes.estimation++; } else if (rowId.startsWith("special-")) { rowTypes.special++; } let rowData = null; if (rowId.startsWith("standard-")) { rowData = standardRowsData.find(data => data.id === rowId); } else if (rowId.startsWith("estimation-")) { rowData = estimationRowsData.find(data => data.id === rowId); } else if (rowId.startsWith("special-")) { rowData = specialRowsData.find(data => data.id === rowId); } if (rowData) { console.log("Identifiant de la ligne :", rowId); console.log("Détails de l'objet :", rowData); rowDataArray.push(rowData); } else { console.log("Aucune donnée trouvée pour l'identifiant de la ligne :", rowId); } }); linkages.forEach((linkage, index) => { console.log(`Liaison ${index + 1} :`, linkage); }); console.log("Nombre de lignes standard :", rowTypes.standard); console.log("Nombre de lignes d'estimation :", rowTypes.estimation); console.log("Nombre de lignes spéciales :", rowTypes.special); sendDataToPHP(rowDataArray); console.log("TRACE end"); } function sendDataToPHP(rowDataArray) { // Afficher les données dans la console console.log("Données envoyées à PHP :", rowDataArray); // Envoyer les données au script PHP fetch('script_export02.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(rowDataArray) }) .then(response => response.json()) .then(data => { // Gérer les différents types de messages renvoyés if (data.status === 'success') { console.log('Succès :', data.message); showMessageModal(data.message); } else if (data.status === 'error') { console.error('Erreur :', data.message); showMessageModal(data.message); } else { console.error('Réponse inattendue :', data); showMessageModal('Réponse inattendue du serveur.'); } }) .catch(error => { console.error('Erreur :', error); showMessageModal('Une erreur est survenue lors de l\'envoi des données.'); }); } //document.getElementById("ChargeButton").addEventListener("click", fetchJsonData); /************************/ function original_fetchJsonData() { // Envoyer une requête GET au script PHP fetch('script_import_02.php') .then(response => response.json()) .then(data => { // Gérer les différents types de messages renvoyés if (data.status === 'success') { //console.log("<--------------- Début file.json --------------------->"); console.log('Données JSON récupérées :', data.data); // Parcourir chaque élément (sous-tableau JSON) de data data.data.forEach((item, index) => { //console.log("<------------------------------------>"); //console.log(`Élément ${index + 1} :`); if (item.id.includes('standard')) { //console.log('Détails de la ligne standard :'); for (const key in item) { if (item.hasOwnProperty(key)) { if (key === 'cells' && Array.isArray(item[key])) { //console.log(` ${key}:`); /* pas utile de voir le détail de chaque cellule item[key].forEach((cell, cellIndex) => { console.log(` Cell ${cellIndex + 1}:`); for (const cellKey in cell) { if (cell.hasOwnProperty(cellKey)) { console.log(` ${cellKey}: ${cell[cellKey]}`); } } });*/ } else { // console.log(` ${key}: ${item[key]}`); } } } } else if (item.id.includes('estimation')) { //console.log('Détails de la ligne d\'estimation :'); for (const key in item) { if (item.hasOwnProperty(key)) { //console.log(` ${key}: ${item[key]}`); } } } else if (item.id.includes('special')) { //console.log('Détails de la ligne spéciale :'); for (const key in item) { if (item.hasOwnProperty(key)) { //console.log(` ${key}: ${item[key]}`); } } } else if (item.id.includes('linkage')) { //console.log('Détails de la liaison :'); for (const key in item) { if (item.hasOwnProperty(key)) { //console.log(` ${key}: ${item[key]}`); } } } else { //console.log('Type de ligne inconnu :', item.id); } }); //console.log("<--------------- FIN file.json --------------------->"); //preparation(data.data); regeneration(data.data); } else if (data.status === 'error') { console.error('Erreur :', data.message); showMessageModal(data.message); } else { console.error('Réponse inattendue :', data); showMessageModal('Réponse inattendue du serveur.'); } }) .catch(error => { console.error('Erreur :', error); showMessageModal('Une erreur est survenue lors de la récupération des données.'); }); } /*****************************/ document.getElementById("loadJsonButton").addEventListener("click", function () { document.getElementById("fileInput").click(); }); document.getElementById("fileInput").addEventListener("change", function (event) { const file = event.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function (e) { try { const data = JSON.parse(e.target.result); console.log('Données JSON récupérées :', data.data); // Parcourir chaque élément (sous-tableau JSON) de data data.forEach((item, index) => { console.log(`Élément ${index + 1} :`); if (item.id.includes('standard')) { console.log('Détails de la ligne standard :'); for (const key in item) { if (item.hasOwnProperty(key)) { if (key === 'cells' && Array.isArray(item[key])) { console.log(` ${key}:`); // pas utile de voir le détail de chaque cellule /*item[key].forEach((cell, cellIndex) => { console.log(` Cell ${cellIndex + 1}:`); for (const cellKey in cell) { if (cell.hasOwnProperty(cellKey)) { console.log(` ${cellKey}: ${cell[cellKey]}`); } } });*/ } else { console.log(` ${key}: ${item[key]}`); } } } } else if (item.id.includes('estimation')) { console.log('Détails de la ligne d\'estimation :'); for (const key in item) { if (item.hasOwnProperty(key)) { console.log(` ${key}: ${item[key]}`); } } } else if (item.id.includes('special')) { console.log('Détails de la ligne spéciale :'); for (const key in item) { if (item.hasOwnProperty(key)) { console.log(` ${key}: ${item[key]}`); } } } else if (item.id.includes('linkage')) { console.log('Détails de la liaison :'); for (const key in item) { if (item.hasOwnProperty(key)) { console.log(` ${key}: ${item[key]}`); } } } else { console.log('Type de ligne inconnu :', item.id); } }); // Appeler la fonction de régénération avec les données récupérées regeneration(data); } catch (error) { console.error('Erreur lors de la lecture du fichier :', error); } }; reader.readAsText(file); } }); function bis_fetchJsonData() { // Utiliser fetch pour lire le fichier JSON local fetch('file_changed.json') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { // Gérer les différents types de messages renvoyés console.log('Données JSON récupérées :', data.data); // Parcourir chaque élément (sous-tableau JSON) de data data.forEach((item, index) => { console.log(`Élément ${index + 1} :`); if (item.id.includes('standard')) { console.log('Détails de la ligne standard :'); for (const key in item) { if (item.hasOwnProperty(key)) { if (key === 'cells' && Array.isArray(item[key])) { console.log(` ${key}:`); // pas utile de voir le détail de chaque cellule /*item[key].forEach((cell, cellIndex) => { console.log(` Cell ${cellIndex + 1}:`); for (const cellKey in cell) { if (cell.hasOwnProperty(cellKey)) { console.log(` ${cellKey}: ${cell[cellKey]}`); } } });*/ } else { console.log(` ${key}: ${item[key]}`); } } } } else if (item.id.includes('estimation')) { console.log('Détails de la ligne d\'estimation :'); for (const key in item) { if (item.hasOwnProperty(key)) { console.log(` ${key}: ${item[key]}`); } } } else if (item.id.includes('special')) { console.log('Détails de la ligne spéciale :'); for (const key in item) { if (item.hasOwnProperty(key)) { console.log(` ${key}: ${item[key]}`); } } } else if (item.id.includes('linkage')) { console.log('Détails de la liaison :'); for (const key in item) { if (item.hasOwnProperty(key)) { console.log(` ${key}: ${item[key]}`); } } } else { console.log('Type de ligne inconnu :', item.id); } }); // Appeler la fonction de régénération avec les données récupérées regeneration(data); }) } /******************************/ function showMessageModal(message) { const modal = new bootstrap.Modal(document.getElementById('messageModal')); const modalBody = document.getElementById('messageModalBody'); modalBody.textContent = message; modal.show(); } function display_import(data) { // Parcourir chaque élément (sous-tableau JSON) de data data.forEach((item, index) => { console.log(`Élément ${index + 1} :`); // Vérifier si l'id contient 'standard', 'estimation' ou 'special' if (item.id.includes('standard')) { console.log('Import : détails de la ligne standard :'); for (const key in item) { if (item.hasOwnProperty(key)) { if (key === 'cells' && Array.isArray(item[key])) { console.log(` ${key}:`); // pas utile de voir le détail de chaque cellule /*item[key].forEach((cell, cellIndex) => { console.log(` Cell ${cellIndex + 1}:`); for (const cellKey in cell) { if (cell.hasOwnProperty(cellKey)) { console.log(` ${cellKey}: ${cell[cellKey]}`); } } });*/ } else { console.log(` ${key}: ${item[key]}`); } } } } else if (item.id.includes('estimation')) { console.log('Import : Détails de la ligne d\'estimation :'); for (const key in item) { if (item.hasOwnProperty(key)) { console.log(` ${key}: ${item[key]}`); } } } else if (item.id.includes('special')) { console.log('Import : Détails de la ligne spéciale :'); for (const key in item) { if (item.hasOwnProperty(key)) { console.log(` ${key}: ${item[key]}`); } } } else if (item.id.includes('linkage')) { console.log('Détails de la liaison :'); for (const key in item) { if (item.hasOwnProperty(key)) { console.log(` ${key}: ${item[key]}`); } } } else { console.log('Type de ligne inconnu :', item.id); } }); } function code_annexe(data) { /* console.log(" ********** Début recherche ******************** "); // Afficher le contenu détaillé des objets //console.log("Contenu de standardRowsData :"); standardRowsData.forEach((row, index) => { console.log(`Ligne standard ${index + 1} :`, row); }); //console.log("Contenu de estimationRowsData :"); estimationRowsData.forEach((row, index) => { console.log(`Ligne d'estimation ${index + 1} :`, row); }); //console.log("Contenu de specialRowsData :"); specialRowsData.forEach((row, index) => { console.log(`Ligne spéciale ${index + 1} :`, row); }); //console.log("Contenu de linkages :"); linkages.forEach((linkage, index) => { console.log(`Liaison ${index + 1} :`, linkage); }); console.log(" ********** Fin recherche ******************** "); console.log(" ********** Début vérification purge ******************** "); standardRowsData.length = 0; estimationRowsData.length = 0; specialRowsData.length = 0; linkages.length = 0; if (standardRowsData.length === 0) { console.log(" standardRowsData empty"); } if (estimationRowsData.length === 0) { console.log(" estimationRowsData empty"); } if (specialRowsData.length === 0) { console.log(" specialRowsData empty"); } if (linkages.length === 0) { console.log(" linkages empty"); } console.log(" ********** Fin vérification purge ******************** "); */ // Afficher le nombre de sous-tableaux dans data //console.log("Nombre de sous-tableaux dans data :", data.length); /*for (const item of data) { if (item.id.includes('special')) { const specialRowData = { id: item.id, name: item.name }; specialRowsData.push(specialRowData); } }*/ /*for (let i = 0; i < data.length; i++) { console.log(" Indice " + i); }*/ } function regeneration(data) { console.log("Purging table and regenerating rows..."); // Clear existing table data tableBody.innerHTML = ""; standardRowsData.length = 0; estimationRowsData.length = 0; specialRowsData.length = 0; linkages.length = 0; objet_selection = []; // Réinitialiser l'objet objet_selection data.forEach(item => { if (item.id.includes('linkage')) { console.log("Creating a linkage..."); const linkage = { id: item.id, standardRowId: item.standardRowId, estimationRowId: item.estimationRowId, }; linkages.push(linkage); } if (item.id.includes('standard')) { console.log("Creating a standard row..."); const standardRowData = { id: item.id, name: item.name, selectValue: item.selectValue, count: item.count, cells: item.cells, selection: item.selection // TAG : SELECTION }; standardRowsData.push(standardRowData); const standardRow = document.createElement("tr"); standardRow.setAttribute("draggable", "true"); standardRow.dataset.rowId = item.id; standardRow.title = standardRow.dataset.rowId; // Ajoutez cette ligne const firstCells = [item.name, "", item.count]; firstCells.forEach((text, index) => { const td = document.createElement("td"); td.dataset.cellId = `cell-${item.id}-${index}`; if (index === 0) { const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = item.name; input.addEventListener("click", function (event) { event.stopPropagation(); input.focus(); input.style.width = "130px"; console.log("Input clicked, setting width to 130px"); }); input.addEventListener("blur", function () { if (!keydownHandled && !alertShown) { alertShown = true; input.classList.remove("editing"); input.blur(); input.style.width = "65px"; console.clear; updateRowData(input); } keydownHandled = false; alertShown = false; }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { keydownHandled = true; if (!alertShown) { alertShown = true; input.classList.remove("editing"); input.blur(); input.style.width = "65px"; console.clear; updateRowData(input); } } }); td.appendChild(input); } else if (index === 1) { const select = document.createElement("select"); for (let i = 1; i <= 10; i++) { const option = document.createElement("option"); option.value = i; option.textContent = `Option ${i}`; select.appendChild(option); } select.value = item.selectValue; select.addEventListener("change", function () { updateRowData(select); }); td.appendChild(select); } else { td.textContent = text; } if (index === 0) { td.classList.add("row-header"); td.addEventListener("click", function (event) { event.preventDefault(); handleRowClick(standardRow, td); // TAG : SELECTION }); td.addEventListener("contextmenu", function (event) { event.preventDefault(); showContextMenu(event, standardRow); }); } standardRow.appendChild(td); }); const headerCells = document.querySelectorAll("thead tr:nth-child(2) th:not(.weekend):not(.holiday)"); const workingDaysCount = headerCells.length; for (let i = 0; i < workingDaysCount - 3; i++) { const td = document.createElement("td"); td.dataset.cellId = `cell-${item.id}-${i}`; td.dataset.cellValue = item.cells[i].value; td.dataset.cellColor = item.cells[i].color; td.dataset.fullDate = item.cells[i].full_date; // Ajouter la clé full_date td.textContent = item.cells[i].value; td.style.backgroundColor = item.cells[i].color; td.addEventListener("click", function () { const newValue = td.dataset.cellValue === "0" ? "1" : "0"; td.dataset.cellValue = newValue; td.textContent = newValue; td.style.backgroundColor = newValue === "1" ? "green" : "white"; td.dataset.cellColor = newValue === "1" ? "green" : "white"; updateCountCell(standardRow); updateRowData(td); }); td.addEventListener("contextmenu", function (event) { event.preventDefault(); if (td.dataset.cellValue === "1") { showColorContextMenu(event, td); } }); // Ajouter l'écouteur d'événement pour afficher la date complète td.addEventListener("click", function (event) { const fullDate = event.target.dataset.fullDate; console.log("Date complète :", fullDate); //alert(fullDate); // Maintenant utiliser fullDate pour d'autres opérations }); td.title = `ID: ${td.dataset.cellId}`; standardRow.appendChild(td); } if (item.selection === "ON") { standardRow.cells[0].style.backgroundColor = "red"; } tableBody.appendChild(standardRow); standardRow.addEventListener("dragstart", dragStart); standardRow.addEventListener("dragover", dragOver); standardRow.addEventListener("drop", drop); } if (item.id.includes('estimation')) { console.log("Creating an estimation row..."); const estimationRowData = { id: item.id, name: item.name, selectValue: item.selectValue, estimationValue: item.estimationValue, selection: item.selection // TAG : SELECTION }; estimationRowsData.push(estimationRowData); const estimationRow = document.createElement("tr"); estimationRow.setAttribute("draggable", "true"); estimationRow.dataset.rowId = item.id; estimationRow.classList.add("estimation-row"); estimationRow.title = estimationRow.dataset.rowId; // Ajoutez cette ligne const estimationFirstCells = [item.name, "", item.estimationValue]; estimationFirstCells.forEach((text, index) => { const td = document.createElement("td"); td.dataset.cellId = `cell-${item.id}-${index}`; if (index === 0) { const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = item.name; input.addEventListener("click", function (event) { event.stopPropagation(); input.focus(); input.style.width = "130px"; console.log("Input clicked, setting width to 130px"); }); input.addEventListener("blur", function () { if (!keydownHandled && !alertShown) { alertShown = true; input.classList.remove("editing"); input.blur(); input.style.width = "65px"; console.clear; updateRowData(input); } keydownHandled = false; alertShown = false; }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { keydownHandled = true; if (!alertShown) { alertShown = true; input.classList.remove("editing"); input.blur(); input.style.width = "65px"; console.clear; updateRowData(input); } } }); td.appendChild(input); } else if (index === 1) { const select = document.createElement("select"); for (let i = 1; i <= 10; i++) { const option = document.createElement("option"); option.value = i; option.textContent = `Option ${i}`; select.appendChild(option); } select.value = item.selectValue; select.addEventListener("change", function () { updateRowData(select); }); td.appendChild(select); } else { const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = text; input.addEventListener("blur", function () { const value = parseInt(input.value, 10); if (isNaN(value) || value < 1 || value > 365) { input.value = "1"; showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365."); } else { updateRowData(input); } input.classList.remove("editing"); input.style.width = "65px"; }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { const value = parseInt(input.value, 10); if (isNaN(value) || value < 1 || value > 365) { input.value = "1"; showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365."); } else { updateRowData(input); } input.classList.remove("editing"); input.blur(); input.style.width = "65px"; } }); td.appendChild(input); } if (index === 0) { td.classList.add("row-header"); td.addEventListener("click", function (event) { event.preventDefault(); handleRowClick(estimationRow, td); // TAG : SELECTION }); td.addEventListener("contextmenu", function (event) { event.preventDefault(); showContextMenu(event, estimationRow); }); } estimationRow.appendChild(td); }); const mergedCell = document.createElement("td"); mergedCell.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3; mergedCell.textContent = ""; mergedCell.classList.add("no-click"); estimationRow.appendChild(mergedCell); if (item.selection === "ON") { estimationRow.cells[0].style.backgroundColor = "red"; } tableBody.appendChild(estimationRow); estimationRow.addEventListener("dragstart", dragStart); estimationRow.addEventListener("dragover", dragOver); estimationRow.addEventListener("drop", drop); } if (item.id.includes('special')) { console.log("Creating a special row..."); const specialRowData = { id: item.id, name: item.name, selection: item.selection // TAG : SELECTION }; specialRowsData.push(specialRowData); const specialRow = document.createElement("tr"); specialRow.classList.add("special-row"); specialRow.setAttribute("draggable", "true"); specialRow.dataset.rowId = item.id; specialRow.title = specialRow.dataset.rowId; // Ajoutez cette ligne const firstCell = document.createElement("td"); firstCell.classList.add("row-header"); const input = document.createElement("input"); input.type = "text"; input.classList.add("editable-input"); input.value = item.name; input.addEventListener("click", function (event) { event.stopPropagation(); input.focus(); input.style.width = "130px"; console.log("Input clicked, setting width to 130px"); }); input.addEventListener("blur", function () { input.classList.remove("editing"); input.style.width = "65px"; updateRowData(input); }); input.addEventListener("keydown", function (event) { if (event.key === "Escape" || event.key === "Enter") { input.classList.remove("editing"); input.blur(); input.style.width = "65px"; updateRowData(input); } }); input.addEventListener("input", function () { updateRowData(input); }); const addButton = document.createElement("button"); addButton.classList.add("add-button"); addButton.textContent = "+"; addButton.addEventListener("click", function () { toggleCollapse(specialRow); }); firstCell.appendChild(input); firstCell.appendChild(addButton); firstCell.addEventListener("contextmenu", function (event) { event.preventDefault(); showSpecialContextMenu(event, specialRow); }); // Ajouter un gestionnaire de clic pour changer la couleur de fond firstCell.addEventListener("click", function () { handleSpecialRowClick(specialRow, firstCell); }); if (item.selection === "ON") { firstCell.style.backgroundColor = "blue"; } specialRow.appendChild(firstCell); const mergedCell = document.createElement("td"); mergedCell.colSpan = 2; mergedCell.textContent = ""; specialRow.appendChild(mergedCell); const td = document.createElement("td"); td.textContent = `${item.name} - Détails`; td.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3; specialRow.appendChild(td); tableBody.appendChild(specialRow); specialRow.addEventListener("dragstart", dragStart); specialRow.addEventListener("dragover", dragOver); specialRow.addEventListener("drop", drop); } }); // Recréer l'objet objet_selection linkages.forEach(linkage => { const standardRowData = standardRowsData.find(data => data.id === linkage.standardRowId); const estimationRowData = estimationRowsData.find(data => data.id === linkage.estimationRowId); if (standardRowData && estimationRowData && standardRowData.selection === "ON" && estimationRowData.selection === "ON") { objet_selection.push(standardRowData.id, estimationRowData.id); } }); // Afficher les liaisons dans la console //displayLinkages(); } document.getElementById("queryButton").addEventListener("click", function () { query(); }); document.getElementById("GraphiqueButton").addEventListener("click", function () { console.log("Envoie ..."); const tableData = traceTable(); console.log("Données envoyées à graphique.php :", tableData); // Filtrer les lignes pour supprimer les lignes spéciales //tableData = tableData.filter(row => !row.id.includes('special')); // Filtrer les lignes pour supprimer celles dont l'id contient "special" //const filteredTableData = tableData.filter(row => !row.id.includes('special')); const filteredTableData = tableData.filter(row => !row.id.includes('special') && !row.id.startsWith('linkage')); // Convertir les données en chaîne JSON const jsonData = JSON.stringify(filteredTableData); console.log("Stop ..."); filteredTableData.forEach(row => { if (row.id) { console.log("ID de la ligne :", row.id); } }); // Créer un formulaire temporaire pour envoyer les données via POST const form = document.createElement('form'); form.method = 'post'; form.action = 'graphique0021.php'; const input = document.createElement('input'); input.type = 'hidden'; input.name = 'data'; input.value = jsonData; form.appendChild(input); document.body.appendChild(form); form.submit(); }); // Récupérer la valeur renvoyée const returnValue = sessionStorage.getItem('returnValue'); if (returnValue === "rechargement") { console.log('Valeur renvoyée :', returnValue); // Faites quelque chose avec la valeur renvoyée //fetchJsonData(); console.log("Fin"); } }); </script> </body> </html>