Workspace: alle Auswahlfelder ohne Systemmenue

Filipe: "die kisten wo die namen drin stehen um auszuwaehlen -- kannst
du doch ueberall besser aussehen lassen". Betraf nicht eine Stelle,
sondern 28 Auswahlfelder auf zehn Seiten.

Deshalb EIN Baustein (assets/js/wahl.js) statt zehn Einzelloesungen.

WIE ER ARBEITET:
Das echte <select> bleibt im Dokument und behaelt seinen Wert -- es wird
nur unsichtbar. Darueber liegt ein eigener Knopf mit eigener Liste.
Damit funktioniert alles weiter, was schon da war: jedes `feld.value`,
jedes `change`-Ereignis, jedes Formular. Ich musste keine einzige der
zehn Seiten in ihrer Logik anfassen.

Faellt das Skript aus, ist wieder das gewohnte Systemmenue da.

DREI ENTSCHEIDUNGEN, DIE WICHTIG WAREN:

1. Nicht display:none fuer das echte Feld, sondern ein Pixel und
   durchsichtig. Ein per display:none verstecktes Feld faellt aus der
   Formularpruefung des Browsers heraus -- `required` wuerde stumm nicht
   mehr greifen.

2. Die Liste haengt an position:fixed, nicht am Elternelement. In einer
   Karte mit overflow:hidden waere sie sonst abgeschnitten. Passt sie
   nach unten nicht mehr hin, klappt sie nach oben.

3. Ein MutationObserver erfasst Felder, die erst spaeter entstehen, und
   Eintraege, die nachgeladen werden. Neu gezeichnet wird im naechsten
   Bild -- so wird ein direkt nach dem Fuellen gesetztes `feld.value`
   noch mitgenommen. Geprueft an der Scout-Pipeline: Prioritaet und
   Stufe entstehen erst beim Aufklappen, beide werden aufgewertet, der
   gewaehlte Wert kommt beim Speichern richtig an.

Tastatur wie gewohnt: Pfeile oeffnen und blaettern, Buchstaben springen
zum passenden Eintrag, Esc schliesst, Klick daneben auch. Gruppen
(optgroup) werden als Zwischenueberschrift dargestellt.

Geprueft ueber zehn Seiten: 28 Felder, KEINES mehr als Systemmenue,
Werte kommen an, Seite reagiert auf die Auswahl, Handy ohne Ueberlauf,
0 Konsolenfehler.
This commit is contained in:
2026-08-31 12:23:49 +02:00
parent e14d9d5042
commit 7c81b17f9c
15 changed files with 381 additions and 74 deletions
+90
View File
@@ -694,3 +694,93 @@ body.suche-offen { overflow: hidden; }
.ki-knopf { transition: none; }
.ki-knopf[data-denkt="ja"] .ki-knopf__funke { animation: none; opacity: .7; }
}
/* ===================================================================
Auswahlfelder (31.08.2026).
Das echte <select> bleibt im Dokument -- es haelt den Wert und macht
jedes vorhandene `feld.value` weiter richtig. Es wird nur unsichtbar
gemacht; sichtbar ist der Knopf darueber.
Bewusst NICHT display:none: Ein so verstecktes Feld faellt aus der
Formularpruefung des Browsers heraus, und `required` wuerde stumm
nicht mehr greifen.
=================================================================== */
.wahl2 { position: relative; display: block; }
.wahl2__echt {
position: absolute; inset: 0;
opacity: 0; pointer-events: none;
/* Nur ein Pixel gross, damit ein Fehlerhinweis des Browsers noch am
richtigen Ort erscheint. */
width: 1px; height: 1px;
}
.wahl2__knopf {
display: flex; align-items: center; justify-content: space-between; gap: 10px;
width: 100%; padding: 10px 12px; cursor: pointer;
background: linear-gradient(#141c28, #101722);
border: 1px solid var(--rand); border-radius: var(--radius-klein);
color: var(--text); font: inherit; text-align: left;
transition: border-color .16s ease, background .16s ease;
}
.wahl2__knopf:hover:not([disabled]) {
border-color: rgba(255, 255, 255, .24);
background: linear-gradient(#18212f, #141b27);
}
.wahl2__knopf:focus-visible,
.wahl2__knopf[aria-expanded="true"] {
outline: none;
border-color: rgba(63, 189, 245, .65);
box-shadow: 0 0 0 3px rgba(63, 189, 245, .16);
}
.wahl2__knopf[disabled] { opacity: .5; cursor: default; }
.wahl2__knopf[data-leer="ja"] .wahl2__text { color: var(--text-still); }
.wahl2__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wahl2__pfeil {
width: 16px; height: 16px; flex: none;
fill: none; stroke: var(--text-still); stroke-width: 1.8;
stroke-linecap: round; stroke-linejoin: round;
transition: transform .18s ease;
}
.wahl2__knopf[aria-expanded="true"] .wahl2__pfeil { transform: rotate(180deg); }
/* Die Liste haengt am Fenster, nicht am Elternelement -- in einer Karte
mit overflow: hidden waere sie sonst abgeschnitten. */
.wahl2__liste {
position: fixed; z-index: 90;
min-width: 180px; max-width: min(420px, calc(100vw - 24px));
overflow-y: auto; padding: 5px;
background: #0d1420;
border: 1px solid rgba(63, 189, 245, .3);
border-radius: 11px;
box-shadow: 0 18px 44px -16px rgba(0, 0, 0, .85);
}
.wahl2__gruppe {
margin: 7px 8px 3px; font-size: .68rem; font-weight: 700;
letter-spacing: .08em; text-transform: uppercase; color: var(--akzent);
}
.wahl2__gruppe:first-child { margin-top: 3px; }
.wahl2__eintrag {
display: block; width: 100%; padding: 8px 11px; cursor: pointer;
background: transparent; border: 0; border-radius: 7px;
color: var(--text-leise); font: inherit; font-size: .88rem; text-align: left;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wahl2__eintrag:hover:not([disabled]) { background: rgba(255, 255, 255, .06); color: var(--text); }
.wahl2__eintrag:focus-visible {
outline: none; background: rgba(63, 189, 245, .16); color: #fff;
}
.wahl2__eintrag[data-an="ja"] {
color: #fff; font-weight: 600;
background: rgba(63, 189, 245, .12);
}
.wahl2__eintrag[disabled], .wahl2__eintrag[data-aus="ja"] {
color: var(--text-still); cursor: default;
}
@media (prefers-reduced-motion: reduce) {
.wahl2__knopf, .wahl2__pfeil { transition: none; }
}