Widgets
Custom Table
Custom Table
Das Custom Table-Widget ermöglicht dir die Darstellung dynamischer, interaktiver Tabellen direkt auf deiner Ninox-Oberfläche – maßgeschneidert nach deinen Anforderungen. Es eignet sich ideal, um strukturierte Daten übersichtlich darzustellen, individuell zu formatieren und mit Aktionen zu verknüpfen (z. B. für Bearbeiten, Löschen, Öffnen von Datensätzen oder API-Aufrufe).
Beispiel:

🧩 Gesamter Anwendungscode
Im Folgenden siehst du einen beispielhaften Anwendungscode, der die Basis deiner Custom Table definiert. Da der Code – je nach Anwendungsfall – sehr umfangreich werden kann, führen wir dich schrittweise von einer einfachen Basis zu komplexeren Varianten.
Der Aufbau gliedert sich in zwei zentrale Bereiche:
data
– definiert den Inhalt und die Struktur deiner Tabelle (Zeilen und Spalten)arcCustomTable()
– ist die globale Funktion, die das Widget rendert. Ihr übergibst du diedata
🔸 uniqueListId
Der Parameter uniqueListId
ist die individuelle Bezeichnung deiner Tabelle. Er sorgt dafür, dass deine Tabelle intern eindeutig identifiziert wird – besonders dann, wenn mehrere Tabellen gleichzeitig auf einer Seite angezeigt werden.
Warum ist das wichtig?
Style-Einstellungen (z. B. Farben, Schriftarten, Hover-Effekte) werden gezielt nur auf die Tabelle mit der angegebenen
uniqueListId
angewendet.Bei mehreren Tabellen auf einer Ansicht kann es sonst zu Konflikten bei CSS-Klassen oder Zuständen kommen.
✅ Best Practice:
Verwende sprechende, eindeutige Namen – am besten in camelCase oder mit Unterstrichen.
🔸 tableId
Mit tableId
gibst du die interne ID der Tabelle in Ninox an, auf die sich das Widget bezieht. Diese ID wird z. B. benötigt, um:
neue Datensätze über den „+“-Button im Footer anzulegen (
create
)bestehende Datensätze zu öffnen oder bearbeiten zu können (
popup
,openFullscreen
,update
)Aktionen korrekt auf Datensätze dieser Tabelle zu beziehen
🔸 height
Mit height
bestimmst du die Höhe des Tabellen-Widgets in Pixeln. So kannst du die Darstellung flexibel an das Layout deiner Seite anpassen – egal, wie viele Daten enthalten sind.
💡 Werte
Der Wert wird in Pixeln angegeben – z. B.
"300px"
,"500px"
oder"800px"
."auto"
: Die Höhe passt sich automatisch an den Inhalt an. Perfekt für dynamische Inhalte – beachte aber mögliche Sprünge im Layout.In Kombination mit
maxHeight
kannst du die automatische Höhe begrenzen.
🔸 minWidth
Mit minWidth
legst du die minimale Breite deiner Tabelle fest – unabhängig davon, wie viele Spalten oder Daten enthalten sind. So stellst du sicher, dass die Tabelle nicht zu schmal dargestellt wird, z. B. bei schmalen Containern, Tabs oder eingebetteten Ansichten.
🔍 Format
Der Wert wird als Text mit Einheit übergeben, z. B.
"600px"
Ohne Angabe kann die Tabelle bei zu wenig Inhalt schmal zusammenfallen – was das Layout stören kann.
💡 Hinweis:
minWidth
wirkt sich auf die äußere Tabellenhülle aus – nicht auf die Spaltenbreiten im Inneren. Für Spalten gibt es separate Optionen wie width
und minWidth
direkt im columns
-Block.
🔸 groupedBy
Mit groupedBy
definierst du, nach welchem Feld (Spalten-Key bzw. field
) deine Tabelle gruppiert werden soll. Gruppen werden dabei visuell als separate Zeilen mit eigener Formatierung dargestellt – die darunterliegenden Einträge lassen sich ein- und ausklappen.
🔍 Verhalten
Du gibst hier den Spaltennamen (
field
) an, der in deinemcolumns
-Block definiert ist.Ist das Feld leer (
""
) oder fehlt ganz, findet keine Gruppierung statt.Gruppierung kann auch auf komplexen Werten basieren (z. B.
Typ
,Kategorie
,Verantwortlicher
etc.).Die Gruppen lassen sich dynamisch durch Klick auf die Gruppenzeile auf- und zuklappen – dieser Zustand wird lokal gespeichert.
groupsCollapsed
Mit groupsCollapsed
legst du fest, ob gruppierte Zeilen standardmäßig eingeklappt oder ausgeklappt dargestellt werden. Die Gruppenüberschrift (groupRow) ist dabei immer sichtbar – nur die zugehörigen Einträge (valueRows) werden bei Bedarf ein- oder ausgeblendet.
Dieser Parameter wirkt nur, wenn groupedBy
gesetzt ist.
true
= Gruppen sind beim Laden eingeklappt (kompakte Ansicht).false
= Gruppen sind beim Laden vollständig geöffnet.
Der Zustand (ein-/ausgeklappt) wird lokal gespeichert, d. h. bei erneutem Öffnen merkt sich das Widget den letzten Zustand pro Benutzer.
Standardwert: false
(Gruppen sind offen) – wenn nicht angegeben, zeigt die Tabelle alle Gruppeneinträge vollständig an.
🔸 embedded
Mit embedded
aktivierst du den eingebetteten Modus der Tabelle. In diesem Modus passt sich die Tabelle optimal an bestehende Layoutstrukturen an – z. B. in einem Container, Tab oder einem flexiblen UI-Bereich.
Standardwert: false
– die Tabelle nimmt dann ihren eigenen, festen Platz auf der Seite ein.
Wenn embedded: true
gesetzt ist, wird das Widget nicht absolut, sondern relativ im Container positioniert und übernimmt dessen Breite und ggf. auch andere Stilvorgaben. Kombiniert mit Parametern wie height
und minWidth
sorgt das für ein sauberes, integriertes Erscheinungsbild.
Besonders nützlich ist embedded
in Dashboards, Tab-Ansichten oder Modalfenstern.
🔸 rowHoverAction
Mit dem rowHoverAction
-Block bestimmst du, ob das Hover-Verhalten auf Tabellenzeilen aktiv sein soll – und falls ja, welche Farben beim Überfahren mit der Maus verwendet werden.
hoverActive: true
aktiviert den Effekt, andernfalls bleibt die Zeile beim Hover unverändert.backgroundColor
definiert die Hintergrundfarbe der Zeile im Hover-Zustand,fontColor
legt die Textfarbe während des Hoverns fest.
Standardwert bei hoverActive
ist true
, falls der Block gesetzt ist. Ohne rowHoverAction
ist das Verhalten neutral – keine Hover-Effekte.
Tipp: Setze gedeckte Farben ein, um den Effekt dezent und UX-freundlich zu halten.
🔸 header
Mit dem header
-Block steuerst du die Darstellung deiner Tabellenkopfzeile (Spaltenüberschriften). Du kannst sie ganz ausblenden, ihre Höhe anpassen sowie Farben und Schriftgrößen individuell gestalten.
showHeader
(true/false): Blendet die gesamte Header-Zeile ein oder aus.height
: Legt die Höhe der Headerzeile in Pixeln fest – z. B."48px"
oder"auto"
.fontColor
: Definiert die Schriftfarbe der Spaltenüberschriften.fontSize
: Gibt die Schriftgröße an (z. B."14px"
).backgroundColor
: Stellt den Hintergrund der Headerzeile ein – z. B."white"
oder ein Hexwert.
Standardverhalten:
Wenn showHeader
nicht angegeben ist, wird die Header-Zeile angezeigt. Ohne weitere Einstellungen werden Standardwerte für Größe, Farbe und Hintergrund verwendet.
💡 Pro-Tipp:
Wenn du showHeader: false
setzt, sollte die Bedeutung der Daten trotzdem klar erkennbar bleiben – z. B. durch die Position oder das Farbschema der Spalten. Ansonsten kann die Orientierung für Nutzer leiden.
🔸 emptyTable
Mit dem emptyTable
-Block legst du fest, was angezeigt werden soll, wenn keine Daten vorhanden sind – also wenn data: []
leer ist. Du kannst Text und Gestaltung des leeren Zustands anpassen und so die Nutzererfahrung deutlich verbessern.
title
: Der Haupttext, der angezeigt wird (meist prominent, z. B. „Keine Einträge gefunden“).value
: Optionaler zusätzlicher Text oder HTML-Elemente im Inneren des leeren Bereichs.backgroundColor
: Hintergrundfarbe für den leeren Bereich – z. B."white"
oder"#f4f6ff"
.
Standardverhalten:
Ohne emptyTable
wird ein schlichter Text „Keine Ergebnisse“ angezeigt.
💡 Pro-Tipp:
Leere Zustände sind keine Fehler – sie sind deine Bühne. Nutze sie für Erklärungen, motivierende Hinweise oder einen klaren Call-to-Action („Jetzt neuen Eintrag erstellen“). So bleiben deine Nutzer nicht im Leeren hängen – im wahrsten Sinne.

🔸 scrollBar
Mit dem scrollBar
-Block konfigurierst du die horizontale Scrollbar deiner Tabelle. Diese wird angezeigt, wenn deine Tabelle mehr Spalten enthält, als in den verfügbaren Bereich passen.
showScrollBar
:true
oderfalse
– bestimmt, ob die Scrollbar überhaupt angezeigt wird.height
: Höhe des Scrollbar-Containers (z. B."10px"
).backgroundColor
: Hintergrundfarbe des Containers.handle.height
: Höhe des Schiebers („Handle“) innerhalb der Leiste.handle.backgroundColor
: Farbe des Scroll-Handles.handle.borderRadius
: Abgerundete Ecken des Schiebers (z. B."5px"
oder"50%"
).
Standardverhalten:
Ohne scrollBar
wird keine sichtbare Scrollbar angezeigt – auch wenn Inhalte horizontal überlaufen.
💡 Pro-Tipp:
Gerade bei vielen Spalten hilft eine dezente, gut sichtbare Scrollbar, um Orientierung zu geben. Nutze weiche Farben und eine runde Handle-Form, damit die UI nicht „technisch“ wirkt – besonders auf Touch-Geräten zahlt sich das aus.
🔸 theme
Mit dem theme
-Parameter kannst du ein vordefiniertes Design-Template für deine Tabelle aktivieren. Das Theme beeinflusst das gesamte visuelle Erscheinungsbild – von Farben über Schriftarten bis hin zum Layout. Aktuell verfügbar sind:
"clean-white"
"naked"
Wichtig:
Damit das Theme korrekt greift, muss die theme
-uniqueId die gleiche uniqueListId
verwenden wie deine Tabelle. Nur so überschreibt das Theme gezielt die richtigen Style-Regeln per CSS.
Standardverhalten:
Wird kein theme
gesetzt, wird das Standarddesign des arcCustomTable-Widgets verwendet (leicht schattiert, kontrastreich).
🔸 footer
Mit dem footer
-Block kannst du einen unteren Bereich unterhalb der Tabelle anzeigen lassen – z. B. für Buttons oder Informationen. Er eignet sich ideal für Aktionsflächen wie „Neuen Eintrag anlegen“ oder zur Anzeige von Summen, Filtern oder Statusinfos.
showFooter
:true
oderfalse
– aktiviert oder deaktiviert den Footer.showActionButton
: Zeigt den Standard-Button „Neuen Datensatz erstellen“ an.actionButtonTitle
: Individueller Text für den Action-Button.backgroundColor
: Hintergrundfarbe des Footers.leftSideContent
: Freier Inhalt (z. B. Text, HTML, Icons) für die linke Seite.rightSideContent
: Inhalt für die rechte Seite – z. B. Statusanzeigen, Summen oder Infos.
Standardverhalten:
Ohne footer
-Block wird kein Footer angezeigt. Wird showFooter: true
gesetzt, aber keine weiteren Optionen, erscheint ein leerer Footerbereich.
So sieht der oben definierte Footer aus:

🔸 table
Im Detail-Bereich table
definierst du alle Spalten (columns) und deren Darstellung, Inhalte und Verhalten. Du legst hier fest, welche Datenfelder angezeigt werden sollen, wie sie aussehen und was beim Klicken passieren soll.
Jede Spalte kann individuell formatiert werden (z. B. Farbe, Ausrichtung, Padding, Aktionen).
Die hier gesetzten Werte überschreiben ggf. globale Einstellungen aus dem
settings
-Block (z. B.fontColor
,backgroundColor
,align
etc.).Du kannst hier auch fixierte Spalten, Gruppierungen, Interaktionen und Inline-Editing steuern.
🔸 Zeilen- und Gruppenparameter
recordId
:
Muss dieNr
des Datensatzes sein (also die interne ID in Ninox).
Wichtig für die Zuordnung von Aktionen, z. B. Öffnen, Bearbeiten, Löschen.
rowColor
:
Setzt die Hintergrundfarbe der jeweiligen Zeile.
Akzeptiert HEX-Werte wie"#f4f6ff"
oder"transparent"
.rowHeight
:
Bestimmt die Höhe der Zeile.
Wert kann"auto"
sein oder eine feste Pixelangabe wie"60px"
.rowPaddingY
→ Vertikales Innenabstands-Polster (top/bottom) innerhalb der Zellen dieser Zeile.
Wird auf alle Zellen angewendet, sofern dort kein individuelles Padding gesetzt ist.groupRowColor
:
Setzt die Hintergrundfarbe für eine Gruppen-Zeile (wenngroupedBy
aktiv ist).
Du kannst entweder HEX-Werte verwenden oder dynamisch auf Felder zugreifen (z. B.row.farbe
).groupRowSettings.height
→ Legt die Höhe der Gruppenzeile fest.
Wert z. B."40px"
oder"auto"
. Wirkt nur, wenn die Zeile eine Gruppenzeile ist.
💡 Pro-Tipp:
Du kannst dynamisch berechnete Farben einsetzen, um Status-Feedback direkt sichtbar zu machen – z. B. grün für „alle erledigt“, grau für „in Arbeit“:
🔸 columns
Im columns
-Array definierst du die einzelnen Spalten deiner Tabelle – also wie sie aussehen, heißen und was darin angezeigt wird. Jede Spalte wird über ein eigenes Objekt innerhalb von columns
beschrieben.
Basics, die du einstellen kannst:
field
: Das Datenfeld, das angezeigt werden soll – muss zu den Werten indata.table.columns
passen.title
: Der sichtbare Name der Spalte im Header.width
: Die Breite der Spalte (z. B."200px"
).align
: Ausrichtung des Inhalts –"left"
,"center"
oder"right"
.backgroundColor
/color
: Hintergrund- und Textfarbe der Spalte.paddingX
/paddingY
: Innenabstände horizontal und vertikal.truncate
: Ob der Text abgeschnitten und mit „…“ versehen werden soll.fixed
:"left"
oder"right"
, um eine Spalte zu fixieren.actions
: Aktionen wieupdate
,popup
,change
,openFullscreen
,delete
.
Gruppen ausklappen mit groupExpandAction
Mit groupExpandAction kannst du bestimmen, bei welchen Spalten die Funktion des Ausklappens aktiviert sein soll. Das funktioniert nur, wenn du eine Gruppierung in deiner Tabelle eingestellt hast. Aktivierst du es bei mindestens einer Spalte (mit groupExpandAction:true), ist es bei den anderen Spalten automatisch deaktiviert, sofern du es dort nicht auch mit aktivierst in den Parametern.
🔸 actions
Mit dem Parameter actions
kannst du festlegen, was passieren soll, wenn ein Nutzer auf eine Zelle klickt oder diese bearbeitet. Aktionen werden auf Zellebene innerhalb von columns
(in data.table
) gesetzt und machen deine Tabelle interaktiv.
💡 Hinweis: Du kannst mehrere Aktionen kombinieren, indem du sie als Array einfügst.
Beispiel:
🔸 Aktion: popup
Mit type: "popup"
definierst du eine Aktion, die beim Klick auf die Zelle den verknüpften Datensatz als Popup öffnet – direkt innerhalb von Ninox. Dadurch können Nutzer Details einsehen oder bearbeiten, ohne die aktuelle Ansicht zu verlassen.
recordId
muss dieNr
des jeweiligen Datensatzes sein.Diese Aktion gilt immer für die ganze Zelle, nicht nur für den Text.
Du kannst mit
showPopupButton: true
zusätzlich einen Button anzeigen lassen, der den Popup explizit auslöst – nützlich, wenn du Editieren und Öffnen visuell trennen möchtest.
Statt die gesamte Zelle klickbar zu machen, kannst du auch einen individuellen Button innerhalb der Zelle anzeigen lassen – z. B. mit dem Widget arcCustomButton
.
Dazu verwendest du:
showPopupButton: true
– aktiviert die Schaltfläche.popupButton
– enthält das gerenderte Button-Element, z. B. perarcCustomButton()
.
🔸 Aktion: delete
Mit type: "delete"
kannst du beim Klick auf eine Zelle den zugehörigen Datensatz löschen. Die Aktion wirkt sich – wie bei popup
– auf die gesamte Zelle aus.
recordId
muss auf dieNr
des Datensatzes zeigen, der gelöscht werden soll.Es wird kein zusätzlicher Bestätigungsdialog eingebaut – das Löschen erfolgt direkt.
💡 Hinweis: Diese Aktion sollte nur mit Bedacht und klar visualisiert eingesetzt werden – z. B. durch eine spezielle Icon-Spalte oder einen rot markierten Button innerhalb der Zelle.
🔸 Aktion: update
Mit type: "update"
kannst du beim Klick auf eine Zelle direkt ein Feld des verknüpften Datensatzes ändern – ohne Popup, ohne Edit-Modus.
recordId
: DieNr
des Datensatzes, der verändert werden soll.field
: Das Feld, das aktualisiert wird (als Text).value
: Der neue Wert, der gesetzt werden soll (Text, Zahl, Bool, etc.).
💡 Pro-Tipp:
Wenn du das Löschen nicht direkt, sondern erst nach einer Sicherheitsabfrage durchführen möchtest, kannst du einen kleinen Umweg über ein Hilfsfeld + Trigger nehmen:
Erzeuge ein Ja/Nein-Feld namens z. B.
trigger_delete
.Füge in der Tabelle eine
update
-Aktion ein, dietrigger_delete
auftrue
setzt.Im Trigger dieses Feldes nutzt du folgenden Dialog:
🔸 Aktion: openFullscreen
Mit type: "openFullscreen"
öffnest du den verknüpften Datensatz direkt im Vollbildmodus – also so, als würde man ihn klassisch in Ninox vollständig aufrufen.
recordId
: DieNr
des Datensatzes, der geöffnet werden soll.
Einsatzszenario:
Wenn du komplexe Datensätze mit vielen Tabs oder Untertabellen hast, ist openFullscreen
die bessere Wahl gegenüber popup
.
🔸 groupValue
Mit groupValue
definierst du den Inhalt der Gruppierungszeile in einer bestimmten Spalte – also das, was in der Zeile angezeigt wird, die z. B. mehrere Datensätze zu einem Projekt, Kunden oder Status bündelt.
Du kannst
groupValue
in jeder Spalte verwenden – auch mehrfach pro Gruppe, wenn gewünscht.Du kannst einfachen Text, HTML oder auch Mini-Widgets einbauen (z. B. Buttons, Layouts oder Statusanzeigen).
Die Gruppierungszeile wird automatisch angezeigt, wenn
groupedBy
imsettings
-Block gesetzt ist.

🔸 groupByValue
Der groupByValue
-Parameter erlaubt es, deine Tabelle nach einem anderen Wert als dem angezeigten value
zu gruppieren. So kannst du die Anzeige der Zelle unabhängig von der Logik der Gruppierung steuern.
value
: Was der Nutzer in der Zelle sieht (z. B. ein Icon, ein Label, ein HTML-Element).groupByValue
: Nach diesem Wert wird die Zeile gruppiert.
Fallback:
Wenn value
oder groupByValue
leer ist, wird die Zeile automatisch der Gruppe arc-no-value
zugeordnet.
Diese Gruppe wird ganz normal dargestellt, kann aber auch gezielt angesprochen oder ausgeblendet werden.
Beispiele
Folgend findest du einige Praxisbeispiele, die dir den unterschiedlichen Einsatz der Custom Table veranschaulichen.
Custom Table Simple

Custom Table Complex

Weiterführende Links: