96 lines
3.6 KiB
JavaScript
96 lines
3.6 KiB
JavaScript
// „Gibt es schon?" — zeigt beim Anlegen eines Eintrags vorhandene Einträge mit
|
|
// ähnlichem Titel an (AUSBAUSTUFEN.md 5.7).
|
|
//
|
|
// Agenten bekommen bei "remember" eine Rückfrage, wenn es schon einen
|
|
// ähnlichen Eintrag gibt. Menschen im Formular bekommen denselben Hinweis,
|
|
// nur ohne Sperre: Die Liste erscheint unter dem Titel, speichern lässt sich
|
|
// trotzdem. Geprüft wird auf dem Server mit derselben Logik wie bei MCP
|
|
// (internal/dubletten), damit beide Wege gleich urteilen.
|
|
//
|
|
// Gefragt wird erst, wenn eine Weile nicht getippt wurde (wartezeit), nicht
|
|
// bei jedem Buchstaben. Antworten, die zu spät für den aktuellen Titel
|
|
// kommen, werden verworfen.
|
|
(function () {
|
|
"use strict";
|
|
|
|
var titel = document.querySelector("input[data-aehnlich-url]");
|
|
var kasten = document.querySelector("[data-aehnlich-liste]");
|
|
if (!titel || !kasten) {
|
|
return;
|
|
}
|
|
var liste = kasten.querySelector("ul");
|
|
var bezeichner = document.querySelector("input[name=slug]");
|
|
var url = titel.getAttribute("data-aehnlich-url");
|
|
// Die Adresse eines Eintrags: aus der Such-URL ".../entries/similar" wird
|
|
// ".../e/<slug>".
|
|
var eintragsBasis = url.replace(/entries\/similar$/, "e/");
|
|
|
|
var wartezeit = 400; // Millisekunden ohne Tippen, bevor gefragt wird
|
|
var zeitgeber = null;
|
|
var letzteFrage = "";
|
|
|
|
function zeige(kandidaten) {
|
|
liste.textContent = "";
|
|
kandidaten.forEach(function (k) {
|
|
var li = document.createElement("li");
|
|
var a = document.createElement("a");
|
|
a.href = eintragsBasis + encodeURIComponent(k.slug);
|
|
a.target = "_blank";
|
|
a.rel = "noopener";
|
|
a.textContent = k.title;
|
|
li.appendChild(a);
|
|
|
|
// Die gemeinsamen Wörter zeigen, warum der Eintrag hier steht.
|
|
// Ist es nur ein allgemeines Wort, sieht man sofort: anderes Thema.
|
|
if (k.gemeinsam && k.gemeinsam.length) {
|
|
var grund = document.createElement("span");
|
|
grund.className = "hilfe";
|
|
grund.textContent = " — gemeinsam: " + k.gemeinsam.join(", ");
|
|
li.appendChild(grund);
|
|
}
|
|
liste.appendChild(li);
|
|
});
|
|
kasten.hidden = kandidaten.length === 0;
|
|
}
|
|
|
|
function frage() {
|
|
var t = titel.value.trim();
|
|
var s = bezeichner ? bezeichner.value.trim() : "";
|
|
var schluessel = t + "\u0000" + s;
|
|
if (schluessel === letzteFrage) {
|
|
return;
|
|
}
|
|
letzteFrage = schluessel;
|
|
|
|
if (t.length < 3) {
|
|
zeige([]);
|
|
return;
|
|
}
|
|
|
|
var adresse = url + "?title=" + encodeURIComponent(t) + "&slug=" + encodeURIComponent(s);
|
|
fetch(adresse, { credentials: "same-origin", headers: { "Accept": "application/json" } })
|
|
.then(function (antwort) { return antwort.ok ? antwort.json() : []; })
|
|
.then(function (kandidaten) {
|
|
// Inzwischen weitergetippt? Dann gehört die Antwort zu einem
|
|
// alten Titel.
|
|
if (schluessel === letzteFrage) {
|
|
zeige(kandidaten || []);
|
|
}
|
|
})
|
|
.catch(function () { /* nur ein Hinweis — ohne ihn geht es auch */ });
|
|
}
|
|
|
|
function spaeterFragen() {
|
|
clearTimeout(zeitgeber);
|
|
zeitgeber = setTimeout(frage, wartezeit);
|
|
}
|
|
|
|
titel.addEventListener("input", spaeterFragen);
|
|
if (bezeichner) {
|
|
bezeichner.addEventListener("input", spaeterFragen);
|
|
}
|
|
// Vorbelegter Titel (z.B. nach einem Fehler zurück im Formular).
|
|
if (titel.value.trim() !== "") {
|
|
frage();
|
|
}
|
|
})();
|