Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

  • Use other event for example mouseup: does not work.
  • Change the order of my custom script and the <script src="_framework/blazor.server.js"></script> : neither order is working...
  • Comment out the line <script src="_framework/blazor.server.js"></script> for diagnostic reasons: The event handler now called and I see the console output in the browser: "click handler called"

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.

like image 664
g.pickardou Avatar asked Apr 23 '20 10:04

g.pickardou


People also ask

How do I use JavaScript in Blazor server app?

Inject a script after Blazor starts cshtml (Blazor Server) when the app is initialized: Add autostart="false" to the <script> tag that loads the Blazor script. Inject a script into the <head> element markup that references a custom JS file after starting Blazor by calling Blazor. start().

Does Dom use event handlers?

DOM elements can have functions hook onto events. The functions are called event handlers and the DOM element is known as an event target. The example code block shows how to register a function as an event handler.


1 Answers

...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");
    });
};
like image 145
g.pickardou Avatar answered Sep 22 '22 15:09

g.pickardou