Budibase GUI Elemente
- Ein Option Picker als Relationship Picker zum Filtern zweckentfremden
- URL Variablen und öffnen im neuen Fenster
- Einen copy to clipboard Button über eine embed Komponente
- Mit einer Embed Komponente den Webseiten Titel ändern.
- Mit einer Embed Komponente alle Attachments in einem Attachmentfield zum Download bereitstellen
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.
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.
Hier dann in einem Relationship Picker im Design view, also unserer App / Screen
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
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.
Nun klicken wir auf den New Data Provider
Wir wählen als Daten unsere Tabelle Adressen aus.
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
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
So sieht dann der fertige Filter aus.
Speichern und fertig.
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.
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
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.
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
Dann die Rechnungsadresse (wichtig den Link und nicht die rel falls intern DB verwendet wird)
Nun sieht das so aus:
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 }}
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.
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.
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
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
Und dort jetzt den picker auswählen
Dann sieht das ganze so aus:
Nun auf Save klicken.
Nochmals auf Save:
Ergebnis
Nun öffnen wir die App / aktualisieren die App mit F5 und gehen auf Kunden und klicken bei einem kudnen auf Verträge.
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
Nun klicken wir auf den Vertrag und scrollen nach unten und sehen, am Deich wurde übernommen
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
Nun scrollen wir wieder nach oben und klciken auf speichern.
Nun wird autoatisch der Vertrag aktualisert mit der neuen Adresse.
Mission erfolgreich.
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
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.
Über Link Komponente:
Eine Linkkomponente erstellen in der Tabelle als Beispiel
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
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
Über einen Button mit Aktion Navigate To:
Aktion Naviagte to auswählen
Jetzt gibt es zwei Varianten Screen und URL
Screen:
- Dann Screen auswählen
- Screen mit Variablen eintragen, Ist genauso wie beim Link, zumindest wenn man Navigate to und dann Screen wählt.
/vertragsdetails/{{ Table.vertraege._id }}/true
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
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
Und dann folgende condition hinzufügen.
- Hide component, wenn die condition zu triff. Bei show, würde das element nur angezeigt werden, wenn die condition gültig wäre.
- if {{ unsere URL.view }} Variable
- =
- true
ist, wird die komponente versteckt.
Ergebnis auf der Seite:
Wird true übergeben, kein button da
Wird false übergeben
Wozu das ganze?
So kann ich mit einem Screen, mehrer Sachen machen und muss nicht screens doppelt designen ;-)
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:
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
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;
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
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 }}'" >
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';