Ein Widget ist ein Steuerelement, das von Widget
erbt. Ein einfaches Widget ist hier ein Widget, dass selbständig funktioniert und keine Information aus der Seite oder aus einem anderen Widgets benötigt.
Ein Widget benötigt:
- Das Steuerelement.
- Einen Controller.
- Falls der View Daten vom Controller benötigt, wird empfohlen, ein View-Model zu erstellen.
- Ein View. Der Name der View sollte wie die Aktion heißen und in einem Ordner mit gleichem Namen des Controllers liegen.
- Falls die View auch Custom Scripts im Browser brauchen, ein .ts Datei. Zum Beispiel NavigationMenuWidget.ts.
In diesem Beispiel wird ein einfaches Widget HelloWorldWidget
erstellt.
Steuerlement
Das Widget muss von Widget
erben. Widget
erbt von WidgetBase
und damit hat das Widget die Basis Felder und Funktionen.
In diesem Beispiel wird eine feste CSS-Klasse im Feld CssClass
gesetzt und eine zweite CSS Klasse, die abhängig von einer konfigurierbaren Option Bold
ist, wird durch die Überschreibung der Methode GetCssClass
gesetzt.
Die Methode GetControllerParameters
wird benutzt, um den Parameter textLanguage
an den Controller zu übernmitteln. Der Controller könnte aber auch direkt auf die Seite und das Widget zugreifen.
Zudem muss das Widget ein ControllerName
definieren.
Widgets können in ActionName
die Aktion im Controller definieren. Wird dies nicht gesetzt, nutzt das Widget die Aktion „Index“.
Man kann auch Standardwerte in anderen Feldern setzen, wie hier die Höhe und Ausrichtungen. Oder wie bei den anderen Steuerelementen, so können auch hier Eigenschaften von Basisklassen modifiziert werden.
Das HelloWorldWidget
braucht zusätzliche Scripts in der UI. Daher ist die Methode GetTSClassName
überschrieben, um die entsprechende .ts Klasse für das Widget zu definieren.
[Serializable]
public class HelloWorldWidget : Widget
{
[DisplayName("Fett")]
public bool Bold { get; set; }
[DisplayName("Sprache")]
public string Language { get; set; }
public HelloWorldWidget() : base()
{
Id = "16B8262B-0461-4871-A07A-66F74EF21559".ToGuid();
ToolboxName = "HelloWorld";
Icon = "earth2";
ControllerName = nameof(HelloWorldWidget);
Height = 300;
HeightType = EnumWidgetHeightType.Pixel;
HorizontalAlign = EnumHorizontalAlign.Center;
VerticalAlign = EnumVerticalAlign.Middle;
CssClass = "hello-world";
}
public override string GetTSClassName()
{
return "BA.Ui.Widgets.HelloWorldWidget";
}
public override string GetCssClass()
{
return base.GetCssClass() + " " + (Bold ? "bold-text" : "regular-text");
}
public override object GetControllerParameters()
{
return new { textLanguage = Language };
}
}
View Model
Das View Model beinhaltet die Informationen, die die View benötigt.
public class HelloWorldWidgetViewModel
{
public string SalutationText { get; set; }
public string ToSalutate { get; set; }
public string ErrorText { get; set; }
}
Controller
Der Controller hat eine Aktion Index
, die das View Model für das Widget vorbereitet und dann die entsprechende PartialView zurückliefert. In dem Fall wird kontrolliert, ob eine Sprache konfiguriert wurde. Falls nicht, wird das Widget einen Fehlertext beinhalten. Wenn „DE“ als Sprache konfiguriert ist, wird der Text auf Deutsch vom Widget ausgegeben. Ansonsten auf Englisch.
Die Aktion soll ein Partial View zurückliefern.
public class HelloWorldWidgetController : WidgetControllerBase
{
public ActionResult Index(string textLanguage)
{
HelloWorldWidgetViewModel viewModel = new HelloWorldWidgetViewModel();
if (string.IsNullOrWhiteSpace(textLanguage))
viewModel.ErrorText = "No language configured";
else
switch (textLanguage.ToUpper())
{
case "DE":
viewModel.SalutationText = "Hallo";
viewModel.ToSalutate = "Welt";
break;
default:
viewModel.SalutationText = "Hello";
viewModel.ToSalutate = "world";
break;
}
return PartialView(viewModel);
}
}
View
Die View (/Views/HelloWorldWidget/Index.cshtml) für das HelloWorldWidget
zeigt den Inhalt nur wenn kein Fehler auftritt. Der Fehlertext befindet sich in dem data-errortext
Attribut.
@model BA.Core.Models.HelloWorldWidgetViewModel
<div class="hello-world-content" data-errortext="@Model.ErrorText">
@if (string.IsNullOrWhiteSpace(Model.ErrorText))
{
<span>@Model.SalutationText</span> <span>@Model.ToSalutate</span>
}
</div>
Um die Ausrichtungen optisch ansprechend umzusetzen, sollte man enstprechende eigenen CSS.Styles anlegen. In diesem Beispiel werden die Klassen benutzt, um die gewünmschten Ausrichtungen zu erzeugen. Jeder Fall wird aber durch die Anforderungen erheblich unterschiedlich sein. Für dieses Beispiel wird folgendes CSS benutzt:
.hello-world .widget-content { position: relative; }
.hello-world .hello-world-content { position: absolute; width: fit-content; }
.hello-world.horizontalAlignRight .hello-world-content { right: 0; }
.hello-world.horizontalAlignCenter .hello-world-content { right: 0; left: 0; margin: auto; }
.hello-world.verticalAlignMiddle .hello-world-content { top: 41%; }
.hello-world.verticalAlignBottom .hello-world-content { bottom: 0 }
.hello-world.bold-text .hello-world-content { font-weight: bolder; }
.hello-world.regular-text .hello-world-content { font-weight: normal; }
UI Script
Die TypeScript Klasse wird bei der Erstellung des Widgets im Browser benutzt. Das HelloWorldWidget
überschreibt die OnContentLoaded
Funktion, um einen möglichen Fehler zu behandeln.
module BA.Ui.Widgets {
"use strict";
export class HelloWorldWidget extends Widget {
public override OnContentLoaded(): void {
let errorText: string = $(this.GetWidgetJQIdSelector() + " .hello-world-content").data("errortext");
if (errorText && errorText != "")
this.SetWidgetState(WidgetState.ContentError, true, errorText, false);
}
}
}
Ergebniss
Jetzt kann das Widget in einer Seite konfiguriert werden. Als Beispiel werden zwei konfiguriert: Eins mit fehlender Sprache und eins auf Deutsch