2021-11-13 09:11:00 +01:00
|
|
|
/* table_editor, par Sébastien L. 2021-11-12
|
2021-11-12 22:17:46 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*****************************/
|
|
|
|
/* Mise en place des données */
|
|
|
|
/*****************************/
|
2022-04-22 14:15:32 +02:00
|
|
|
let lastX;
|
|
|
|
let lastY;
|
|
|
|
|
2021-11-12 22:17:46 +01:00
|
|
|
function build_table(data) {
|
2023-11-17 13:53:17 +01:00
|
|
|
let output = "";
|
|
|
|
let sumsUE = {};
|
|
|
|
let sumsRessources = {};
|
|
|
|
let value;
|
|
|
|
|
|
|
|
data.forEach((cellule) => {
|
|
|
|
output += `
|
|
|
|
<div
|
2021-11-13 09:11:00 +01:00
|
|
|
class="${cellule.style || ""}"
|
2021-11-12 22:17:46 +01:00
|
|
|
data-editable="${cellule.editable || "false"}"
|
|
|
|
data-module_id="${cellule.module_id}"
|
|
|
|
data-ue_id="${cellule.ue_id}"
|
2021-11-13 09:11:00 +01:00
|
|
|
data-x="${cellule.x}"
|
|
|
|
data-y="${cellule.y}"
|
|
|
|
data-nbX="${cellule.nbX || 1}"
|
|
|
|
data-nbY="${cellule.nbY || 1}"
|
|
|
|
data-data="${cellule.data}"
|
2021-11-13 09:43:13 +01:00
|
|
|
data-orig="${cellule.data}"
|
2022-03-17 15:53:24 +01:00
|
|
|
title="${cellule.title || ""}"
|
2021-11-12 22:17:46 +01:00
|
|
|
style="
|
|
|
|
--x:${cellule.x};
|
|
|
|
--y:${cellule.y};
|
2021-11-13 09:11:00 +01:00
|
|
|
--nbX:${cellule.nbX || 1};
|
|
|
|
--nbY: ${cellule.nbY || 1};
|
2022-07-04 16:42:10 +02:00
|
|
|
">${cellule.data}</div>`; // ne pas mettre d'espace car c'est utilisé par :not(:empty) après
|
2022-10-31 11:44:22 +01:00
|
|
|
|
2023-11-17 13:53:17 +01:00
|
|
|
if (cellule.style.includes("champs")) {
|
|
|
|
if (cellule.editable == true && cellule.data) {
|
|
|
|
value = parseFloat(cellule.data) * 100;
|
|
|
|
} else {
|
|
|
|
value = 0;
|
|
|
|
}
|
|
|
|
sumsRessources[cellule.y] = (sumsRessources[cellule.y] ?? 0) + value;
|
|
|
|
sumsUE[cellule.x] = (sumsUE[cellule.x] ?? 0) + value;
|
|
|
|
}
|
|
|
|
});
|
2022-04-22 14:15:32 +02:00
|
|
|
|
2023-11-17 13:53:17 +01:00
|
|
|
output += showSums(sumsRessources, sumsUE);
|
|
|
|
document.querySelector(".tableau").innerHTML = output;
|
|
|
|
installListeners();
|
2021-11-13 09:11:00 +01:00
|
|
|
}
|
|
|
|
|
2022-04-22 14:15:32 +02:00
|
|
|
function showSums(sumsRessources, sumsUE) {
|
2023-11-17 13:53:17 +01:00
|
|
|
lastX = Object.keys(sumsUE).length + 2;
|
|
|
|
lastY = Object.keys(sumsRessources).length + 2;
|
2022-04-22 14:15:32 +02:00
|
|
|
|
2023-11-17 13:53:17 +01:00
|
|
|
let output = "";
|
2022-04-22 14:15:32 +02:00
|
|
|
|
2023-11-17 13:53:17 +01:00
|
|
|
Object.entries(sumsUE).forEach(([num, value]) => {
|
|
|
|
output += `
|
|
|
|
<div
|
2022-04-22 14:15:32 +02:00
|
|
|
class="sums"
|
|
|
|
data-editable="false"
|
|
|
|
data-x="${num}"
|
|
|
|
data-y="${lastY}"
|
|
|
|
style="
|
|
|
|
--x:${num};
|
|
|
|
--y:${lastY};
|
|
|
|
--nbX:1;
|
|
|
|
--nbY:1;
|
|
|
|
">
|
2023-12-06 18:57:07 +01:00
|
|
|
${(value / 100).toLocaleString(undefined, {
|
|
|
|
minimumFractionDigits: 0,
|
|
|
|
maximumFractionDigits: 2,
|
|
|
|
})}
|
2022-04-22 14:15:32 +02:00
|
|
|
</div>`;
|
2023-11-17 13:53:17 +01:00
|
|
|
});
|
2022-04-22 14:15:32 +02:00
|
|
|
|
2023-11-17 13:53:17 +01:00
|
|
|
Object.entries(sumsRessources).forEach(([num, value]) => {
|
|
|
|
output += `
|
|
|
|
<div
|
2022-04-22 14:15:32 +02:00
|
|
|
class="sums"
|
|
|
|
data-editable="false"
|
|
|
|
data-x="${lastX}"
|
|
|
|
data-y="${num}"
|
|
|
|
style="
|
|
|
|
--x:${lastX};
|
|
|
|
--y:${num};
|
|
|
|
--nbX:1;
|
|
|
|
--nbY:1;
|
|
|
|
">
|
2023-12-06 18:57:07 +01:00
|
|
|
${(value / 100).toLocaleString(undefined, {
|
|
|
|
minimumFractionDigits: 0,
|
|
|
|
maximumFractionDigits: 2,
|
|
|
|
})}
|
2022-04-22 14:15:32 +02:00
|
|
|
</div>`;
|
2023-11-17 13:53:17 +01:00
|
|
|
});
|
2022-04-22 14:15:32 +02:00
|
|
|
|
2023-11-17 13:53:17 +01:00
|
|
|
return output;
|
2022-04-22 14:15:32 +02:00
|
|
|
}
|
|
|
|
|
2021-11-13 09:11:00 +01:00
|
|
|
/*****************************/
|
|
|
|
/* Gestion des évènements */
|
|
|
|
/*****************************/
|
2022-03-15 23:09:41 +01:00
|
|
|
|
2021-11-13 09:11:00 +01:00
|
|
|
function installListeners() {
|
2023-11-17 13:53:17 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2021-11-13 09:11:00 +01:00
|
|
|
});
|
2023-11-17 13:53:17 +01:00
|
|
|
cellule.addEventListener("input", processSums);
|
|
|
|
});
|
2021-11-13 09:11:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************/
|
|
|
|
/* Interaction avec les cellules */
|
|
|
|
/*********************************/
|
|
|
|
function selectCell(obj) {
|
2023-11-17 13:53:17 +01:00
|
|
|
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;
|
2021-11-13 09:11:00 +01:00
|
|
|
}
|
2023-11-17 13:53:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
document.querySelectorAll(".selected, .modifying").forEach((cellule) => {
|
|
|
|
cellule.classList.remove("selected", "modifying");
|
|
|
|
cellule.removeAttribute("contentEditable");
|
|
|
|
cellule.removeEventListener("keydown", keyCell);
|
|
|
|
});
|
|
|
|
obj.classList.add("selected");
|
2021-11-13 09:11:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function modifCell(obj) {
|
2023-11-17 13:53:17 +01:00
|
|
|
if (obj) {
|
|
|
|
obj.classList.add("modifying");
|
|
|
|
obj.contentEditable = true;
|
|
|
|
obj.addEventListener("keydown", keyCell);
|
|
|
|
obj.focus();
|
|
|
|
}
|
2021-11-13 09:11:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function key(event) {
|
2023-11-17 13:53:17 +01:00
|
|
|
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;
|
|
|
|
}
|
2021-11-13 09:11:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function ArrowMove(x, y) {
|
2023-11-17 13:53:17 +01:00
|
|
|
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);
|
|
|
|
}
|
2021-11-13 09:11:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function keyCell(event) {
|
2023-11-17 13:53:17 +01:00
|
|
|
if (event.key == "Enter") {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
if (!save(this)) {
|
|
|
|
return;
|
2021-11-13 09:11:00 +01:00
|
|
|
}
|
2023-11-17 13:53:17 +01:00
|
|
|
this.classList.remove("modifying");
|
|
|
|
let selected = document.querySelector(".selected");
|
|
|
|
ArrowMove(0, 1);
|
|
|
|
if (selected != document.querySelector(".selected")) {
|
|
|
|
modifCell(document.querySelector(".selected"));
|
|
|
|
}
|
|
|
|
}
|
2021-11-13 09:11:00 +01:00
|
|
|
}
|
|
|
|
|
2022-04-22 14:15:32 +02:00
|
|
|
function processSums() {
|
2023-11-17 13:53:17 +01:00
|
|
|
let sum = 0;
|
|
|
|
document
|
|
|
|
.querySelectorAll(
|
|
|
|
`[data-editable="true"][data-x="${this.dataset.x}"]:not(:empty)`
|
|
|
|
)
|
|
|
|
.forEach((e) => {
|
|
|
|
let val = parseFloat(e.innerText);
|
|
|
|
if (!isNaN(val)) {
|
|
|
|
sum += val * 100;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
document.querySelector(
|
|
|
|
`.sums[data-x="${this.dataset.x}"][data-y="${lastY}"]`
|
2023-12-06 18:57:07 +01:00
|
|
|
).innerText = (sum / 100).toLocaleString(undefined, {
|
|
|
|
minimumFractionDigits: 0,
|
|
|
|
maximumFractionDigits: 2,
|
|
|
|
});
|
2023-11-17 13:53:17 +01:00
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
document
|
|
|
|
.querySelectorAll(
|
|
|
|
`[data-editable="true"][data-y="${this.dataset.y}"]:not(:empty)`
|
|
|
|
)
|
|
|
|
.forEach((e) => {
|
|
|
|
let val = parseFloat(e.innerText);
|
|
|
|
if (!isNaN(val)) {
|
|
|
|
sum += val * 100;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
document.querySelector(
|
|
|
|
`.sums[data-x="${lastX}"][data-y="${this.dataset.y}"]`
|
2023-12-06 18:57:07 +01:00
|
|
|
).innerText = (sum / 100).toLocaleString(undefined, {
|
|
|
|
minimumFractionDigits: 0,
|
|
|
|
maximumFractionDigits: 2,
|
|
|
|
});
|
2022-04-22 14:15:32 +02:00
|
|
|
}
|
|
|
|
|
2021-11-13 09:11:00 +01:00
|
|
|
/******************************/
|
|
|
|
/* Affichage d'un message */
|
|
|
|
/******************************/
|
|
|
|
function message(msg) {
|
2023-11-17 13:53:17 +01:00
|
|
|
var div = document.createElement("div");
|
|
|
|
div.className = "message";
|
|
|
|
div.innerHTML = msg;
|
|
|
|
document.querySelector("body").appendChild(div);
|
|
|
|
setTimeout(() => {
|
|
|
|
div.remove();
|
|
|
|
}, 3000);
|
2021-11-13 09:11:00 +01:00
|
|
|
}
|