File "stable034.html"

Full Path: /home/analogde/www/Dev tableau/stable034.html
File size: 20.09 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;
            max-height: 400px; /* Ajout de la hauteur maximale */
        }
        th:nth-child(n+1):nth-child(-n+3), td:nth-child(n+1):nth-child(-n+3) {
            position: sticky;
            z-index: 4;
            background: white;
            border-right: 2px solid black;
        }
        th:nth-child(1), td:nth-child(1) {
            left: 0;
            width: 210px;
            min-width: 210px;
            max-width: 210px;
        }
        th:nth-child(2), td:nth-child(2) {
            left: 210px;
            width: 80px;
            min-width: 80px;
            max-width: 80px;
        }
        th:nth-child(3), td:nth-child(3) {
            left: 290px;
            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" class="sticky-row">
                <th></th>
                <th></th>
                <th>Jours</th>
            </tr>
            <tr id="month-row" class="sticky-row">
                <th class="unused-cell"></th>
                <th></th>
                <th class="unused-cell">Mois</th>
            </tr>
            <tr id="day-row" class="sticky-row">
                <th class="unused-cell"></th>
                <th></th>
                <th class="unused-cell">Semaine</th>
            </tr>
            <tr id="numero-row" class="sticky-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>

<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");
        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);
        }
    }

    function addSpecialRow()
    {
    }

    function toggleCollapse(row)
    {

    }

    function handleDragStart(event)
    {

    }

    function handleDragOver(event)
    {

    }

    function handleDrop(event)
    {

    }

    function handleCellClick(event)
    {

    }

    function showContextMenu(event)
    {

    }

    function showCellContextMenu(event)
    {

    }

    function hideContextMenus()
    {

    }

    function changeCellValues(row)
    {

    }

    function generatePDF()
    {

    }

    function showDeleteConfirmationModal()
    {
    }

    function deleteRow()
    {

    }

    function resetRow(row)
    {

    }

    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() {
        });

        const changeColorRedButton = document.getElementById('changeColorRed');
        changeColorRedButton.addEventListener('click', function() {
        });

        const changeColorGreenButton = document.getElementById('changeColorGreen');
        changeColorGreenButton.addEventListener('click', function() {

        });

        const changeColorBlueButton = document.getElementById('changeColorBlue');
        changeColorBlueButton.addEventListener('click', function() {

        });

        const changeColorNoneButton = document.getElementById('changeColorNone');
        changeColorNoneButton.addEventListener('click', function() {
        });

        const changeValuesButton = document.getElementById('changeValues');
        changeValuesButton.addEventListener('click', function() {
        });

        const resetRowButton = document.getElementById('resetRow'); // Nouveau bouton
        resetRowButton.addEventListener('click', function() {
        });

        const cellColorRedButton = document.getElementById('cellColorRed');
        cellColorRedButton.addEventListener('click', function() {
        });

        const cellColorGreenButton = document.getElementById('cellColorGreen');
        cellColorGreenButton.addEventListener('click', function() {
        });

        const cellColorBlueButton = document.getElementById('cellColorBlue');
        cellColorBlueButton.addEventListener('click', function() {
        });

        const cellColorYellowButton = document.getElementById('cellColorYellow');
        cellColorYellowButton.addEventListener('click', function() {
        });

        const cellColorPurpleButton = document.getElementById('cellColorPurple');
        cellColorPurpleButton.addEventListener('click', function() {
        });

        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() {

        });

        // Add event listener for the DB button
        document.getElementById('dbButton').addEventListener('click', function()
        {

        });

        // Check table height and adjust scrollbar visibility
        const tableContainer = document.querySelector('.table-container');
        const table = tableContainer.querySelector('table');
        if (table.clientHeight > 400) {
            tableContainer.style.overflowY = 'scroll';
        } else {
            tableContainer.style.overflowY = 'hidden';
        }
    };

    function getTableData()
    {

    }

    function logTableData()
    {
    }

    function sendTableData() {

    }

    function readTableData() {

    }

    function updateTable(data)
    {

    }
</script>
</body>
</html>