File "stable037.html"

Full Path: /home/analogde/www/Design/Dev tableau/stable037.html
File size: 37.84 KB
MIME-type: text/html
Charset: utf-8

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tableau Dynamique</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
    <style>
        table {
            width: auto;
            min-width: 1200px;
            border-collapse: separate;
            border-spacing: 0;
        }
        th, td {
            border: 1px solid black;
            padding: 8px;
            text-align: center;
            white-space: nowrap;
            box-sizing: border-box;
        }
        thead th {
            background: #f8f8f8;
            position: sticky;
            top: 0;
            z-index: 2;
        }
        .table-container {
            width: 100%;
            overflow-x: auto;
            position: relative;
            margin-top: 20px;
            border: 1px solid #ddd;
        }
        th:nth-child(n+1):nth-child(-n+3), td:nth-child(n+1):nth-child(-n+3) {
            z-index: 4;
            background: white;
            border-right: 2px solid black;
        }
        th:nth-child(1), td:nth-child(1) {
            width: 210px;
            min-width: 210px;
            max-width: 210px;
        }
        th:nth-child(2), td:nth-child(2) {
            width: 80px;
            min-width: 80px;
            max-width: 80px;
        }
        th:nth-child(3), td:nth-child(3) {
            width: 100px;
            min-width: 100px;
            max-width: 100px;
        }
        td:first-child {
            display: flex;
            justify-content: center;
            align-items: center;
        }
        select {
            width: 100%;
            max-width: 80px;
        }
        input[type="text"] {
            width: calc(100% - 20px);
            box-sizing: border-box;
        }
        button {
            margin-top: 20px;
            padding: 10px;
            font-size: 16px;
        }
        .cell-active {
            background-color: green;
        }
        th:nth-child(n+4), td:nth-child(n+4) {
            width: 50px;
            min-width: 50px;
            max-width: 50px;
        }
        .unused-cell {
            background-color: #cccccc;
        }
        .dragging {
            opacity: 0.5;
        }
        .collapse-cell {
            background-color: orange;
        }
        .special-cell {
            display: flex;
            justify-content: space-between;
            align-items: center;
            position: relative;
            padding: 0;
        }
        .special-cell input {
            width: calc(100% - 30px);
            margin-right: 10px;
            height: 20px;
        }
        .special-cell button {
            width: 20px;
            height: 20px;
            background-color: orange;
            border: none;
            cursor: pointer;
            display: flex;
            justify-content: center;
            align-items: center;
            margin: 0;
        }
        .context-menu {
            display: none;
            position: absolute;
            background-color: white;
            border: 1px solid #ccc;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            z-index: 1000;
        }
        .context-menu ul {
            list-style: none;
            padding: 0;
            margin: 0;
        }
        .context-menu ul li {
            padding: 8px 12px;
            cursor: pointer;
            display: flex;
            align-items: center;
        }
        .context-menu ul li:hover {
            background-color: #f0f0f0;
        }
        .context-menu ul li .color-box {
            width: 15px;
            height: 15px;
            margin-right: 10px;
        }

        /* Classe pour définir la largeur du ComboBox */
        .combo-box {
            width: 450px; /* Largeur fixe */
            padding: 5px;
            font-size: 16px;
            border: 1px solid #ccc;
            border-radius: 5px;
            background-color: #fff;
            cursor: pointer;
        }
        .combo-box {
            width: 50%; /* Largeur de 50% du parent */
            max-width: 300px; /* Empêche de devenir trop grand */
        }
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.23/jspdf.plugin.autotable.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="planning-description">
    <p id="planningDescription">Planning du 1er juin 2024 au 30 juin 2025</p>
</div>
<div class="table-container">
    <table>
        <thead>
            <tr id="header-row">
                <th></th>
                <th></th>
                <th>Jours</th>
            </tr>
            <tr id="month-row">
                <th class="unused-cell"></th>
                <th></th>
                <th class="unused-cell">Mois</th>
            </tr>
            <tr id="day-row">
                <th class="unused-cell"></th>
                <th></th>
                <th class="unused-cell">Semaine</th>
            </tr>
            <tr id="numero-row">
                <th class="unused-cell">Blocs</th>
                <th>Priorité</th>
                <th class="unused-cell">Total</th>
            </tr>
        </thead>
        <tbody id="table-body"></tbody>
    </table>
</div>
<button id="getDataButton">Récupérer les données du tableau</button>
<button id="sendDataButton">Envoyer les données</button>
<button id="readDataButton">Lire les données</button>
<button id="addRowButton">Ajouter une ligne</button>
<button id="addSpecialRowButton">Ajouter une ligne spéciale</button>
<button id="generatePDFButton">PDF</button>
<button id="dbButton">DB</button>

<div id="contextMenu" class="context-menu">
    <ul>
        <li id="deleteRow">Supprimer</li>
        <li id="addRowContext">Ajouter une ligne</li>
        <li id="changeColorRed">Changer la couleur en rouge</li>
        <li id="changeColorGreen">Changer la couleur en vert</li>
        <li id="changeColorBlue">Changer la couleur en bleu</li>
        <li id="changeColorNone">Pas de couleur</li>
        <li id="changeValues">Changer</li>
        <li id="resetRow">Remise à zéro</li> <!-- Option pour remise à zéro -->
    </ul>
</div>

<div id="specialRowContextMenu" class="context-menu">
    <ul>
        <li id="deleteSpecialRow">Supprimer</li>
        <li id="addRowAfterSpecial">Ajouter une ligne</li>
    </ul>
</div>

<div id="cellContextMenu" class="context-menu">
    <ul>
        <li id="cellColorRed"><span class="color-box" style="background-color: red;"></span> Rouge</li>
        <li id="cellColorGreen"><span class="color-box" style="background-color: green;"></span> Vert</li>
        <li id="cellColorBlue"><span class="color-box" style="background-color: blue;"></span> Bleu</li>
        <li id="cellColorYellow"><span class="color-box" style="background-color: yellow;"></span> Jaune</li>
        <li id="cellColorPurple"><span class="color-box" style="background-color: purple;"></span> Violet</li>
    </ul>
</div>

<!-- Modal de confirmation -->
<div class="modal fade" id="confirmationModal" tabindex="-1" role="dialog" aria-labelledby="confirmationModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <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">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                Êtes-vous sûr de vouloir supprimer cette ligne ?
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
                <button type="button" class="btn btn-danger" id="confirmDeleteButton">Supprimer</button>
            </div>
        </div>
    </div>
</div>

<script>
    const numCols = 100;
    let targetRow = null;
    let targetCell = null;
    let currentContextRow = null;

    function getHolidaysForYear(year) {
        // Jours fériés fixes
        const fixedHolidays = [
            `${year}-01-01`,  // Jour de l'An
            `${year}-05-01`,  // Fête du Travail
            `${year}-05-08`,  // Victoire 1945
            `${year}-07-14`,  // Fête Nationale
            `${year}-08-15`,  // Assomption
            `${year}-11-01`,  // Toussaint
            `${year}-11-11`,  // Armistice 1918
            `${year}-12-25`   // Noël
        ];

        // Jours fériés mobiles (Pâques et jours associés)
        const easter = getEasterSunday(year);
        const easterMonday = new Date(easter);
        easterMonday.setDate(easter.getDate() + 1);

        const ascension = new Date(easter);
        ascension.setDate(easter.getDate() + 39);

        const pentecote = new Date(easter);
        pentecote.setDate(easter.getDate() + 50);

        const mobileHolidays = [
            easterMonday.toISOString().split('T')[0], // Lundi de Pâques
            ascension.toISOString().split('T')[0],   // Ascension
            pentecote.toISOString().split('T')[0]    // Lundi de Pentecôte
        ];

        return [...fixedHolidays, ...mobileHolidays];
    }

    function getEasterSunday(year) {
        // Algorithme de calcul de la date de Pâques pour une année donnée
        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 getHolidays(startYear, endYear) {
        let holidays = [];
        for (let year = startYear; year <= endYear; year++) {
            holidays = holidays.concat(getHolidaysForYear(year));
        }
        return holidays;
    }

    function createTable() {
        const theadRow = document.getElementById("header-row");
        const monthRow = document.getElementById("month-row");
        const dayRow = document.getElementById("day-row");
        const numeroWeekRow = document.getElementById("numero-row");
        let currentDate = new Date('2024-06-01');
        const endDate = new Date('2025-06-30');
        const startYear = currentDate.getFullYear();
        const endYear = endDate.getFullYear();
        const holidays = getHolidays(startYear, endYear);
        let lastMonth = "";
        let currentColor = "#E0E0E0";
        let weekNumber = getISOWeekNumber(currentDate);
        let lastThMonth = null;
        let colSpanMonth = 0;
        let lastWeekNumber = null;
        let weekTh = null;
        let colSpanWeek = 0;

        function getISOWeekNumber(date) {
            const dateCopy = new Date(date.getTime());
            dateCopy.setHours(0, 0, 0, 0);
            dateCopy.setDate(dateCopy.getDate() + 3 - (dateCopy.getDay() + 6) % 7);
            const firstThursday = new Date(dateCopy.getFullYear(), 0, 1);
            return Math.ceil(((dateCopy - firstThursday) / 86400000 + 1) / 7);
        }

        while (currentDate <= endDate) {
            const dayOfWeek = currentDate.getDay();
            const dateString = currentDate.toISOString().split('T')[0];

            if (dayOfWeek !== 0 && dayOfWeek !== 6 && !holidays.includes(dateString)) {
                let th = document.createElement("th");
                th.textContent = currentDate.getDate();
                theadRow.appendChild(th);

                let currentWeekNumber = getISOWeekNumber(currentDate);

                let monthShort = currentDate.toLocaleString('default', { month: 'long' });
                monthShort = monthShort.charAt(0).toUpperCase() + monthShort.slice(1);
                if (monthShort === lastMonth) {
                    colSpanMonth++;
                    lastThMonth.colSpan = colSpanMonth;
                } else {
                    lastMonth = monthShort;
                    colSpanMonth = 1;
                    lastThMonth = document.createElement("th");
                    lastThMonth.textContent = monthShort + " " + currentDate.getFullYear();
                    monthRow.appendChild(lastThMonth);

                    if (parseInt(currentDate.toLocaleString('default', { month: 'numeric' })) % 2 === 0) {
                        lastThMonth.style.backgroundColor = "#E0E0E0";
                    } else {
                        lastThMonth.style.backgroundColor = "#B0C4DE";
                    }
                }

                th.style.backgroundColor = (currentDate.getMonth() % 2 === 0) ? "#FFA500" : "#0000FF";

                let dayTh = document.createElement("th");
                dayTh.textContent = currentDate.toLocaleString('default', { weekday: 'short' }).charAt(0).toUpperCase();
                dayRow.appendChild(dayTh);

                if (dayOfWeek === 1) {
                    currentColor = (currentColor === "#E0E0E0") ? "#B0C4DE" : "#E0E0E0";
                    weekNumber = getISOWeekNumber(currentDate);
                }
                dayTh.style.backgroundColor = currentColor;

                if (currentWeekNumber === lastWeekNumber) {
                    colSpanWeek++;
                    weekTh.colSpan = colSpanWeek;
                } else {
                    weekTh = document.createElement("th");
                    weekTh.textContent = currentWeekNumber;
                    weekTh.colSpan = 1;
                    numeroWeekRow.appendChild(weekTh);

                    lastWeekNumber = currentWeekNumber;
                    colSpanWeek = 1;
                }
            }
            currentDate.setDate(currentDate.getDate() + 1);
        }
    }

    function addRow(event) {
        const tbody = document.getElementById("table-body");
        const headerRow = document.getElementById("header-row");
        const numDateCells = headerRow.querySelectorAll("th").length - 3;

        let row = document.createElement("tr");
        row.setAttribute('draggable', 'true');

        row.addEventListener('dragstart', handleDragStart);
        row.addEventListener('dragover', handleDragOver);
        row.addEventListener('drop', handleDrop);

        let inputCell = document.createElement("td");
        inputCell.classList.add('sticky-cell'); // Assurez-vous que cette classe est ajoutée
        let input = document.createElement("input");
        input.type = "text";
        input.addEventListener('click', function(event) {
            event.stopPropagation();
            input.focus();
        });
        input.addEventListener('keydown', function(event) {
            if (event.key === 'Enter') {
                input.blur();
            }
        });
        inputCell.appendChild(input);
        inputCell.addEventListener('contextmenu', showContextMenu);
        row.appendChild(inputCell);

        let selectCell = document.createElement("td");
        let select = document.createElement("select");
        for (let j = 1; j <= 5; j++) {
            let option = document.createElement("option");
            option.textContent = j;
            select.appendChild(option);
        }
        selectCell.appendChild(select);
        row.appendChild(selectCell);

        let totalCell = document.createElement("td");
        totalCell.textContent = "0";
        row.appendChild(totalCell);

        let total = 0;
        for (let j = 0; j < numDateCells; j++) {
            let cell = document.createElement("td");
            let value = Math.random() < 0.5 ? "1" : "0";
            cell.textContent = value;
            if (value === "1") {
                cell.classList.add('cell-active');
            }
            total += parseInt(value);
            cell.addEventListener('click', handleCellClick);
            cell.addEventListener('contextmenu', showCellContextMenu);
            row.appendChild(cell);
        }

        totalCell.textContent = total;

        if (event) {
            const targetRow = event.target.closest('tr');
            if (targetRow) {
                targetRow.parentNode.insertBefore(row, targetRow.nextSibling);
            } else {
                tbody.appendChild(row);
            }
        } else {
            tbody.appendChild(row);
        }

        // Forcer le recalcul des styles
        row.getBoundingClientRect();
    }

    function addSpecialRow() {
        const tbody = document.getElementById("table-body");
        let row = document.createElement("tr");
        row.classList.add('special-row');
        row.setAttribute('draggable', 'true');
        row.addEventListener('dragstart', handleDragStart);
        row.addEventListener('dragover', handleDragOver);
        row.addEventListener('drop', handleDrop);

        let specialCell = document.createElement("td");
        specialCell.classList.add('special-cell');

        let input = document.createElement("input");
        input.type = "text";
        input.addEventListener('click', function() {
            input.focus();
        });
        input.addEventListener('keydown', function(event) {
            if (event.key === 'Enter') {
                input.blur();
            }
        });
        specialCell.appendChild(input);

        let button = document.createElement("button");
        button.textContent = "+";
        button.addEventListener('click', function() {
            toggleCollapse(row);
        });
        specialCell.appendChild(button);

        specialCell.addEventListener('contextmenu', showContextMenu);

        row.appendChild(specialCell);

        tbody.appendChild(row);
    }

    function toggleCollapse(row) {
        const tbody = document.getElementById("table-body");
        const rows = Array.from(tbody.querySelectorAll('tr'));
        const index = rows.indexOf(row);
        const nextSpecialRowIndex = rows.findIndex((r, i) => i > index && r.classList.contains('special-row'));
        const isCollapsed = row.classList.toggle('collapsed');

        rows.forEach((r, i) => {
            if (i > index && (nextSpecialRowIndex === -1 || i < nextSpecialRowIndex)) {
                r.style.display = isCollapsed ? 'none' : '';
            }
        });

        row.querySelector('td').style.backgroundColor = isCollapsed ? 'orange' : 'white';
    }

    function handleDragStart(event) {
        event.dataTransfer.setData('text/plain', event.target.rowIndex);
        setTimeout(() => {
            event.target.classList.add('dragging');
        }, 0);
    }

    function handleDragOver(event) {
        event.preventDefault();
        const draggingRow = document.querySelector('.dragging');
        const targetRow = event.target.closest('tr');
        if (targetRow && draggingRow !== targetRow) {
            const tbody = document.getElementById("table-body");
            if (targetRow.rowIndex > draggingRow.rowIndex) {
                tbody.insertBefore(draggingRow, targetRow.nextSibling);
            } else {
                tbody.insertBefore(draggingRow, targetRow);
            }
        }
    }

    function handleDrop(event) {
        event.preventDefault();
        const draggingRow = document.querySelector('.dragging');
        if (draggingRow) {
            draggingRow.classList.remove('dragging');
        }
    }

    function handleCellClick(event) {
        const cell = event.target;
        const row = cell.parentElement;
        const totalCell = row.querySelector('td:nth-child(3)');
        let total = parseInt(totalCell.textContent);
        if (cell.textContent === "0") {
            cell.textContent = "1";
            cell.classList.add('cell-active');
            total += 1;
        } else {
            cell.textContent = "0";
            cell.classList.remove('cell-active');
            total -= 1;
        }
        totalCell.textContent = total;

        // Reset row background color if all cells are "0"
        const allCells = row.querySelectorAll('td:not(:nth-child(1)):not(:nth-child(2)):not(:nth-child(3))');
        const allZero = Array.from(allCells).every(cell => cell.textContent === "0");
        if (allZero) {
            row.style.backgroundColor = '';
        }
    }

    function showContextMenu(event) {
        event.preventDefault();
        const targetRow = event.target.closest('tr');
        const isSpecialRow = targetRow.classList.contains('special-row');
        const contextMenu = isSpecialRow ? document.getElementById('specialRowContextMenu') : document.getElementById('contextMenu');

        console.log(`Showing context menu for ${isSpecialRow ? 'special row' : 'standard row'}`);

        contextMenu.style.display = 'block';
        contextMenu.style.left = `${event.pageX}px`;
        contextMenu.style.top = `${event.pageY}px`;

        document.addEventListener('click', function hideContextMenu(event) {
            if (!contextMenu.contains(event.target)) {
                contextMenu.style.display = 'none';
                document.removeEventListener('click', hideContextMenu);
            }
        });

        // Store the target row for later use
        currentContextRow = targetRow;
    }

    function showCellContextMenu(event) {
        event.preventDefault();
        if (event.target.textContent === "1") {
            const cellContextMenu = document.getElementById('cellContextMenu');
            cellContextMenu.style.display = 'block';
            cellContextMenu.style.left = `${event.pageX}px`;
            cellContextMenu.style.top = `${event.pageY}px`;

            targetCell = event.target;

            document.addEventListener('click', function hideCellContextMenu(event) {
                if (!cellContextMenu.contains(event.target)) {
                    cellContextMenu.style.display = 'none';
                    document.removeEventListener('click', hideCellContextMenu);
                }
            });
        }
    }

    function hideContextMenus() {
        const contextMenu = document.getElementById('contextMenu');
        const specialRowContextMenu = document.getElementById('specialRowContextMenu');
        const cellContextMenu = document.getElementById('cellContextMenu');

        contextMenu.style.display = 'none';
        specialRowContextMenu.style.display = 'none';
        cellContextMenu.style.display = 'none';
    }

    function changeCellValues(row) {
        const cells = row.querySelectorAll('td:not(:nth-child(1)):not(:nth-child(2)):not(:nth-child(3))');
        let total = 0;
        cells.forEach(cell => {
            if (cell.textContent === "0") {
                cell.textContent = "1";
                cell.classList.add('cell-active');
            } else {
                cell.textContent = "0";
                cell.classList.remove('cell-active');
            }
            total += parseInt(cell.textContent);
        });
        row.querySelector('td:nth-child(3)').textContent = total;
    }

    function generatePDF() {
        const { jsPDF } = window.jspdf;
        const doc = new jsPDF();
        const table = document.querySelector('table');

        // Extract table headers
        const headers = [];
        const thead = table.querySelector('thead');
        thead.querySelectorAll('tr').forEach(row => {
            const rowHeaders = [];
            row.querySelectorAll('th').forEach(th => {
                rowHeaders.push(th.textContent.trim());
            });
            headers.push(rowHeaders);
        });

        // Extract table body
        const body = [];
        const tbody = table.querySelector('tbody');
        tbody.querySelectorAll('tr').forEach(row => {
            const rowData = [];
            row.querySelectorAll('td').forEach(td => {
                rowData.push(td.textContent.trim());
            });
            body.push(rowData);
        });

        // Use autoTable to generate the PDF
        doc.autoTable({
            head: headers,
            body: body,
            startY: 10,
            theme: 'grid',
            styles: {
                fontSize: 8,
                cellPadding: 2,
                overflow: 'linebreak',
                halign: 'center',
                valign: 'middle'
            },
            headStyles: {
                fillColor: [240, 240, 240],
                textColor: [0, 0, 0],
                fontStyle: 'bold'
            },
            columnStyles: {
                0: { cellWidth: 'auto' },
                1: { cellWidth: 'auto' },
                2: { cellWidth: 'auto' }
            }
        });

        doc.save('tableau.pdf');
    }

    function showDeleteConfirmationModal() {
        $('#confirmationModal').modal('show');
    }

    function deleteRow() {
        if (currentContextRow) {
            currentContextRow.remove();
            hideContextMenus();
        }
    }

    function resetRow(row) {
        const cells = row.querySelectorAll('td:not(:nth-child(1)):not(:nth-child(2)):not(:nth-child(3))');
        let total = 0;
        cells.forEach(cell => {
            cell.textContent = "0";
            cell.classList.remove('cell-active');
            cell.style.backgroundColor = 'white';
        });
        row.querySelector('td:nth-child(3)').textContent = total;
    }

    window.onload = function() {
        createTable();

        const addRowButton = document.getElementById('addRowButton');
        addRowButton.addEventListener('click', addRow);

        const addRowContextButton = document.getElementById('addRowContext');
        addRowContextButton.addEventListener('click', function() {
            addRow({ target: currentContextRow });
            contextMenu.style.display = 'none';
        });

        const deleteRowButton = document.getElementById('deleteRow');
        deleteRowButton.addEventListener('click', showDeleteConfirmationModal);

        const deleteSpecialRowButton = document.getElementById('deleteSpecialRow');
        deleteSpecialRowButton.addEventListener('click', showDeleteConfirmationModal);

        const addRowAfterSpecialButton = document.getElementById('addRowAfterSpecial');
        addRowAfterSpecialButton.addEventListener('click', function() {
            addRow({ target: currentContextRow });
            specialRowContextMenu.style.display = 'none';
        });

        const changeColorRedButton = document.getElementById('changeColorRed');
        changeColorRedButton.addEventListener('click', function() {
            if (currentContextRow) {
                currentContextRow.style.backgroundColor = 'red';
                contextMenu.style.display = 'none';
            }
        });

        const changeColorGreenButton = document.getElementById('changeColorGreen');
        changeColorGreenButton.addEventListener('click', function() {
            if (currentContextRow) {
                currentContextRow.style.backgroundColor = 'green';
                contextMenu.style.display = 'none';
            }
        });

        const changeColorBlueButton = document.getElementById('changeColorBlue');
        changeColorBlueButton.addEventListener('click', function() {
            if (currentContextRow) {
                currentContextRow.style.backgroundColor = 'blue';
                contextMenu.style.display = 'none';
            }
        });

        const changeColorNoneButton = document.getElementById('changeColorNone');
        changeColorNoneButton.addEventListener('click', function() {
            if (currentContextRow) {
                currentContextRow.style.backgroundColor = '';
                contextMenu.style.display = 'none';
            }
        });

        const changeValuesButton = document.getElementById('changeValues');
        changeValuesButton.addEventListener('click', function() {
            if (currentContextRow) {
                changeCellValues(currentContextRow);
                contextMenu.style.display = 'none';
            }
        });

        const resetRowButton = document.getElementById('resetRow'); // Nouveau bouton
        resetRowButton.addEventListener('click', function() {
            if (currentContextRow) {
                resetRow(currentContextRow);
                contextMenu.style.display = 'none';
            }
        });

        const cellColorRedButton = document.getElementById('cellColorRed');
        cellColorRedButton.addEventListener('click', function() {
            if (targetCell && targetCell.textContent === "1") {
                targetCell.style.backgroundColor = 'red';
                cellContextMenu.style.display = 'none';
            }
        });

        const cellColorGreenButton = document.getElementById('cellColorGreen');
        cellColorGreenButton.addEventListener('click', function() {
            if (targetCell && targetCell.textContent === "1") {
                targetCell.style.backgroundColor = 'green';
                cellContextMenu.style.display = 'none';
            }
        });

        const cellColorBlueButton = document.getElementById('cellColorBlue');
        cellColorBlueButton.addEventListener('click', function() {
            if (targetCell && targetCell.textContent === "1") {
                targetCell.style.backgroundColor = 'blue';
                cellContextMenu.style.display = 'none';
            }
        });

        const cellColorYellowButton = document.getElementById('cellColorYellow');
        cellColorYellowButton.addEventListener('click', function() {
            if (targetCell && targetCell.textContent === "1") {
                targetCell.style.backgroundColor = 'yellow';
                cellContextMenu.style.display = 'none';
            }
        });

        const cellColorPurpleButton = document.getElementById('cellColorPurple');
        cellColorPurpleButton.addEventListener('click', function() {
            if (targetCell && targetCell.textContent === "1") {
                targetCell.style.backgroundColor = 'purple';
                cellContextMenu.style.display = 'none';
            }
        });

        document.getElementById('getDataButton').addEventListener('click', logTableData);
        document.getElementById('sendDataButton').addEventListener('click', sendTableData);
        document.getElementById('readDataButton').addEventListener('click', readTableData);
        document.getElementById('addSpecialRowButton').addEventListener('click', addSpecialRow);
        document.getElementById('generatePDFButton').addEventListener('click', generatePDF);

        // Add event listener for the Escape key
        document.addEventListener('keydown', function(event) {
            if (event.key === 'Escape') {
                hideContextMenus();
            }
        });

        // Add event listener for the confirmation button in the modal
        document.getElementById('confirmDeleteButton').addEventListener('click', function() {
            deleteRow();
            $('#confirmationModal').modal('hide');
        });

        // Add event listener for the DB button
        document.getElementById('dbButton').addEventListener('click', function() {
            fetch('votre_script_php.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ action: 'db_action' })
            })
            .then(response => response.json())
            .then(data => {
                alert(data.message);
            })
            .catch(error => {
                console.error('Erreur:', error);
            });
        });
    };

    function getTableData() {
        let rows = document.querySelectorAll('tbody tr');
        let tableData = [];
        rows.forEach(function(row) {
            let rowData = [];
            let cells = row.querySelectorAll('td');
            cells.forEach(function(cell) {
                if (cell.querySelector('select')) {
                    rowData.push(cell.querySelector('select').value);
                } else if (cell.querySelector('input')) {
                    rowData.push(cell.querySelector('input').value);
                } else {
                    rowData.push(cell.innerText);
                }
            });
            tableData.push(rowData);
        });
        return tableData;
    }

    function logTableData() {
        let data = getTableData();
        console.log(data);
        console.log(JSON.stringify(data, null, 2));
    }

    function sendTableData() {
        let data = getTableData();
        let jsonData = JSON.stringify(data);
        fetch('insert02.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: jsonData
        })
        .then(response => response.json())
        .then(data => {
            alert(data.message);
        })
        .catch(error => {
            console.error('Erreur:', error);
        });
    }

    function readTableData() {
        fetch('lecture.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            }
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                updateTable(data.data_json);
            } else {
                alert('Erreur lors de la récupération des données.');
            }
        })
        .catch(error => {
            console.error('Erreur:', error);
        });
    }

    function updateTable(data) {
        let tableData = JSON.parse(data);
        const tbody = document.getElementById("table-body");
        while (tbody.firstChild) {
            tbody.removeChild(tbody.firstChild);
        }
        tableData.forEach(rowData => {
            if (rowData.length === 1) {
                addSpecialRow();
                let specialRow = tbody.lastChild;
                specialRow.querySelector('input').value = rowData[0];
            } else {
                let row = document.createElement("tr");
                row.setAttribute('draggable', 'true');
                row.addEventListener('dragstart', handleDragStart);
                row.addEventListener('dragover', handleDragOver);
                row.addEventListener('drop', handleDrop);

                let inputCell = document.createElement("td");
                inputCell.classList.add('sticky-cell');
                let input = document.createElement("input");
                input.type = "text";
                input.value = rowData[0];
                input.addEventListener('click', function(event) {
                    event.stopPropagation();
                    input.focus();
                });
                input.addEventListener('keydown', function(event) {
                    if (event.key === 'Enter') {
                        input.blur();
                    }
                });
                inputCell.appendChild(input);
                inputCell.addEventListener('contextmenu', showContextMenu);
                row.appendChild(inputCell);

                let selectCell = document.createElement("td");
                let select = document.createElement("select");
                for (let j = 1; j <= 5; j++) {
                    let option = document.createElement("option");
                    option.textContent = j;
                    select.appendChild(option);
                }
                select.value = rowData[1];
                selectCell.appendChild(select);
                row.appendChild(selectCell);

                let totalCell = document.createElement("td");
                row.appendChild(totalCell);

                let total = 0;
                for (let j = 3; j < rowData.length; j++) {
                    let cell = document.createElement("td");
                    cell.textContent = rowData[j];
                    if (rowData[j] === "1") {
                        cell.classList.add('cell-active');
                    }
                    total += parseInt(rowData[j]);
                    cell.addEventListener('click', handleCellClick);
                    cell.addEventListener('contextmenu', showCellContextMenu);
                    row.appendChild(cell);
                }

                totalCell.textContent = total;
                tbody.appendChild(row);
            }
        });
    }

    // Workaround for Firefox sticky issue
    window.addEventListener('scroll', function() {
        const stickyCells = document.querySelectorAll('.sticky-cell');
        stickyCells.forEach(cell => {
            const rect = cell.getBoundingClientRect();
            if (rect.top <= 0) {
                cell.style.position = 'fixed';
                cell.style.top = '0';
            } else {
                cell.style.position = '';
            }
        });
    });
</script>
</body>
</html>