Reputation: 343
I have a button, which executes a JS function:
<button class="btn-orange btn" onclick="expand(this.closest('.profile'))">JavaScript</button>
And a button, which executes C# and switches icons depending on a bool:
<button class="btn-orange btn"
@onclick="@(() =>
{
if (tempBool)
{
tempBool = !tempBool;
}
else
{
tempBool = true;
}
})">
<i class="fa @(tempBool ? "fa-compress" : "fa-expand")" aria-hidden="true"></i>
</button>
How can I combine them?
I tried it with the OnClientClick
Event, with JsRuntime.InvokeVoidAsync("expand(this.closest(.profile))");
, or by putting both in the onclick event.
How can I execute a JavaScript function and C# in a button onclick event?
My JavaScript code I try to execute
EventPageExpandable.js:
function expand(card) {
card.classList.toggle('profile--expanded');
// If card is not expanded after toggle, add 'unexpanded' class
if (!card.classList.contains('profile--expanded')) card.classList.toggle('profile--unexpanded');
// Else if card is expanded after toggle and still contains 'unexpanded' class, remove 'unexpanded'
else if (card.classList.contains('profile--expanded') && card.classList.contains('profile--unexpanded')) card.classList.toggle('profile--unexpanded');
}
How I tried to use JsRuntime:
await JsRuntime.InvokeVoidAsync("EventPageExpandable.expand", "this.closest('.profile')");
Or like this? But both doesn't work.
await JsRuntime.InvokeVoidAsync("expand", "this.closest('.profile')");```
Upvotes: 5
Views: 5720
Reputation: 12378
There are a couple of ways you can fire both C# and javascript handlers for one DOM event
1. Rely on Event Bubbling
Put the C# eventhandler on your button or control as normal. Wrap your button in a div or span. Put the javascript onclick on the containing div or span.
<div onclick="console.log('I fired too!')>
<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.”
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>
Upvotes: 1
Reputation: 156
Inject the JSRuntime:
@inject IJSRuntime JsRuntime
Bind the onclick event of the button:
<button @onclick=ButtonClicked>Test</button>
and execute the JavaScript function:
private async Task ButtonClicked()
{
Console.WriteLine("From C#");
await JsRuntime.InvokeVoidAsync("console.log", "From js");
}
When invoking JS-functions, pass the function name as first argument followed by all parameters
Upvotes: 7