generated from cms/tibi-docs
296 lines
13 KiB
Markdown
296 lines
13 KiB
Markdown
# fields
|
|
|
|
Felder im _tibi-server_ müssen einen bestimmten Datentyp haben. Über den _tibi-admin_ können die Felder über Widgets in unterschiedlichen Ausprägungen dargestellt werden (view-Widgets), bzw. dem Benutzer eine Eingabe abverlangen (input-Widgets).
|
|
|
|
Es gibt grundlegende Angaben, die jedes Feld haben muss um vom _tibi-server_ akzeptiert zu werden. Darüber hinaus kann auch jedes Feld ein `meta` Objekt haben, was dem _tibi-admin_ mitteilt, wie er dieses Feld für Ausgabe und Eingabe behandel soll.
|
|
|
|
Zunächst folgt der grundlegende Aufbau des Feld-Objektes:
|
|
|
|
```yaml
|
|
# Der Name des Feldes wird in der Datenbank zum Objekt ebenso
|
|
# wie in der Ein- und Ausgabe über die API verwendet.
|
|
name: date
|
|
|
|
# Über "type" wird der Datentyp in der Datenbank festgelegt.
|
|
# Mögliche Typen sind weiter unten aufgelistet.
|
|
type: date
|
|
|
|
# Direkt am Feld kann eine Index-Definition erfolgen.
|
|
# Folgende mögliche Werte können ihn die Liste aufgenommen werden:
|
|
# "single" - Standard-Index für diese Feld
|
|
# "unique" - Das Feld muss einen eindeutigen Wert haben
|
|
# "text" - Alle "text"-Indexanganben aller Felder werden zu einem
|
|
# gemeinsamen Volltext-Index kombiniert
|
|
#
|
|
# Die Angabe des Volltextindex ist besser unter "collections.X.indexes"
|
|
# vorzunehmen.
|
|
index:
|
|
- single
|
|
|
|
# Jede Datenübertragung an des Server wird validiert, d.h. es werden
|
|
# keine Datentypen angenommen, die nicht zu "type" passen.
|
|
# Darüber hinaus kann via "validator" eine zusätzliche Validierung
|
|
# vorgenommen werden.
|
|
# Dazu gibt es ein extra Kapitel.
|
|
validator:
|
|
required: true
|
|
eval: new Date($this) > new Date()
|
|
|
|
# Und natürlich gibt es auch hier ein "meta" Objekt zur Steuerung
|
|
# des tibi-admin.
|
|
meta:
|
|
# Das "label" des Feldes wird als Label vor dem Widget verwendet.
|
|
label:
|
|
de: Titel
|
|
en: title
|
|
|
|
# Abgelkeitet vom "type" gibt es Standard-Widgets. für spezielle
|
|
# Aufgaben stehen aber eine Hand voll Widgets bereit, die später
|
|
# beschrieben werden.
|
|
widget: date
|
|
|
|
# Standardwerte für neue Enträge können entweder direkt angegeben
|
|
# werden oder via Javascript client-seitig generiert werden.
|
|
# In den Kontext injizierte Variablen werden später beschrieben.
|
|
defaultValue:
|
|
# Das Ergebnis von "eval" wird hier als Standardwert verwendet.
|
|
# (hier das aktuelle Datum)
|
|
eval: new Date()
|
|
|
|
# Sollen Felder abhängig von bestimmten Bedingungen ein- oder
|
|
# ausgeblendet werden, geschieht das über Anweisungen in "dependsOn".
|
|
dependsOn:
|
|
# Das Feld wird nur eingeblendet wenn der Wert von "type"
|
|
# (auf gleicher Ebene wie das Feld "date" selbst)
|
|
# gleich "news" ist.
|
|
eval: $parent?.type == "news"
|
|
```
|
|
|
|
## validator Objekt
|
|
|
|
<video width="100%" controls muted autoplay loop>
|
|
<source src="validator.webm" type="video/webm">
|
|
</video>
|
|
|
|
Wie im Beispiel von **fields/date.yml** unter `validator` zu sehen ist, wird dort ein Datum nach dem aktuellen erwartet. Wie der Validator sich auf die UI auswirkt, ist im obigen Video zu sehen.
|
|
|
|
Das `validator` Objekt wird _tibi-server_ seitig genutzt um die Daten zu validieren. Da das `validator` Objekt dem _tibi-admin_ ebenso zur Verfügung steht, kann vorab eine client-seitige Validierung zusätzlich durchgeführt werden.
|
|
|
|
Attribute des Objektes:
|
|
|
|
| Attribut | Datentyp | Beschreibung |
|
|
| ----------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| `required` | boolean | wenn `true`, dann ist zwingend eine Eingabe zu diesem Feld nötig |
|
|
| `allowZero` | boolean | in Kombination mit `required: true`, wenn `true`, dann ist der jeweilige "Null"-Wert des Datentyps erlaubt<br><br>z.B. `type: string` erlaubt den leeren String und `type: number` erlaubt `0` |
|
|
| `eval` | string | Javascript-Code der zu true evaluieren muss um den Wert des Feldes als gültig zu definieren |
|
|
|
|
### eval-Attribut
|
|
|
|
Der Javascript-Code in diesem Attribut kann folgende Rückgabe-Werte haben:
|
|
|
|
| Wert | Bedeutung |
|
|
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
| `true` | Der Wert des Feldes ist gültig |
|
|
| `false` | Der Wert des Feldes ist ungültig |
|
|
| `"Text"` | Wird ein String zurückgegeben ist, wird der Wert es Feldes ebenso als ungültig erachtet und der String selbst ist eine benutzerdefinierte Fehlermeldung, die in der Serverantwort gelesen werden kann. |
|
|
|
|
Da der `eval` Code serverseitig immer ausgeführt wird und ein Fehlschlag zwangsläufig zum Abbruch der Serveraktion führt, ist es wichtig, dass der Validator berücksichtigt wird.
|
|
|
|
Optional kann der Code auch zusätzlich über eine Lauffähigkeit ohne Fehler (z.B. keine Verwendung nicht vorhandender Kontext-Variablen oder Verwendung von `try ... catch`) im _tibi-admin_ verfügen. Das hat den Vorteil, dass eine Vorab-Validierung stattfindet, bevor der Datensatz an der Server gesendet wird.
|
|
|
|
Sollte der `eval` Code im _tibi-admin_ nicht lauffähig sein (nicht abgefangene Exception), wird der Validator clientseitig ingoriert und nur die serverseitige Prüfung beeinflusst die Aktion.
|
|
|
|
#### siehe
|
|
|
|
- [Server Javascript Kontext](./../../server-javascript-kontext/allgemeines.md)
|
|
|
|
## dependsOn
|
|
|
|
<video width="100%" controls muted autoplay loop>
|
|
<source src="dependsOn.webm" type="video/webm">
|
|
</video>
|
|
|
|
Obige Darstellung wie im Video wird beispielsweise durch folgende Feld-Konfiguration erreicht:
|
|
|
|
```yaml
|
|
# in einer Kollektions-Konfiguration
|
|
fields:
|
|
- name: type
|
|
type: string
|
|
meta:
|
|
label:
|
|
de: Typ
|
|
en: Type
|
|
widget: select
|
|
choices:
|
|
- name:
|
|
de: Standardseite
|
|
en: Standard page
|
|
id: page
|
|
- name:
|
|
de: News
|
|
en: News
|
|
id: news
|
|
|
|
- name: title
|
|
type: string
|
|
meta:
|
|
label:
|
|
de: Titel
|
|
en: Title
|
|
|
|
- name: date
|
|
type: date
|
|
meta:
|
|
label:
|
|
de: Titel
|
|
en: title
|
|
widget: date
|
|
defaultValue:
|
|
eval: new Date()
|
|
dependsOn:
|
|
eval: $parent?.type == "news"
|
|
|
|
```
|
|
|
|
`meta.dependsOn` kann als Objekt mit `eval`-Attribut für Javascript oder als `string` mit dem Feldnamen (Punktschreibweise, z.B. `"additionalData.author"`) angegeben werden.
|
|
|
|
Wird der Feldname verwendet wird nur geprüft, ob das Feld belegt ist. TODO
|
|
|
|
Die `eval` Variante verwendet als Javascript-Kontext Variablen die auf folgenden Seite beschrieben werden:
|
|
|
|
- [Admin Javascript Kontext](./../../admin-javascript-kontext/allgemeines.md)
|
|
- [collection.meta..eval](./../../admin-javascript-kontext/collection.meta..eval.md)
|
|
- [field.meta..eval](./../../admin-javascript-kontext/field.meta..eval.md)
|
|
|
|
Die Rückgabe des Javascript-Codes beeinflusst die Einblendung des betroffenen Feldes in folgender Weise:
|
|
|
|
| Rückgabe | Bedeutung |
|
|
| -------- | -------------------------- |
|
|
| `true` | Das Feld wird angezeigt |
|
|
| `false` | Das Feld wird ausgeblendet |
|
|
|
|
## defaultValue
|
|
|
|
Für die Vorlegung neu anzulegender Datensätze kann in `field.meta.defaultValue` direkt der Standardwert hinterlegt werden, oder über `field.meta.defaultValue.eval` ein Javascript-Code angegeben werden, der den Wert ermittelt. Die Rückgabe des Javascript-Codes, sowie auch die direkte Vergabe des Wertes muss dem Datentyp des Feldes entsprechen.
|
|
|
|
Der Javascript-Kontext ist der gleiche wie bei `field.meta.dependsOn.eval`.
|
|
|
|
## containerProps
|
|
|
|
Um Felder auf breiten Bildschirmen eine schmalere Breite zu geben, wird das containerProps Attribut empfohlen. Es hat ein class Attribut, welches klassen ins HTML injiziert. Es gibt außerdem noch das Layout attribut mit breakBefore und breakAfter, welche dafür sorgen, dass vorher bzw. nachher keine weiteren HTML Elemente platz finden. Hier ist des weiteren das size Objekt drin, welches 3 attribute hat. Die attribute sollten col-1 bis col-12 beeinhalten, diese klassen werden ins html injiziert, können also dem zufolge auch misbraucht werden. Die klassen bei den attributen werden bei unterschiedlichen Bildschirmbreiten aktiv.
|
|
|
|
```yaml
|
|
containerProps:
|
|
#optional class prop
|
|
layout:
|
|
breakBefore: false
|
|
breakAfter: false
|
|
size:
|
|
default: "col-8"
|
|
small: "col-12"
|
|
large: "col-4"
|
|
```
|
|
|
|
## inputProps
|
|
|
|
Wenn man das Input element direkt bearbeiten möchte (Bspw. readonly oder ähnliches), so kann man diese hier als Objekt übergeben:
|
|
|
|
## hide
|
|
|
|
möchte man, dass ein bestimmtes Feld nicht im TibiAdmin sichtbar ist, so muss man die property hide auf true setzen.
|
|
|
|
```yaml
|
|
inputProps: { readonly: true, placeholder: { de: "Wert wird automatisch gesetzt", en: "Value is set automatically" } }
|
|
```
|
|
|
|
## direction
|
|
|
|
Für type Object[] gibt es im Meta objekt das direction attribut, dies kann entweder:
|
|
|
|
- `horizontal`: flex-direction: row
|
|
oder
|
|
- `vertical`: flex-direction: column
|
|
annehmen.
|
|
|
|
## metaElements
|
|
|
|
Möchte man bestimmte Elemente über das Zahnrad greifbar machen (bei type: Object[]), so kann man dies über dieses Attribut tun. Es ist entweder über eine Liste, oder über tablist möglich.
|
|
!!!include(../api/collections/fields/info.yml)!!!
|
|
|
|
## folding
|
|
|
|
Das folding Objekt ist ebenfalls ein Teil im Meta object und dient dazu, type ObjectArray einen Wert in den Header im HTML einzuschreiben (von den einzelnen Objekten). Es wird vorallem dazu genutzt, die Rows bzw. Columns der Website rein zu rendern, um praktisch ein direktes Prview zu haben. Ebenfalls gibt es das force attribut, welches dafür sorgt, dass die objekte IMMER geöffnet sind und man sie nicht schließen kann. Sinnvoll für Rows. die Generelle struktur verdeutlicht folgendes Code Beispiel:
|
|
|
|
```yaml
|
|
folding:
|
|
force: false
|
|
previewUnfolded:
|
|
raw: true
|
|
eval: |
|
|
//js
|
|
(() => {
|
|
return $this?.title ? "<h2 style=\"\">" + $this.title + "</h2>" : ""
|
|
})()
|
|
//!js
|
|
previewFolded:
|
|
eval: |
|
|
//js
|
|
(async () => {
|
|
const { getRenderedElement, Row } = await import($projectBase + "_/assets/dist/admin.mjs")
|
|
|
|
const container = getRenderedElement(Row, {
|
|
props: {
|
|
row: Object.assign({}, $this),
|
|
contentId: $?.id,
|
|
apiBaseURL: $projectBase,
|
|
},
|
|
addCss: [
|
|
$projectBase + "_/assets/dist/index.css",
|
|
$projectBase + "_/assets/dist/admin.css",
|
|
],
|
|
})
|
|
let style = "max-width: 1220px;"
|
|
container.style = style
|
|
return container
|
|
})()
|
|
//!js
|
|
```
|
|
|
|
Hierbei ist raw dafür da, das ganze als HTML direkt zu rendern, wenn es true ist. Der prefiewFolded bereich rendert letzten endes die Seite selbst, für diese Funktionallität ist mehreres notwendig.
|
|
|
|
- `Row und Column Komponenten`: Dies sind letzenendes jene komponenten die gerendert werden, daher muss man sie natürlich auch bereits programmiert haben.
|
|
- `admin.ts file`: Dieses file wird im src Folder platziert und durch ES-Build über den oben genutzen Pfad verfügbar gemacht. Hier ist ein Beispiel:
|
|
|
|
```ts
|
|
import Row from "./components/Row.svelte"
|
|
import Col from "./components/Col.svelte"
|
|
|
|
function getRenderedElement(component, options?: { props: { [key: string]: any }; addCss?: string[] }) {
|
|
const el = document.createElement("div")
|
|
el.attachShadow({ mode: "open" })
|
|
|
|
const target = document.createElement("body")
|
|
el.shadowRoot.appendChild(target)
|
|
|
|
options?.addCss?.forEach((css) => {
|
|
const link = document.createElement("link")
|
|
link.rel = "stylesheet"
|
|
link.href = css
|
|
link.type = "text/css"
|
|
el.shadowRoot.appendChild(link)
|
|
})
|
|
|
|
new component({
|
|
target: target,
|
|
props: options?.props,
|
|
})
|
|
|
|
return el
|
|
}
|
|
|
|
export { getRenderedElement, Row, Col }
|
|
```
|
|
|
|
Das props Attribut nimmt ein Objekt entgegen, welches als keys die namen hat, wie in der svelte Komponente über export exportiert wurde. Die Komponenten werden in eine Shadow Dom geladen, um sie seperat vom restlichen code halten zu können.
|