/* table_editor, par Sébastien L. 2021-11-12 */ /*****************************/ /* Mise en place des données */ /*****************************/ let lastX; let lastY; function build_table(data) { let output = ""; let sumsUE = {}; let sumsRessources = {}; data.forEach((cellule) => { output += ` <div class="${cellule.style || ""}" data-editable="${cellule.editable || "false"}" data-module_id="${cellule.module_id}" data-ue_id="${cellule.ue_id}" data-x="${cellule.x}" data-y="${cellule.y}" data-nbX="${cellule.nbX || 1}" data-nbY="${cellule.nbY || 1}" data-data="${cellule.data}" data-orig="${cellule.data}" title="${cellule.title || ""}" style=" --x:${cellule.x}; --y:${cellule.y}; --nbX:${cellule.nbX || 1}; --nbY: ${cellule.nbY || 1}; "> ${cellule.data} </div>`; if (cellule.editable) { sumsRessources[cellule.y] = (sumsRessources[cellule.y] ?? 0) + (parseFloat(cellule.data) || 0); sumsUE[cellule.x] = (sumsUE[cellule.x] ?? 0) + (parseFloat(cellule.data) || 0); } }) output += showSums(sumsRessources, sumsUE); document.querySelector(".tableau").innerHTML = output; installListeners(); } function showSums(sumsRessources, sumsUE) { lastX = Object.keys(sumsUE).length + 2; lastY = Object.keys(sumsRessources).length + 2; let output = ""; Object.entries(sumsUE).forEach(([num, value]) => { output += ` <div class="sums" data-editable="false" data-x="${num}" data-y="${lastY}" style=" --x:${num}; --y:${lastY}; --nbX:1; --nbY:1; "> ${value} </div>`; }) Object.entries(sumsRessources).forEach(([num, value]) => { output += ` <div class="sums" data-editable="false" data-x="${lastX}" data-y="${num}" style=" --x:${lastX}; --y:${num}; --nbX:1; --nbY:1; "> ${value} </div>`; }) return output; } /*****************************/ /* Gestion des évènements */ /*****************************/ function installListeners() { if (read_only) { return; } document.body.addEventListener("keydown", key); document.querySelectorAll("[data-editable=true]").forEach(cellule => { cellule.addEventListener("click", function () { selectCell(this) }); cellule.addEventListener("dblclick", function () { modifCell(this) }); cellule.addEventListener("blur", function () { let currentModif = document.querySelector(".modifying"); if (currentModif) { if (!save(currentModif)) { return; } } }); cellule.addEventListener("input", processSums); }); } /*********************************/ /* Interaction avec les cellules */ /*********************************/ function selectCell(obj) { if (obj.classList.contains("modifying")) { return; // Cellule en cours de modification, ne pas sélectionner. } let currentModif = document.querySelector(".modifying"); if (currentModif) { if (!save(currentModif)) { return; } } document.querySelectorAll(".selected, .modifying").forEach(cellule => { cellule.classList.remove("selected", "modifying"); cellule.removeAttribute("contentEditable"); cellule.removeEventListener("keydown", keyCell); }) obj.classList.add("selected"); } function modifCell(obj) { if (obj) { obj.classList.add("modifying"); obj.contentEditable = true; obj.addEventListener("keydown", keyCell); obj.focus(); } } function key(event) { switch (event.key) { case "Enter": modifCell(document.querySelector(".selected")); event.preventDefault(); break; case "ArrowRight": ArrowMove(1, 0); break; case "ArrowLeft": ArrowMove(-1, 0); break; case "ArrowUp": ArrowMove(0, -1); break; case "ArrowDown": ArrowMove(0, 1); break; } } function ArrowMove(x, y) { if (document.querySelector(".modifying") || !document.querySelector(".selected")) { return; // S'il n'y a aucune cellule selectionnée ou si une cellule est encours de modification, on ne change pas } let selected = document.querySelector(".selected"); let next = document.querySelector(`[data-x="${parseInt(selected.dataset.x) + x}"][data-y="${parseInt(selected.dataset.y) + y}"][data-editable="true"]`); if (next) { selectCell(next); } } function keyCell(event) { if (event.key == "Enter") { event.preventDefault(); event.stopPropagation(); if (!save(this)) { return } this.classList.remove("modifying"); let selected = document.querySelector(".selected"); ArrowMove(0, 1); if (selected != document.querySelector(".selected")) { modifCell(document.querySelector(".selected")); } } } function processSums() { let sum = 0; document.querySelectorAll(`[data-editable="true"][data-x="${this.dataset.x}"]`).forEach(e => { sum += parseFloat(e.innerText) || 0; }) document.querySelector(`.sums[data-x="${this.dataset.x}"][data-y="${lastY}"]`).innerText = sum; sum = 0; document.querySelectorAll(`[data-editable="true"][data-y="${this.dataset.y}"]`).forEach(e => { sum += parseFloat(e.innerText) || 0; }) document.querySelector(`.sums[data-x="${lastX}"][data-y="${this.dataset.y}"]`).innerText = sum; } /******************************/ /* Affichage d'un message */ /******************************/ function message(msg) { var div = document.createElement("div"); div.className = "message"; div.innerHTML = msg; document.querySelector("body").appendChild(div); setTimeout(() => { div.remove(); }, 3000); }