/* 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 += `
${cellule.data}
`; if (cellule.editable && cellule.data) { sumsRessources[cellule.y] = (sumsRessources[cellule.y] ?? 0) + parseInt(cellule.data); sumsUE[cellule.x] = (sumsUE[cellule.x] ?? 0) + parseInt(cellule.data); } }) 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 += `
${value}
`; }) Object.entries(sumsRessources).forEach(([num, value]) => { output += `
${value}
`; }) 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 += parseInt(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 += parseInt(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); }