// Onglets, cartes Leaflet, fenêtre de choix de dossier, journal des traitements. (function () { "use strict"; // --- Onglets (#journees, #sources…) -------------------------------------- function afficherOnglet() { const liens = document.querySelectorAll(".onglets a"); if (!liens.length) return; const nom = (location.hash || liens[0].getAttribute("href")).slice(1); let trouve = false; liens.forEach(a => { const actif = a.getAttribute("href") === "#" + nom; a.classList.toggle("actif", actif); trouve = trouve || actif; }); if (!trouve) { liens[0].classList.add("actif"); } document.querySelectorAll(".onglet").forEach(s => { s.classList.toggle("actif", s.id === "onglet-" + (trouve ? nom : liens[0].getAttribute("href").slice(1))); }); document.querySelectorAll(".onglet.actif .carte").forEach(cadrer); } window.addEventListener("hashchange", afficherOnglet); document.addEventListener("DOMContentLoaded", afficherOnglet); // --- Cartes ----------------------------------------------------------------- // Une carte préparée dans un onglet caché n'a pas de taille : on la recadre // la première fois qu'elle devient visible. function cadrer(el) { if (!el._carte || !el.offsetWidth) return; el._carte.invalidateSize(); if (!el._cadree) { el._cadree = true; if (el._bornes) el._carte.fitBounds(el._bornes, { padding: [20, 20] }); else el._carte.setView([46.5, 2.5], 5); } } function initCartes(racine) { if (!window.L) return; racine.querySelectorAll(".carte[data-couches]").forEach(el => { if (el._carte) return; const carte = L.map(el, { scrollWheelZoom: false }); el._carte = carte; L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { maxZoom: 18, attribution: "© OpenStreetMap" }).addTo(carte); const groupe = L.featureGroup().addTo(carte); JSON.parse(el.dataset.couches).forEach(c => { c.segments.forEach(s => { L.polyline(s, { color: c.couleur, weight: 4, opacity: 0.85, dashArray: c.pointille ? "6 8" : null }) .bindTooltip(c.nom + (c.km ? " · " + c.km + " km" : ""), { sticky: true }) .addTo(groupe); }); }); el._bornes = groupe.getLayers().length ? groupe.getBounds() : null; carte.setView([46.5, 2.5], 5); cadrer(el); // La molette ne zoome qu'après un clic dans la carte (pas en faisant défiler la page). carte.on("click", () => carte.scrollWheelZoom.enable()); carte.on("mouseout", () => carte.scrollWheelZoom.disable()); }); } // --- Après chaque échange htmx -------------------------------------------- document.addEventListener("htmx:afterSettle", e => { initCartes(e.detail.elt.parentElement || document); document.querySelectorAll(".journal").forEach(j => { j.scrollTop = j.scrollHeight; }); }); document.addEventListener("DOMContentLoaded", () => { initCartes(document); document.querySelectorAll(".journal").forEach(j => { j.scrollTop = j.scrollHeight; }); }); // --- Fenêtre (choix de dossier) ------------------------------------------- function fermer() { document.getElementById("fenetre").innerHTML = ""; } document.addEventListener("click", e => { if (e.target.matches("[data-fermer-fond]")) fermer(); if (e.target.matches("[data-fermer]") && !e.target.hasAttribute("hx-post")) fermer(); }); document.addEventListener("htmx:afterRequest", e => { if (e.detail.elt.matches && e.detail.elt.matches("[data-fermer]") && e.detail.successful) fermer(); }); document.addEventListener("keydown", e => { if (e.key === "Escape") fermer(); }); // Les messages (erreurs) s'effacent d'eux-mêmes. document.addEventListener("htmx:afterSwap", e => { if (e.detail.target.id === "messages") { clearTimeout(window._rtgMessage); window._rtgMessage = setTimeout(() => { e.detail.target.innerHTML = ""; }, 6000); } }); })();