cardo.Button2
Das Modul cardo.Button wurde für cardo4 völlig neu geschrieben. Die bisherigen Ansätze mit XML/XSD wurden durch einen Mix aus GeoSQL/Scriban/Markdown ersetzt.
Die beiden Module koexistieren, eine automatische Übernahme der Pläne ist nicht möglich.
cardo.Button ist dabei als eigene, interaktiv zu startende, Anwendung verfügbar und auch als "Engine", die von cardo Anwendungen eingebunden werden kann.
Objekte
Plan-Definition
Der Begriff "Plan" ist Nutzern des Moduls bekannt und wird hier weiterverwendet. Ein "Plan" beschreibt die Ausführung von Datenabfragen und auch die Formatierung der Ausgabe.
cardo.Button gibt nicht direkt die Speicherorte von Plänen vor. Diese können bspw. im Dateisystem oder auch in einem anwendungsintegriertem "Wilma" abgelegt werden.
Ein Plan im neuem cardo.Button ist dabei ein einfaches Textdokument, welches mit der cardo Template-Engine, die seinerseits auf Scriban basiert, gelesen wird.
Als Besonderheit gilt die Konvention, dass am Anfang der Datei die Metadaten zu dem Plan hinterlegt werden müssen. Dabei handelt es sich um ein JSON-Objekt vom Typ IButtonPlanDefinition, welches in einem Kommentar-Block am Anfang stehen muss. Hierzu ein einfaches Beispiel.:
{{##~~ { title:"Mein erster Plan", args:{ "tableName":{ title:"Name der Tabelle", type:"Text", isRequired:true } } } ~~##}}
Ergebnisse der Plan-Ausführung
Ein Plan kann eine Liste von Ergebnissen liefern. Grundlegend sind folgende Typen vorgesehen:
- Text (HTML, oder PlainText)
- Instanz eines cardo Wellknowntype (interaktive Datentabelle, nur in der cardo Umgebung nutzbar)
- PDF Dokument
- Daten (JSON)
In cardo gibt es eine Ausgabekomponente, die den Antworttyp auswertet und eine entsprechende Oberfläche dafür generiert.
"BO"
Wie bei allen über die cardo Template-Engine verwendeten Techniken gibt es diverse Erweiterungen die bereitgestellt werden (z.B. uxGeo ...) und das Business-Objekt, kurz "BO", welches immer zur Verfügung steht.
Das "BO" in Button enthält selber keine Daten, stellt aber Eigenschaften und Methoden zur Interaktion mit der Plan-Ausführung zur Verfügung.
Eigenschaften
"TableRowLimit" (10.000)
BO.TableRowLimit = number | null
Das generelle Zeilenlimit für Datenabfragen. Der Standardwert ist 10.000. Wird das Limit erreicht, wird der Plan mit einem Fehler abgebrochen.
"Args"
BO.Args = readonly IDictionary<object>
Hier sind alle im Plan definierten "args" streng typisiert hinterlegt. Die Werte werden vor der Ausführung entsprechend der Plan-Definition validiert und ggf. konvertiert.
"Format"
BO.Format = readonly Types.OutputFormat
Wenn der Plan mehrere Ausgabeformate definiert hat, ist hier das aktuell ausgewählte Format hinterlegt.
"StringContentInterpretation" (PlainText)
BO.StringContentInterpretation = "PlainText" | "Markdown"| "Html" | "DocumentParts" |"None"
Legt fest, wie die Textausgabe des Templates interpretiert wird. Mögliche Werte:
PlainText: Text wird HTML-Encoded zurückgeliefert, Umbrüche als br
Markdown: Text wird von einem Markdown-Converter in HTML konvertiert
Html: Text wird unverändert zurückgeliefert
DocumentParts: Das Ergebnis enthält unsere IDU spezifische Dokumentauszeichnungen und wird zu einem PDF Dokument konvertiert.
None: Die Textausgabe des Plans wird ignoriert.
"CurrentPlan"
Die Definition des aktuell ausgeführten Plans ähnlich IButtonPlanDefinition (inkl. der ReportId), aber hier als C# Objekt, d.h. die Namen der Eigenschaften sind nicht identisch (title => Title etc.)
Methoden
"DbSQL()"
BO.DbSQL(dbAlias: string) : ISQLBuilderBase
Gibt jeweils eine neue Instanz eines Datenbank-Abfrage-Objektes zurück, initialisiert mit einer Datenbankverbindung aus den cardo Einstellungen.
Die Datenbankverbindung muss dabei mit dem Attribut "ButtonDataSource" versehen sein.
Die Datenbankverbindung wird mit dem Aufruf der Methode erstellt und beim Beenden des Plans automatisch geschlossen.
Sie sollten hier Datenbankverbindungen anlegen, mit einem Benutzer mit möglichst wenigen Berechtigungen.
"GeoSQL()"
BO.GeoSQL() : ISQLBuilderBase
Gibt die Instanz eines Datenbank-Abfrage-Objektes zurück, hier immer mit Iwan7 als Datenquelle (GeoSQL Abfragen). Gegenüber der DbSQL Instanz ist hier noch zusätzlich die Methode MapLayerTagsToLayerName verfügbar.
"AppDbSQL()"
Diese Methode steht nicht in der Standard-Button Anwendung zur Verfügung, kann aber von Anwendungen die Reporting integrieren bereitgestellt werden. I.d.R. wird hier die konfigurierte Anwendungsdatenbank zurückgeliefert.
"SetJSONResult()"
BO.SetJSONResult(o: {}) : void
Hinterlegt die übergebenen Daten als JSON Output des Plans.
"JSONFromObject"
BO.JSONFromObject(o: object) : {}
Konvertiert das übergebene Objekt zu JSON.
"EndScript()"
BO.EndScript(keepStringOutput:boolean = true) : {}
Beendet die Ausführung geordnet an dieser Stelle.
"AddTrustedDownloadHost()"
BO.AddTrustedDownloadHost(hostName:string ) :void
Hinterlegt die Quelle als vertrauenswürdig. Die greift bspw. bei der PDF Konvertierung, wenn Ressourcen, wie Bilder, für das Einbetten abgerufen werden müssen.
Beispielhafte Definition eines Plans
{{##~~ { title:"Mein erster Plan", args:{ "txt":{ title:"Ein nicht optionaler Text", type:"Text", isRequired:true }, "gebietsFilter":{ title:"Optional räumliche Einschränkung", type:"Geom", isRequired:false, typeHint:"GeomPolygonOrMultiOnly", }, "nsgIds":{ title:"Auswahl Naturschutzgebiete", type:"Int32", isRequired:true isArray: true, /*Nachschlageliste aus einer Ebene*/ lookup: { query: { query:"(select id, name from L404 order by name) a", valueColumnName: "id", labelColumnName: "name", source: "GeoSQL" } } }, "zustand":{ title:"Auswahl Zustand", type:"Text", isRequired:true /*Nachschlageliste Werteliste*/ lookup: { records: [ {value: "A", label: "Gut"}, {value: "B", label: "Schlecht"} ] } } } ~~##}}
Anhang
Typdefinitionen
enum OutputFormat
{
/**
*/
Default = 0,
/**
* Text (unformatiert)
*/
TextPlain = 1,
/**
* HTML
*/
Html = 2,
/**
* JSON Daten
*/
JSON = 3,
/**
* PDF Dokument
*/
PDF = 4,
/**
* cardo Datentabelle
*/
NativeCardoType = 5,
}
enum DataTypeType
{
/**
*/
Null = 0,
/**
*/
Boolean = 1,
/**
*/
SingleByte = 2,
/**
*/
Int16 = 3,
/**
*/
UInt16 = 4,
/**
*/
Int32 = 5,
/**
*/
UInt32 = 6,
/**
*/
Int64 = 7,
/**
*/
UInt64 = 8,
/**
*/
Double = 9,
/**
*/
DateTime = 10,
/**
*/
Text = 11,
/**
*/
Binary = 12,
/**
*/
Geom = 13,
/**
*/
Object = 14,
/**
*/
GuidType = 15,
}
/**
* Spezialisierungen der UI für die Typen in den Argumenten
*/
enum KindSpecTypes
{
/**
*/
None = 0,
/**
* Typ DateTime: nur den Date-Part anzeigen
*/
DateOnly = 1,
/**
* Typ String: TextArea (statt TextField)
*/
TextArea = 2,
/**
* Typ Geom: nur (Einzel-) Punkt
*/
GeomPointOnly = 3,
/**
* Typ Geom: nur (Multi)Punkt
*/
GeomPointOrMultiOnly = 4,
/**
* Typ Geom: nur (Einzel-) Linie
*/
GeomLineOnly = 5,
/**
* Typ Geom: nur (Multi)Linie
*/
GeomLineOrMultiOnly = 6,
/**
* Typ Geom: nur (Einzel-) Polygon (auch Circle)
*/
GeomPolygonOnly = 7,
/**
* Typ Geom: nur (Multi)Polygon (auch Circle)
*/
GeomPolygonOrMultiOnly = 8,
}
enum ResultValueInterpretation
{
/**
* Wert ist String
*/
Html = 0,
/**
* Wert ist String
*/
PlainText = 1,
/**
* Wert ist ein WellknownType
*/
CardoObject = 2,
/**
* Wert ist ein PDF (als Image-Url, oder byte[], siehe RunReport Arg "blobAsDataUrl")
*/
PDF = 3,
/**
* Wert ist ein JSON (als IJsonResult oder String, siehe RunReport Arg "jsonAsString")
*/
JSON = 4,
}
interface ILookupQuerySource
{
/**
* Der Name der Wertespalte
*/
valueColumnName: string;
/**
* Der Name der Anzeigespalte (muss ungleich der Werte-Spalte sein)
*/
labelColumnName: string;
/**
* Die SQL-Abfrage, die valueColumnName und labelColumnName liefern muss
*/
query: string;
/**
* Hier sind 3 Angaben möglich:
* - der Name einer administrativen Ebene (Lxxx) oder das Schlüsselwort "GeoSQL" (unter Beachtung Groß/Kleinschreibung)
* - Schlüsselwort "AppDb" (unter Beachtung Groß/Kleinschreibung (nicht in der Standard-Button Anwendung verfügbar)
* - der Alias einer in cardo hinterlegten Datenbank (mit der Option Button-DataSource)
*/
source: string;
}
/**
* Nachschlagedatensatz aus Wert und Label.
*/
interface ILookupRecord
{
/**
* Wert des Nachschlagedatensatzes.
*/
value: any;
/**
* Label des Nachschlagedatensatzes.
*/
label: string;
}
/*
* Definition der Werte einer Nachschlageliste, das ist
* eine der Eigenschaften:
*/
type TLookupSourceTaggedUnion =
{
{ query:ILookupQuerySource }
| { records: ILookupRecord[] }
| { enumTypeName:string };
}
/**
* Definition eines Argumentes für einen Report
*/
interface IButtonArgumentServerMetadata
{
/**
* Der Anzeigename, nicht optional
*/
title: string;
/**
* Beschreibung, optional
*/
htmlDescription?: string | null;
/**
* Der technische Datentyp
*/
type: DataTypeType;
/**
* (nullable)
* Spezielle Hinweise für die Eingabefelder, je nach Datentyp
*/
typeHint?: KindSpecTypes | null;
/**
* Eine Liste von Werte
*/
isArray: boolean;
/**
* Gibt an, ob dieses Argument optional ist
*/
isRequired: boolean;
/**
* Ein JavaScript-Objekt, welches von cardo verwendet werden kann, um das Argument aus
* der Umgebung bereitstellen zu können. Wird z.Z. nur in der "Fancy-Search" verwendet.
* Bsp.: {column:"ID",layerName:"L1"}
*/
clientValueFrom?: any | null;
/**
* Vorgabewerte aus einer Nachschlageliste
*/
lookup?: TLookupSourceTaggedUnion | null;
}
/**
* Definition eines "Reports" / ButtonPlan
*/
interface IButtonPlanDefinition
{
/**
* Der Anzeigename, nicht optional (wenn leer, dann wird der Wilma-Paragraph Titel verwendet)
*/
title: string;
/*
* optionaler Name einer Gruppe, wird in der Standardansicht ausgewertet.
* Wenn nicht vorhanden, oder null, dann wird der Node-Titel aus Wilma verwendet.
*/
groupName?: string | null;
/**
* Beschreibung, optional
*/
htmlDescription?: string | null;
/**
* Liste von Gruppen/Nutzer, für die das sichtbar ist
* Es gilt:
* - leeres Array, dann für niemanden sichtbar
* - null (oder gar nicht vorhanden), für jeden sichtbar
* - sonst: Login-ID des Nutzers oder eine der Gruppen ist enthalten (der Vergleich erfolgt case-insensitiv)
*
* Beachte:
* Wenn der Aufruf via Public-URL erfolgt, dann ist das Verhalten so, dass eine Leere Liste den Zugriff verweigert, d.h.
*/
visibleFor?: string[] | null;
/**
* Mögliche Ausgabeformate
*/
formats?: OutputFormat[] | null;
/**
* Argumente, die zum Starten (erforderlich) sind
*/
args?: IDictionary<IButtonArgumentServerMetadata> | null;
}
Zuletzt geändert: 01.10.2026 07:25:47 (erstmals erstellt 01.10.2026) // Alias: "Button2"