g.pickardou
g.pickardou

Reputation: 35822

How to add client DOM javascript event handler when using Blazor Server?

...yes I know... Blazor Server is served side, and I can handle DOM events with my C# code at server side... still it makes sense to add a pure client side javascript event handler and surprisingly it seems it is not possible, because _framework/blazor.server.js swallows them...

Here are the simplest isolated steps to reproduce what am I doing.

  1. Create a Blazor App using VS 2019 template, choose Blazor Server App in the next step.
  2. In Index.razor add a line anywhere <div id="test">Hello, click me!</div>

  3. In _Host.cshtml add the following script after or before the already existing <script src="_framework/blazor.server.js"></script> line:

    ... pulling my hair out, I can not insert code block, here, see after the step 4...

  4. Run the app, and press F12 to see the console output.

here is the script in step 3:

<script>
    console.log("script is executing...");
    console.log("element found, its innerText is: " + document.getElementById("test").innerText);

    document.getElementById("test").addEventListener("click",
        function() {
            console.log("click handler called");
        });
</script>

enter image description here

Question

Am I missing something? Is it possible to make this work, without a server roundtrip? If it is not possible, then many of the existing javascript widgets, and jQuery plugins how will initialize themself?

What I've tried so far?

To answer in advance "why I would like to do this?":

I would like for example implement a DOM behavior where clicking on an element it changes something in its attributes. I do know, I can attach a C# handler, then call a back javascript function but I would not like this roundtrip. Besides of that, maybe there are many existing javascript plugin and lib which relies on that its initialization script attaches event handler on DOM.

Upvotes: 9

Views: 5943

Answers (1)

g.pickardou
g.pickardou

Reputation: 35822

...based on the documentation what agua from mars pointed to in his comment: (If anyone has better idea then please answer or comment)

If I run my client side script which is attaching the event handlers after the server OnAfterRender event, then it works. If I run it any way before (for example in OnInitialized event) it will not work:

So here is a working solution: Index.razor

@code
{
    protected override void OnAfterRender(bool firstRender)
    {
        _jsRuntime.InvokeVoidAsync("attachHandlers");
    }
}

_Host.cshtml:

window.attachHandlers = () => {
    document.getElementById("test").addEventListener("click", function()
    {
         console.log("click handler called");
    });
};

Upvotes: 2

Related Questions