Budibase

Quelloffen, aber nicht kostenlos

Budibase ist eine quelloffene Low-Code-Plattform. Der Quellcode steht bei Github zur Verfügung. Dennoch ist der Einsatz der Software nicht gänzlich kostenlos; Budibase lässt sich nur mit einem npm-Paket betreiben, das direkt beim Hersteller bezogen werden muss. Dabei unterscheidet der Anbieter von einem im Funktionsumfang eingeschränkten Free-Plan bis hin zum Business-Plan mit allen Funktionen für 400 US-Dollar, beziehungsweise dem maßgeschneiderten Enterprise-Plan mit Preisen auf Anfrage. Unternehmen können Budibase entweder selbst on-Premises hosten oder als Cloud-Software vom Hersteller beziehen. Die Preise sind dabei identisch.

Installation

Installation

Installation über einen Docker container mit ssl

Voraussetzungen:

Docker: https://www.docker.com/get-started

Docker installieren

Siehe Buch -> Installation

Budibase installieren

Als Befehl ohne ssl einfach port 10000

sudo docker run -d -t \
  --name=budibase \
  -p 10000:80 \
  -v /home/duffy/budibasedata:/data \
  --restart unless-stopped \
  budibase/budibase:latest

Environment Parameter

Variablenname Beschreibung
CUSTOM_DOMAIN Wenn eine Domain im Format domain.com festgelegt ist, versucht Budibase automatisch, ein SSL-Zertifikat zu erstellen und HTTPS für diese Domain zu verwenden. Die Domain muss bereits auf den Budibase-Container gerichtet sein, damit dies korrekt überprüft werden kann.
INTERNAL_API_KEY Ein API-Schlüssel, der zum Zugriff auf viele Kernkomponenten verwendet werden kann. Dieser sollte auf eine zufällige Zeichenkette aktualisiert werden.
JWT_SECRET Ein geheimer Schlüssel, der zum Sichern aller Sitzungen mit Budibase verwendet wird. Dies sollte auf eine zufällige Zeichenkette aktualisiert werden. Beachten Sie, dass das Ändern dieser Zeichenkette alle vorhandenen Sitzungen ungültig macht.
MINIO_ACCESS_KEY und MINIO_SECRET_KEY Diese beiden Umgebungsvariablen sollten auf eine Kombination aus zufälligen Zeichenketten festgelegt werden, um den Zugriff auf MinIO abzusichern. Diese können auch verwendet werden, um sich im MinIO-Browser anzumelden, wenn gewünscht.
REDIS_PASSWORD Das Passwort, das zum Zugriff auf die Redis-Instanz verwendet wird. Dies sollte auf eine zufällige Zeichenkette festgelegt werden, um die Sicherheit zu gewährleisten.
COUCHDB_USER und COUCHDB_PASSWORD Diese beiden Umgebungsvariablen definieren den CouchDB-Benutzernamen und das Passwort, die zum Zugriff auf den Hauptadministrationsbenutzer verwendet werden. Diese können auch verwendet werden, um auf die Fauxton-Benutzeroberfläche zuzugreifen.

oder als Composer Datei mit ssl

Dazu ein neues Verzeichnis namens certs im Verzeichnis wo die composer Datei liegt / hinsoll erstellen.

mkdir certs

Nun ins Verzeichnis gehen und das Zertifikat anlegen.


cd /home/duffy/budibasedockertemplate/certs
openssl req -newkey rsa:4096 -x509 -sha256 -days 365000 -nodes -out selfsigned.crt -keyout private.key

nun die Fragen beantworten.
DE
und der Common Nname als URL.
Bei selbstsigniert eigentlich egal. Hauptsache steht was drin.

Ausgabe:

......................................++++
.....................++++
writing new private key to 'private.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:budibase.local.lan
Email Address []:

Nun wieder in das Verzeichnis wo die composer-datei liegt zurück gehen.

cd ..

Nun wieder ein Verzeichnis zurück ins Template Verzeichnis und eine neue nginx Config namens "nginx-proxy.conf" anlegen

nano nginx-proxy.conf

Inhalt dieser Datei:
Client_max_body_size gibt an wie groß eine Datei zum Upload sein darf. Bruacht man größere größen diese anpassen.
Wenn im nginx dieser Fehler im Log auftaucht:

Fehler: client intended to send too large bod

Nun der Inhalt

events {
  worker_connections 1024;
}

http {
  server {
    listen 80;
    return 301 https://$host$request_uri;
  }

  server {
    listen 443 ssl;
    ssl_certificate /etc/ssl/certs/selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/private.key;

    location / {
      proxy_pass http://budibase:80;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      client_max_body_size 100M;
    }
  }
}




Die composer Datei:


version: "3"

services:
  budibase:
    restart: unless-stopped
    image: budibase/budibase:latest
    expose:
      - "80"
    healthcheck:   -> ein heltcheck der 3 mal überprüft ob der dienst läuft wenn nicht wird er als unheatly. markiert. siehe unten bei restart on failure
      test: ["CMD", "curl", "--fail", "http://localhost:80/"]
      interval: 30s
      timeout: 10s
      retries: 3

    volumes:
      - budibase_data:/data   -> Bezieht sich unten auf das Volume, wo die Budibase Daten gespeichert werden sollen, alspo persitentlaufwerk
  nginx:
    image: nginx:stable
    container_name: nginx-proxy
    volumes:
      - ./nginx-proxy.conf:/etc/nginx/nginx.conf:ro   -> Es können anstatt Verzeichnisse auch Dateien angebene werden. Hoer nginx config. Im lesen Mdous
      - ./certs/selfsigned.crt:/etc/ssl/certs/selfsigned.crt:ro  Hier der Öffentliche Schlüssel für ssl auch lesend
      - ./certs/private.key:/etc/ssl/private/private.key:ro  Hier der Private Schlüssel für ssl auch lesend.
    ports:
      - "80:80" -> port 80 - weitergelietet auf port 80
      - "443:443" -> 443 port auf 443 port
    depends_on:
      - budibase -> braucht budibase gestartet
    restart: unless-stopped   -> wenn oben budibase fehlerhaft ist startet der nginx mit neu

volumes:
  budibase_data:  -> name
    driver: local 
    driver_opts:
      type: none
      o: bind
      device: /home/duffy/budibasedata ->  verzeichnis wo die budibase daten liegen auf dem host

Und Komplett ohne Erläuterung

version: "3"

services:
  budibase:
    restart: unless-stopped
    image: budibase/budibase:latest
    expose:
      - "80"
    healthcheck:
    test: ["CMD", "curl", "--fail", "http://localhost:80/"]
      interval: 30s
      timeout: 10s
      retries: 3
    volumes:
      - budibase_data:/data
  nginx:
    image: nginx:stable
    container_name: nginx-proxy
    volumes:
      - ./nginx-proxy.conf:/etc/nginx/nginx.conf:ro
      - ./certs/selfsigned.crt:/etc/ssl/certs/selfsigned.crt:ro
      - ./certs/private.key:/etc/ssl/private/private.key:ro
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - budibase
    restart: unless-stopped

volumes:
  budibase_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /home/duffy/budibasedata

Nun den container starten/aktualisieren.

docker-compose down
docker-compose up -d

Fürs aktualisieren erst down  nehmen und dann up.
Für den ersten start nur up.

docker-compose up -d

Nun kann ein Webbrowser geöffnet werden, mit https. Das zertifikat beim ersten aufruf naturlich zur ausnahme hinzufügen

https://ip_vom_dockerhost

Bildschirmfoto vom 2023-04-25 16-15-25.png

Nun kann ein Admin Benutzer erstellt werden.







Budibase Internal DB

Budibase Internal DB

Beziehungen Relationships

Beschreibung:

Ein Nachteil von der Budibase DB ist, das in einigen GUI Elementen wie auch im AUtomator die Verknüpften Tabellen Felder nicht angezeigt werden. Aber es gibt Gott sei Dank ein Workaround dafür.
Wir wollen in diesem Beispiel bestellungen kunden zu ordnen.

Ausgangssituation.

In unserem Beispiel haben wir eine Tabelle Kunden und eine Tabelle Bestellungen.
Wir haben die Anzahl der Felder so minimalistisch gelassen, weil es hier ums Prinzip geht

Die Tabelle Kunden hat folgene Felder.

AutoID
Name
Vorname

Die Tabelle Bestellungen hat folgende Felder

AutoID
artikel
anzahl
preis
gesamtpreis

Der Gesamtpreis ist vom Typ Formula. Also ein berechneter Wert.
Die formel dazu heißt

{{ multiply anzahl preis }}

Beziehung herstellen

WIr gehen auf die Tabelle Kunden und erstellen ien neues Feld mit dem Namen bestellung.
als Type wählen wir Relationship
Dann wählen wir die Tabelle aus mit der Verknüpft werden soll.
also Bestellungen

Welche Beziehung soll es sein.
Hier kann ein Kunde mehrere Bestellungen, Also one kunden row -> many bestellungen rows
nun wird auch automatisch ein feld in der tabelle bestellungen angelegt.
Wir müssen nur noch den namen angeben.
Kunden oder kunde macht vielleicht sinn

Auswahl_076.png

Über add row fügen wir zwei kunden ein.
Max Mustermann
und Anna Schulz

Jetzt sieht unsere Tabelle Kunden so aus.

Auswahl_077.png

Nun legen wir eine Bestellung an, werden aber gleich sehen das da was nicht stimmt bzw blöd ist

Eine neue Row in bestellungen anlegen.
Artikel intel i5
preis 150
anzahl 2
und nun können wir den kunden auswählen.
und da haben wird, es werden die IDs vom  Kunden angezeigt.
Ein bisschen blöd sich die ids zu merken wer nun Max oder Anna ist

Auswahl_078.png

Grundsätzlich erstell ich noch ein Feld in der tabelle mit dem namen der tabelle und anzeige dran.
Bei Kunden zum Beispiel. kundenanzeige.
Es gibt bei feldern ein Flag das geschaltet werden kann, das dieses als Anzeige Benutzt werden soll, bei Beziehungen.
Wir erstellen ein neues Feld kundenanzeige vom typ Formula

Wir wollen das in diesem Feld der Vorname und Nachname zusammen angezeigt wird.

Das ist die Formel. Über das Blitzsymbol kann man schnell die Formel zusammen klicken.

{{ Vorname }} {{ Name }}

Auswahl_079.png

Auswahl_080.png

Und nun kommt der Clou. Den schieber use as table display coloumn aktivieren.
In einer tabelle kann das immer nur ein Feld sein. Würded Ihr ein anderes Feld dies einhaken, würde hier der Haken wieder rausgehen.

Auswahl_081.png

Nun gehen wir wieder in unsere Bestellungen und wählen den Kunden aus.
Tadaaa, jetzt ist es lesbarer als nur die IDs.

Auswahl_087.png

Nun wollen wir natürlich eine App draus bauen.
Allerdings kann Budibase nicht auf die verlinke id zugreifen.
Wir erstellen uns zwei screens.
Eine mit ner Tabelle für die kunden.
Dazu Komponente table block hinzufügen
und die Tabelle kunden auswählen

Auswahl_088.png

Jetz konfigurieren wir noch de culoums. Denn die Bestellungen und die Kundenazeige wollen wir da nicht drin haben.
in unserem Beispiel sollen die Bestellungen über einen Button geöffnet werden als modal.
So das  alle Bestellungen für den Kunden auf einen Blick sind.N

Und das ist der Grund warum in Budibase ein Workaround nutzen muss, denn Relationship Felder werden nicht angezeigt.
Aber dazu später.

Unser Screen sieht jetzt so aus

Auswahl_089.png

Nun erstellen wir einen zweiten screen mit einer Tabelle die die Bestellungen beinhaltet.
ich hab den Screen Details genannt.
Wieder einen Tabell hinzugefügt und die Spalten angepasst.
Die Spalte Kunde brauchen wir nicht, da ja nur bestellungen von einem kunden aufgerufen werden.
Unser Screen sieht dann so aus.

Auswahl_090.png

Nun gehen wir in den ersten screen zurück und erstellen einen Button in der Tabelle

Auswahl_091.png

Diesem Button geben wir folgende Eigenschaften. Dazu kilicken wir den Button an.
Nun geben wir den button einen Namen buttonBestellungen anzeigen
Dann Anzeigetexte Betsellungen öffnen.

Auswahl_092.png

Nun auf define actions klicken.
Dort Update State Action hinzufügen

Eine Vaaible mit KUNDENID angeben und dann auf den Blitz klicken

Auswahl_094.png

Nun als Wert die ID von der Tabell Kunden angeben.
Über den Asistenten -> Table -> _id
schnell ausgwählt

Auswahl_093.png

Nun ein navigate als zwiete Aktion hinzufügen. Dort denn screen details auswählen:
ob im Vollbild oder Modal geöffnet werden soll bleibt euch überlassen.
ich find das Modal aber an Budibase ja so genial, deshalb lass ich Modal drin.

Auswahl_095.png

So nun kommt der eigentliche Workaround, aber erstmal schauewn wir uns an, wass denn nicht funktioniert.
Dazu gehen wir in den Screen details.
klicken unseren Dataprovider an
und gehen auf define Filters.
Denn hier wollen wir ja nur die Betsellungen vom kunden mit der ID die vir in die variable gesetzt haben lesen.

Aber hier ist das Problem kein Feld kunden in der auswahl!!!!

Auswahl_096.png
Da behlfen wir uns eines kleinen tricks.
Wir gehen die Tabelle Bestellen zurück und fügen ein neues Feld hinzu.
Dieses nennen wir kundenrel.
Ich mach das immer so, das ich in einer tabelle wo ich ein relationsfeld habe, dieses feld nochmals erstelle allerdings mit rel am ende und vom typ formula. Dann nur static und folgende Formel rein.
wichtig unter javascript!!!
wichtig ist auf die Groß und Kleinsschreibung des Feldnamens zu achten.
Deshalb schreib ich alle Feldnamen in tabellen immer alles klein

return $("kunden") ? $("kunden").map(x => x._id) : ""

Nun in der Tabelle bestellungen das neue Feld erstellen mit Static

Auswahl_098.png

Nun nachdem auf dem Blitz geklickt wurde auf Javascript klicken und die oben genannte formel angeben.
wichtig ist auf die Groß und Kleinsschreibung des Feldnamens zu achten.
Deshalb schreib ich alle Feldnamen in tabellen immer alles klein

Auswahl_1020.png

Nun sieht das ganze so aus und speichern

Auswahl_100.png

Nun haben wir einen pointer auf die ID.

Auswahl_102.png

Jetzt legen wir noch eine betsellung an, damit wir zwei datensätze haben.
Nachdem wir diese angelegt haben. Sind in unserer Datenbak zwei Kunden und zwei Bestellungen.
Wir haben die Bestellungen jeweils einem Kunden zugeordnet.
Da wir den filter noch definiert haben werden beide angezeigt

Auswahl_103.png

Nun wieder auf define filzter im Dataprovider

Jetzt steht kundenrel in der Auswahl. Jippie

Auswahl_104.png

Nun die Formel vervollständigen.
Dazu equal auswählen und bindings, dann wird der blitz freigeschaltet.
Dann auf den blitz klicken

Auswahl_105.png

unter State werden alle Variablen angezeigt die angelegt wurden.
Nun auf State klicken und die Variable KUNDENID raussuchen.
Wenn wir nachher noch mehrere Screens haben, wir können diese Variable immer wieder überschreiben, beim button. Denn es kann ja immer nur ein fenster gleichzeitig angezigt werden.
Deshalb ist in meinem gesamten Programm auch KUNDENID verwendetbar.
Weil wo ichs brauche schreib ich die neue ID rein, über die Buttons im Home screen oder wo auch immer ich das brauche.

Auswahl_106.png

Nun sieht die Formel so aus, noch speichern fertig.

Auswahl_107.png

Nun können wir auf preview gehen und auf den Home screen

Nun bei dem jeweiligen Kunden auf bestellungen öffnen klicken

Auswahl_108.png

Und eh voila, ein Modal mit den Bestellungen für den Kunden, in diesem Falle Max

Auswahl_110.png

Und hier Anna

Auswahl_111.png

Wir legen noch eine Bestellung für Anna an.
Dazu wieder in die Data wechseln und eine row anlegen in bestellungen und Anna zuordnen.
Nun hat Anna zwei Bestellungen.

Auswahl_112.png

Fertig, kleiner Trick große wirkung, mit dem extra Feld in das die id kopiert wird.

Budibase GUI Elemente

Budibase GUI Elemente

Ein Option Picker als Relationship Picker zum Filtern zweckentfremden

Beschreibung:

Leider gibt es in Budibase keinen Relationship Picker (Dropdownmenü wo man die Liste nochmals filtern kann.
Zum Beispiel Zeige aus der Liste nur einträge von Kunden so und so an.

In Unserem Beispiel haben wir folgende Tabellen.
Kunden
Adressen
Verträge.

Bei Kunden und adressen reicht der Relationship picker noch aus, da wir eine Tabelle filtern.
Sprich wir filtern die Tabelle Adressen nach einem Kunden.
Also einfache Verschachtelung. Kunde -> Adressen.

Spanndend wird es jetzt mit den Verträgen. Denn ein Vertrag hat mehrere Relationen.

Ein Vertrag hate eine Relation zu Kunden und eine Relation zu den Adressen.
Denn ein Kunde kann mehrere Adressen haben,  genauso wie ein Kunde mehrere Verträge haben kann.
Mit dem normalen Relation ship Picker, werden dann wenn beim Vertrag die Adresse ausgewählt werden kann, leider alle Adressen angeben, von allen Kunden.
Wir möchten aber gerne das nur die Adressen von dem Kunden dessen Vertrag gerade bearbeitet wird aufgelistet wird.
Das ganze ist ein wenig tricky, aber es geht.

Hier zur veranschaulichung aus der Tabelle Verträge.
Hier sind zwei Verträge.
Von Anna die Rechnungsadresse am Deich und von John die Holler Landstraße.

Auswahl_946.png

Klicken wir im Data view auf den Eintrag um die Straße auszuwählen, werden uns alle angezeigt.
Dieses verhalten wäre im Designview mit nem Relaltionship picker genau das selbe.

Auswahl_947.png

Hier dann in einem Relationship Picker im Design view, also unserer App / Screen

237632437-1608c542-bc76-41cb-91ef-b6e9eb288c62.png

Die letzen beiden Adressen sollten nicht angezeigt werden, da diese nicht zu Anna gehören.
Da wir dieses aber mit dem Realtion Picker nicht filtern können müssen wir uns was anderes überlegen.

Der Workaround

Dazu gehen wir in das bearbeiten Sidepanel / Screen oder  hinzufügen Sidepanel / screen wo wir einen vertrag editieren.
Ich habe in meinem Beispiel ein Sitepanel.

Wenn auf den Vertrag geklickt wird, öffnet sich ein Sidepanel

Auswahl_948.png

Nun in den Data view Modus. In das Sitepanel gehen.
Nun im Conatiner einen Neuen Data Provider hinzufügen.
Warum genau an der Stelle, damit sich später usner Option Picker dem Sidepanel von der Größe anpasst.
Diesen Data Provider schieben wir dann ganz nach unten (STRG+Pfeilstate drücken zum verschieben)
So das es so aus sieht. Die Fieldgroup und den Picker gibt es noch nicht. Den erstellen wir gleich. Ist aber schon auf dem Bild.

Auswahl_949.png

Nun klicken wir auf den New Data Provider

Wir wählen als Daten unsere Tabelle Adressen aus.

Auswahl_950.png

Klicken dann auf define Filter.

Wir wählen als feld kundenrel aus, oder wie auch immer ihr das Feld genannt habt, wenn ihr eine interne DB verwendet.
Wenn Ihr mysql verwendet wird eure direkte relationsfeld zum kunden angezeigt, die ihr dann warscheinlich kunden nennt.
Da ich aber die interne DB verwende hab ich ein zweites Feld als pointer. Dieses wähle ich und dann noch bindings auswählen.
Wer mehr zu den Workaround wissen will : Beziehungen Relationships

Auswahl_951.png

Nun auf den Blitz klicken und euren State für die kundenid raussuchen die ja schon vorher gespeichert war, da Ihr ja nur Verträge von Kunde XY angezeigt bekommt. So filtern wir dann auch die Adressen nur nach diesem Kunden durch die Stateid

Auswahl_952.png

So sieht dann der fertige Filter aus.
Speichern und fertig.

Auswahl_953.png

Somit wäre unser filter fertig.
Nun noch eine Fieldgrupper unterhalb des neuen Data Provider anlegen, damit sich die Elemnet die in die Fieldgroup dann anpassen. Hier wählen wir noch aus, das Labels also beschriftungen auf der Linken Seite seien sollen.

Auswahl_954.png

Nun erstellen wir in dieser Group unseren Option Picker.
Fangen wir mit den ersten 4 Feldern an:

Name  : name der das Steuerlement bennent, aht keine Auswirkung auf Tabellenfelder etc. Nur für die reine GUI
Field : Manuell per Hand eintragen. Und zwar erstellen wir dadurch ein neues feld. Name beliebig, der Name darf nur nicht in der Tabelle Verträge vorhanden sein.
Denn das wird ein neues Formularfeld, das uns zum zuweisen in der Tabelle zur verfügung steht.
ich habe es rechnungsadressepicker genannt. Dann weis man gleich das ist das Pickerfeld.
Label: Das ist die Beschreibung in der GUI vom Picker

Auswahl_955.png

Nun geht  es weiter
Beim Typ kann man auswählen Selct (Also lIste) oder Punkte (Wir nehmen Liste)

Default value machen wir zum Schluss, hier eben überspringen

Options source, wählen wir Data Provider aus.

Nun können wir unter Options provider unseren Data Provider auswählen, den eben gerade erstellten

Unter Label coulumn können wir aus der Tabelle Adressen auswählen, welche Spalte benutzt werden soll das zur Anzeige dient.
In diesem Fall für uns die Adressen, denn die IDS kann ja keiner Lesen.

Und value Column, das ist das was tatsächlich der Wert ist, sprich die Variable hinter dem Picker.
In unserem Fall die _id. Denn wir wollen ja die _id, in dem Feld Rechnungsadresse im der Tabelle Verträge speichern.

Auswahl_956.png

Nun noch der Default value.
Wir wollen wenn der Wert in der Tabelle Verträge vergeben ist, das im Picker dieser dann schon drin ist.
Sonst ist mit aktualiseren eines Datensatzes ja blöd, man müsste sich das sont ja vorher merken und wieder neu ausfüllen.
Dazu klicken wir auf den Blitz:

Und wählen:
Repeater

Auswahl_958.png

Dann die Rechnungsadresse (wichtig den Link und nicht die rel falls intern DB verwendet wird)

Auswahl_957.png

Nun sieht das so aus:

Auswahl_959.png

Jetz müssen wir noch per Hand hinter dem Feldnamen .0._id hinzufügen. Denn das ist ein Array/Datensatz und wir wollen nur das ID Feld nicht den ganzen Datensatz. Denn dadurch wird dann im Picker der Wert gesetzt der zur Zeit in dem Datensatz in Verträge angeben ist. Ist n och keine Adresse angeben, wird glücklicher weise Choose angezeigt.
Dann siesht das ganze so aus, nun auf save klicken:

{{ Repeater.vertraege.rechnungsadressemeldeadresse.0._id }}

Auswahl_961.png

Nun sieht unsere Sidebar so aus.
Angezeigt wird sogar schon ein Wert, allerdings wenn wir diesen ändern würden und auf speichern klicken, passiwert da noch nichts. Den default Wert laden, das geht natürlich schon, da wir das ja gerade definiert haben.
Also oben auf den Speichern button klicken.
Dann auf define Actions klicken.

Auswahl_963.png

Nun auf Save row klicken.
Dann im Fenster auf Add column klicken.
Damit können wir eine spalte überschreiben mit einem anderen Wert.
in diesem Fall aus die Rechnungsadresse aus unserem Picker.

Auswahl_964.png

Nun die Rechnungsadresse auswählen, wichtig auch hier wieder dier Link typ also die echte Relation nicht der selbsterstelle pointer. Entfällt natürlich bei einermysql wieder. Ist nur für interne db. SOnst gäb es ja nur den link

Auswahl_965.png

Und bei Value auf den Blitz klicken.

Und bei auf das zweite Formular klicken, heißt bei mir Form. Dieses ist fürs Sidepanel.
Denn FormMainTable ist für die Tabelle. Oder wie auch immer eure Formulare heißen

Auswahl_966.png

Und dort jetzt den picker auswählen

Auswahl_967.png

Dann sieht das ganze so aus:
Nun auf Save klicken.

Auswahl_968.png

Nochmals auf Save:

Auswahl_969.png

Ergebnis

Nun öffnen wir die App / aktualisieren die App mit F5 und gehen auf Kunden und klicken bei einem kudnen auf Verträge.
Auswahl_970.png

Nun öffnet sich die Seite mitb den Verträgen und dort scrollen wir bis zu den Adressen:
Wie zu sehen gehört der Vertrag Anna Schulte und die Adresse ist am Deich

Auswahl_971.png

Nun klicken wir auf den Vertrag und scrollen nach unten und sehen, am Deich wurde übernommen

Auswahl_972.png

Nun wählen wir eine andere Adresse und sehen es gibt nur 3 Adressen.
Nämlich die , die Anna gehören. Gleichzeitig wählen wir jetzt zz  zz zz aus

Auswahl_973.png

Nun scrollen wir wieder nach oben und klciken auf speichern.

Auswahl_974.png

Nun wird autoatisch der Vertrag aktualisert mit der neuen Adresse.
Mission erfolgreich.

Auswahl_975.png




Budibase GUI Elemente

URL Variablen und öffnen im neuen Fenster

Beschreibung:

Es gibt in Budibase zwei Möglichkeiten Daten in Variablen zu Speichern.
einmal über States oder über URL Variablen.

In einer URL Variable sieht man den Inhalt in der URL.
Also für sensible Daten die States benutzen.

Warum dann URL Variablen???

Weil States in einem neuen Fenster keine Gültigkeit mehr haben.
States sind nur in einem Fennster gültig(Show Modal gillt auch noch) Da im Browserfenster geöffnet wird.

in der regel wird in einer URL Variable nur die ID und ander Paramter die dafür zuständig sind GUI elemente ein und auszublenden.

Sind es sensible GUI elemente die zum Beispiel nur bestimmte Benutzer sehen dürfen.
Würde ich in der Datenbank ein extra Feld anlegen, was dann als condition vom user benutzt werden kann.


Definition von URL Variablen

URL Variablen werden im Namen des Screens angehangen.
eine Variable ist immer /:varname

/screenname/:id

Sollen mehrer Variablen definiert werden:

/screenname/:id/:meinwert

In meinem Beispielbild die Variable id und die Variable view

Auswahl_152.png

Auf Variablen zugreifen:

In dem Screen kann mit

{{ URL.id }} und {{ URL.view }} 

drauf zugegriffen werden.

Screen öffnen Variablen übergeben:

Übergeben werden die Variablen entweder manuell in einer Link komponente oder über die Aktion Navigate to.
man kann sie natürlich auch manuell an die Adresszeile anfügen. z.b für Debug zwecke. Dann gvibts eine andere Ansicjht oder.

Eine Linkkomponente erstellen in der Tabelle als Beispiel

Auswahl_143.png

Nun in den eigenschftaen des Links einen Namen vergeben und ein Ziel.
Variablen werden einfach mit einem / angegeben

/screenname/wert

sollen mehre variablen übergeben werden einfach mit  slash hintereinander.
Auf die Reihenfolge achten, die Variablen werden in der Reihenfolge zugeordnet wie sie beim definieren angelegt wurden.

/screenname/wert1/wert2

In meinem Beispiel

/vertragsdetails/{{ Table.vertraege._id }}/true

Dazu auf den Blitz klciken

Auswahl_140.png

und dann dort eingeben.
Es können wieder Variablen übergeben werden wie auch, static text.
Der static text ist hier true.
Die Variable die ID von der row wo der Link drin ist

Auswahl_142.png

Über einen Button mit Aktion Navigate To:

Im Button define Actions anklicken

Auswahl_144.png

Aktion Naviagte to auswählen
Jetzt gibt es zwei Varianten Screen und URL

Screen:

/vertragsdetails/{{ Table.vertraege._id }}/true

Auswahl_145.png

URL:

Mit URL hab ich die Möglichkeit den Screen in einem neuen Fenster / Tab zu öffnen.
Damit aber auch ein Screen geöffnet werden werden kann muss dem eine # vorangestellt werden.
Sonst gibt es einen Zugriffsfehler.

#/vertragsdetails/{{ Table.vertraege._id }}/true

Auswahl_146.png


Abrufen der URL Variablen im neuen Screen, als Beispiel mit einem Button der nicht dargestellt werden soll:

Condition festlegen:

Da wir hier view auf true gesetzt  haben wird im neuen Fenster der Button save nicht dargestellt.
Da wir in dem Screen, den button unter condition folgenden filter hinzugefügt haben.
Dazu in dem Screen auf den Button klicken der nicht dargestellt werden soll, wenn wie in unserem Beispiel view auf true gestellt ist.
Dort dann auf configure conditions klicken

Auswahl_147.png

Und dann folgende condition hinzufügen.

Auswahl_148.png

Ergebnis auf der Seite:


Wird true übergeben, kein button da

Auswahl_149.png

Wird false übergeben

Auswahl_150.png

ist der Button da

Auswahl_151.png

Wozu das ganze?
So kann ich mit einem Screen, mehrer Sachen machen und muss nicht screens doppelt designen ;-)

Budibase GUI Elemente

Einen copy to clipboard Button über eine embed Komponente

Beschreibung:

Dropdown Menüs und Datumsfelder lassen sich mit dem Mauscursor nicht kopieren.
Also zweckentfremden wir die embed Komponente mit einem Javascript zum kopieren.

!!!! Wichtig diese JavaScript Funktion fuktioniert nur auf Webseiten mit HTTPS, unter HTTP wird vom Browser diese Funktion deaktiviert, es gibt dann auch keine Fehlermeldung, es passiert nix!!!!!!!

Durchführung:

Eine embed Komponente an die gewünschte Stelle hinzufügen.

Dann diesen HTML-Code einfügen
!!!WICHTIG bei Text nicht bei Javascript is ja HTML-Code!!!
Die Variable value mit der Variable ersetzten (also zum Beispiel textfeld aus der koiiert werden soll.)

<button onclick="( function() 
{  navigator.clipboard.writeText('{{ value }}').then(function (){alert (' {{ value }} Copied!')}) }
)()">Copy Link</button>

Hier ein Beispiel mit Deustchem Text und echten Variablen

<button onclick="( function() 
{  navigator.clipboard.writeText('{{  Form.Fields.rechnungsadressemeldeadresse  }}').then(function (){alert (' {{ Form.Fields.rechnungsadressemeldeadresse }} in die Zwischenablage kopiert!')}) }
)()">Copy</button>

Hier ein Beispiel wenn ein Datum umformatiert werden soll.


Denn in Budibase wird ein Datumsfeld in diesem Format zurückgegben, wenn es durch keine Komponente wie eine Datumskomponente umformatiert wird : 1981-06-03T00:00:00.000

<button onclick="( function() 
{  
    var value = '{{ value }}'; // Das Originaldatum
    var date = new Date(value); // Erstellen eines neuen Date-Objekts mit dem Wert
    var day = String(date.getDate()).padStart(2, '0'); // Extrahieren und Formatieren des Tages
    var month = String(date.getMonth() + 1).padStart(2, '0'); // Extrahieren und Formatieren des Monats
    var year = date.getFullYear(); // Extrahieren des Jahres

    // Zusammenfügen der Teile in das gewünschte Format
    var formattedDate = day + '.' + month + '.' + year;

    navigator.clipboard.writeText(formattedDate).then(function (){
        alert (formattedDate+' Copied!')
    })
})()">Copy Link</button>

Nun sieht die Rückgabe so aus:

Auswahl_153.png

Beispiel Option Picker, da Option Picker nur den Wert also in der Regel die ID zurückgeben und nicht das Label.


Hier ein Workaround.
hier wird der Button komplett mit einer JavaScript Funktion gebaut.
Also diesmal nicht  auf Text sondern auf JavaScript gehen

Auswahl_1017.png

Dort dann dieses Script einfügen

const rows = $("dataRechnungsadressemeldeadresse.Rows"); //holt alle rows vom Data Provider
//unsere einzelenen Felder als Variablen deklarieren
let street = "strasse"; 
let ort = "ort";
let plz = "plz";

//durch alle rows gehen und eine laufvariable i erstellen
for (let i in rows) {
   //wenn die row id von den rows mit dem  picker übereinstimmen, denn der picker enhält ja nur die id dann ist das unser Datensatz
   if ($("Form.Fields.rechnungsadressemeldeadressepicker") == rows[i]._id)
    {
            //nun speichern wir die einzelenen Felder in den Variablen um sie dann weiter zu verwenden
            street = rows[i].strasse;
            ort = rows[i].ort;
            plz = rows[i].plz;
    }
}
//Hier setzten wir unsere Variablen zusammen
let text = street +" "+ plz +" " + " " + ort;
//Hier erstellen wir den Button mit dem Clipboard und setzten dort unsere Text Varibalen ein
let button = `<button name="rechnungsadressemeldeadresse" onclick="( function() 
{  
    navigator.clipboard.writeText('${text}').then(function (){alert ('${text}  Copied!')}) }
)()">Copy Link</button>`;
//Die JavaScript funktionen gegben in Budibase immer das was angezeigt werden soll zurück, in unserem Beispiel der Button.
return button;

Und hier der Komplette Code ohne Erläuterung

const rows = $("dataRechnungsadressemeldeadresse.Rows");
let street = "strasse";
let ort = "ort";
let plz = "plz";
for (let i in rows) {
   if ($("Form.Fields.rechnungsadressemeldeadressepicker") == rows[i]._id)
    {
            street = rows[i].strasse;
            ort = rows[i].ort;
            plz = rows[i].plz;
    }
}
let text = street +" "+ plz +" " + " " + ort;
let button = `<button name="rechnungsadressemeldeadresse" onclick="( function() 
{  
    navigator.clipboard.writeText('${text}').then(function (){alert ('${text}  Copied!')}) }
)()">Copy Link</button>`;
return button;

Extrahieren der Straße Beispiel

//die funktion die die straße rausfiltert
function extractStreet(address) {
  let streetMatch = address.match(/^[^\d]*/);
  if (streetMatch === null) {
    return "Fehler: Keine Straße gefunden.";
  }
  return streetMatch[0].trim();
}

const rows = $("dataRechnungsadressemeldeadresse.Rows"); //holt alle rows vom Data Provider
//unsere einzelenen Felder als Variablen deklarieren
let street = "strasse"; 
let ort = "ort";
let plz = "plz";

//durch alle rows gehen und eine laufvariable i erstellen
for (let i in rows) {
   //wenn die row id von den rows mit dem  picker übereinstimmen, denn der picker enhält ja nur die id //dann ist das unser Datensatz
   if ($("Form.Fields.rechnungsadressemeldeadressepicker") == rows[i]._id)
    {
            //nun speichern wir die einzelenen Felder in den Variablen um sie dann weiter zu verwenden
            street = rows[i].strasse;
            ort = rows[i].ort;
            plz = rows[i].plz;
    }
}
//Hier setzten wir unsere Variablen zusammen
let text = extractStreet(street); //hier haben wir ein funktion oben die mit einem regulären ausdruck die Straße rausfiltert
//Hier erstellen wir den Button mit dem Clipboard und setzten dort unsere Text Varibalen ein
let button = `<button name="rechnungsadressemeldeadresse" onclick="( function() 
{  
    navigator.clipboard.writeText('${text}').then(function (){alert ('${text}  Copied!')}) }
)()">Copy Strasse</button>`;
//Die JavaScript funktionen gegben in Budibase immer das was angezeigt werden soll zurück, in unserem //Beispiel der Button.
return button;

Extrahieren der Hausnummer Beispiel:

function extractHouseNumber(address) {
  let numberMatch = address.match(/\d+[a-z]?/i);
  if (numberMatch === null) {
    return "Fehler: Keine Hausnummer gefunden.";
  }
  return numberMatch[0];
}


const rows = $("dataRechnungsadressemeldeadresse.Rows"); //holt alle rows vom Data Provider
//unsere einzelenen Felder als Variablen deklarieren
let street = "strasse"; 
let ort = "ort";
let plz = "plz";
let text = "text"

//durch alle rows gehen und eine laufvariable i erstellen
for (let i in rows) {
   //wenn die row id von den rows mit dem  picker übereinstimmen, denn der picker enhält ja nur die id //dann ist das unser Datensatz
   if ($("Form.Fields.rechnungsadressemeldeadressepicker") == rows[i]._id)
    {
            //nun speichern wir die einzelenen Felder in den Variablen um sie dann weiter zu verwenden
            street = rows[i].strasse;
            ort = rows[i].ort;
            plz = rows[i].plz;
    }
}
//Hier setzten wir unsere Variablen zusammen
text = extractHouseNumber(street);
//Hier erstellen wir den Button mit dem Clipboard und setzten dort unsere Text Varibalen ein
let button = `<button name="rechnungsadressemeldeadresse" onclick="( function() 
{  
    navigator.clipboard.writeText('${text}').then(function (){alert ('${text}  Copied!')}) }
)()">Copy Hausnummer</button>`;
//Die JavaScript funktionen gegben in Budibase immer das was angezeigt werden soll zurück, in unserem //Beispiel der Button.
return button;

 

Budibase GUI Elemente

Mit einer Embed Komponente den Webseiten Titel ändern.

Beschreibung:

Es gibt Situationen, da möchte man den Webseitentitel gerne in Kundenname oder Vertragsnamen Nr etc. drin haben.
Da der Titel ja von Budibase vorgegben wird, behelfen wir uns einer embed Komponente um den Titel zu setzten.

Durchführung:

Eine embed Komponente erstellen und im Textteil folgendes einfügen.
Die Embed Komponente muss die erste Komponente in der Reihenfolge sein

Auswahl_1007.png


Die {{ variabel mit dem Text ersetzen wenn eine Variable gewünscht ist.
text natürlich den eigenen Bedürfnissen anpassen.

<img style="display: none;" src onerror="document.title = '{{ Variabel }}'" >

Auswahl_1008.png



Budibase GUI Elemente

Mit einer Embed Komponente alle Attachments in einem Attachmentfield zum Download bereitstellen

Beschreibung:

Es gibt momente, da möchte man einfach auf dem Formular alle Attachments in einem Attachment Field als Download link im Formular haben.
Mit einem Repeater Block und darin enthaltenden Embed-Komponente, könnte man das so realisieren:

Quelltext Embed Komponente:

Die variable Attachmaents enthält das AttachmentField aus dem Repeater.
sind keine Attachments droin. Wird einfach der text ausgegeben, No Attachments here.
Im Javascript Teil der Embed-Komponente

const attachments = $("New Repeater block.test.attachments");

if(attachments) {
  let html = '';
    for (const attachment of attachments) {
      html += `<a href="${attachment.url}" download>${attachment.name}</a><br>`;
    }

  return html;
}
return 'No attachments here';