Ein Widget kann ein Parameter im Browser bereitstellen. Damit andere Widgets es als Parameterquelle auswählen können, soll es das korrekte Interface implementieren. Das wäre das Interface IProvideWidgetParameter.

In diesem Beispiel wird das TopUserProfilesWidget erstellt, welches die ersten 3 Benutzer Profile anzeigt und den geklickten Eintrag als Parameter bereitstellt.

TopUserProfilesWidget.cs

TopUserProfilesWidget implementiert das Interface IProvideWidgetParameter. Das Widget hat deshalb die Methode GetProvidedParameterDefinitions. Die Methode wird eine OrmsWidgetParameterDefinition für den Parametertyp OrmsWidgetParameter. Damit werden alle DataWidgets TopUserProfilesWidgets als Parameterquelle selektieren können, die diesen Parametertyp benötigen.

Das Objekt WidgetParameterDefinition bekommt als Parameter des Constructors einen Anzeigetext des Parameters (kann eine Übersetzungs-Guid sein), einen technischen Namen und den Parameter Typ. Der Technische Name ist das, was DataWidgets für die Kommunikation nutzen werden. Das Objekt OrmsWidgetParameterDefinition bekommt zusätzlich die entsprechende Guid für die Datentabelle. In diesem Fall für Benutzerprofile.

[Serializable]
public class TopUserProfilesWidget : Widget, IProvideWidgetParameter
{
    public TopUserProfilesWidget() : base()
    {
        Id = "669B0B80-6CFC-4388-AA09-FBAC5BC4D213".ToGuid();
        ToolboxName = "TopUserProfiles";
        Icon = "bank_building";
        ControllerName = nameof(TopUserProfilesWidget);
        PixelHeight = 300;
        HeightType = EnumWidgetHeightType.Pixel;
        CssClass = "top-user-profiles";
    }

    public override string GetTSClassName()
    {
        return "BA.Ui.Widgets.TopUserProfilesWidget";
    }

    public IReadOnlyList<WidgetParameterDefinition> GetProvidedParameterDefinitions()
    {
        return new List<WidgetParameterDefinition>() 
        {
              { new OrmsWidgetParameterDefinition("42F7A053-91FC-44F3-9A6B-EA6E6B3B176D", "clickedUserProfile", EnumDataSource.UserProfileGuid, typeof(OrmsWidgetParameter)) }
         };
    }
}

TopUserProfilesWidgetViewModel.cs

Das ViewModel beinhaltet in dem Fall eine Liste von Tuple<string, OrmData>, mit den EntityTitles und die OrmData für den Parameter im Browser.

public class TopUserProfilesWidgetViewModel
{
    public List<(string EntityTitle, OrmData ormData)> TopUserProfiles;

    public TopUserProfilesWidgetViewModel()
    {
        TopUserProfiles = new List<(string EntityTitle, OrmData ormData)>();
    }
}

TopUserProfilesWidgetController.cs

Der Controller wird die erste 3 BenutzerProfile aus der DB lesen und die das ViewModel packen.

public class TopUserProfilesWidgetController : WidgetControllerBase
{
    public ActionResult Index()
    {
        TopUserProfilesWidgetViewModel viewModel = new TopUserProfilesWidgetViewModel();
        IQueryable<OrmUserProfile> query = API.Api.ORM.GetQuery<OrmUserProfile>();
        foreach (OrmUserProfile uProfile in query.OrderBy(ff => ff.LastName).Take(3))
        {
            OrmData uProfileData = new OrmData()
            {
                OrmTypeGuid = uProfile.OrmType,
                OrmGuid = uProfile.Oid,
                CacheId = uProfile.RecordCacheId,
                TemporaryKey = uProfile.TemporaryKey
            };

            viewModel.TopUserProfiles.Add((uProfile.EntityTitle, uProfileData));
        }

        return PartialView(viewModel);
    }
}

View: /Views/TopUserProfilesWidget/Index.cshtml

@model BA.Core.Models.TopUserProfilesWidgetViewModel

<div>
    <ul>
        @foreach ((string entityTitle, BA.Core.Configuration.Pages.Parameters.OrmData ormData) in Model.TopUserProfiles)
        {
            string jsonOrmData = Newtonsoft.Json.JsonConvert.SerializeObject(ormData);
            <li data-ormdata="@jsonOrmData">@entityTitle</li>
        }
    </ul>
</div> 

BA.Ui.Widgets.TopUserProfilesWidget.ts

Die TypeScript Klasse überschreibt die OnContentLoaded Funktion, um die Click Events auf die Einträge anzuhängen. Wenn ein Eintrag geklickt wird, wird den Parameter vom TopUserProfilesWidget aktualisiert und alle die Widgets, die den lesen, werden darauf reagieren.

module BA.Ui.Widgets {
    "use strict";
    export class TopUserProfilesWidget extends Widget {
        public override OnContentLoaded(): void {
            let othis: TopUserProfilesWidget = this;
        $(this.GetWidgetJQIdSelector() + " ul li").click(function () {
                let parameter: BA.Ui.Widgets.Parameters.OrmsWidgetParameter = new BA.Ui.Widgets.Parameters.OrmsWidgetParameter();
                parameter.Orms.push($(this).data("ormdata"));
                othis.SetProvidedParameter<BA.Ui.Widgets.Parameters.OrmsWidgetParameter>("clickedUserProfile", parameter);
            });
        }
    }
}

Eine Alternative ist das Objekt OrmData nicht als JSON im Browser zu rendern, sondern die einzelne Infos (Oid, OrmTyp, CacheId und TemporaryKey). In dem Fall kann man damit eine Instanz von OrmData in .ts erstellen.

Die Funktion SetProvidedParameter bekommt den Name des Parameters in der WidgetParameterDefinition als String und den neuen Parameter. In diesem Fall „clickedUserProfile“.

Ergebnisse

Nun kann das Widget in einer Seite konfiguriert werden. Als Beispiel wird es mit einem HelloWorldWidget konfiguriert, das von TopUserProfilesWidget den Parameter liest.

Beim Laden kann das HelloWorldWidget keinen Parameter lesen, wenn nichts angeklickt war.

Auf „Abraham Alder“ Klicken: