Files
mont_vendor_maps/static/js/admin.js

93 lines
3.2 KiB
JavaScript

(function () {
const matrixForm = document.getElementById("matrixForm");
const matrixScroll = document.getElementById("matrixScroll");
const matrixTable = document.getElementById("matrixTable");
const topScroll = document.getElementById("matrixHScroll");
const topScrollInner = document.getElementById("matrixHScrollInner");
if (!matrixForm || !matrixScroll || !matrixTable || !topScroll || !topScrollInner) return;
let isDirty = false;
let syncing = false;
let saveTimer = null;
let saveInFlight = false;
function markDirty() {
isDirty = true;
}
function updateTopScrollWidth() {
topScrollInner.style.width = matrixTable.scrollWidth + "px";
}
function syncScrollFromTop() {
if (syncing) return;
syncing = true;
matrixScroll.scrollLeft = topScroll.scrollLeft;
syncing = false;
}
function syncScrollFromMatrix() {
if (syncing) return;
syncing = true;
topScroll.scrollLeft = matrixScroll.scrollLeft;
syncing = false;
}
async function autoSaveMatrix() {
if (saveInFlight) return;
saveInFlight = true;
try {
const formData = new FormData(matrixForm);
const response = await fetch(window.location.href, {
method: "POST",
body: formData,
credentials: "same-origin",
});
if (!response.ok) throw new Error("save failed");
isDirty = false;
} catch (error) {
} finally {
saveInFlight = false;
}
}
matrixForm.addEventListener("change", (event) => {
if (!(event.target && event.target.matches('input[type="checkbox"]'))) return;
markDirty();
if (saveTimer) clearTimeout(saveTimer);
saveTimer = setTimeout(autoSaveMatrix, 250);
});
matrixForm.addEventListener("submit", () => {
isDirty = false;
});
window.addEventListener("beforeunload", (event) => {
if (!isDirty) return;
event.preventDefault();
event.returnValue = "";
});
document.addEventListener("click", (event) => {
const anchor = event.target.closest("a");
if (!anchor || !isDirty) return;
const ok = window.confirm("Есть несохраненные изменения матрицы. Нажмите OK, чтобы остаться и сначала сохранить.");
if (!ok) return;
event.preventDefault();
});
document.addEventListener("submit", (event) => {
const form = event.target;
if (!form || form === matrixForm || !isDirty) return;
const ok = window.confirm("Есть несохраненные изменения матрицы. Нажмите OK, чтобы остаться и сначала сохранить.");
if (!ok) return;
event.preventDefault();
});
topScroll.addEventListener("scroll", syncScrollFromTop);
matrixScroll.addEventListener("scroll", syncScrollFromMatrix);
window.addEventListener("resize", updateTopScrollWidth);
updateTopScrollWidth();
syncScrollFromMatrix();
})();