Die Seite springt nicht mehr -- und die Kachel zaehlt mit
Zwei Meldungen von Filipe, und sie gehoeren zusammen: Er hat beides am
selben Klick gemerkt.
"immer wenn ich auf was drücke dan geht das fenster wieder hoch. die
seite soll sich nicht immer wieder bewegen wenn ich auf was drücke."
"und wieso steht bei vanvan 0 von 28 obwohl ich alle durch habe."
DER SPRUNG: In karte() stand ein scrollIntoView OHNE Bedingung -- und
die Funktion wird an vier Stellen gerufen. Beim Oeffnen einer Person
ist es richtig; nach dem ersten Klick auf einen Punkt, beim Aufklappen
aller Kategorien und nach dem Anlegen eines Schritts ist es falsch. Man
tippt unten auf "Läuft" und steht wieder ganz oben. `springen` ist
jetzt Vorgabe NEIN, und genau eine Stelle sagt ja.
Und selbst ohne Sprung bewegte sich die Seite: Der Neuaufbau aendert
die Hoehe der Karte (eine Zeile "Schritt läuft" kommt dazu), der
Browser behaelt nur die Pixelzahl. Die Hoehe wird deshalb gehalten.
"Alle aufklappen" holt die Karte gar nicht mehr neu -- Aufklappen ist
eine Sache der Anzeige, dafuer braucht es den Server nicht.
DIE NULL: Die Kachel kommt aus /entwicklung/lage -- EINMAL, beim Laden
der Seite. Die Karte holt ihren Stand bei jedem Oeffnen neu. Wer 28
Punkte durchklickt, sieht in der Karte 28 von 28 und auf der Kachel
darueber die Zahl von vorhin. Zwei Wahrheiten auf einem Bildschirm, und
die falsche steht oben.
Die Liste NICHT neu zu holen ist Absicht -- jeder Neuaufbau bewegt die
Seite, und darueber ging die andere Meldung. Stattdessen wandert die
Zahl mit, zusammen mit dem Kopf der Karte und den Koepfen der
Kategorien ("3 / 7", "2 x hakt").
WAS DIE PRUEFUNG AN MIR SELBST GEFUNDEN HAT, dreimal:
- Sie mass nach dem Sprung aufs Aufgabenbrett weiter und verglich
zwei leere Texte. Zwei leere Texte sind gleich und beweisen nichts
-- gemeldet hat es die Zahl in der Bedingung daneben.
- Danach verglich sie Fridas Kachel mit Riekes Karte und meldete
einen Unterschied zwischen zwei verschiedenen Menschen. Beinahe
haette ich einen Fehler gesucht, den es nicht gab.
- Und "wo etwas hakt, steht es im Kopf" waere ab heute auch ueber
vier VERSTECKTEN Hinweisen gruen gewesen: Der Hinweis steht jetzt
immer im Baum, damit er nachgezogen werden kann, ohne den Kopf neu
zu bauen. Jetzt wird auf sichtbar geprueft, nicht auf vorhanden.
server/pruef-schritt.mjs 65 Pruefungen (vorher 57), 0 Fehler
Beide Meldungen werden am selben Klick nachgestellt: Hoehe und Zahl
vorher merken, EINMAL druecken, beides nachsehen. Mit Gegenprobe --
auf eine Person zu druecken DARF springen, sonst hiesse "springt
nicht" nur, dass gar nichts mehr scrollt.
pruef-css-klassen, pruef-entwicklung 43, pruef-neue-seiten 93 -- 0 Fehler
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -214,6 +214,10 @@
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.e-block__hakt-wort { font-size: .78rem; }
|
||||
/* Die Zahl steht in einem eigenen Feld, damit sie nachgezogen
|
||||
werden kann, ohne den ganzen Kopf neu zu bauen -- ein neu
|
||||
gebauter Kopf waere wieder eine Bewegung auf der Seite. */
|
||||
.e-block__hakt-zahl { font-size: .78rem; font-variant-numeric: tabular-nums; }
|
||||
|
||||
.e-block__koerper { padding: 0 15px 13px; }
|
||||
.e-block__titel { margin: 0 0 4px; font-size: 1.02rem; font-weight: 650; color: var(--text); }
|
||||
|
||||
@@ -69,6 +69,62 @@
|
||||
};
|
||||
let offen = null; // die gerade geöffnete Person
|
||||
|
||||
/* DIE ZAHL AUF DER PERSONENKACHEL LEBT WOANDERS ALS DIE IN DER KARTE
|
||||
(15.09.2026).
|
||||
|
||||
Filipe: „und wieso steht bei vanvan 0 von 28 obwohl ich alle durch
|
||||
habe."
|
||||
|
||||
Weil die Kachel aus /entwicklung/lage kommt -- EINMAL, beim Laden
|
||||
der Seite. Die Karte holt sich ihren Stand bei jedem Öffnen neu.
|
||||
Wer 28 Punkte durchklickt, sieht in der Karte 28 von 28 und auf der
|
||||
Kachel darüber weiterhin die Zahl von vorhin. Zwei Wahrheiten auf
|
||||
einem Bildschirm, und die falsche steht oben.
|
||||
|
||||
Die Liste deshalb NICHT neu zu holen ist Absicht: Jeder Neuaufbau
|
||||
bewegt die Seite, und genau darüber hat Filipe sich im selben
|
||||
Atemzug beschwert. Stattdessen wandert die Zahl mit. */
|
||||
const personZahlen = new Map(); // Personennummer -> Element mit „x von 28"
|
||||
let letzteKarte = null; // { id, daten } der gerade offenen Karte
|
||||
|
||||
/** Alle sichtbaren Zähler auf den Stand bringen, den die Karte hat.
|
||||
* Ohne Neuladen, ohne Sprung. */
|
||||
function zaehlerNachziehen() {
|
||||
if (!letzteKarte) return;
|
||||
const r = letzteKarte.daten;
|
||||
const alle = r.bloecke.flatMap((b) => b.punkte);
|
||||
const gesetzt = alle.filter((pt) => pt.meins).length;
|
||||
const satz = `${gesetzt} von ${r.gesamt} angesehen`;
|
||||
|
||||
const kopf = document.querySelector('#karte .e-karte__stand');
|
||||
if (kopf) kopf.textContent = satz;
|
||||
const kachel = personZahlen.get(letzteKarte.id);
|
||||
if (kachel) kachel.textContent = satz;
|
||||
|
||||
/* Und die Köpfe der Kategorien -- sonst steht zugeklappt „0 / 7“
|
||||
über sieben beantworteten Fragen. */
|
||||
for (const b of r.bloecke) {
|
||||
const abschnitt = document.querySelector(`.e-block[data-block="${b.schluessel}"]`);
|
||||
if (!abschnitt) continue;
|
||||
const n = b.punkte.filter((pt) => pt.meins).length;
|
||||
const haktHier = b.punkte.filter((pt) => pt.meins?.stufe === 'hakt').length;
|
||||
const stand = abschnitt.querySelector('.e-block__stand');
|
||||
if (stand) {
|
||||
stand.textContent = `${n} / ${b.punkte.length}`;
|
||||
if (n === b.punkte.length) stand.dataset.fertig = 'ja';
|
||||
else delete stand.dataset.fertig;
|
||||
}
|
||||
if (n === b.punkte.length) abschnitt.dataset.fertig = 'ja';
|
||||
else delete abschnitt.dataset.fertig;
|
||||
const hakt = abschnitt.querySelector('.e-block__hakt');
|
||||
if (hakt) {
|
||||
hakt.hidden = !haktHier;
|
||||
const zahl = hakt.querySelector('.e-block__hakt-zahl');
|
||||
if (zahl) zahl.textContent = `${haktHier} ×`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Die vier Knöpfe ------------------------------------------------
|
||||
Sie stehen immer in derselben Reihenfolge, auch wenn einer gesetzt
|
||||
ist. Ein Knopfsatz, der sich umsortiert, sobald man ihn benutzt,
|
||||
@@ -115,8 +171,12 @@
|
||||
k.append(el('span', 'e-person__rolle', p.rolle_name));
|
||||
|
||||
const zahlen = el('span', 'e-person__zahlen');
|
||||
zahlen.append(el('span', 'e-person__zahl',
|
||||
`${p.gesetzt} von ${lage.gesamt_fremd} angesehen`));
|
||||
const wieViele = el('span', 'e-person__zahl',
|
||||
`${p.gesetzt} von ${lage.gesamt_fremd} angesehen`);
|
||||
/* Die Kachel merkt sich ihr Zahlenfeld -- daran zieht
|
||||
zaehlerNachziehen() sie nach, ohne die Liste neu zu holen. */
|
||||
personZahlen.set(p.id, wieViele);
|
||||
zahlen.append(wieViele);
|
||||
/* DIE ABWEICHUNG STEHT VORNE UND NICHT IM DETAIL. Sie ist das
|
||||
Ergebnis dieser Seite: Wo zwei Leute dasselbe sehen, gibt es
|
||||
nichts zu besprechen. */
|
||||
@@ -133,23 +193,45 @@
|
||||
zahlen.append(z);
|
||||
}
|
||||
k.append(zahlen);
|
||||
k.addEventListener('click', () => karte(p.id));
|
||||
/* NUR HIER WIRD GESPRUNGEN: Wer eine Person anklickt, will zu ihrer
|
||||
Karte. Überall sonst bleibt die Seite stehen, wo sie steht. */
|
||||
k.addEventListener('click', () => karte(p.id, true));
|
||||
return k;
|
||||
}
|
||||
|
||||
/* ---- Die Karte einer Person ----------------------------------------- */
|
||||
async function karte(id) {
|
||||
/* DIE SEITE BEWEGT SICH NUR NOCH, WENN MAN ES WILL (15.09.2026).
|
||||
|
||||
Filipe: „immer wenn ich auf was drücke dan geht das fenster wieder
|
||||
hoch. die seite soll sich nicht immer wieder bewegen wenn ich auf
|
||||
was drücke."
|
||||
|
||||
Hier stand ein `scrollIntoView` ohne Bedingung -- und diese Funktion
|
||||
wird an VIER Stellen gerufen: beim Öffnen einer Person (da ist es
|
||||
richtig), nach dem ersten Klick auf einen Punkt, beim Aufklappen
|
||||
aller Kategorien und nach dem Anlegen eines Schritts. Dreimal von
|
||||
vier war es falsch: Man tippt unten auf „Läuft“ und steht wieder
|
||||
ganz oben.
|
||||
|
||||
`springen` ist deshalb VORGABE NEIN. Wer springen will, sagt es --
|
||||
und das tut genau eine Stelle. Und selbst ohne Sprung wird die
|
||||
Höhe gehalten: Der Neuaufbau kann die Karte kürzer oder länger
|
||||
machen (eine Zeile „Schritt läuft“ kommt dazu), und dann rutscht
|
||||
alles darunter weg. */
|
||||
async function karte(id, springen = false) {
|
||||
offen = id;
|
||||
const ziel = $('karte');
|
||||
const vorherY = window.scrollY;
|
||||
ziel.hidden = false;
|
||||
ziel.textContent = '';
|
||||
ziel.append(el('p', 'leise', 'wird geladen …'));
|
||||
ziel.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
if (springen) ziel.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
|
||||
const a = await hole(`/workspace/api/entwicklung/person/${id}`);
|
||||
if (!a.ok) { melde('Die Karte ließ sich nicht laden.'); return; }
|
||||
const r = await a.json();
|
||||
stufen = r.stufen;
|
||||
letzteKarte = { id, daten: r };
|
||||
ziel.textContent = '';
|
||||
|
||||
const kopf = el('div', 'e-karte__kopf');
|
||||
@@ -215,10 +297,18 @@
|
||||
alleKnopf.textContent = alleZu() ? 'Alle zuklappen' : 'Alle aufklappen';
|
||||
};
|
||||
alleBeschriften();
|
||||
/* Jede Kategorie legt hier ihren eigenen Umschalter ab. */
|
||||
const umschalter = [];
|
||||
alleKnopf.addEventListener('click', () => {
|
||||
if (alleZu()) offeneBloecke.clear();
|
||||
/* AN ORT UND STELLE, NICHT ÜBER EINEN NEUAUFBAU. Vorher rief
|
||||
dieser Knopf karte() -- die Karte wurde neu geholt, neu
|
||||
gezeichnet, und die Seite sprang. Aufklappen ist eine Sache der
|
||||
Anzeige; dafür braucht es den Server nicht. */
|
||||
const zu = alleZu();
|
||||
if (zu) offeneBloecke.clear();
|
||||
else for (const b of r.bloecke) offeneBloecke.add(b.schluessel);
|
||||
karte(id);
|
||||
for (const u of umschalter) u(!zu);
|
||||
alleBeschriften();
|
||||
});
|
||||
leiste.append(alleKnopf);
|
||||
/* HIER STAND KURZ „2 von 28 angesehen" -- dieselbe Zahl, die zwei
|
||||
@@ -234,6 +324,9 @@
|
||||
const haktHier = b.punkte.filter((pt) => pt.meins?.stufe === 'hakt').length;
|
||||
|
||||
const abschnitt = el('section', 'e-block');
|
||||
/* Der Schlüssel am Element -- daran findet zaehlerNachziehen()
|
||||
den richtigen Kopf wieder, ohne eine zweite Liste zu führen. */
|
||||
abschnitt.dataset.block = b.schluessel;
|
||||
abschnitt.dataset.offen = offen ? 'ja' : 'nein';
|
||||
if (gesetzt === b.punkte.length) abschnitt.dataset.fertig = 'ja';
|
||||
|
||||
@@ -254,22 +347,29 @@
|
||||
const stand = el('span', 'e-block__stand', `${gesetzt} / ${b.punkte.length}`);
|
||||
if (gesetzt === b.punkte.length) stand.dataset.fertig = 'ja';
|
||||
schalter.append(stand);
|
||||
if (haktHier) {
|
||||
const h = el('span', 'e-block__hakt', `${haktHier} ×`);
|
||||
h.title = haktHier === 1 ? 'Hier hakt ein Punkt.' : `Hier haken ${haktHier} Punkte.`;
|
||||
h.append(el('span', 'e-block__hakt-wort', 'hakt'));
|
||||
schalter.append(h);
|
||||
}
|
||||
/* DER HAKT-HINWEIS STEHT IMMER DA, nur meistens verborgen: So
|
||||
kann er nachgezogen werden, ohne den Kopf neu zu bauen -- und
|
||||
ein neu gebauter Kopf wäre wieder eine Bewegung. */
|
||||
const h = el('span', 'e-block__hakt');
|
||||
h.hidden = !haktHier;
|
||||
h.append(el('span', 'e-block__hakt-zahl', `${haktHier} ×`));
|
||||
h.append(el('span', 'e-block__hakt-wort', 'hakt'));
|
||||
h.title = 'Punkte, bei denen du „Da hakt es“ gesetzt hast.';
|
||||
schalter.append(h);
|
||||
|
||||
const umschalten = (auf) => {
|
||||
abschnitt.dataset.offen = auf ? 'ja' : 'nein';
|
||||
koerper.hidden = !auf;
|
||||
schalter.setAttribute('aria-expanded', String(auf));
|
||||
};
|
||||
umschalter.push(umschalten);
|
||||
schalter.addEventListener('click', () => {
|
||||
if (offeneBloecke.has(b.schluessel)) offeneBloecke.delete(b.schluessel);
|
||||
else offeneBloecke.add(b.schluessel);
|
||||
/* Nur DIESEN Abschnitt umschalten statt die Karte neu zu holen:
|
||||
Ein Neuaufbau bei jedem Klick ließe die Seite unter den
|
||||
Fingern springen -- und bei 28 Punkten sieht man das. */
|
||||
const jetztOffen = offeneBloecke.has(b.schluessel);
|
||||
abschnitt.dataset.offen = jetztOffen ? 'ja' : 'nein';
|
||||
koerper.hidden = !jetztOffen;
|
||||
schalter.setAttribute('aria-expanded', String(jetztOffen));
|
||||
umschalten(offeneBloecke.has(b.schluessel));
|
||||
alleBeschriften();
|
||||
});
|
||||
titel.append(schalter);
|
||||
@@ -282,6 +382,14 @@
|
||||
abschnitt.append(koerper);
|
||||
ziel.append(abschnitt);
|
||||
}
|
||||
|
||||
/* Die Zahl auf der Personenkachel mitziehen -- sie kommt aus einer
|
||||
Liste, die nur beim Laden der Seite geholt wird. */
|
||||
zaehlerNachziehen();
|
||||
/* UND DIE HÖHE HALTEN. Ohne diese Zeile springt die Seite auch ohne
|
||||
scrollIntoView: Der Neuaufbau ändert die Höhe der Karte, und der
|
||||
Browser behält nur die Pixelzahl, nicht die Stelle. */
|
||||
if (!springen) window.scrollTo({ top: vorherY, behavior: 'instant' });
|
||||
}
|
||||
|
||||
function punktZeile(personId, pt, erwartung) {
|
||||
@@ -340,10 +448,18 @@
|
||||
return;
|
||||
}
|
||||
melde('');
|
||||
/* Neu laden, sobald der erste Klick auf einem Punkt sitzt: Erst
|
||||
danach darf der Stand des anderen überhaupt ausgeliefert
|
||||
werden, und dann soll er auch sichtbar werden. */
|
||||
if (!pt.meins) await karte(personId);
|
||||
/* DER STAND WANDERT SOFORT MIT -- ohne den Server noch einmal zu
|
||||
fragen. Daran hängen drei sichtbare Zahlen: der Kopf der Karte,
|
||||
der Kopf der Kategorie und die Personenkachel oben, die sonst
|
||||
bei „0 von 28" stehen bliebe. */
|
||||
const warNeu = !pt.meins;
|
||||
pt.meins = { ...(pt.meins || {}), stufe, anlass: feld.value };
|
||||
zaehlerNachziehen();
|
||||
/* Neu laden NUR beim ersten Klick auf einem Punkt: Erst danach
|
||||
darf der Stand des anderen überhaupt ausgeliefert werden, und
|
||||
dann soll er auch sichtbar werden. Ohne Sprung -- karte()
|
||||
hält seit heute die Höhe. */
|
||||
if (warNeu) await karte(personId);
|
||||
}));
|
||||
|
||||
z.append(feld);
|
||||
|
||||
Reference in New Issue
Block a user