Skip to content

Blazor Html WebComponents CustomEvents easier handling #27651

@MichaelPeter

Description

@MichaelPeter

Hi AspNetCore Team,

we are using Html WebComponents as base for our applications and interacting with them is extremly complex
from blazor, especially with CustomEvents

Here is a sample html web component:

customElements.define('webcomp-event', class extends HTMLElement {
    constructor() {
        super(); // always call super() first in the constructor.

        this._clickCount = 0;
        // Attach a shadow root to <fancy-tabs>.
        const shadowRoot = this.attachShadow({ mode: 'open' });
        shadowRoot.innerHTML = `
            <label>
            <input type="checkbox" id="my-checkbox"></input>
            Change to Raise event
            </label>
        `;

        // Internal event listener
        shadowRoot.querySelector('#my-checkbox').addEventListener('click', (e) => {
            this._clickCount++;
            this.customCheckEvent = new CustomEvent("customcheck", {
                detail: {
                    clickCount: this._clickCount,
                    isChecked: e.target.checked
                },
                bubbles: true,
                composed: true,
                cancelable: false,
            });

            this.dispatchEvent(this.customCheckEvent);
            console.log(`input.clickEvent ${e.target.checked}`);
        });
    }
});

I would like to have something like that for handling custom Events in Blazor:

<webcomp-event @oncustom:customcheck="CustomHandlerAsync"></webcomp-event>

@code {
    // Framework class:
    public class CustomEventHandlerArgs : EventArgs
    {
        public dynamic Detail { get; set; }
    }

    public async Task CustomHandlerAsync(CustomEventHandlerArgs args)
    {
        await JSRuntime.InvokeVoidAsync("alert", $"FromBlazor ClickCount: {args.Detail.clickCount} IsChecked: {args.Detail.isChecked}");
    }

}

But what I currently need to do is the following:

Index.razor:

<webcomp-event @ref="_eventRef"></webcomp-event>

@code {
private DotNetObjectReference<Index> _thisRef;

    private ElementReference _webcompSetProperty;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // Events

        _thisRef = DotNetObjectReference.Create<Index>(this);
        await JSRuntime.InvokeVoidAsync("registerBlazorCustomHandler", _eventRef, "customcheck", _thisRef,                "HandleCounterClickAsync");
     }

    [JSInvokable("HandleCounterClickAsync")]
    public async Task HandleCounterClickAsync(bool isChecked, int clickCount)
    {
        await JSRuntime.InvokeVoidAsync("alert", $"FromBlazor ClickCount: {clickCount} IsChecked: {isChecked}");
    }

    public void Dispose()
    {
        _thisRef?.Dispose();
    }
}

Javascript:

function registerBlazorCustomHandler(component, eventName, callbackClass, callBackMethodName) {
    component.addEventListener(eventName, (e) => {
        console.log(`blazorjshandler clickcount: + ${e.detail.clickCount}`);
        callbackClass.invokeMethodAsync(callBackMethodName, e.detail.isChecked, e.detail.clickCount);
    });
}

Could this be improved:

I build a repository with differnet html web component issues, there are also other issues in there :
https://github.com/MichaelPeter/BlazorWebComponentTestApp

importaint are
https://github.com/MichaelPeter/BlazorWebComponentTestApp/blob/master/Pages/Index.razor
and
https://github.com/MichaelPeter/BlazorWebComponentTestApp/blob/master/wwwroot/scripts/TestWebComponents.js

Related:
#27070
#27654

Metadata

Metadata

Assignees

No one assigned

    Labels

    ✔️ Resolution: DuplicateResolved as a duplicate of another issueStatus: Resolvedarea-blazorIncludes: Blazor, Razor ComponentsenhancementThis issue represents an ask for new feature or an enhancement to an existing one

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions