Benutzerdefinierte Komponente
Erstelle benutzerdefinierte, datengesteuerte Seitenoberflächen mit Ninox Script und JSX-ähnlichem Markup.
Mit Benutzerdefinierte Komponente erstellst du eigene Oberflächen auf einer Seite. Schreibe dafür einen einzelnen Ninox-Script-Ausdruck, der ein Markup-Element zurückgibt. Du verwendest JSX‑ähnliche Tags direkt in Ninox Script. Kombiniere Live-Datensatzdaten, Buttons und Ereignisse mit fertig gestalteten Bausteinen. Dafür brauchst du keine separate Widget-Datei, keinen Bundler und keinen Upload.
Wenn du bereits ein Funktionsfeld erstellen kannst, kennst du bereits das Wesentliche. Ein Ausdruck in der Benutzerdefinierten Komponente wird im Kontext des aktuellen Datensatzes ausgewertet. Der einzige Unterschied besteht darin, dass er keine Zahl oder keinen Text zurückgibt, sondern eine Benutzeroberfläche.
Benutzerdefinierte Komponente hinzufügen
Tab Hinzufügen öffnen
Öffne im Einstellungsbereich den Tab Hinzufügen.
Benutzerdefinierte Komponente hinzufügen
Ziehe die Benutzerdefinierte Komponente aus Basiskomponenten an die gewünschte Stelle auf der Seite.
Benutzerdefinierte Komponente konfigurieren
Erweitere in den Einstellungen der Komponente den Bereich Allgemein. Wähle unter Logik , um den Skript-Editor zu öffnen. Gib den Ausdruck ein, der deine Benutzerdefinierte Komponente zurückgibt.
Ergebnis prüfen
Prüfe das erwartete Ergebnis. Ziehe die Komponente, um sie zu verschieben. Nutze die Anfasser, um ihre Größe anzupassen.
Schreibe deinen ersten Ausdruck
Dein Ausdruck muss den Typ react zurückgeben. Dabei handelt es sich um ein einzelnes Wurzelelement in Tag-Syntax. Alle übrigen Funktionen von Ninox Script funktionieren weiter: let, function, if/else, for, switch, select und die gesamte Funktionsbibliothek.
<div class="p-4">
<h2 class="text-lg font-bold">Hello, {first_name}</h2>
<p class="text-default-500">Welcome back.</p>
</div>Das Ergebnis wird direkt auf der Seite im Kontext des aktuellen Datensatzes gerendert. Gibt der Ausdruck nicht den Typ react zurück, siehst du: „Der Ausdruck muss den Typ react zurückgeben. Verwende HTML-Tag-Syntax, um deine Oberfläche zu erstellen.“
Tags: HTML und Komponenten
Die Elementsyntax ist JSX‑ähnlich:
<tag ...attributes>...children...</tag> // with children
<tag ... /> // self-closingDer erste Buchstabe des Tag-Namens bestimmt den Typ:
Kleinschreibung
Natives HTML-Element
div, span, p, button, input, a, img, ul, li, h1–h6, table
Großschreibung
Eine Komponente
Deine eigene function oder eine integrierte Komponente wie <Button>, <Card>, <Field>
Standard-HTML-Attribute funktionieren bei Tags in Kleinschreibung: class, id, style, href, src, type, placeholder usw.
Bei Tags in Großschreibung löst Ninox den Namen in dieser Reihenfolge auf: Zuerst verwendet Ninox deine eigene function mit diesem Namen. Gibt es keine, verwendet Ninox eine integrierte Komponente mit diesem Namen. Ist auch diese nicht vorhanden, erscheint die Warnung „Funktion nicht gefunden“.
Benenne eigene Funktionen nicht nach integrierten Tags.
Attribute: statisch und dynamisch
Zeichenfolge in Anführungszeichen: ein Literal
Geschweifte Klammern: ein beim Rendern ausgewerteter Ninox-Ausdruck
Attribut ohne Wert: Kurzform für ={true}
Einfacher Text wird unverändert gerendert.
{ ... } bettet den Wert eines Ausdrucks als Text ein.
Erstelle Listen mit einer Schleife, die ein Array von Elementen zurückgibt.
Deine Datensatzdaten verwenden
Der Ausdruck läuft im Kontext des aktuellen Datensatzes, genau wie ein Funktionsfeld:
Referenziere ein Feld über seinen Namen, etwa
first_name,amountoderstatus.Greife auf verknüpfte Datensätze zu, etwa
Contacts.emailoderline_items.Verwende die gesamte Ninox-Script-Funktionsbibliothek, etwa
select,sum,format,openRecord,alertundicon.
Verwende { field_name }, wenn du nur den Wert als Text benötigst. Verwende das Tag <Field>, wenn du das echte, bearbeitbare Widget benötigst.
Event-Handler
Jedes Attribut, dessen Name mit on beginnt, etwa onClick, onChange oder onPress, ist ein Event-Handler. Er läuft beim Auslösen des Ereignisses, nicht beim Rendern. Er muss eine Funktion sein.
Handler können Seiteneffekte auslösen, etwa eine Nachricht anzeigen, einen Datensatz öffnen, in ein Feld schreiben oder reaktiven Status aktualisieren.
Verwende einen Parameter, um Daten zum Ereignis zu lesen.
Das empfangene Ereignis ist eine sichere Momentaufnahme. Es ist ein einfaches Objekt mit nur den relevanten primitiven Feldern, zum Beispiel:
Ein Mausereignis stellt
clientX/buttonbereit.Ein Tastaturereignis stellt
key/codeund ein verschachteltestargetbereit (id,name,value,checked,tagNameusw.).
Live-DOM-Knoten werden deinem Skript nicht direkt verfügbar gemacht.
Bevorzuge bei HeroUI-Komponenten wie <Button> onPress statt onClick. Es verhält sich bei Maus, Touch und Tastatur einheitlich.
Reaktiver Status mit let
Ein let in einem Ausdruck einer Benutzerdefinierten Komponente ist ein reaktiver Komponentenstatus. Er funktioniert wie ein kleiner Speicher:
Seine Initialisierung läuft einmalig und setzt den Wert. Spätere Render-Vorgänge verwenden den gespeicherten Wert.
Eine Neuzuweisung (
:=) in einem Event-Handler speichert den neuen Wert und rendert die Komponente erneut.Nur Neuzuweisungen in einem Handler bleiben bestehen. Ein
let, das du beim Rendern neu zuweist, etwa eine Schleifensumme, wird bei jedem Rendern zurückgesetzt. Es bleibt ein gewöhnlich berechneter Wert.Der Status gilt pro Instanz. Ein
letim Schleifenrumpf oder in einer großgeschriebenenfunction-Komponente erhält jedes Mal einen eigenen unabhängigen Wert.Der Status wird zurückgesetzt, wenn sich der Datensatz ändert oder du den Ausdruck bearbeitest.
Zählerbeispiel:
Status pro Instanz in einer Komponente innerhalb einer Schleife:
Eine Berechnung zur Renderzeit (kein Status, wird bei jedem Rendern neu berechnet):
Das Tag <Field>
<Field> bindet ein Datenbankfeld direkt mit dem entsprechenden Ninox-Editor ein. Je nach Feldtyp wird beispielsweise ein Texteingabefeld, ein Datumswähler, eine Auswahlliste, ein Datei-Upload oder eine Referenzauswahl angezeigt. Es gibt nicht nur den Feldwert aus, sondern stellt ein voll funktionsfähiges Eingabeelement bereit. Das Tag ist selbstschließend.
Attribute
field
✅
Der Skriptname des Feldes.
module
Modulname. Standardmäßig der aktuelle Kontext.
table
Tabellenname. Standardmäßig der aktuelle Kontext.
row
Zeilen-ID (Zahl). Standardmäßig die Zeile des aktuellen Kontexts.
readonly
Rendert das Feld schreibgeschützt.
So funktioniert die Zielauswahl
Standardmäßig ist das Feld mit dem aktuellen Modul, der aktuellen Tabelle und dem aktuellen Datensatz verknüpft.
module,tableundrowgreifen jeweils unabhängig auf den umgebenden Kontext zurück. Du musst daher nur die Werte angeben, die vom Standard abweichen.Sobald du
moduleodertableüberschreibst, gilt die aktuelle Zeile nicht mehr. Sie gehört zu einer anderen Tabelle. Gib daher eine expliziterowan:rowakzeptiert eine Zahl (row={1}), eine numerische Zeichenfolge (row="1") oder einen Ausdruck (row={this.id},row={item.id}).Mache ein Feld mit
readonlyschreibgeschützt:
Änderungen in einem <Field> werden in den Zieldatensatz zurückgeschrieben, außer bei readonly.
Referenz- und Rückreferenzfelder
<Field> unterstützt Referenz- und Rückreferenzfelder vollständig. Die Auswahl wird wie an anderen Stellen in Ninox gerendert. Bei diesen Typen zeigt die eingebettete Auswahl die ersten fünf Spalten der referenzierten Tabelle.
Faustregel: Verwende <Field field="…" /> für das echte interaktive Widget. Verwende { field_name }, wenn du nur den Wert als Text benötigst.
Integrierte Komponenten (HeroUI)
Diese sofort einsatzbereiten Komponenten werden über Tags mit großgeschriebenen Namen eingebunden. Sie passen sich automatisch dem aktuell verwendeten Hell- oder Dunkelmodus an.
Verfügbare Komponenten
ButtonIconCardCardHeaderCardBodyCardFooterModalModalContentModalHeader
ModalBodyModalFooterPopoverPopoverTriggerPopoverContentProgressTabsTab
TableTableHeaderTableColumnTableBodyTableRowTableCellTooltipField
Button
Die Beschriftung steht in den Kindelementen.
Häufige Props:
color,variant,size,radiusBoolean-Props:
isDisabled,isLoading,isIconOnly,fullWidthBevorzuge
onPress.
Card
Card unterstützt shadow, radius, fullWidth, isHoverable und isPressable.
Tabs
Jedes <Tab> benötigt einen eindeutigen key und einen title.
Table
Die Anzahl der Zellen muss den Spalten entsprechen. Gib jeder Zeile einen eindeutigen key.
Table unterstützt isStriped, isCompact, hideHeader, removeWrapper und selectionMode.
Progress
Tooltip
content und genau ein Trigger-Kindelement. Verfügbare Props sind placement, color, delay und closeDelay.
Popover
Modal
Steuere die Sichtbarkeit mit einem Boolean-Wert für isOpen, der an ein reaktives let gebunden ist. Größen reichen von sm bis 5xl oder full. Dieses Beispiel bettet auch bearbeitbare <Field>s ein:
Modal unterstützt:
isOpenonOpenChangeonClosesizeplacementbackdropradiusscrollBehaviorBoolean-Props:
isDismissableisKeyboardDismissDisabledhideCloseButtonshouldBlockScroll.
Eigene Komponenten mit function
Definiere wiederverwendbare Elemente mit einer großgeschriebenen function:
Attribute werden anhand ihres Namens (nicht ihrer Position) Parametern zugeordnet. Für Parameter ohne passende Zuordnung wird
nullverwendet.Ein Parameter namens
children(Typreact[]) erhält die verschachtelten Kindelemente:
Erstelle deine Benutzeroberfläche aus kleinen, wiederverwendbaren Komponenten.
Styling mit Tailwind-Klassen
Gestalte Elemente mit Tailwind-Utility-Klassen im Attribut class. Beachte dabei eine wichtige Regel:
Es steht nur eine feste, geprüfte Auswahl an Tailwind-Utilities bereit. Da Klassenzeichenfolgen zur Laufzeit berechnet werden, kann Tailwind sie beim Build nicht erkennen.
Klassen außerhalb der unterstützten Auswahl haben keine Wirkung. Klassen mit beliebigen Werten funktionieren nie. Das betrifft alle Klassen mit eckigen Klammern wie w-[473px], bg-[#1e90ff] oder [&>div]:….
Verwende für individuelle Werte stattdessen das Attribut style:
Verfügbare Klassen
Layout
block inline-block inline flex inline-flex grid hiddenflex-row/col/wrapitems-*justify-*self-*grid-cols-1..6(+12)col-span-1..6/fullflex-1 grow shrink
Abstände
p/px/py/pt/pr/pb/plm…(einschließlichm*-auto)gap/gap-x/gap-yspace-x/space-ymit den Werten0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24
Größen
w-full/auto/fit/screenund Brüche wiew-1/2,w-1/3,w-2/3,w-1/4usw.max-w-xs..4xl/fullmin-w-0feste Höhen
h-4 … h-64h-full/auto/fitmax-h-40/60/80/96/fullsize-4/6/8/10/12
Es gibt keine Utilities für die Höhe des Wurzelelements wie h-screen. Versuche nicht, die Gesamthöhe der Komponente festzulegen.
Typografie
text-xs..4xlfont-thin..extraboldtext-left/center/right/justifyitalic,underline,line-through,uppercase,lowercase,capitalize,truncate,whitespace-nowrap,break-wordsleading-*tracking-*
Farben
text-/bg-/border-in allen Standard-Tailwind-Familien (slate…rose) mit Abstufungen von50bis900sowiewhite,black,transparent,currentBevorzuge die semantischen Theme-Tokens:
default,primary,secondary,success,warning,danger,foreground,content1-4,divider,overlaymit optionalen Suffixen wie-50..900oder-foreground. Beispiele sindbg-primary,text-foreground,bg-content1,text-default-500undborder-divider. Diese passen sich automatisch an das helle oder dunkle Design an.
Rahmen und Eckenradius
border border-0/2/4/8seitliche Rahmen
border-solid/dashed/dottedrounded … rounded-full
Effekte
shadow shadow-sm..2xl shadow-innerring ring-0/1/2/4opacity-0/25/50/75/90/100.
Position und Überlauf
static,relative,absolute,fixed,stickyinset-0top/right/bottom/left-0z-0..50overflow-*
Hintergründe, Anpassung und Seitenverhältnis
bg-cover/contain/centerobject-cover/contain/fillaspect-square/video
Interaktivität und Bewegung
cursor-*select-*pointer-events-*transition,transition-colors,transition-transformduration-100/150/200/300/500ease-*scale-95/100/105rotate-45/90
Variantenpräfixe
Nur diese Präfixe werden erzeugt:
hover:,focus:,dark:für Farb-Utilitiesmd:,lg:für Layout-, Abstands-, Größen- und Text-Utilities
Nicht verfügbar: active:, disabled:, group-hover:, sm:, xl:, 2xl:. Steuere Zustände wie aktiv oder deaktiviert mit einem Event-Handler und einem reaktiven let. Du kannst die Klassenzeichenfolge auch selbst berechnen:
Die integrierten HeroUI-Komponenten sind unabhängig von der Safelist immer vollständig gestaltet. Mit Komponenten wie <Card>, <Button> und ähnlichen erhältst du daher am einfachsten ein professionelles und konsistentes Erscheinungsbild.
Die Option „Shadow DOM verwenden“
Jede Benutzerdefinierte Komponente verfügt über die Option Shadow DOM verwenden (standardmäßig deaktiviert).
Ist diese Option aktiviert, wird die Komponente innerhalb eines Shadow DOM gerendert, wodurch ihre Styles isoliert werden. Das CSS der Komponente kann keine Auswirkungen auf den Rest der Seite haben, und umgekehrt können Styles der Seite nicht in die Komponente hineinwirken. Aktiviere diese Option, wenn die Gestaltung einer Komponente vollständig unabhängig vom übrigen Seitenlayout sein soll.
Hinweise:
Tailwind- und HeroUI-Klassen funktionieren weiterhin im Shadow DOM. Ninox lädt das Theme-Stylesheet in den Shadow Root.
Da dieses Stylesheet asynchron geladen wird, kann der Inhalt beim ersten Rendern kurzzeitig ohne Styles angezeigt werden.
Interaktivität wie Ereignisse, HeroUI-Popovers oder die Fokusverwaltung funktionieren auch über die Grenze des Shadow DOM hinweg. Es gibt keine funktionalen Unterschiede.
Lass die Option deaktiviert, wenn du keine Stilisolierung benötigst.
Sicherheit und Einschränkungen
Sicherheitsmechanismen
Dein Ausdruck erzeugt einen strukturierten Elementbaum, keinen HTML-String. Dadurch gibt es keine Angriffsfläche für die direkte Einbindung von HTML- oder JavaScript-Code.
Bestimmte Tags werden blockiert:
script,iframe,object,embed,link,meta,base,body,head,html,title.<style>ist erlaubt. Ist Shadow DOM aktiviert, werden die Styles auf die Komponente beschränkt.URLs in Attributen wie
href,src,actionund ähnlichen werden geprüft. Zulässig sind nur die Protokolle:http,https,mailtoundtel. Das Protokolldata:ist ausschließlich für das Attributsrcfür Inline-Bilder erlaubt.Event-Handler verwenden nur Ninox Script und werden mit den regulären Berechtigungen deines Skripts ausgeführt. Die Ausführung von JavaScript-Code in Form von Zeichenketten wird nicht unterstützt.
Diese Sicherheitsmechanismen dienen der Inhaltsisolation für vertrauenswürdige Arbeitsbereich-Builder, also die Autoren der Ausdrücke. Wenn vollständig nicht vertrauenswürdiger Code von Drittanbietern ausgeführt werden soll, verwende stattdessen Custom Widgets. Diese werden in einer isolierten iframe-Sandbox ausgeführt.
Wichtige Hinweise
Der Ausdruck muss einen Wert vom Typ
reactzurückgeben. Er benötigt ein einzelnes Wurzelelement, sonst wird nichts gerendert.Es stehen nur die freigegebenen Tailwind-Klassen zur Verfügung. Beliebige Werte und viele Varianten-Präfixe werden nicht unterstützt.
Lege die Gesamthöhe der Komponente nicht im Wurzelelement fest. Die Seite verwaltet die Größe.
Eingebettete Auswahlfelder für Referenzen und Rückreferenzen zeigen die ersten fünf Spalten der referenzierten Tabelle.
Der reaktive
let-Status wird zurückgesetzt, wenn sich der Datensatz ändert oder du den Ausdruck bearbeitest. Nur Neuzuweisungen in Handlern bleiben erhalten.Tritt in einer Komponente ein Fehler auf, bleibt dieser auf die betreffende Komponente beschränkt. Die übrigen Komponenten und die restliche Seite funktionieren weiterhin.
Fehlerbehebung
„Der Ausdruck muss den Typ react zurückgeben.“
Dein Ausdruck endet nicht mit einem Tag. Der letzte Ausdruckswert muss ein Element sein.
Eine CSS-Klasse hat keine Wirkung
Die Klasse wird nicht unterstützt oder verwendet einen beliebigen Wert ([...]). Nutze eine unterstützte Klasse oder das Attribut style.
Ein Klick löst nichts aus
Der Handler muss eine Funktion sein: onClick={function () do … end}, nicht onClick={doThing()}.
Ein Zähler oder Schalter wird sofort zurückgesetzt
Du hast let beim Rendern neu zugewiesen statt innerhalb eines Handlers. Nur Neuzuweisungen in Handlern bleiben erhalten.
„Funktion nicht gefunden“ bei einem großgeschriebenen Tag
Es handelt sich weder um eine definierte function noch um eine integrierte Komponente. Prüfe Schreibweise und Groß-/Kleinschreibung.
<Field>-Fehler: „hat keine Zeile im Kontext“
Du hast module oder table angegeben und musst daher auch explizit row angeben.
<Field>-Fehler: „kann nur innerhalb einer Benutzerdefinierten Komponente verwendet werden“
<Field> funktioniert nur innerhalb eines Ausdrucks einer Benutzerdefinierten Komponente.
Ein Tag fehlt in der Ausgabe
Der Tag kann blockiert sein, etwa script oder iframe. Möglich ist auch eine URL mit nicht erlaubtem Protokoll.
Zuletzt aktualisiert
War das hilfreich?