I am working through some Blazor examples, and while trying to work with some JSInterop solutions, I ran into an issue with jQuery UI elements. I am not a proficient Javascript programmer, but I am proficient enough with .NET so I may be missing something simple. The first jQuery UI component I have tried to work with is the "resizable" component, found here: https://jqueryui.com/resizable/
Here is what my current code looks like:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width">
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/site.css" rel="stylesheet" />
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<app>Loading...</app>
<script src="_framework/blazor.server.js"></script>
<script>
$( function() {
$( "#resizable" ).resizable();
});
</script>
</body>
</html>
I am certain that the issue isn't with loading the libraries, and I have placed the script after loading blazor.server.js
.
Now, my Index.cshtml has the following in the html portion:
<body>
<div class="container-fluid">
<div id="resizable" class="ui-widget-content">
<div class="row row-no-gutters" style="width: 100%; height: 50%">
<h3 class="ui-widget-header">Resizable</h3>
</div>
</div>
</div>
</body>
Ideally, this would yield a resizable div, but the resulting html element is not resizable. From my understanding, Blazor JSInterop no longer requires JS functions to be registered. What am I doing wrong?
To use jQuery UI components in a Blazor application follow the steps: Reference the source scripts for jQuery and its UI components. Create the elements required for rendering jQuery UI components in the razor page [index. razor].
To add a component to the project, right-click on the Pages folder and choose Add -> Razor Component. Refer to the following image. In the Add New Item- Blazor App dialog, provide the name EmployeeCard and click Add. Syncfusion's Blazor components suite is the expert's choice for building modern web apps.
Load JS from an injected script in wwwroot/index. html (Blazor WebAssembly) or Pages/_Host. cshtml (Blazor Server) when the app is initialized: Add autostart="false" to the <script> tag that loads the Blazor script.
There is no need any more to add a method in the global index page (_Hosts.cshtml
in ASP.NET Core 5.0), which would fill those file with view-specific logic and dependencies. At least with v5 we have IJSObjectReference
allowing us to call $('table').DataTable()
directly from our .razor
file like this:
<table>
<thead>
<tr>
<td>Id</td>
<td>Name</td>
</tr>
</thead>
<tbody>
<!-- your data -->
</tbody>
</table>
@code {
[Inject]
protected IJSRuntime JSRuntime { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender) {
if (firstRender) {
var jQuery = await JSRuntime.InvokeAsync<IJSObjectReference>("$", "table");
await jQuery.InvokeVoidAsync("DataTable");
}
}
}
It's also possible to pass options to the plugin with an anonymous type. For example, to disable the search, we'd call in JS
$('#example').dataTable({
"searching": false
});
In Blazor we create an anonymous type with the same structure and pass it as parameter to the DataTable
call:
var options = new {
searching = false
};
await jQuery.InvokeVoidAsync("DataTable", options);
The problem is that of timing: your jQuery function executes before your Blazor app has rendered.
The way I solved this is by replacing the "onready" ($(...)
) function with a named function (e.g. onBlazorReady
) that I then invoke from my Blazor's MainLayout
component at the right time.
The right time being OnAfterRender
.
For example:
MainLayout.razor:
@code {
[Inject]
protected IJSRuntime JsRuntime { get; set; }
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
JsRuntime.InvokeVoidAsync("onBlazorReady");
}
}
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width">
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/site.css" rel="stylesheet" />
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<app>Loading...</app>
<script src="_framework/blazor.server.js"></script>
<script>
onBlazorReady() {
$("#resizable").resizable();
});
</script>
</body>
</html>
As you can see, I'm injecting IJSInterop
so that I can call my onBlazorReady
JS function after the LayoutComponent has rendered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With