Skip to main content
Skip table of contents

Javascript im Frontend

be Dynamic YAML Templates

Ein Designprinzip des be Portals ist eine umfassende, individuell konfigurierbare Anpassbarkeit. Damit kann das be Portal an die Anforderungen und Bedürfnisse des Benutzers angepasst werden, ohne den Code im Produkt zu ändern. Diese Anpassbarkeit spiegelt sich auch in der Konfiguration, den Pages und Workflows wider.

Dynamische YAML-Konfiguration im Frontend erfolgt über YAML und JavaScript und kann für viele Felder genutzt werden. Zu beachten ist, dass das Ergebnis des JavaScript dem Werteschema des Feldes entspricht.

Nutzung im YAML Format

Die dynamischen Elemente im Schema werden über script_or_<type> Definitionen im YAML Schema beschrieben.

$expr

Ein JavaScript Ausdruck (expression), welches den Wert der Eigenschaft dynamisch zur Laufzeit berechnet.

Der JavaScript Code kann über die Variable $ auf Kontextdaten zugreifen.

Beispiele:

  • `Berechneter` + ` Text`

  • `Wert: ` + $.variables.custom_var

$statement

Ein JavaScript-Code, der den Wert der Eigenschaft dynamisch zur Laufzeit berechnet.
Der JavaScript-Code muss den Wert per return zurückgeben.

Der JavaScript-Code kann über die Variable $ auf Kontextdaten zugreifen.

Beispiele:

  • return `Berechneter` + ` Text`

  • return `Wert: ` + $.variables.custom_proc_var

$script

Ein JavaScript-Code, der in der Regel durch eine Aktion ausgelöst wird (bspw. Button → Klick-Event, EntityGrid → onLoaded-Event).
Der JavaScript-Code kann beliebige Aktionen ausführen, wie z.B. Variablenzuweisungen oder Backend-Aufrufe.

Der JavaScript-Code kann über die Variable $ auf Kontextdaten zugreifen.

Beispiele:

  • $.variables.var1 = 'Hello World';

  • backend.execute($.variables.backendAction);

Variablenzuweisungen werden innerhalb eines $script synchron durchgeführt. Erst nach dem letzten Ausdruck innerhalb dieses $script erfolgt jedoch das “Speichern” der Variablenänderungen (wodurch z.B. abhängige Controls aktualisiert werden).
Wenn Variablenänderungen schon während der $script-Ausführung gespeichert werden sollen, ist der Aufruf von await $.controller.flush(); erforderlich.
Außerdem werden innerhalb eines $script Variablen vom Typ entityInstance nicht automatisch aktualisiert, wenn sich bspw. deren primaryKey ändert. Dies passiert erst nach vollständig $script-Ausführung oder nach einem await $.controller.flush()-Aufruf. Wenn die EntityInstance jedoch schon innerhalb des $script aktualisiert werden soll, kann dies mit dem Aufruf von await $.controller.refreshEntityInstance('<entityInstanceName>') erreicht werden.

Kontext Objekte

Der JavaScript-Code bekommt beim Aufruf einen Kontext übergeben. Dieser Kontext stellt den aktuellen Zustand der be Portal Oberfläche für das Skript dar, während es ausgeführt wird. Der Kontext hat klar definierte Eigenschaften und enthält auch einige Hilfsfunktionen, die bei der Ausführung des Skripts verwendet werden können.

Innerhalb des Kontexts werden verschiedene Klassen von Objekten zur Verfügung gestellt. Allgemein gibt es das GenericContextObject, sowie spezielle Klassen auf Basis von YAML Objekten, die mit Hilfsfunktionen zum Auslesen der YAML Informationen angereichert werden.

Der JavaScript Code kann über die Variable $ auf Kontextdaten zugreifen. Verfügbare Kontextdaten sind:

  • $.pageId

  • $.loginUser (Information des eingeloggten Users)

  • $.users (User-bezogene Funktionen)

  • $.format (Formatierungsfunktionen)

  • $.variables (im Fall einer Page mit definierten Variablen)

  • $.controller (im Fall einer JavaScript-Ausführung per $script)

  • $.event (im Fall eines ausgelösten Events)

  • $.processVariables (im Fall eines Workflow Formulars)

  • $.tableRowContext [deprecated] (hier stehen die Werte der aktuellen Tabellenzeile zur Verfügung)

  • $.dataSet (hier stehen die Werte der aktuellen Tabellenzeile zur Verfügung)

  • $.ocrData (im Fall eines durch OCR analysierten PDF-Dokuments im Eingangsrechnungsworkflows)

  • $.workflow (Workflow-spezifische Funktionen)

  • $.dialog (Funktionen für das Management von Sub-page Modals)

  • $.customControl (Zugriff auf die iFrames von CustomControls für die Kommunikation mit diesen)

  • $.debug (Hilfs-Funktionen zum debuggen)

  • $.notify (Funktionen zum Anzeigen von Toasts)

  • $.command (Funktionen zum Ausführen von Commands)

  • $.backend (Funktionen zum Ausführen von beas Backend Skripten)

  • $.isMobile (Hilfs-Funktion um herauszufinden ob man sich auf einem mobilen Device befindet)

  • $.expertModeEnabled() (Funktion um herauszufinden, ob der Expertenmodus aktiviert ist)

  • $.navigation

  • $.documents

pageId

ID der Page durch welche das JavaScript ausgeführt wird im Format:

<Package-Key>.<PageId>:<Unique-Identfifier>

Der Identifier wird zur Laufzeit erstellt, damit mehrere Page Instanzen mit der gleichen ID unterschieden werden können.

Beispiel:

YAML
id: BSP.beispiel-page
controls:
  - controlType: button
    label: Zeige Page ID
    events:
      click:
        $script: |
          debug.log($.pageId);

loginUser

Informationen zum eingeloggten User

Eigenschaft

Beschreibung

name

Anzeigename des Benutzers

emailAddress

E-Mail Adresse aus dem Personalstamm

groups

Array von Gruppen IDs zu welchen der Beutzer zugeordnet ist

roles

Array von Rollennamen zu welchen der Beutzer zugeordnet ist

isPortalUser

true wenn der Benutzer die Rolle BE.portalUser hat, false andernfalls

personnelId

Datensatz ID im Personalstamm

userKey

Eindeutiger Benutzerschlüssel.

U für DabUSR

A für DabALD

ID des jeweiligen Datensatzes

Methode

Beschreibung

hasRole(roleName)

Gibt an ob der Benutzer zu einer Rolle gehört. Der Vergleich erfolgt CaseInsensitive

isPackageAdmin(packageKey)

Gibt an ob der User admin für das Package ist. Der Vergleich erfolgt CaseInsensitive

isPackageUser(packageKey)

Gibt an ob der User user für das Package ist. Der Vergleich erfolgt CaseInsensitive

packageRoles(packageKey)

Gibt ein Array von Package Rollen zurück, zu denen Der User gehört. Der Vergleich erfolgt CaseInsensitive

Beispiel:

YAML
controls:
  - controlType: button
    label: Zeige Login User
    events:
      click:
        $script: |
          $.debug.log($.loginUser);
          $.debug.log($.loginUser.isPackageAdmin('ERU'));
          $.loginUser.packageRoles('ERU').forEach(role => $.debug.log(role));

users

Über $.usersstehen Hilfsfunktionen für den Umgang mit User-Daten bereit. Nachfolgende Funktionen sind darin enthalten.

Methoden

Beschreibung

keyToName(userKey)

Gibt den dem userKey entsprechenden Benutzernamen zurück, falls möglich. Ansonsten wird der userKey zurückgegeben.

Beispiel:

YAML
controls:
  - controlType: button
    label: Zeige Login User
    events:
      click:
        $script: |
          debug.log($.users.keyToName('U65'));
          debug.log($.users.keyToName($.loginUser.userKey));

format

Über $.format stehen Formatierungsfunktionen bereit.

Methode

Beschreibung

date(value, options?)

Der value kann bspw. eine Zeit in Millisekunden oder ein menschenlesbares Datum als String sein.

Optional können options gesetzt werden, welche standardmäßig folgende Ausprägungen haben:

JS
{ year: '2-digit',
  month: '2-digit',
  day: '2-digit',}

Weitere Optionsmöglichkeiten werden im Unterpunkt “mögliche Optionen” beschrieben.

datetime(value, options?)

Der value kann bspw. eine Zeit in Millisekunden oder ein menschenlesbares Datum als String sein.

Optional können options gesetzt werden, welche standardmäßig folgende Ausprägungen haben:

JS
{ year: '2-digit',
  month: '2-digit',
  day: '2-digit',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric',}

Weitere Optionsmöglichkeiten werden im Unterpunkt “mögliche Optionen” beschrieben.

time(value, options?)

Der value kann bspw. eine Zeit in Millisekunden oder ein menschenlesbares Datum als String sein.

Optional können options gesetzt werden, welche standardmäßig folgende Ausprägungen haben:

JS
{ hour: 'numeric',
  minute: 'numeric',
  second: 'numeric',}

Weitere Optionsmöglichkeiten werden im Unterpunkt “mögliche Optionen” beschrieben.

duration(value, pretty?)

Der value ist eine in Millisekunden angegebene Zeitdauer. Sie wird standardmäßig nach dem Pattern D'd' HH:mm:ss formatiert, also z.B. “5d 13:46:32“.

Wurde der Parameter pretty (Boolean - true oder false) gesetzt, so wird der Wert nach dem Pattern D'd' H'h' M'm' S's' formatiert, also z.B. "5d 13h 46m 32s".

Beispiel:

JS
controls:
  - controlType: button
    label: Zeige Login User
    events:
      click:
        $script: |
          const now = new Date(); // 24.05.2024 - 13:05:23 Uhr
          debug.log($.format.date(now)); // Ausgabe: "24.05.24"
          debug.log($.format.datetime(now)); // Ausgabe: "24.05.24, 13:05:23"
          debug.log($.format.time(now)); // Ausgabe: "13:05:23"
          // mit Optionen:
          debug.log($.format.datetime(now, {weekday:'long',
                                            year:'numeric',
                                            month:'long',
                                            hour12:true}));
          // Ausgabe: "Freitag, 24. Mai 2024 um 1:05:23 PM"

mögliche Optionen:

Bei den $.format - Methoden date, datetime und time ist es möglich options optional bei der Erstellung mitzugeben. Diese options müssen als Objekt definiert werden und können folgende Parameter mit folgenden Werten enthalten:

year - Repräsentation des Jahres - mögliche Werte: 'numeric' und '2-digit'

month - Repräsentation des Monats- mögliche Werte: 'numeric', '2-digit', 'long', 'short', 'narrow'

day - Repräsentation des Tages- mögliche Werte: 'numeric' und '2-digit'

hour - Repräsentation der Stunde - mögliche Werte: 'numeric' und '2-digit'

minute - Repräsentation der Minute - mögliche Werte: 'numeric' und '2-digit'

second - Repräsentation der Sekunde - mögliche Werte: 'numeric' und '2-digit'

Weitere Optionen sind in der offiziellen Mozilla-Dokumentation zu finden: Parameter DateTimeFormat

variables

Die Variablen einer Page können über den Javascript-Kontext gelesen und geschrieben werden. Im Beispiel wird eine Variable matchcode mit dem Wert TOPF_B1 vorbelegt.

Im Input kann der Matchcode angepasst werden und per Button-Klick wird der Name in der Debug-Konsole ausgegeben. Mit dem Löschen-Button wird der Matchcode auf einen leeren String gesetzt.

YAML
# article.page.yml
data:
  variables:
    matchcode:
      type: string
      value: TOPF_B1
controls:
  - controlType: input
    type: text
    value:
      $bind: matchcode
  - controlType: button
    label: Zeige Matchcode
    events:
      click:
        $script: |
          debug.log($.variables.matchcode);
  - controlType: button
    label: Lösche Matchcode
    color: danger
    events:
      click:
        $script: |
          $.variables.matchcode = '';

controller

Der $.controller-Kontext steht in $script-Codes bereit und unterstützt bei der Steuerbarkeit von Asynchronität.

Methode

Beschreibung

flush()

async - Speichert Variablenänderungen, die bisher innerhalb dieses $script vorgenommen wurden.

refreshEntityInstance(variableName)

async - Aktualisiert die angegebene EntityInstance-Variable innerhalb des aufrufenden $script. Die Funktion wird benötigt, wenn die EntityInstance-Aktualisierung nicht erst nach, sondern bereits während der $script-Ausführung erforderlich ist.

scriptFinished()

Gibt zurück, ob die Ausführung des synchronen $script-Codes abgeschlossen ist. Wenn in einem $script asynchroner Code ausgeführt und nicht darauf gewartet wird, wurde u.U. der abschließende, implizite flush()-Aufruf bereits durchgeführt. Ist dies der Fall, kann das mit dieser Funktion geprüft werden, um ggf. im asynchronen Code einen manuellen, abschließenden flush()-Aufruf durchzuführen.

Beispiel:
Anzeige des Feldes bez1 zur einer artnr mit Lade-Text (während die Daten geladen werden) und Benachrichtigung (sobald die Daten geladen wurden)

YAML
data:
  variables:
    artnr:
      type: string
      value: TOPF_B1
    article:
      type: entityInstance
      source: odata
      entity: Dab010
      primaryKey:
        $bind: artnr
    loadingText:
      type: string
controls:
  - controlType: text
    value:
      $bind: loadingText
  - controlType: input
    type: text
    value:
      $bind: artnr
  - controlType: text
    value:
      $bind: article.bez1
  - controlType: button
    label: Artikel TOPF_B2
    events:
      click:
        $script: |
          $.variables.loadingText = 'Lade Daten...';
          await $.controller.flush(); // notwendig, damit die Variablenänderung gespeichert und der Lade-Text im Control angezeigt wird
          $.variables.artnr = 'TOPF_B2';
          // $.variables.article.bez1 hätte hier noch den Wert der vorherigen artnr (TOPF_B1)
          await $.controller.refreshEntityInstance('article');
          // $.variables.article.bez1 hat hier den neuen Wert
          notify.success('Artikel TOPF_B2 hat die Bezeichnung ' + $.variables.article.bez1);
          $.variables.loadingText = '';
          // $.controller.flush() ist hier nicht notwendig, da es am Ende des $script automatisch ausgeführt wird

event

Eigenschaften

Beschreibung

elementId?

Eindeutige, intern vergebene ID des Oberflächen Controls

pageId

Eindeutige Page ID

Je nach Event hat das Objekt weitere Eigenschaften.

beforeValueChanged / afterValueChanged

Eigenschaften

Beschreibung

previousValue

Wert der Variablen vor der Änderung

value

Wert der Variablen nach der Änderung

variableName

Name der Variable die sich geändert hat.

processVariables

processVariables sind das gleiche wie variables mit dem Unterschied, dass diese Variablen vom Prozess definiert werden und nicht von der Page.

tableRowContext

[DEPRECATED]: Der tableRowContext ist veraltet, sodass eine einwandfreie Funktionsweise nicht mehr garantiert ist. Stattdessen sollte dataSet (Javascript im Frontend | dataSet) verwendet werden.

Der tableRowContext ist genauso aufgebaut wie die Prozessvariablen. Es ist jedoch ein Objekt mit allen Spalten als Eigenschaften und dem Zelleninhalt als Wert. Folgende Tabelle:

CODE
| Name | City | Amount |
------------------------
| Max | Ulm   | 1337   |

sieht im Kontext so aus:

TYPESCRIPT
$ = {
  tableRowContext: {
    Name: {
      type: "Text",
      value: "Max"
    },
    City: {
      type: "Text",
      value: "Ulm"
    },
    Amount: {
      type: "Amount",
      value: 1337
    }
  }
}

dataSet

Bei Listen-Controls existiert bei bestimmten Eigenschaften ein dataSet-Objekt, um datensatzspezifische Skripte schreiben zu können. Dieses Objekt enthält die Felder des jeweiligen Datensatzes.

Folgende Tabelle:

CODE
| Name | City   | Amount |
------------------------
| Max  | Ulm    |  1337  |
| Tim  | Berlin |  4711  |

sieht im zeilenspezifischen Kontext (z.B. beim Highlighting) so aus:

TYPESCRIPT
// Zeile 1:
$ = {
  dataSet: {
    Name: "Max",
    City: "Ulm",
    Amount: 1337
  }
}

// Zeile 2:
$ = {
  dataSet: {
    Name: "Tim",
    City: "Berlin",
    Amount: 4711
  }
}

ocrData

Das ocrData Objekt steht im Kontext zur Verfügung, wenn es die Prozessvariable std_proc_be_ocr_result gibt.

TYPESCRIPT
interface OcrContextObject {
    [propertyName: string]: any;
    isAvailable(): boolean;
    formatConfidence(propertyName: string): string;
}

Der ocrData Kontext enthält alle Properties die hier (https://businessexpress.cloud/docs/be-documents-service/latest/index.html) definiert sind, sofern sie von der OCR Erkennung erkannt wurden.

Es gibt außerdem die Methode isAvailable(), mit der geprüft werden kann, ob das OcrContextObject Eigenschaften enthält und die Methode formatConfidence(), mit der die Confidence der übergebenen Property als formatierten String zurückgegeben wird, z. B. 0.87 -> 87 %

Beispiel:

TYPESCRIPT
$.ocrData = {
  total: {
    value: 1378.37,
    rawValue: "1378,37 €",
    confidence: 0.86,
  },
}

$.ocrData.isAvailable();             // = true
$.ocrData.formatConfidence('total'); // = '86.0 %'

workflow

$.workflow steht auf Pages zur Verfügung, die Teil eines Workflows sind.

CODE
ocrData: OcrContextObject;
complete: () => Promise<void>;
completeWithVariables: (variables: Record<string, any>) => Promise<void>;
error: (errorCode: string) => Promise<void>;
escalate: (escalationCode: string) => Promise<void>;
saveVariable: (variableName: string) => Promise<void>;
setNextUser: (userKey: string) => Promise<void>;
setNextGroups: (groupKeys: string[]) => Promise<void>;
userAssignment: (definition: Partial<UserAssignmentDefinition>, callback: () => void) => void;
confirmation: (definition: Partial<ConfirmationDefinition>, callback: () => void) => void;
isAssignedToMe: () => boolean;
assignedUser: () => string;

Methoden

Beschreibung

complete

Schließt den aktuellen Workflow-Schritt ab

completeWithVariables(variables)

Schließt den aktuellen Workflow-Schritt ab. Es kann ein variables Objekt übergeben werden, mit Prozess Variablen, die in den Workflow übernommen werden

error(errorCode)

Löst für den aktuellen Workflow-Schritt den Fehler mit dem übergebenen Fehlercode aus.

escalate(escalationCode)

Löst für den aktuellen Workflow-Schritt die Eskalation mit dem übergebenen Eskalations-Code aus.

saveVariable(variableName)

Speichert die angegebene Page-Variable sofort in Camunda ab. Sofern die Variable in Camunda nicht existiert, wird sie erstellt.

setNextUser(userKey)

Kann in completeButtons verwendet werden, um den Benutzer für den nächsten Prozessschritt zu setzen.

setNextGroups(groupKeys)

Kann in completeButtons verwendet werden, um Gruppen für den nächsten Prozessschritt zu setzen.

userAssignment(definition, callback)

Kann in completeButtons verwendet werden, um einen Dialog anzuzeigen, mit dem der Benutzer und/oder die Gruppen für den nächsten Prozessschritt auszuwählen.

definition

  • condition

  • status

  • text

  • confirmButtonText

  • selectionOptional

  • userSelectionAvailable

  • groupSelectionAvailable

  • defaultValueUser

  • defaultValueGroupKeys

  • restrictToUserKeys

  • restrictToPersonnelIds

  • restrictToGroupKeys

  • selected

confirmation(definition, callback)

Zeigt einen Confirm-Dialog mit der übergebenen Definition an.
Bei positiver Rückmeldung wird der Callback ausgeführt.

definition

  • title

  • text

  • buttonText

isAssignedToMe()

Gibt zurück, ob der ausgewählte Task dem aktuell angemeldeten User zugewiesen ist.

assignedUser()

Gibt für den ausgewählten Task den userKey des zugewiesenen Users zurück. Ist die Aufgabe keinem User zugewiesen, so wird null zurückgegeben.

Eigenschaften

Beschreibung

ocrData

Siehe Beschreibung ocrData weiter oben.

dialog

Erlaubt die Nutzung von Sub-Page Modals.

Beispiel:

CODE
controls:
  - controlType: button
    label: btn
    events:
      click:
        $script: |
          $.dialog.show(
            'PKG.page',
            (event) => {debug.log(JSON.stringify(event));}, 
            {size: 'medium', 'title' : 'hello world'});
 

Dies erzeugt ein Modal, dass die Page PKG.page. Der callback der hier mitgegeben wird ist relevant für weitere dialog Funktionen die in der entsprechenden subpage benutzt werden können (siehe unten). Zusätzlich hat das Modal eine Toolbar mit Button, die in der aufgerufenen Page definiert werden können. Die Definition von diesen findet innerhalb von contributes statt.

Zum Beispiel:

YAML
contributes:
  dialog:
    buttons: 
      - label:
          $expr: |
            $.variables.someLabel + "!";
        color: danger
        disabled:
          $bind: isDisabled
        events:
          click:
            $script: | 
               $.dialog.cancel(), 
      - label: speichern
        color: success
        events:
          click:
            $script: | 
               $.dialog.success({ out: "resultData"})

Dies erzeugt zwei Button in der Toolbar des Modals. Zusätzlich stehen in der Subpage die Funktionen:

$.dialog.cancel(payload), $.dialog.close(payload) und $.dialog.success(payload) zur Verfügung, wobei der payload optional ist. Alle diese Funktionen schließen das Modal und führen den callback der $.dialog.show Funktion aus, wobei

CODE
event = {
  resultCode: /* 'close', 'success' or 'cancel' */,
  resultData: payload
}

ist.

customControls

Beispiel:

YAML
controls:
  - controlType: custom
    name: myCustomControl
    id: idMyCustomControl
    width: 20vh
    events: 
      receiveMessage:
        $script: |
          debug.log('receive iFrame: ' + $.message);
  - controlType: button
    label: SendStaticMessage
    events:
      click:
        $script: |
          $.customControl('idMyCustomControl').postMessage("Statische Nachricht");

debug

Hilfs Funktionen zum Debuggen

Methoden

Beschreibung

log(message)

Gibt Nachricht auf der Browser Konsole aus

logIfDebug(message)

Gibt Nachricht auf der Browser Konsole aus aber nur wenn der Expertenmodus aktiv ist

Beispiel:

CODE
controls:
  - controlType: button
    label: Debug Log
    events:
      click:
        $script: |
          $.debug.log('Button Clicked!')

notify

Hilfs Funktionen zum Anzeigen von Toasts

Methoden

Beschreibung

success(message)

Zeigt grünen Toast an

error(message)

Zeigt roten Toast an

info(message)

Zeigt blauen Toast an

warning(message)

Zeigt orangen Toast an

show(type, message)

Zeigt je nach Typ einen Toast mit entsprechender Farbe an

type

  • success

  • error

  • info

  • warning

Beispiel:

CODE
controls:
  - controlType: button
    label: Toasts zeigen
    events:
      click:
        $script: |
          $.notify.success('Erfolgreich');
          $.notify.error('Fehler');
          $.notify.info('Erledgit');
          $.notify.warning('Wenig Speicher');
          $.notify.show('success', 'Erfolgreich');

command

Funktionen zum Ausführen von Commands

Methoden

Beschreibung

execute(commandFQN)

Führt das command mit dem angegebenen FQN aus.

Beispiel:

CODE
pageId: BSP.command-page
commands:
  - name: ExampleCommand
    label: Beispiel Kommande
    action:
      $script: |
        $.debug.log('Beispiel Kommando ausgeführt!')
controls:
  - controlType: button
    label: Kommando ausführen
    events:
      click:
        $script: |
          $.command.execute('BSP.command-page.ExampleCommand')

backend

Funktionen zum Ausführen von beas Backend Skripten

Methoden

Beschreibung

execute(functionName)

Führt im beas die Funktion mit dem angegebenen Namen aus.

Beispiel:

CODE
controls:
  - controlType: button
    label: Einbuchen
    events:
      click:
        $script: |
          $.backend.execute('bdeEinbuchen')

isMobile

Hilfs-Funktion um herauszufinden ob man sich auf einem mobilen Device befindet

Beispiel:

CODE
controls:
  - controlType: button
    label: Mobilgerät?
    events:
      click:
        $script: |
          $.debug.log(`Mobil (true/false)? ${$.isMobile}`)

expertModeEnabled

Hilfs-Funktion um herauszufinden, ob der Expertenmodus aktiv ist.
Wenn der Expertenmodus geändert wird, erfolgt sofort eine Aktualisierung des JavaScript-Kontexts.

Beispiel:

CODE
controls:
  - controlType: text
    value: Experteninformation nur im Expertenmodus sichtbar
    visible:
      $expr: | # js
        $.expertModeEnabled()

navigation

Funktion zur Navigation zu einer URL.

CODE
controls:
  - controlType: button
    events:
      click:
        $script: | # js
          $.navigation.navigate('https://www.google.de/', '_self');
          // $.navigation.navigate('/administration/system-settings');

confirm

Hilfsfunktion zur Erstellung von Confirm-Dialogen.

Methoden

Beschreibung

show(title, bodyText, buttons, size)

Erstellung eines Custom-Dialogs mit folgenden Parametern:

  • title: Titeltext des Dialogs

  • bodyText: Beschreibungstext des Dialogs

  • buttons: Array anzuzeigender Buttons im Format {label: string, callback: () => void, type?: string, stylingMode?: string}

    • label: Anzeigetext auf Button

    • callback: Funktion, welche beim drücken des Buttons ausgeführt werden soll

    • type?: bestimmt die Farbe des Buttons, mögliche Zustände:

      • normal (weiß)

      • success (grün)

      • danger (rot)

      • default (blau)

    • stylingMode?: bestimmt den Füllgrad des Buttons, Möglichkeiten sind:

      • contained (ausgefüllt)

      • outlined (umrandet)

      • text (nur Text)

  • size: Größe des Dialogs

    • small

    • medium

    • large

default(title, bodyText, onConfirm, confirmBtnText?, cancelBtnText?, size?)

Erstellung eines Default-Dialogs mit “Abbrechen” und “Bestätigen” Button mit folgenden notwendigen Parametern:

  • title: Titeltext des Dialogs

  • bodyText: Beschreibungstext des Dialogs

  • onConfirm: Methode, welche beim “Bestätigen” ausgeführt werden soll

optionale Parameter:

  • confirmBtnText: Text des “Bestätigen”-Buttons (default: “Bestätigen”)

  • cancelBtnText: Text des “Abbrechen”-Buttons (default: “Abbrechen”)

  • size: Größe des Dialogs (default: small)

prompt(title, bodyText, buttons, size)

Erstellung eines Custom Dialogs mit Eingabefeld. Die Callbacks, die in den Button definiert werden haben hierbei als Argument den Eingabewert.

YAML
- controlType: button
  label: Neuen Artikel anlegen
  events:
    click:
      $script: |
        const artikelAnlegen = function(type) {
          $.variables.newArticleType = type;
          $.backend('createArticle');
        }
      
        $.confirm.show(
          'Artikel anlegen', 
          'Welchen Artikel möchten Sie anlegen?', 
          [
            { label: 'Kaufteil', callback: () => artikelAnlegen('T'), type: 'default', stylingMode: 'contained' },
            { label: 'Baugrupppe', callback: () => artikelAnlegen('B'), type: 'danger', stylingMode: 'outlined' },            
            { label: 'Artbeitswert', callback: () => artikelAnlegen('A'), type: 'success', stylingMode: 'text' },
          ], 
          'medium'
        )
        
- controlType: button
  label: Artikel löschen
  events:
    click:
      $script: |
        const articleNumber = $.variables.articleNumber;
        const deleteArticle = function() {
          $.variables.articles.$.delete();
          $.notify.success(`Der Artikel wurde ${articleNumber} gelöscht`);
          $.backend('reorgArticles');
        }
        $.confirm.default(
          'Artikel löschen', 
          `Möchten Sie den Artikel ${articleNumber} wirklich löschen?`, 
          deleteArticle
        )  

documents

Methoden

Beschreibung

download(uuid)

Lädt das Dokument mit der angegebenen uuid herunter.

Beispiel:

YAML
- controlType: button
  label: Download
  events:
    click: 
      $script: |
        $.documents.download($.variables.documentUuid);

messaging

Grundlagen des Messagings: https://dontenwill.atlassian.net/wiki/spaces/BPOH/pages/986841157

Methoden

Beschreibung

user(userKey?: string): MessagingContext

Erstellt einen MessagingContext mit dem aktuellen oder dem angegebenen User. Der receiver-type nach der MQTT-Topic-Struktur ist hierbei user.

MessagingContext:

Methoden

Beschreibung

publish(useCase: string, message: any)

Versendet eine MQTT-Nachricht in dem als useCase angegebenen Sub-Topic mit einer beliebigen message.

Beispiel:

YAML
- controlType: button
  label: Jump via MQTT for my User and User 'U2'
  events:
    click: 
      $script: |
        $.messaging.user().publish('jump', {'key': 'article', 'id': 123});
        $.messaging.user('U2').publish('jump', {'key': 'article', 'id': 123});

odata

Methoden

Beschreibung

executeAction(actionName: string, body: Record<string, any>, namespace?: string): Promise<any>

Führt die ungebundene OData Action aus und gibt das Ergebnis zurück. Der body kann optional angegeben werden.

executeFunction(functionName: string, params: Record<string, any>, namespace?: string): Promise<any>

Führt die ungebundene OData Funktion aus und gibt das Ergebnis zurück. Die Parameter können als Objekt übergeben werden, wobei der Name des Parameter der Property-Name ist.

executeEntityAction(entityName: string, primaryKeyValue: any, actionFQN: string, body: Record<string, any>): Promise<any>

Führt die OData Action aus und gibt das Ergebnis zurück. Der body kann optional angegeben werden.

executeEntityCollectionAction(entityName: string, actionFQN: string, body: Record<string, any>): Promise<any>

Führt die OData Action aus und gibt das Ergebnis zurück. Der body kann optional angegeben werden.

executeEntityFunction(entityName: string, primaryKeyValue: any, functionFQN: string, body: Record<string, any>): Promise<any>

Führt die OData Funktion aus und gibt das Ergebnis zurück. Die Parameter können als Objekt übergeben werden, wobei der Name des Parameter der Property-Name ist.

executeEntityCollectionFunction(entityName: string, actionFQN: string, body: Record<string, any>): Promise<any>

Führt die OData Funktion aus und gibt das Ergebnis zurück. Die Parameter können als Objekt übergeben werden, wobei der Name des Parameter der Property-Name ist.

Beispiel:

YAML
- controlType: button
  label: OData Aktion
  events:
    click: 
      $script: |
        await $.odata.executeAction('NeuberechngungPreise', {articleType: 'A'});
- controlType: button
  label: OData Funktion
  events:
    click: 
      $script: |
        await $.odata.executeFunction('HoechsterPreis', {articleNumber: 'JFK_4747_AKJF'});
CODE
executeEntityAction: async (entityName: string, primaryKeyValue: any, actionFQN: string, body: Record<string, any> = null): Promise<any> => {
  const service = StaticInjector.get<ODataMethodsService>(ODataMethodsService);
  return service.executeEntityAction(entityName, primaryKeyValue, actionFQN, body);
},
executeEntityCollectionAction: async (entityName: string, actionFQN: string, body: Record<string, any> = null): Promise<any> => {
  const service = StaticInjector.get<ODataMethodsService>(ODataMethodsService);
  return service.executeEntityCollectionAction(entityName, actionFQN, body);

},
executeFunction: async (functionName: string, params: Record<string, any> = null, namespace: string = 'OData.Beng'): Promise<any> => {
  const service = StaticInjector.get<ODataMethodsService>(ODataMethodsService);
  return service.executeUnboundFunction(functionName, params, namespace);
},
executeEntityFunction: async (entityName: string, primaryKeyValue: any, functionFQN: string, params: Record<string, any> = null): Promise<any> => {
  const service = StaticInjector.get<ODataMethodsService>(ODataMethodsService);
  return service.executeEntityFunction(entityName, primaryKeyValue, functionFQN, params);
},
executeEntityCollectionFunction: async (entityName: string, functionFQN: string, params: Record<string, any> = null): Promise<any> => {
  const service = StaticInjector.get<ODataMethodsService>(ODataMethodsService);
  return service.executeEntityCollectionFunction(entityName, functionFQN, params);
},

Modularisierung von JavaScript Code

Oft möchte man gleichen Code in mehr als einer Expression verwenden. Dieser Code kann in Module ausgelagert werden, welche automatisch für alle Javascript Elemente einer page zur Verfügung stehen.

Im folgenden wird beschrieben, wie man Module in einer Page bereitstellt und wie diese Module zu definieren sind.

Modul definieren und verwenden

Ein Modul kann Funktionen, Konstanten und Klassen exportieren. Es wird nicht automatisch alles exportiert, was in dem Modul definiert ist, es muss explizit angegeben werden, welche Teile exportiert werden sollen.

Export von Funktionen:

JS
// Datei: mathUtils.js
const PI = 3.1415;

function square(num) {
  return num * num;
}

function circularArea(radius) {
  return PI * square(radius);
}

// Es wird nur die Funktion circularArea exportiert. 
// square und PI sind in den Expressions also nicht verfügbar.
return { circularArea }

Export von Konstanten und Klassen

JS
// Datei: articleHelper.js
const ArticleNoLength = 20;

class ArticleHelper {
  trimArticleNumber(articleNumber) {
    return articleNumber.substring(0, ArticleNoLength);
  }
}

return { ArticleNoLength, ArticleHelper }

Module brauchen einen Namen, damit diese verwendet werden können. Der Name wird entweder in der Page-Definition angegeben oder leitet sich vom Namen der JS-Datei ab.

YAML
- controlType: inputContainer
  controls:
    - controlType: label
      value: "Artikel-Nummer"
    - controlType: input
      type: text
      value:
        $statement: |
          const helper = new articleHelper.ArticleHelper();
          return helper.trimArticleNumber("MUTTER M-1");

Inline Module

JS Module können direkt in einer Page definiert werden. Alle exportierten Funktionen stehen in den Expressions und Statements auf der Page zur Verfügung

YAML
import:
  - name: base64
    src: |
      function decode(encoded) {
        return atob(encoded);
      }
      function encode(decoded) {
        return btoa(decoded)
      }
      // Export der Funktionen
      return { decode, encode }

Module in JS Dateien

Wenn Module größer werden oder wenn Sie auf verschiedenen Pages verwendet werden sollen, macht es Sinn, diese in eigene Dateien auszulagern. Der Name der JS Datei ist dabei der Name des Moduls.

Module müssen nicht explizit in Pages importiert werden. Die Verfügbarkeit der Module leitet sich von der Ordner-Struktur des .pages Ordners ab. Ein Modul ist in allen Pages verfügbar, welches sich im gleichen Ordner befindet. Außerdem ist es in allen Pages in Unterordnern verfügbar.

Im folgenden Beispiel ist das Modul utils auf allen Pages verfügbar. Das Module articleHelper jedoch nur auf der Page article

TEXT
Projekt Root-Ordner
|
|_ .pages
|____ article
|______ article.page.yml
|______ articleHelper.js
|____ main.page.yml
|____ utils.js

Debugging von Skripten

Skripte, die auf Pages definiert werden oder die aus JavaScript Modulen kommen, können im Browser debugged werden. Es können Breakpoints gesetzt werden, an denen die Ausführen des Programms angehalten wird. Dabei kann der komplette Kontext untersucht werden.

Die Ausführung wird nur angehalten, wenn die DevTools des Browsers geöffnet sind.

Beispiel zum Setzen eins Breakpoints:

YAML
controls:
  - controlType: button
    label: Debugging von Skripten
    events:
      click:
        $script: |
          const now = new Date();
          const text = `heutiges Datum: ${now}`;
          debugger; // diese Zeile setzt einen Breakpoint
          $.notify.info(text);

Fehlerhandling von Skripten

Skripte, die auf Pages definiert werden oder die aus JavaScript Modulen kommen, können Kompilierfehler enthalten und somit unbrauchbar werden. Damit Page-Entwickler über derartige Fehler informiert werden, erfolgt eine Evaluierung dieser JavaScripts zu dem String Fehler in der JavaScript-Property!. Darüber hinaus wird der Fehler mit Zusatzinformationen auf der Browser-Konsole ausgegeben, um die Fehlersuche zu vereinfachen.

Beispiel eines fehlerhaften JavaScripts:

YAML
controls:
  - controlType: text
    value:
      $expr: |
        'thisIsInvalidJavaScript'{{{}}}

Beispiel-Fehlerausgabe auf der Konsole:

CODE
VM2746:56 Custom JavaScript is invalid.
Path: <pageId>.text.value
Error:
 SyntaxError: Unexpected token '{'
    at [...]
Code:
 'thisIsInvalidJavaScript'{{{}}}
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.