45 lines
1.7 KiB
JavaScript
45 lines
1.7 KiB
JavaScript
// Warnt, bevor ungespeicherte Änderungen verloren gehen.
|
|
//
|
|
// Gilt für Formulare mit dem Attribut data-unsaved (das
|
|
// Bearbeitungsformular eines Eintrags). Hat jemand dort etwas geändert und
|
|
// verlässt die Seite, ohne zu speichern — ein Klick in der Seitenleiste, Tab
|
|
// schließen, zurück —, fragt der Browser nach. Den Text der Rückfrage legt der
|
|
// Browser selbst fest; eigene Texte erlauben moderne Browser nicht mehr.
|
|
//
|
|
// Als "geändert" gilt nur, was sich wirklich vom Ausgangsstand unterscheidet:
|
|
// Wer etwas tippt und wieder löscht, wird nicht gefragt. Abgeschickt wird
|
|
// ohne Rückfrage, und "Abbrechen" ist eine bewusste Entscheidung, die
|
|
// trotzdem nachfragt — sie ist nur ein Link.
|
|
(function () {
|
|
"use strict";
|
|
|
|
// state fasst alle Felder eines Formulars zu einer Zeichenkette zusammen.
|
|
function state(form) {
|
|
var parts = [];
|
|
new FormData(form).forEach(function (val, name) {
|
|
if (name !== "csrf_token") {
|
|
parts.push(name + "=" + val);
|
|
}
|
|
});
|
|
return parts.join("\u0000");
|
|
}
|
|
|
|
document.querySelectorAll("form[data-unsaved]").forEach(function (form) {
|
|
var outgoing = state(form);
|
|
var saving = false;
|
|
|
|
form.addEventListener("submit", function () {
|
|
saving = true;
|
|
});
|
|
|
|
window.addEventListener("beforeunload", function (event) {
|
|
if (saving || state(form) === outgoing) {
|
|
return;
|
|
}
|
|
// Beides nötig: preventDefault für aktuelle Browser, returnValue
|
|
// für ältere.
|
|
event.preventDefault();
|
|
event.returnValue = "";
|
|
});
|
|
});
|
|
})();
|