3

I'm trying to achieve the next in Blazor WebAssembly; I need to be able to listen for an event in a component, and use both Javscript and C# code like the next way:

<button onclick="console.log('Showing event from Js: ' + event); @Test()">Test</button>

@code {
   public void Test()
   {
       JSRuntime.InvokeVoidAsync("console.log", "Showing log from C#");
   }
}

The first problem is that I get the error "cannot implicitly convert type void to object", so if I change the Test method signature just to return an object

public object Test()
{
    JSRuntime.InvokeVoidAsync("console.log", "Showing log from C#");
    return null;
}

The App compiles but once the page is loaded, the "Test()" function is executed automatically, and if I click the button, it just executes the Javascript code, and not both pieces of code.

I know I should handle events in Blazor prefixing the event name with "@" symbol in order to call a C# method, and execute Javascript code there using the interop, but in that way, I can't use the default Javascript "event" which I need to use, instead of the Blazor "event" version.

Thanks in advance!

2 Answers 2

1

You can only have 1 onclick attribute, so either call the C## method from JS or call the JS code from C#. In both cases you will need Interop, there is no support for combining this in the way you are trying to.

the "Test()" function is executed automatically

Yes, in onclick="... @Test()" it is executed when the page renders, not when the button is clicked.

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, I tried with the interop (From both .NET and Js sides) and it works great, but I wanted to achieve that I mentioned above trying to get a cleaner code, Anyway, thanks for your reply and for clarifying about the reason for the automatic C# method called on render
1

There are perhaps 3 different ways you can fire both C# and javascript handlers for one DOM event.

1. Rely on Event Bubbling

Wrap your button in a div or span. Put the javascript onclick on the containing div or span, and leave the C# onclick on the button.

<div onclick="console.log('Showing event from Js: ' + event)>
<button @onclick="Test">Test</button>
</div>

As well as mouse events and most key events, the DOM will also bubble select, change, and some other events


2. Use EventListeners

You can have both JS and C# fire on the same DOM event by placing the C# as an inline attribute as normal, but adding the javascript as an event listener.

For instance at the bottom of your App.razor or _Host.cshtml <body>

    <script src="_framework/blazor.web.js"></script>
    <script>        
        document.addEventListener("click", function(e){
            if (e.target.id !== "testButton")return
            console.log("You clicked ", e.target.innerText)
            })

You may need to look up, “how to add event listeners to dynamically generated elements.”


  1. Use a "good enough" spare event

Inline, with varying degrees of correctness, you can sometimes use a "spare" javascript event, several of which will fire on the same element at nearly the same time. But I don't have a compelling example of when you would choose this over option 1, event bubbling.

<input @onchanged="Test" onblur="javascript:…" />
<input @oninput="Test" onkeyup="javascript:…" />
<select @onchanged="Test" oninput="javascript:…">...</select>
<select @bind="Test" oninput="javascript:…">...</select>
<button @onclick="Test" onmouseup="javascript:…">...</button>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.