Custom Table
Die Custom Table besteht aus einem Anwendungscode, den du in einem Ninox Formel-Feld auf deiner Wunschoberfläche in der Datenbank einfügst. Dieser besteht aus einem allgemeinen Part (settings), in dem du Grundeinstellungen vornimmst und einem Detail-Bereich (table), in dem du deine Tabelle individuell gestalten und befüllen kannst. (Farben, Werte, Aktionen …)
Gesamter Anwendungscode
Folgend siehst du einen beispielhaften Anwendungscode, der die Basis deiner Custom Table definiert. Da der Code bei der Custom Table sehr umfassend werden kann, leiten wir dich von simpel zu komplex durch.
Mit data definierst du die Inhalte deiner Tabelle. Mit der globalen Funktion arcCustomTable() gibst du dann diese Daten aus.
let current := this;
let projectList := 'Produktion Varianten';
let data := {
uniqueListId: "Materialzuweisung" + Nr,
tableId: tableId(first(projectList)),
height: "500px",
groupedBy: "",
groupsCollapsed: false,
theme: arcCustomThemeCleanWhite({
uniqueId: "Produktionsliste"
}),
embedded: false,
rowHoverAction: {
hoverActive: true,
backgroundColor: "",
fontColor: ""
},
header: {
showHeader: true,
height: "",
fontColor: "",
backgroundColor: "",
fontSize: ""
},
emptyTable: {
title: "Keine Materialzuweisung gefunden"
},
scrollBar: {
showScrollBar: false,
height: "",
backgroundColor: "",
handle: {
height: "",
borderRadius: "",
backgroundColor: ""
}
},
table: projectList.[{
recordId: Nr,
rowColor: "",
rowHeight: "auto",
rowPaddingY: "5px",
groupRowColor: "",
groupRowSettings: {
height: "30px",
},
columns: [{
field: "Feldname für Feld-ID",
title: "Titel",
value: "Ninox Wert",
color: "",
backgroundColor: "",
width: "",
align: "left",
paddingX: "",
paddingY: "",
groupExpandAction: false,
groupValue: arcCustomIcon({
name: "caret-down"
}),
groupByValue: "",
actions: [{
type: "popup",
showPopupButton: false,
recordId: Nr
}]
}]
}],
footer: {
showFooter: false,
showActionButton: true,
actionButtonTitle: "",
leftSideContent: "",
rightSideContent: "Gesamt: " + cnt(projectList) + " Projekte"
}
};
arcCustomTable(data)
Allgemeine Settings
In den allgemeinen Settings nimmst du die Grundeinstellungen deiner Tabelle vor. Diese wirkt sich auf alle Spalten und Zeilen deiner Tabelle aus. Folgend werden dir die einzelnen Parameter erläutert:
uniqueListID ist die individuelle Bezeichnung deiner Tabelle. Achte darauf, dass du hier einen einzigartigen Titel vergibst. Das ist wichtig, falls du mehrere Tabellen auf einer Seite darstellen möchtest und deine Style-Einstellungen nur für diese Tabelle gelten sollen.
uniqueListId: "Projektliste Offen",
tableID gibt die ID deiner darzustellenden Tabelle an.
tableId: tableId(first(projectList)),
height gibt die Höhe deiner Tabelle an.
groupedBy gibt den Wert (Spalte - "field") an, nach dem gruppiert werden soll. Trägst du nichts ein in die "", so wird nach nichts gruppiert.
groupedBy: "",
groupedby: "Status",
groupedBy: Gruppierung,
groupsCollapsed
groupsCollapsed definiert, ob deine Zeilen zusammengestaucht (nur die groupRows) oder ausgeklappt (groupRows und valueRows) angezeigt werden. Dieser Parameter greift natürlich nur, wenn du gruppierte Zeilen definiert hast.
groupsCollapsed: false,
groupscollapsed: "",
embedded
embedded benutzt du, wenn du die Table in einem Layout integrierst und diese somit eingebettet wird. Standardmäßig ist dies aber auf false gesetzt.
embedded: false,
embedded: true,
embedded: "",
rowHoverAction Block
Mit dem rowHoverAction Block kannst du bestimmen, ob das hovern über die row angezeigt werden soll und welche Farbe der Hintergrund und welche die Schrift beim hovern haben soll.
rowHoverAction: { hoverActive: true,
backgroundColor: "#9ca4a9",
fontColor: "#fff" }
header Block
Mit dem header Block kannst du mit showHeader: false
die header Zeile deiner customTable ausblenden. Außerdem kannst du Höhe, Schriftfarbe, Schriftgröße und Hintergrundfarbe einstellen.
header: { showHeader: false,
height: "70px",
fontColor: "#fff",
backgroundColor: "#3a4a54",
fontSize: "17px" }
emptyTable Block
Mit dem emptyTable Block kannst du für deine customTable, mit title
den Text bestimmen, der angezeigt werden soll, wenn deine Table keine Werte ausgibt.
emptyTable: { title: "Keine Produkte gefunden..." }
scrollBar Block
Im scrollbar Block kannst du Einstellungen für die horizontale Scrollbar vornehmen. Mit showScrollbar: true
kannst du bestimmen, dass die Scrollbar angezeigt werden soll. Außerdem kannst du die Höhe und Hintergrundfarbe des containers sowie die Höhe und Hintergrundfarbe und den borderRadius des handle (Schiebers) bestimmen.
scrollBar: { showScrollbar: true,
height: 40px,
backgroundColor: "#3a4a54"
handle: { height: "20px",
borderRadius: 20px
backgroundColor: "#fff", }
theme ist ein vorgefertigtes Design / Gestaltungsvorlage, die bestimmt, wie deine Tabellen-Oberfläche in Bezug auf Farben, Schriftarten, Layout und andere Design-Elemente aussieht. Aktuell gibt es ein alternativen Theme für die Custom Table: Clean White.
theme: arcCustomThemeCleanWhite({
uniqueId: "Projektliste Demo 1"
}),
Footer der Tabelle
footer definiert, ob du einen unteren Bereich deiner Tabelle definieren möchtest. Hier kannst du auch Aktionen hinzufügen.
footer: {
showFooter: true,
showActionButton: true,
actionButtonTitle: "Neue Aufgabe hinzufügen",
leftSideContent: "",
rightSideContent: "Gesamt: " + cnt(filteredList) + " Aufgaben"
}
So sieht der oben definierte Footer aus:
showFooter definiert, ob ein Footer angezeigt wird oder nicht.
showFooter: true,
showFooter: false,
showActionButton definiert ob ein Aktions Button angezeigt wird oder nicht. Die Aktion bedeutet immer, dass ein neuer Datensatz in der referenzierten Tabelle erstellt wird. (create record)
showActionButton: true,
showActionButton: false,
actionButtonTitle definiert den Text innerhalb deines Buttons.
actionButtonTitle: "Neue Aufgabe hinzufügen",
leftSideContent definiert, was auf der linken Seite deines Footers stehen soll. Hier bist du frei in der Gestaltung.
rightSideContent definiert, was auf der rechten Seite deines Footers stehen soll. Hier bist du frei in der Gestaltung.
rightSideContent: "Gesamt: " + cnt(filteredList) + " Aufgaben"
Standard-Werte als Fallback
💡 Hinweis: Alle Werte der Parameter werden in Anführungszeichen angegeben. Trägst du nichts in die Anführungszeichen ein, so greift das System auf ein Fallback zurück, der im globalen Code definiert ist. Das heißt es gibt voreingestellte Standard-Werte, sodass immer etwas ausgegeben wird. Hier siehst du den Code der Standard-Werte:
uniqueListId: "",
tableId: "",
height: "",
groupedBy: "",
theme: "",
embedded:"",
popupButtonTitle: "",
table: projectList.[{
recordId: "",
rowColor: "",
rowHeight: "",
groupRowColor: "",
showFooter: "",
showActionButton: "",
actionButtonTitle: "",
rightSideContent: ""
lefttSideContent: ""
field: "",
title: "",
value: "",
width: "",
align: "",
backgroundColor: "",
color: "",
fixed: "",
actions: [{
recordId: "",
type: "",
field: "",
value: "",
}],
groupValue: ""
Detail-Bereich
Im Detail-Bereich (table) definierst du alle Styles und Werte deiner Tabellenspalten & -inhalte. Das heißt: Jede Spalte kann individuell gestaltet werden. Die Styles überschreiben in dem Fall die Werte aus den Allgemeinen Settings.
table: projectList.[{
recordId: Nr,
rowColor: "",
rowHeight: "auto",
groupRowColor: "",
rowHeight kannst du in folgenden Werten angeben:
rowHeight: "50px",
rowHeight: "auto",
rowPaddingY definiert wie viel padding nach oben und unten in einer Zeile eingestellt werden soll.
groupRowColor kannst du in folgenden Werten angeben:
groupRowColor: "#444363",
groupRowColor: if cnt(Firma.Projekte) = cnt(Firma.Projekte[Abgeschlossen != null]) then
"#F0FFF1"
else
"#eee"
end,
groupRowColor: text(color(Auswahlfeld))
groupRowHeight kannst du in folgenden Werten angeben:
groupRowSettings: {
height: "30px"
}
Parameter für die Spalten
columns definiert deine einzelnen Spalten in der Tabelle. Folgend siehst du die Basics, die du einstellen kannst.
columns: [{
field: "Feldname für Feld-ID",
title: "Titel",
value: "Ninox Wert",
width: "10%"
}
Die Custom Table kann um einiges komplexer und individueller gestaltet werden. Folgend werden dir alle Parameter aufgelistet, die du bei columns einsetzen und definieren kannst.
field: "",
title: "",
value: "",
width: "",
align: "",
fixed: "",
paddingX: "",
paddingY: "",
groupExpandAction: "",
actions: [{
recordId: "",
type: "",
field: "",
value: ""
}],
groupValue: ""
Align
align gibt an wie sich dein Inhalt innerhalb der Zelle ausrichtet. Du hast folgende Möglichkeiten:
align: "left",
align: "center",
align: "right",
Fixed
fixed gibt an, ob deine Spalte am Rand haften bleiben soll und somit immer sichtbar ist. Scrollst du bei vielen Inhalten in der Tabelle nach rechts, bleibt deine gefixte Leiste immer sichtbar.
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.
groupExpandAction: true,
groupExpandAction: false,
groupExpandAction: "",
Aktionen
Du kannst für deine Zellen-Werte drei verschiedene Aktionen ausführen: popup, delete und update. Der Grundschreibweise einer Aktion wird wie folgt geschrieben:
actions: [{
recordId: "",
type: "",
field: "",
value: "",
}],
💡 Hinweis: Du kannst auch mehrere Aktionen auf einem Feld ausführen. Diese trennst du durch ein Komma (,). Zum Beispiel so:
actions: [{
recordId: Nr,
type: "popup"
}, {
recordId: Nr,
type: "change",
field: "A"
}],
Aktion Popup
type: "popup" öffnet einen Record. Diese Funktion wirkt sich auf jede einzelne Zelle aus.
actions: [{
recordId: Nr,
type: "popup",
showPopupButton: true,
popupButton: arcCustomButton({
uniqueId: "ButtonProjekt" + Nr,
icon: "",
title: "Open",
fontSize: "13px",
fontColor: "",
iconColor: "",
backgroundColor: "",
borderColor: ""
})
}]
Aktion Delete
type: "delete" löscht einen Record. Diese Funktion wirkt sich auf jede einzelne Zelle aus.
actions: [{
recordId: Nr,
type: "delete"
}]
Aktion Update
type: "update" aktualisiert / manipuliert einen Record. Diese Funktion wirkt sich auf jede einzelne Zelle aus.
actions: [{
recordId: Nr,
type: "update",
field: "G",
value: if erledigt=true then null else true end,
}]
Aktion openFullscreen
type: "openFullscreen" öffnet Datensätze im Fullscreen. Diese Funktion wirkt sich auf jede einzelne Zelle aus.
actions: [{
recordId: Nr,
type: "openFullscreen",
}]
💡 Hinweis: Um die Ninox Feld-ID bestimmter Felder herauszufinden, gibt es zwei Möglichkeiten:
Du Trägst den richtigen Feldnamen bei dem Parameter field ein. Nach dem Speichern wird dir die Feld-ID in der Kopfzeile deiner Tabelle angezeigt. Achte darauf, dass der field Inhalt exakt so geschrieben ist, wie der Ninox Feldname. Andernfalls wird die ID nicht angezeigt. Außerdem werden die Feldnamen nur ausgegeben, wenn du im Bearbeitungsmodus bist.
2. Du verwendest die nützliche Funktion arcFieldFinder().
Group Value
Mit groupValue definierst du den Inhalt, der in der Gruppierungszeile angezeigt werden soll. Diesen Parameter kannst du in jeder Spalte definieren - auch mehrfach. Du kannst in den groupValue reinen Text hinterlegen oder auch weitere Mini-Widgets wie das Layout, den Button oder andere integrieren.
groupValue: Projekte.Bezeichnung
groupValue: "Projekt:" + Projekte.Bezeichnung
groupValue: arcCustomProgressBar({
uniqueId: "",
width: "",
fontSize: "",
fontColor: "",
backgroundColor: "",
progressColor: "",
valueTotal: "",
valueProgress: "",
valueText: ""
})
groupByValue
Der groupByValue Parameter erlaubt es nach anderen Werten als dem cell content (value) zu gruppieren. Items mit leerem value oder leerem groupByValue werden in einer "arc-no-value" Gruppe gruppiert.
groupByValue: Projekte.Nr
groupByValue: Typ
groupByValue: ""
Beispiele
Folgend findest du einige Praxisbeispiele, die dir den unterschiedlichen Einsatz der Custom Table veranschaulichen.
Custom Table Simple
let current := this;
let projectList := (select Projekte);
let data := {
uniqueListId: "Projektliste Offen",
tableId: tableId(first(projectList)),
height: "auto",
groupedBy: "",
popupButtonTitle: "Open",
table: projectList.[{
recordId: Nr,
rowColor: "",
groupRowColor: "#eee",
columns: [{
field: "Feldname für Feld-ID",
title: "Titel",
value: "Ninox Wert",
width: "10%"
}, {
field: "Feldname für Feld-ID",
title: "Titel",
value: "Ninox Wert",
width: "15%"
}, {
field: "Feldname für Feld-ID",
title: "Titel",
value: "Ninox Wert",
width: "10%"
}, {
field: "Firma.Name",
title: "Firma",
value: Firma.Name,
width: "10%"
}, {
field: "Bezeichnung",
title: "Projekt",
value: Bezeichnung,
width: "15%",
actions: [{
type: "popup",
recordId: Nr
}, {
type: "change",
recordId: Nr,
field: "A"
}]
}, {
field: "Umsatz",
title: "Umsatz",
value: text(Umsatz + 1000),
width: "20%"
}, {
field: "Aufgaben",
title: "Status Aufgaben",
value: "<h1>",
width: "100px"
}, {
field: "Abgeschlossen",
title: "Abgeschlossen am",
value: text(Abgeschlossen),
width: "100px"
}]
}],
footer: {
showFooter: false,
actionButtonTitle: "",
rightSideContent: "Gesamt: " + cnt(projectList) + " Projekte"
}
};
arcCustomTable(data)
Custom Table Complex
let current := this;
arcCustomTable(data);
let list := do as transaction
select Aufgaben
end;
let filteredList := list[if current.Suche != null then
testx(Mitarbeiter.'First Name' + "," + text(Mitarbeiter.'Last Name') + "," +
text(Aufgabe) +
"," +
text(Projekte.Bezeichnung) +
"," +
"", "(?:" + current.Suche + ")\.*[^]", "gi")
else
true
end and
if current.'Erledigte einblenden' = true then
true
else
Erledigt != true
end];
let data := {
uniqueListId: "Projektliste A",
tableId: tableId(first(list)),
height: "500px",
theme: "",
groupedBy: text('Gruppieren nach'),
embedded: false,
table: filteredList.[{
recordId: Nr,
rowColor: "",
rowHeight: "60px",
groupRowColor: let currentRecord := this;
if cnt(filteredList[Projekte.Bezeichnung = currentRecord.Projekte.Bezeichnung and Erledigt = true]) = cnt(filteredList[Projekte.Bezeichnung = currentRecord.Projekte.Bezeichnung]) then
"#dcf2de"
else
"#eee"
end,
columns: [{
field: "Erledigt",
title: arcCheckBox({
uniqueId: "checkbox all check",
value: Erledigt,
embedded: true,
clickAction: {
recordId: Nr,
fieldId: "G",
value: if cnt(list[Erledigt = true]) != cnt(list) then
false
else
if cnt(list[Erledigt = null]) = cnt(list) then
null
else
if cnt(list[Erledigt = true]) = cnt(list) then
true
end
end
end
}
}),
value: arcCheckBox({
uniqueId: "checkbox single check",
value: Erledigt,
embedded: true,
clickAction: {
recordId: Nr,
fieldId: "G",
value: if Erledigt = true then null else true end
}
}),
width: "100px",
align: "center",
fixed: "left",
groupValue: arcCustomIcon({
name: "caret-down"
})
}, {
field: "Bild",
title: "Logo",
width: "150px",
value:"",
actions: [{
recordId: Projekte.Nr,
type: "popup"
}],
groupValue: "",
}, {
field: "Projekt",
title: "Projekt",
width: "",
value: Projekte.Bezeichnung,
actions: [{
recordId: Projekte.Nr,
type: "popup"
}],
groupValue: Projekte.Bezeichnung,
}, {
field: "Aufgaben",
title: "Aufgabe",
value: Aufgabe,
align: "left",
width: "200px",
actions: [{
recordId: Nr,
type: "popup"
}, {
recordId: Nr,
type: "change",
field: "A"
}],
groupValue: if current.'Gruppieren nach' = 3 then
html(---
<b>{ Aufgabe }</b>
---)
end
}, {
field: "Mitarbeiter",
title: "Mitarbeiter",
value:"",
actions: [{
recordId: Mitarbeiter.Nr,
type: "popup"
}]
}, {
field: "delete",
title: "",
width: "40px",
align: "center",
value: "",
actions: [{
recordId: Nr,
type: "delete"
}]
}]
}],
footer: {
showFooter: true,
showActionButton: true,
actionButtonTitle: "Neue Aufgabe hinzufügen",
rightSideContent: "Gesamt: " + cnt(filteredList) + " Aufgaben"
}
};
arcCustomTable(data)
Weiterführende Links:
> NX Custom Table