DataGrid: Grundlagen
Zurück: Demo-Übersicht
1. Übersicht und Zweck
Status: [Live], verifiziert gegen wkfluentui@a477094.
dataGrid() rendert eine panel-füllende, resize-feste Desktop-Tabelle mit
optionaler Sortierung, Zeilenauswahl und Massenaktionen — der zentrale
Baustein für „viele gleichartige Datensätze als Tabelle„ in dieser
Bibliothek. Diese Seite dokumentiert den Basiskontrakt (Spalten, Zeilen,
erzeugtes Markup, Tabellen-Optik, Spaltenbreiten-Persistenz); feature-
spezifische Details (Sortierung, Selection, Massenaktionen, Filtering,
Paging, Export, Accessibility) stehen auf den jeweiligen Unterseiten der
Demo-Übersicht.
Zielgruppe: jedes DokuWiki-Plugin, das eine Liste gleichartiger Datensätze (Datenbank-Zeilen, Dateiliste, Konfigurationseinträge …) als Tabelle zeigen will, statt eine eigene Table-Rendering-Logik zu bauen.
2. Voraussetzungen
- DokuWiki mit aktiviertem Plugin
wkfluentui. helper_plugin_wkfluentui_widgetsgeladen überplugin_load('helper', 'wkfluentui_widgets')— nichtplugin_load('helper', 'wkfluentui')(liefertnull, s. api → Abschnitt „Troubleshooting").- Für
sortUrl/bulkActionsmit Server-Endpunkten: ein Formular-POST-Handler mitsectok-Prüfung auf Aufrufer-Seite (das Widget liefert nur Markup, keine Server-Logik).
3. Konzepte
Ein natives <table>, keine div-Nachbildung. Bewusste
Architekturentscheidung: getrennte Head-/Body-Tabellen oder
ein div-Raster desynchronisieren Spaltenbreiten ohne JavaScript; ein
natives <table> hält Kopf und Body ausgerichtet und trägt korrekte
implizite Tabellensemantik kostenlos. role=„grid“ (plus
aria-multiselectable bei multi) wird nur gesetzt, sobald ein
Auswahlmodell aktiv ist — eine reine Anzeige-Tabelle ohne Auswahl bleibt
semantisch eine Tabelle, kein „Grid“-Widget.
Klartext vs. vertrauenswürdiges HTML: $rows-Zellwerte sind
standardmäßig Klartext (hsc()-escaped durch das Widget); ein Wert der
Form ['html' => string] rendert stattdessen unverändertes,
bereits vom Aufrufer escaptes HTML — dieselbe Konvention wie überall in
dieser API (s. api → Abschnitt
„Konzepte", Escaping-Konvention).
Container-getriebenes Responsive: kein Viewport-Breakpoint, das Grid folgt der Breite seines Panels — Details: Adaptivity.
4. Erste Schritte
/** @var helper_plugin_wkfluentui_widgets $widgets */ $widgets = plugin_load('helper', 'wkfluentui_widgets'); $columns = [ ['key' => 'id', 'label' => 'ID', 'align' => 'right', 'mono' => true, 'width' => '4rem'], ['key' => 'name', 'label' => 'Name'], ['key' => 'status', 'label' => 'Status', 'sortable' => false], ]; $rows = [ ['id' => 1, 'name' => 'Firewall-Regel prüfen', 'status' => 'offen'], ['id' => 2, 'name' => 'Backup-Job verifizieren', 'status' => 'erledigt'], ]; echo $widgets->dataGrid($columns, $rows, [ 'ariaLabel' => 'Aufgabenliste', 'empty' => 'Keine Einträge.', ]);
Falsch: $rows als reines Werte-Array ohne Spalten-Keys übergeben
([1, 'Firewall-Regel prüfen', 'offen']). dataGrid() liest
Zellwerte über $row[$col['key']] — ohne passende Keys bleiben alle
Zellen leer, es gibt keine Fehlermeldung (s. Abschnitt 11,
Troubleshooting).
5. Verwendung
| Einsatz | Muster |
|---|---|
| Ergebnisliste mit Sortierung | $opts['sort']/sortUrl — Sorting |
| Mehrfachauswahl + Bulk-Operation | $opts['selection'] => 'multi' + rowKey + bulkActions — Selection · Data Editing |
| Formular-Panel im Drawer/Auxbar | persistKey setzen, damit Spaltenbreiten über Reloads erhalten bleiben (Abschnitt 6) |
| Erstkonsument in Produktion | wksqliteds — dbadmin/ResultGrid ist ein dünner Adapter über dataGrid() |
6. API-Referenz
| Metadatum | Wert |
|---|---|
| Sprache | PHP |
| Namespace | helper_plugin_wkfluentui_widgets |
| Datei | lib/plugins/wkfluentui/helper/widgets.php |
| Sichtbarkeit | public |
| Stabilität | stabil (Tier 1) |
public function dataGrid(array $columns, array $rows, array $opts = []): string
Zusammenfassung: Rendert eine Desktop-Datentabelle aus Spalten- Definitionen und Zeilen-Daten, optional mit Sortierung, Zeilenauswahl und Massenaktionen-Toolbar.
Rückgabewert: string — vollständiges HTML-Fragment
(<div class="wk-datagrid">…</div>). Leerer String, wenn
$columns leer ist (keine Tabelle ohne Spalten) — unabhängig davon, ob
$rows Einträge enthält.
7. Parameter, Optionen und Zustände
$columns (je Eintrag)
| Schlüssel | Typ | Pflicht | Standardwert | Bedeutung |
|---|---|---|---|---|
key | string | Ja | – | Spalten-Key, muss einem $rows-Zeilenschlüssel entsprechen |
label | string | Ja | – | Kopfzeilentext (hsc()-escaped) |
align | 'left'|'right' | Nein | left | right für numerische Spalten |
mono | bool | Nein | false | Monospace-Darstellung (–wk-admin-font-mono) |
sortable | bool | Nein | true | false unterdrückt Sortier-UI für diese Spalte |
width | string | Nein | – | CSS-Startbreite; wird bei Client-Resize überschrieben |
$rows
Liste von Assoziativ-Arrays key => Zellwert. Ein String wird als
Klartext escaped; ['html' => string] rendert vertrauenswürdiges,
Aufrufer-escaptes HTML ungeprüft.
$opts
| Schlüssel | Typ | Default | Feature-Seite |
|---|---|---|---|
sort | array [key, 'asc'|'desc'] | – | Sorting |
sortUrl | callable | – | Sorting |
persistKey | string | – | diese Seite, Abschnitt 3 (Konzepte) und unten (Spaltenbreiten) |
selection | 'none'|'single'|'multi' | none | Selection |
selectable | bool (Alias für selection => 'single') | false | Selection |
rowKey | string | – | Pflicht bei multi — Selection |
bulkActions | array | – | Data Editing |
rowActions | callable | – | api → rowActions() |
actionsHeader | string oder ['html' => string] | leer | api → rowActions() |
empty | string | — | Leer-Zustandstext |
ariaLabel | string | – | Accessibility |
Erzeugtes Markup
<div class="wk-datagrid" data-wk-selection="…" data-wk-persist="…">
→ optional <div class="wk-datagrid__bulkbar"> → ein natives
<div class="wk-datagrid__body"><table>…</table></div> mit sticky
<thead class="wk-datagrid__head">. Jede Kopfzelle trägt
scope="col" (explizite Spaltenkopf-Semantik — konsistent zur
Entscheidung, native Tabellensemantik statt eines ARIA-Nachbaus zu
nutzen, s. Abschnitt 3).
Fehlerverhalten
| Bedingung | Verhalten | |
|---|---|---|
$columns leer | Rückgabe ''`` (leerer String), kein Fehler |
| ''$rows leer | Tabelle rendert mit Kopfzeile + Leer-Zustandszeile (empty-Text), kein Fehler |
selection => 'multi' ohne rowKey | stille Degradierung auf none — kein Fehler, keine Warnung (Checkbox-Werte ohne eindeutigen Schlüssel wären bedeutungslos) | |
$rows-Zeile ohne passenden $columns[]['key'] | Zelle rendert leer, kein Fehler (s. Abschnitt 4, „Falsch„) | |
unbekannter $opts['selection']-Wert | stille Degradierung auf none |
8. Vollständige Beispiele
Sortierbare, mehrfach auswählbare Tabelle mit Massenaktion (kombiniert Grundlagen + Sorting + Selection + Bulk-Actions):
$columns = [ ['key' => 'id', 'label' => 'ID', 'align' => 'right', 'mono' => true, 'width' => '4rem'], ['key' => 'name', 'label' => 'Name'], ['key' => 'status', 'label' => 'Status'], ]; echo $widgets->dataGrid($columns, $rows, [ 'sort' => ['name', 'asc'], 'persistKey' => 'aufgaben:liste', 'selection' => 'multi', 'rowKey' => 'id', 'bulkActions' => [ ['label' => 'Erledigt markieren', 'element' => '<button type="submit" name="do" value="done" class="wk-btn">Erledigt markieren</button>'], ], 'ariaLabel' => 'Aufgabenliste', 'empty' => 'Keine Aufgaben.', ]);
9. Einschränkungen und Randfälle
- Kein virtuelles Scrollen — siehe Data Paging and Scrolling.
- Keine editierbaren Zellen in dieser Ausbaustufe — siehe Data Editing (Massenaktionen), Abschnitt Grid-Editing.
- Kein Spalten-Header-Filter — siehe Filtering.
- Keine Mehrspalten-Sortierung — siehe Sorting → Einschränkungen.
persistKeymuss über Seitenaufrufe hinweg stabil und pro Grid-Instanz eindeutig sein — zwei Grids mit demselbenpersistKeyteilen sich versehentlich denselbenlocalStorage-Zustand.
10. Accessibility und Kompatibilität
- Vollständiger ARIA-/Tastatur-Überblick: Accessibility (konsolidiert, nicht hier dupliziert).
- Ohne JavaScript bleibt die Tabelle vollständig nutzbar; Sortierung erfordert bei No-JS
sortUrl(serverseitiger Fallback), sonst bleiben Kopfzeilen unsortierbar-still. - Browserkompatibilität: keine Anforderungen über CSS-Grid/Flexbox-Grundunterstützung hinaus (identisch zum Rest der Bibliothek).
11. Troubleshooting
Symptom: Zellen bleiben leer, obwohl $rows Daten enthält.
Ursache: $rows-Zeilenschlüssel stimmen nicht mit $columns[]['key']
überein (Tippfehler oder reines Werte-Array statt Assoziativ-Array).
Lösung: jeden $columns[]['key'] gegen die tatsächlichen
array_keys() einer $rows-Zeile prüfen.
Symptom: Checkbox-Spalte fehlt trotz selection => 'multi'.
Ursache: rowKey fehlt in $opts — das Widget degradiert still auf
none (s. Abschnitt 7, Fehlerverhalten).
Lösung: $opts['rowKey'] auf einen eindeutigen Spalten-Key
setzen.
12. Verwandte Themen
- Demo-Übersicht — alle Kategorien
- FluentUI: Öffentliche Helper-API — vollständiger Methodenvertrag aller Helper
- FluentUI: Basis-Widget-Katalog — DeclarativeTable (Tier-2-Katalog)
- SQLite Data Studio: Admin-Oberfläche — Erstkonsument (SQL-Workbench)