{# -*- mode: jinja-html -*- #}
<h1>{% if not read_only %}Édition des p{% else %}P{%endif%}artitions</h1>

<main>
	<div class="wait"></div>

	<section id="zonePartitions">
		<h2>Partitions et groupes</h2>
		<div>
			<label class="edition">
				<input type="checkbox" autocomplete="off">
				Modifier les partitions et groupes - tout s'enregistre automatiquement dès qu'il y a modification
			</label>
			<div class="filtres">
				<div class="partitions">
					<h3>Afficher les partitions</h3>
					<div></div>
				</div>
				<div class="masques">
					<h3>
						Afficher les étudiants affectés aux groupes<br>
						<small>Ne s'actualise pas automatiquement lors d'une modification</small>
					</h3>
					<div></div>
				</div>
			</div>
		</div>
	</section>

	<section id="zoneChoix">
		<h2>Etudiants</h2>
		<div class="etudiants"></div>
	</section>

	<section id="zoneGroupes">
		<h2>Groupes</h2>
		<div class="groupes"></div>
	</section>
</main>

<script>

	go();
	async function go() {
		document.querySelector('.wait').style.display = "";
		let params = (new URL(document.location)).searchParams;
		let formsemestre_id = params.get('formsemestre_id');

		let partitions = await fetchData("/ScoDoc/{{formsemestre.departement.acronym}}/api/formsemestre/" + formsemestre_id + "/partitions");
		let etudiants = await fetchData("/ScoDoc/{{formsemestre.departement.acronym}}/api/formsemestre/" + formsemestre_id + "/resultats");

		etudiants.sort((a, b) => {
			return a.nom_short.localeCompare(b.nom_short)
		})

		processDatas(partitions, etudiants);
		processEvents();

		document.querySelector('.wait').style.display = "none";
	}

	function fetchData(request) {
		return fetch(request)
			.then(r => { return r.json() })
			.then(data => {
				return data;
			}).catch(error => {
				document.querySelector("main").innerHTML = "<h2>Une erreur s'est produite lors du transfert des données.</h2>";
				throw 'Fin du script - données invalides';
			})
	}

	function processDatas(partitions, etudiants) {

		/* Filtres et groupes */
		let outputPartitions = "<div>";
		let outputMasques = "";
		let outputGroupes = "";
		let arrayPartitions = Object.values(partitions).sort((a, b) => {
			return a.numero - b.numero;
		})

		arrayPartitions.forEach((partition) => {
			// Filtres
			if (partition.groups_editable) {
				outputPartitions += `<div data-idpartition="${partition.id}"><span class="editing move">||</span><span>${partition.partition_name}</span><span class="editing modif">✏️</span><span class="editing suppr">❌</span></div>`;
			} else {
				outputPartitions += `<div data-idpartition="${partition.id}"><span>${partition.partition_name}</span></div>`;
			}

			outputMasques += `<div data-idpartition="${partition.id}"><div data-idpartition="${partition.id}" data-idgroupe=aucun>Non affectés - ${partition.partition_name}</div>`;

			// Groupes
			outputGroupes += `
				<div class=partition data-idpartition="${partition.id}">
					<h3>${partition.partition_name}</h3>
					<div class=groupe data-idgroupe=aucun>
						<div>Non affecté(s)</div>
						<div class=etudiants></div>
					</div>
					${(() => {
					let arrayGroups = Object.values(partition.groups).sort((a, b) => {
						return a.numero - b.numero;
					})
					let output = "";
					arrayGroups.forEach((groupe) => {
						/***************/
						if (partition.groups_editable) {
							outputMasques += `<div data-idgroupe="${groupe.id}"><span class="editing move">||</span><span>${groupe.group_name}</span><span class="editing modif">✏️</span><span class="editing suppr">❌</span></div>`;
						} else {
							outputMasques += `<div data-idgroupe="${groupe.id}"><span>${groupe.group_name}</span></div>`;
						}
						/***************/
						output += templateGroupe_zoneGroupes(groupe.id, groupe.group_name);
					})
					return output;
				})()}
				</div>`;
			outputMasques += `
					<div class="editing ajoutGroupe">+</div>
				</div>`;
		})
		document.querySelector(".filtres>.partitions>div").innerHTML = outputPartitions + `
				<div class="editing ajoutPartition">+</div>
			</div>`;
		document.querySelector(".filtres>.masques>div").innerHTML = outputMasques;
		document.querySelector("#zoneGroupes>.groupes").innerHTML = outputGroupes;


		/* Etudiants */
		output = "";
		etudiants.forEach(etudiant => {
			output += `
				<div>
					<div class=nom data-etudid="${etudiant.etudid}" data-nom="${etudiant.nom_disp}" data-prenom="${etudiant.prenom}">${etudiant.nom_disp} ${etudiant.prenom}<br><small>${etudiant.bac}</small></div>
					${(() => {
					let output = "<div class=grpPartitions>";
					arrayPartitions.forEach((partition) => {
						output += `
							<div class=partition data-idpartition="${partition.id}">
								<div>${partition.partition_name}</div>
								${(() => {
								let output = "";
								let affected = false;
								let arrayGroups = Object.values(partition.groups).sort((a, b) => {
									return a.numero - b.numero;
								})
								arrayGroups.forEach((groupe) => {
									output += `
										<label><input type=radio name="${partition.id}-${etudiant.etudid}" value="${groupe.id}" ${(etudiant.partitions[partition.id] == groupe.id) ? "checked" : ""}><span>${groupe.group_name}</span></label>`;

									if (etudiant.partitions[partition.id] == groupe.id) {
										affected = true;
										document.querySelector(`#zoneGroupes [data-idgroupe="${groupe.id}"]>.etudiants`).innerHTML += templateEtudiant_zoneGroupes(etudiant);
									}
								})
								if (!affected) {
									document.querySelector(`#zoneGroupes [data-idpartition="${partition.id}"]>[data-idgroupe="aucun"]>.etudiants`).innerHTML += templateEtudiant_zoneGroupes(etudiant);
								}
								return `<label title="Aucun groupe"><input type=radio name="${partition.id}-${etudiant.etudid}" value="aucun" ${(!affected) ? "checked" : ""}><span class=aucun> - </span></label>` + output;
							})()}
							</div>`;
					})
					return output + "</div>";
				})()}
				</div>`;
		})
		document.querySelector("#zoneChoix>.etudiants").innerHTML = output;
	}

	function templateGroupe_zoneGroupes(idGroupe, name) {
		return `<div class=groupe data-idgroupe="${idGroupe}">
					<div>${name}</div>
					<div class=etudiants></div>
				</div>`;
	}

	function templateEtudiant_zoneGroupes(etudiant) {
		return `<div data-etudid="${etudiant.etudid}" data-nom="${etudiant.nom_disp}" data-prenom="${etudiant.prenom}">${etudiant.nom_disp} ${etudiant.prenom}</div>`
	}

	/******************************/
	/* Gestionnaire d'événements  */
	/******************************/
	function setEditMode() {
		let editing = document.querySelector("[contentEditable=true]");
		if (!editing) {
			document.querySelector("body").classList.toggle("editionActivated");
			return;
		} 
		this.checked = true;
		if(!editing.classList.contains("highlight")) {
			editing.classList.add("highlight");
			setTimeout(()=>{editing.classList.remove("highlight")}, 1000);
		}
	}
	function processEvents() {
		/*--------------------*/
		/* Edition partitions */
		/*--------------------*/
		document.querySelector(".edition>input").addEventListener("input", setEditMode);
		document.querySelectorAll(".ajoutPartition, .ajoutGroupe").forEach(btnPlus => { btnPlus.addEventListener("click", addPartition) })
		document.querySelectorAll(".modif").forEach(btn => { btn.addEventListener("click", editText) })
		document.querySelectorAll(".suppr").forEach(btn => { btn.addEventListener("click", suppr) })
		document.querySelectorAll(".move").forEach(btn => { btn.addEventListener("mousedown", moveStart) })

		/*---------*/
		/* Filtres */
		/*---------*/
		document.querySelectorAll(".filtres>div>div>div>div:not(.editing)").forEach(btn => { btn.addEventListener("click", filtre) })

		/*--------------------*/
		/* Changement groupe  */
		/*--------------------*/
		document.querySelectorAll("label").forEach(btn => { btn.addEventListener("mousedown", (event) => { event.preventDefault() }) });
		document.querySelectorAll(".etudiants input").forEach(input => { input.addEventListener("input", assignment) })
	}

	/**********************/
	/* Filtrage           */
	/**********************/
	function filtre() {
		if (document.querySelector("body").classList.contains("editionActivated")) {
			return;
		}

		let nbUnselected = this.parentElement.querySelectorAll(".unselect").length;
		let nbBtn = this.parentElement.children.length;

		if (nbUnselected == 0) {
			Array.from(this.parentElement.children).forEach(e => {
				e.classList.toggle("unselect");
			})
		}
		this.classList.toggle("unselect");

		nbUnselected = this.parentElement.querySelectorAll(".unselect").length;
		if (nbUnselected == nbBtn) {
			Array.from(this.parentElement.children).forEach(e => {
				e.classList.toggle("unselect");
			})
		}

		if (!this.dataset.idgroupe) {
			// Partitions
			let groupesSelected = [];
			this.parentElement.querySelectorAll(":not(.unselect)").forEach(e => {
				groupesSelected.push(e.dataset.idpartition);
			})
			document.querySelectorAll(`
				.etudiants .partition[data-idpartition],
				#zoneGroupes [data-idpartition]
			`).forEach(e => {
				if (groupesSelected.includes(e.dataset.idpartition)) {
					e.classList.remove("hide")
				} else {
					e.classList.add("hide")
				}
			})
		} else {
			// Groupes
			let groupesSelected = {};

			this.parentElement.parentElement.querySelectorAll("[data-idgroupe]:not(.unselect)").forEach(e => {
				let idpartition = e.parentElement.dataset.idpartition;
				if (!groupesSelected[idpartition]) {
					groupesSelected[idpartition] = [];
				}
				groupesSelected[idpartition].push(e.dataset.idgroupe)
			})
			document.querySelectorAll("#zoneChoix .etudiants>div").forEach(e => {
				let found = true;
				Object.entries(groupesSelected).forEach(([idpartition, tabGroupes]) => {
					if (!tabGroupes.includes(
						e.querySelector(`[data-idpartition="${idpartition}"] input:checked`).value
					)
					) {
						found = false
					}
				})

				if (found) {
					e.classList.remove("hide")
				} else {
					e.classList.add("hide")
				}
			})
		}
	}
	/****************************/
	/* Affectation à un groupe  */
	/****************************/
	function assignment() {
		let groupe = this.parentElement.parentElement.parentElement.parentElement;
		let nom = groupe.children[0].dataset.nom;
		let prenom = groupe.children[0].dataset.prenom;
		let etudid = groupe.children[0].dataset.etudid;
		let idPartition = this.parentElement.parentElement.dataset.idpartition;
		let idGroupe = this.value;

		document.querySelector(`#zoneGroupes [data-idPartition="${idPartition}"] [data-etudid="${etudid}"]`).remove();

		let etudiant = {
			etudid: etudid,
			nom_disp: nom,
			prenom: prenom
		}

		let results = document.querySelector(`#zoneGroupes [data-idPartition="${idPartition}"] [data-idgroupe="${idGroupe}"]>.etudiants`);
		results.innerHTML += templateEtudiant_zoneGroupes(etudiant);

		/* Tri */
		let results2 = [...results.children];
		results2.sort((a, b) => {
			return (a.dataset.nom + a.dataset.prenom).localeCompare(b.dataset.nom + b.dataset.prenom)
		})
		results.innerHTML = "";
		results.append(...results2);

		/* Save */
		this.classList.add("saving");
		if (idGroupe == "aucun") {
			var url = `/ScoDoc/{{formsemestre.departement.acronym}}/api/partition/${idPartition}/remove_etudiant/${etudid}`;
		} else {
			var url = `/ScoDoc/{{formsemestre.departement.acronym}}/api/group/${idGroupe}/set_etudiant/${etudid}`
		}
		fetch(url, { method: "POST" })
			.then(r => { return r.json() })
			.then(r => {
				if (r.etudid == etudid) {
					this.classList.remove("saving");
					this.classList.add("saved");
					setTimeout(() => { this.classList.remove("saved") }, 800);
					return;
				}
				throw 'Les données retournées ne sont pas valides';
			})
			.catch(error => {
				document.querySelector("main").innerHTML = "<h2>Une erreur s'est produite lors de la sauvegarde des données.</h2>";
			})
	}


	/****************************/
	/* Ajout partition / groupe */
	/****************************/
	function addPartition() {
		let date = new Date;
		if (this.classList.contains("ajoutPartition")) {
			// Partition
			var name = "Nouvelle " + date.getSeconds();
			let params = (new URL(document.location)).searchParams;
			let formsemestre_id = params.get('formsemestre_id');
			var url = "/ScoDoc/{{formsemestre.departement.acronym}}/api/formsemestre/" + formsemestre_id + "/partition/create";
			var payload = { partition_name: name };
		} else {
			// Groupe
			var name = "Nouveau " + date.getSeconds();
			var url = `/ScoDoc/{{formsemestre.departement.acronym}}/api/partition/${this.parentElement.dataset.idpartition}/group/create`;
			var payload = { group_name: name };
		}
		var div = document.createElement("div");
		div.innerHTML = `
			<span class="editing move">||</span>
			<span>${name}</span>
			<span class="editing modif">✏️</span>
			<span class="editing suppr">❌</span>`;

		div.querySelector(".modif").addEventListener("click", editText);
		div.querySelector(".suppr").addEventListener("click", suppr);
		div.querySelector(".move").addEventListener("mousedown", moveStart);
		this.parentElement.insertBefore(div, this);

		div.querySelector(".modif").click();

		// Save
		fetch(url,
			{
				method: "POST",
				headers: {
					'Accept': 'application/json',
					'Content-Type': 'application/json'
				},
				body: JSON.stringify(payload)
			})
			.then(r => { return r.json() })
			.then(r => {
				if (r.message == "invalid partition_name" || r.message == "invalid group_name") {
					message("Le nom " + name + " existe déjà");
					div.remove();
					return;
				}
				if (this.classList.contains("ajoutPartition")) {
					div.dataset.idpartition = r.id;

					// Ajout dans la zone masques
					div = document.createElement("div");
					div.dataset.idpartition = r.id;
					div.innerHTML = `
						<div data-idpartition="${r.id}" data-idgroupe=aucun>Non affectés - ${name}</div>
						<div class="editing ajoutGroupe">+</div>`;

					div.querySelector("div").addEventListener("click", filtre);
					div.querySelector(".ajoutGroupe").addEventListener("click", addPartition);

					document.querySelector("#zonePartitions .masques>div").appendChild(div);

					// Ajout de la zone pour chaque étudiant
					let outputGroupes = "";

					document.querySelectorAll("#zoneChoix .grpPartitions").forEach(e => {
						let etudid = e.previousElementSibling.dataset.etudid;

						// Préparation pour la section suivante
						let etudiant = {
							etudid: etudid,
							nom_disp: e.previousElementSibling.dataset.nom,
							prenom: e.previousElementSibling.dataset.prenom
						}
						outputGroupes += templateEtudiant_zoneGroupes(etudiant);
						////////////////////////

						let div = document.createElement("div");
						div.className = "partition";
						div.dataset.idpartition = r.id;
						div.innerHTML = `
							<div>${name}</div>
							<label title="Aucun groupe">
								<input type="radio" name="${r.id}-${etudid}" value="aucun" checked>
								<span class="aucun">❌</span>
							</label>
						`;
						div.querySelector("input").addEventListener("input", assignment);
						e.appendChild(div);
					});

					// Ajout de la zone groupes
					document.querySelector("#zoneGroupes>.groupes").innerHTML += `
						<div class=partition data-idpartition="${r.id}">
							<h3>${name}</h3>
							<div class=groupe data-idgroupe=aucun>
								<div>Non affecté(s)</div>
								<div class=etudiants>${outputGroupes}</div>
							</div>
						</div>`;
				} else {
					div.dataset.idgroupe = r.id;

					// Ajout du bouton pour chaque étudiant
					let idpartition = this.parentElement.dataset.idpartition;
					document.querySelectorAll(`#zoneChoix .etudiants [data-idpartition="${idpartition}"]`).forEach(e => {
						let etudid = e.parentElement.parentElement.dataset.etudid;
						let label = document.createElement("label");
						label.innerHTML = `<input type=radio name="${idpartition}-${etudid}" value="${r.id}"><span>${name}</span>`;
						label.querySelector("input").addEventListener("input", assignment);
						e.appendChild(label);
					})

					// Ajout du groupe dans la zone Groupes
					document.querySelector(`#zoneGroupes .partition[data-idpartition="${idpartition}"]`).innerHTML += templateGroupe_zoneGroupes(r.id, name);
				}

			})
			.catch(error => {
				document.querySelector("main").innerHTML = "<h2>Une erreur s'est produite lors de la sauvegarde des données.</h2>";
			})
	}

	/********************/
	/* Edition du texte */
	/********************/
	function editText() {
		let e = this.previousElementSibling;
		e.classList.add("editingText");
		e.setAttribute("contenteditable", "true");
		e.addEventListener("keydown", writing);

		// On sélectionne la zone
		const range = document.createRange();
		const selection = window.getSelection();
		selection.removeAllRanges();
		range.selectNodeContents(e);
		selection.addRange(range);
	}

	function writing(event) {
		switch (event.key) {
			case 'Enter':
				saveEditing(this);
				event.preventDefault();
				break;
			case 'Escape':
				saveEditing(this);
				event.preventDefault();
				break;
		}
	}

	function saveEditing(obj) {
		obj.classList.remove("editingText");
		obj.setAttribute("contenteditable", "false");
		obj.removeEventListener("keydown", writing);

		// Save
		if (obj.parentElement.dataset.idpartition) {
			var url = `/ScoDoc/{{formsemestre.departement.acronym}}/api/partition/${obj.parentElement.dataset.idpartition}/edit`;
			var payload = { partition_name: obj.innerText }

			document.querySelector(`.masques [data-idpartition="${obj.parentElement.dataset.idpartition}"][data-idgroupe="aucun"]`).innerText = "Non affectés - " + obj.innerText;
			document.querySelectorAll(`#zoneChoix .etudiants [data-idpartition="${obj.parentElement.dataset.idpartition}"]>div`).forEach(e => { e.innerText = obj.innerText });
			document.querySelector(`#zoneGroupes [data-idpartition="${obj.parentElement.dataset.idpartition}"]>h3`).innerText = obj.innerText;
		} else {
			var url = `/ScoDoc/{{formsemestre.departement.acronym}}/api/group/${obj.parentElement.dataset.idgroupe}/edit`;
			var payload = { group_name: obj.innerText }

			document.querySelectorAll(`#zoneChoix .etudiants [value="${obj.parentElement.dataset.idgroupe}"]+span`).forEach(e => { e.innerText = obj.innerText });
			document.querySelector(`#zoneGroupes [data-idgroupe="${obj.parentElement.dataset.idgroupe}"]>div`).innerText = obj.innerText;
		}

		fetch(url,
			{
				method: "POST",
				headers: {
					'Accept': 'application/json',
					'Content-Type': 'application/json'
				},
				body: JSON.stringify(payload)
			})
			.then(r => { return r.json() })
			.then(r => {
				if (!r) {
					document.querySelector("main").innerHTML = "<h2>Une erreur s'est produite lors de la sauvegarde des données.</h2>";
				}
			})
			.catch(error => {
				document.querySelector("main").innerHTML = "<h2>Une erreur s'est produite lors de la sauvegarde des données.</h2>";
			})
	}

	/*********************************/
	/* Suppression parcours / groupe */
	/*********************************/
	function suppr() {
		if (this.parentElement.dataset.idpartition) {
			var data = `data-idpartition="${this.parentElement.dataset.idpartition}"`;
		} else {
			var data = `data-idgroupe="${this.parentElement.dataset.idgroupe}"`;
		}
		let div = document.createElement("div");
		div.className = "confirm";
		div.innerHTML = `
			<div>
				<h1>Vous être sur le point de supprimer <span>${this.previousElementSibling.previousElementSibling.innerText}</span>,<br>cette opération est irréversible</h1>
				<div>
					<div class="ok" ${data}>Supprimer</div>
					<div class="nok">Annuler</div>
				</div>
			</div>
		`;
		document.body.append(div);
		document.querySelector(".ok").addEventListener("click", supprConfirmed);
		document.querySelector(".nok").addEventListener("click", closeConfirm);
	}

	function supprConfirmed() {
		closeConfirm();
		/* Suppression des éléments dans la page */
		if (this.dataset.idpartition) {
			document.querySelectorAll(`[data-idpartition="${this.dataset.idpartition}"]`).forEach(e => { e.remove() })
			var url = "/ScoDoc/{{formsemestre.departement.acronym}}/api/partition/" + this.dataset.idpartition + "/delete";
		} else {
			document.querySelectorAll(`[value="${this.dataset.idgroupe}"]`).forEach(e => {
				if (e.checked == true) {
					e.parentElement.parentElement.querySelector("label").click()
				}
				e.parentElement.remove()
			})
			document.querySelectorAll(`[data-idgroupe="${this.dataset.idgroupe}"]`).forEach(e => { e.remove() })
			var url = "/ScoDoc/{{formsemestre.departement.acronym}}/api/group/" + this.dataset.idgroupe + "/delete";
		}

		//Save
		fetch(url, { method: "POST" })
			.then(r => { return r.json() })
			.then(r => {
				if (r.OK != true) {
					document.querySelector("main").innerHTML = "<h2>Une erreur s'est produite lors de la sauvegarde des données.</h2>";
				}
			})
	}

	function closeConfirm() {
		document.querySelector(".confirm").remove();
	}

	/*************************/
	/* Changement de l'ordre */
	/*************************/
	let moveData = {};
	function moveStart(event) {
		moveData.x = event.pageX;
		moveData.y = event.pageY;
		moveData.element = this.parentElement;
		moveData.element.classList.add("moving");
		moveData.element.parentElement.classList.add('grabbing');
		document.body.addEventListener("mousemove", move);
		moveData.element.parentElement.querySelectorAll("div:not([data-idgroupe=aucun])").forEach(e => {
			e.addEventListener("mouseup", newPosition)
		})
		document.body.addEventListener("mouseup", moveEnd);
	}

	function move(event) {
		event.preventDefault();
		moveData.element.style.transform = `translate(${event.pageX - moveData.x}px,  ${event.pageY - moveData.y}px)`
	}

	function moveEnd() {
		document.body.removeEventListener("mousemove", move);
		document.body.removeEventListener("mouseup", moveEnd);
		moveData.element.parentElement.classList.remove('grabbing');
		moveData.element.style.transform = "";
		moveData.element.classList.remove("moving");
		moveData.element.parentElement.querySelectorAll("div:not([data-idgroupe=aucun])").forEach(e => {
			e.removeEventListener("mouseup", newPosition)
		})
		moveData = {};
	}

	function newPosition() {
		moveData.element.parentElement.insertBefore(moveData.element, this);

		let positions = [];
		Array.from(moveData.element.parentElement.children).forEach(e => {
			if ((e.dataset.idpartition && e.dataset.idgroupe != "aucun") || (e.dataset.idgroupe && e.dataset.idgroupe != "aucun")) {
				positions.push(parseInt(e.dataset.idgroupe || e.dataset.idpartition))
			}
		})

		// Save positions
		if (this.parentElement.parentElement.parentElement.className == "partitions") {
			let params = (new URL(document.location)).searchParams;
			let formsemestre_id = params.get('formsemestre_id');
			var url = `/ScoDoc/{{formsemestre.departement.acronym}}/api/formsemestre/${formsemestre_id}/partitions/order`;

			document.querySelectorAll(`#zonePartitions .masques>div`).forEach(parent => {
				positions.forEach(position => {
					parent.append(parent.querySelector(`[data-idpartition="${position}"]`))
				})
			})
			document.querySelectorAll(`#zoneChoix .grpPartitions`).forEach(parent => {
				positions.forEach(position => {
					parent.append(parent.querySelector(`[data-idpartition="${position}"]`))
				})
			})
			document.querySelectorAll(`#zoneGroupes>.groupes`).forEach(parent => {
				positions.forEach(position => {
					parent.append(parent.querySelector(`[data-idpartition="${position}"]`))
				})
			})
		} else {
			var url = `/ScoDoc/{{formsemestre.departement.acronym}}/api/partition/${this.parentElement.dataset.idpartition}/groups/order`;

			document.querySelectorAll(`#zoneChoix .etudiants .partition[data-idpartition="${this.parentElement.dataset.idpartition}"]`).forEach(partition => {
				positions.forEach(position => {
					partition.append(partition.querySelector(`[value="${position}"]`).parentElement)
				})
			})
			document.querySelectorAll(`#zoneGroupes .partition[data-idpartition="${this.parentElement.dataset.idpartition}"]`).forEach(partition => {
				positions.forEach(position => {
					partition.append(partition.querySelector(`[data-idgroupe="${position}"]`))
				})
			})
		}

		fetch(url,
			{
				method: "POST",
				headers: {
					'Accept': 'application/json',
					'Content-Type': 'application/json'
				},
				body: JSON.stringify(positions)
			})
			.then(r => { return r.json() })
			.then(r => {
				if (!r) {
					document.querySelector("main").innerHTML = "<h2>Une erreur s'est produite lors de la sauvegarde des données.</h2>";
				}
			})
			.catch(error => {
				document.querySelector("main").innerHTML = "<h2>Une erreur s'est produite lors de la sauvegarde des données.</h2>";
			})

	}

	/*************************/
	/* Message               */
	/*************************/

	function message(msg) {
		var div = document.createElement("div");
		div.className = "message_curtom";
		div.innerHTML = msg;
		document.querySelector("body").appendChild(div);
		setTimeout(() => {
			div.remove();
		}, 3000);
	}

</script>