In a Blazor application, you can call JavaScript functions from C# (.NET) methods and vice versa. This is referred to as “JavaScript interoperability” or “JS interop.” The JS interop allows you to integrate JavaScript libraries into your Blazor application, and its primary function is to handle DOM manipulation and browser API calls.
Please refer to this link to
learn more about JS interop in Blazor.
Please refer to this link for
calling and implementing JS interop in Blazor.
Using JavaScript onmousemove and onkeypress events to trigger the Timer function in a Razor component can identify whether a user is active or inactive. If the user has not performed any onmousemove or onkeypress events, the user is considered in an inactive state and the Timer function is called after certain TimeInterval to log the user out.
Follow these steps to log the user out automatically if they’re not active:
Call the onmousemove and onkeypress properties in a JavaScript function to fire the Timer function in the Razor component. [_Host.cshtml]
Now call the Timer method to identify whether the user is active or not. Add navigation to the logout action when the user is inactive. [MainLayout.razor]
@using System.Timers
@inject NavigationManager UriHelper
@inject IJSRuntime JSRuntime
// . . .
@code {
[CascadingParameter]
private Task<AuthenticationState> stateAuthenticate { get; set; }
private Timer timerObj;
protected override async Task OnInitializedAsync()
{
// Set the Timer delay.
timerObj = new Timer(7000);
timerObj.Elapsed += UpdateTimer;
timerObj.AutoReset = false;
// Identify whether the user is active or inactive using onmousemove and onkeypress in JS function.
await JSRuntime.InvokeVoidAsync("timeOutCall", DotNetObjectReference.Create(this));
}
[JSInvokable]
public void TimerInterval()
{
// Resetting the Timer if the user in active state.
timerObj.Stop();
// Call the TimeInterval to logout when the user is inactive.
timerObj.Start();
}
private void UpdateTimer(Object source, ElapsedEventArgs e)
{
InvokeAsync(async() => {
// Log out when the user is inactive.
var authstate = await stateAuthenticate;
if (authstate.User.Identity.IsAuthenticated)
{
UriHelper.NavigateTo("logout", true);
}
});
}
}
To get a browser’s culture in Blazor WebAssembly, call the (navigator.language) property in JavaScript using the JavaScript interop function in Blazor. It will return the current browser’s language version.
Follow this code to get the browser’s culture in Blazor WebAssembly.
To convert the date and time to a client’s or user’s time zone in Blazor Server, use the JavaScript function to get the current offset time difference from UTC in minutes using the GetLocalDateTime() method in Blazor using JavaScript Interop. Display the local time by the current offset time difference.
Follow these steps to convert the server time zone to the user’s time zone.
To define the TimeZoneService class and the GetLocalDateTime() method, create a new file named TimeZoneService.cs in your project. Inside the TimeZoneService.cs file, define the TimeZoneService class and implement the GetLocalDateTime() method.
using Microsoft.JSInterop; namespace BlazorServerApp { public class TimeZoneService { private readonly IJSRuntime _jsRuntime; private TimeSpan? _userOffset; public TimeZoneService ( IJSRuntime jsRuntime ) { _jsRuntime = jsRuntime; } public async ValueTask GetLocalDateTime ( DateTimeOffset dateTime ) { if (_userOffset == null) { int offsetInMinutes = await _jsRuntime.InvokeAsync("blazorGetTimezoneOffset"); _userOffset = TimeSpan.FromMinutes(-offsetInMinutes); } return dateTime.ToOffset(_userOffset.Value); } } }
To register the time zone service, add the following code snippet to the Program.cs file. [Program.cs]
builder.Services.AddScoped();
Create a JavaScript file named BlazorInterop.js within the wwwroot directory and include the provided code snippet in it. [BlazorInterop.js]
function blazorGetTimezoneOffset() { return new Date().getTimezoneOffset(); }
To add a reference to the JavaScript file, open the Pages/_Layout.cshtml or _Host.cshtml file, and include the following line of code: [_Layout.cshtml/_Host.cshtml]
<script src="~/BlazorInterop.js">
Finally, you can utilize the service to display a date and time in your application. [Index.razor]
To get the current data and time from client, use
the date object (new Date()) in JavaScript
using JavaScript Interop. It will return the browser’s date
and time. Following is the code to get the current date and time from the
client in Blazor WebAssembly.
<body>
. . .
. . .
<script>
function GetDateTime() {
// Date object will return browser's date and time by default in JavaScript.
document.getElementById("date-time").innerHTML = new Date();
}
</script>
</body >
Google reCaptcha is a process that helps to protect websites form spam and abuse. To implement Google reCaptcha in Blazor, refer to the Google reCaptcha script link the WebAssembly app and render the reCaptcha by calling the JavaScript function. Follow these steps to implement Google reCaptcha in Blazor WebAssembly.
Add the Google reCaptcha renderer function in a separate JavaScript file under the wwwroot folder. [googlereCaptcha.js]
Now call the rendering reCaptcha function in JavaScript from the Razor page using JavaScript Interop and show the reCaptcha response on button click. Note: To start using reCaptcha, you need to generate the API site key for your site. Refer to this link to generate the site key. [Index.razor]
To call a JavaScript method with parameters in Blazor WebAssembly, you can follow the code snippet provided below:
[Index.razor]
@page "/"
@inject IJSRuntime JsRuntime
<p>Here's an example of how to call a JavaScript method with parameters in Blazor WebAssembly.</p>
@code {
protected override async void OnInitialized ()
{
string content = "JavaScript function called with parameter";
await JsRuntime.InvokeVoidAsync("jsFunction", content);
}
}
[index.html]
<body>
. . .
. . .
<script>
function jsFunction(value) {
// Parameter value has been passed here.
console.log(value);
};
</script>
</body >
Close a browser window from a page in Blazor WebAssembly using
JavaScript Interop with the window.close() method. The window.close() method closes the currently opened window.
In the following example, open a new browser window and
close it using the window.close() method with a button onclick event.
Window dimension values are read using JavaScript Interop with the window.innerHeight and window.innerWidth properties. Follow these steps to get the window dimension value in Blazor WebAssembly.
[Index.razor]
@page "/"
@inject IJSRuntime JsRuntime
<h1>Window Dimensions</h1>
<button class="btn btn-primary" @onclick="OnButtonClick">Get Dimensions</button><br /><br />
<p>Window Height: @Height</p>
<p>Window Width: @Width</p>
@code {
public int Height { get; set; }
public int Width { get; set; }
private async Task OnButtonClick()
{
var dimension = await JsRuntime.InvokeAsync<WindowDimension>("getWindowDimensions");
Height = dimension.Height;
Width = dimension.Width;
}
public class WindowDimension
{
public int Width { get; set; }
public int Height { get; set; }
}
}
@page "/"
@inject IJSRuntime JsRuntime;
<button class="btn btn-primary" @onclick="OnButtonClick">Call C# from JS</button><br /><br />
<p>@content</p>
@code {
private static string content { get; set; }
[JSInvokable] // Return call back from JavaScript with parameter to C#.
public static void JStoCSCall(string value)
{
content = value;
}
private async Task OnButtonClick() // Invoked by button clicking and calls JavaScript function.
{
await JsRuntime.InvokeAsync<object>("invokeJSfromCS");
}
}
[index.html]
<body>
. . .
. . .
<script>
Function invokeJSfromCS () {
var value = "C# Method called from JavaScript with parameter";
// Invoke to call C# function from JavaScript with parameter.
DotNet.invokeMethod('BlazorWasmApp', 'JStoCSCall', value);
}
</script>
</body >
In the following example, the cookie consent banner temple will display to notify you to accept cookies. Follow the below steps to create a consent cookie in Blazor.
1. Configure the HttpContextAccessor and CookiePolicyOptions to the Program.cs file to create a consent cookie.
Blazor doesn’t manipulate the DOM directly at C# side. You can call the JavaScript method by using JavaScript Interop to get an element by ID or class.
The getElementsByClassName() method returns a collection of all elements in the document with the specified class names.
The getElementById() method returns a collection of all elements in the document with the specified ID names.
[Index.razor]
@page "/"
@inject IJSRuntime JsRuntime
<h1 id="headingElement">Hello, world!</h1>
<p class="para-element">Welcome to your new app.</p>
@code {
protected override async void OnAfterRender(bool firstRender)
{
await JsRuntime.InvokeVoidAsync("elementId");
}
}
[_Host.cshtml]
<body>
. . .
. . .
<script>
function elementId() {
// Get element with the specified ID name
var idValue = document.getElementById("headingElement");
console.log(idValue.innerHTML);
// Get element with the specified Class name
var classValue = document.getElementsByClassName("para-element");
console.log(classValue[0].innerHTML);
}
</script>
</body>
In Blazor, you can call a JavaScript method using JavaScript interop to scroll the page to the top position.
In the following code, the button event triggers when the button is clicked and scrolls to the page top.
[Index.razor]
@page "/"
@inject IJSRuntime JsRuntime
<div style="background-color:lightgrey;padding:60px 60px 1000px">
<h2>Blazor App</h2>
This example demonstrates how to scroll to the top based on the button click event.<br />
Scroll down and click the button; it scrolls to the top position.
</div>
<div><br />
<button @onclick="OnButtonClick" class="btn btn-primary">Click Button</button>
</div>
@code {
private async void OnButtonClick()
{
await JsRuntime.InvokeVoidAsync("OnScrollEvent");
}
}
[_Host.cshtml]
<body>
. . .
. . .
<script>
// When the user clicks the button, the page scrolls to the top
function OnScrollEvent() {
document.documentElement.scrollTop = 0;
}
</script>
</body>
<body>
. . .
. . .
<script>
function copyClipboard() {
/* Get the text field */
var copyText = document.getElementById("form-control");
/* Select the text field */
copyText.select();
/* Copy the text inside the text field */
document.execCommand("copy");
/* Alert the copied text */
alert("Copied the text: " + copyText.value);
}
</script>
</body>
You can add smooth scrolling to a Blazor app using a combination of Blazor components and JavaScript interop, similar to the functionality available in jQuery UI components.
Step 1: Create a New Blazor App Run the following command to create a new Blazor WebAssembly app:
.NET CLI
dotnet new blazorserver -n SmoothScrollDemo
Step 2: Add CSS Styles Open the wwwroot/css/site.css file and add the following CSS class for smooth scrolling:
[wwwroot/css/site.css]
.smooth-scroll {
scroll-behavior: smooth;
}
Step 3: Create a SmoothScroll Component Create a new Blazor component named SmoothScroll.razor:
[SmoothScroll.razor]
<!-- Pages/SmoothScroll.razor -->
@page "/Smoothscroll"
@inject IJSRuntime JSRuntime
<h3>Smooth Scrolling Example</h3>
<div class="smooth-scroll">
<p>
This is a demonstration of smooth scrolling in a Blazor app.
Click the button below to smoothly scroll to the bottom of the page.
</p>
<button @onclick="ScrollToBottom">Scroll to Bottom</button>
</div>
<div class="content">
<!-- Add some content here to make the page longer -->
<h4>Smooth Scrolling in Blazor: Elevating User Experience with Elegance</h4>
<p>In the realm of modern web development, the user experience reigns supreme, and every nuance plays a pivotal role in crafting an immersive and delightful interaction. One such understated yet highly impactful element is the art of smooth scrolling. Blazor, the cutting-edge web framework by Microsoft, empowers developers with the ability to seamlessly integrate this feature into HTML elements. By adding an enchanting fluidity to the scrolling mechanism, Blazor transforms the user journey into an elegant dance, enhancing engagement and delivering a heightened sense of sophistication.</p>
<h4>The Essence of Smooth Scrolling</h4>
<p>Smooth scrolling, at its core, is the art of imbuing scrolling actions with an exquisite gracefulness. Unlike the conventional abrupt and jarring movements that characterize traditional scrolling, smooth scrolling introduces a harmonious glide that seamlessly navigates users through various sections or elements on a web page. This simple yet transformative touch has the power to transcend the mundane, transforming user interactions into a symphony of motion and elegance.</p>
<h4>Unveiling the Benefits</h4>
<ol>
<li>
<h6>Enhanced User Engagement:</h6>
By eliminating the disorienting jumps, smooth scrolling creates a captivating rhythm that keeps users immersed and engaged as they explore the content.
</li>
<li>
<h6>Visual Fluidity:</h6>
The graceful transitions between sections establish a visual continuity that feels natural and intuitive, amplifying the overall aesthetics of the website.
</li>
<li>
<h6>Improved Readability:</h6>
For lengthy articles or content-rich pages, smooth scrolling guarantees a comfortable reading experience by gradually revealing the content.
</li>
<li>
<h6> Subtle Sophistication: </h6>
Smooth scrolling lends an air of refinement to the user journey, elevating the perception of the website's design and enhancing its overall brand image.
</li>
<li>
<h6>Extended Time on Page:</h6>
The fluidity and beauty of smooth scrolling entice users to linger, thereby increasing their time spent on the website and fostering a deeper connection.
</li>
</ol>
</div>
@code {
private async Task ScrollToBottom()
{
await JSRuntime.InvokeVoidAsync("scrollToBottom");
}
}
Step 4: Add the following JavaScript function for scrolling to the bottom of the page in _Host.cshtml.
To avoid memory leaks, dispose the DotNetObjectReference instance created by a component properly and allow proper garbage collection. The DotNetObjectReference instance should be disposed either at component side or JavaScript side.
Use the following patterns to dispose DotNetObjectReference at the component level.
Implement IDisposable interface in the component.
Add Dispose method and dispose DotNetObjectReference object inside the
Dispose method.
To add Bing Maps to a Blazor application follow the steps.
Include the Bing Maps Web API scripts in the index.html/_Host.cshtml/_Layout.cshtml, This is used to retrieve the Bing Maps-related information by sending a request to the Bing Maps server and loading the same to the Blazor application.
Initialize maps in a Blazor application by using a JavaScript interop in the razor file [index.razor].
[Script.js]
function loadBingMap() {
var map = new Microsoft.Maps.Map(document.getElementById('map'), {});
var pushpin = new Microsoft.Maps.Pushpin(map.getCenter(), null);
map.entities.push(pushpin);
return "";
}
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].
Initialize the jQuery components in the OnAfterRender lifecycle method in your Blazor application by using the JavaScript Interop’s InvokeVoidAsync method.
@page "/"
@inject IJSRuntime jsRuntime
<h1>jQuery UI Components in Blazor</h1>
<br />
<h2>jQuery Accordion Component</h2>
<br />
<div id="accordion">
<h3>ASP.NET</h3>
<div>
<p>
Microsoft ASP.NET is a set of technologies in the Microsoft .NET Framework for building Web applications and XML Web services.
ASP.NET pages execute on the server and generate markup such as HTML, WML, or XML that is sent to a desktop or mobile browser.
ASP.NET pages use a compiled,event-driven programming model that improves performance and enables the separation of application logic and user interface.
</p>
</div>
<h3>ASP.NET MVC</h3>
<div>
<p>
The Model-View-Controller (MVC) architectural pattern separates an application into three main components: the model, the view, and the controller.
The ASP.NET MVC framework provides an alternative to the ASP.NET Web Forms pattern for creating Web applications.
The ASP.NET MVC framework is a lightweight, highly testable presentation framework that (as with Web Forms-based applications) is integrated with existing ASP.NET features, such as master pages and membership-based authentication.
</p>
</div>
<h3>JavaScript</h3>
<div>
<p>
JavaScript (JS) is an interpreted computer programming language.
It was originally implemented as part of web browsers so that client-side scripts could interact with the user, control the browser, communicate asynchronously, and alter the document content that was displayed.
More recently, however, it has become common in both game development and the creation of desktop applications.
</p>
</div>
</div>
<br />
<div class="jquery-btn">
<button>Click Me</button>
</div>
<br />
<p>Clicked: <span class="click-count">0</span></p>
<br />
@code {
protected override async void OnAfterRenderAsync(bool firstRender)
{
await jsRuntime.InvokeVoidAsync("renderjQueryComponents");
await base.OnAfterRenderAsync(firstRender);
}
}
[script.js]
var clickCount = 0;
function renderjQueryComponents() {
$("#accordion").accordion();
$(".jquery-btn button").button();
$(".jquery-btn button").click(function () {
console.log('Clicked');
$('.click-count')[0].innerText = ++clickCount;
});
}
function initialize() {
var latlng = new google.maps.LatLng(40.716948, -74.003563);
var options = {
zoom: 14, center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), options);
}
In the above example, Google Maps is initialized in the OnAfterRenderAsync life cycle method. By invoking it using a JavaScript interop, this will initialize Google Map API when the page is rendered.
There is
no direct way to detect whether the page is loaded on mobile or desktop in
Blazor. We have to find out through the userAgent property from the JavaScript
side using a JSInterop call. In order to find out, add a “script.js” file in
the wwwroot folder and include the isDevice method call. You can then invoke
the isDevice method to identify the correct device.
Refer to
the following code for further details.
[wwwroot/script.js]
function isDevice() {
return /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile/i.test(navigator.userAgent);
}
If you want to show a message using a simple browser alert message box, it is easy to do in Blazor. In Blazor, you can call a JavaScript method using JavaScript interop.
In the following code snippets, the text entered in the text box will be displayed in the alert box. In order to call the JavaScript method in Blazor, you should register the method in the browser window class. You can pass the message you want to show by passing method parameters in the JSRuntime.InvokeAsync method.
In Blazor, you can retrieve the IP address of the current request by utilizing the IHttpContextAccessor service. To do this,
Add builder.Services.AddHttpContextAccessor in your Program.cs file.
Then, inject IHttpContextAccessor into your component or service where you require the IP address.
Finally, obtain the client’s IP address using HttpContext.Connection.RemoteIpAddress.
@page "/"
@using Microsoft.AspNetCore.Http
<h3> Here's an example of how to retrieve the IP address from HttpContext in Blazor</h3>
<p>Localhost IP address: @ipAddress</p>
@code {
private string? ipAddress;
[Inject]
private IHttpContextAccessor? httpContextAccessor { get; set; }
protected override void OnInitialized ()
{
ipAddress = httpContextAccessor?.HttpContext?.Connection?.RemoteIpAddress?.ToString();
}
}
We can focus an InputText Blazor element not directly but by using JavaScript in Blazor. We can set an ID for the InputText and then pass it to JavaScript using interop by method InvokeVoidAsync. In the JavaScript function, use the focus DOM input method for focusing the input element with the received ID from Blazor.
Refer to the following code snippet.
[script.js]
function focusInput(id) {
document.getElementById(id).focus();
}
We can change a C# property’s value in Blazor from JavaScript by invoking the method DotNet.invokeMethodAsync in the script file (.js file). It takes the parameters Assembly name (Application name), the method name (public static method), and method parameter where we can change the C# static parameter.
Refer to
the following code snippet for more details.
[script.js]
function ChangeContentJS() {
DotNet.invokeMethodAsync('InvokeFromJsApp', "ChangeParaContentValue", "New Content");
}
[Index.razor]
@page "/"
@inject IJSRuntime JSRuntime
<h1>Change C# property value from JavaScript</h1>
<br />
<button @onclick='ButtonClickHandler'>Change Content - JS</button>
<br />
<p>@ParaContent</p>
@code {
public static string ParaContent = "Some Text Content";
public async Task ButtonClickHandler()
{
await JSRuntime.InvokeAsync<string>("ChangeContentJS");
}
[JSInvokable]
public static void ChangeParaContentValue(string value)
{
ParaContent = value;
}
}
In the previous
example, we have changed the ParaContent C# field value from the JavaScript by
calling the static method ChangeParaContentValue from JavaScript, along
with the new value as one of parameters in invokeMethodAsync.
The C# method should be defined as static and it should have a JSInvokable attribute.
The arguments in the JavaScript method Dotnet.invokeMethodAsync should be
@inject IJSRuntime jsRuntime
<div tabindex="0" @ref="myDiv">
To focus this div element when refreshing the page.
</div>
@code {
string KeyPressed = "";
protected ElementReference myDiv; // set the @ref for attribute
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await jsRuntime.InvokeVoidAsync("SetFocusToElement", myDiv);
}
}
}
To detect keypress event in a div tag, use the @onkeydown event on the current element. In the created example there is a div element with keydown event, and on rendering, the focus to the div element is set by using the JS Interop.
Error CS1061 ‘IJSRuntime’ does not
contain a definition for ‘Current’ and no accessible extension method ‘Current’
accepting a first argument of type ‘IJSRuntime’ could be found (are you missing
a using directive or an assembly reference?)
Solution
In ASP.NET Core 3.0.0-preview3, the Microsoft.Interop.JSRuntime.Current has been removed.
Add the .NET function invoke statement to a script in the head of Pages/_Host.cshtml file.
<script>
function CSMethod() {
DotNet.invokeMethodAsync('BlazorTestApp', 'CSCallBackMethod');
}
</script>
Here we are defining a JavaScript function “CSMethod”. This function will have a callback to our .NET function “CSCallBackMethod” which is defined in index.razor.
To invoke C# method from JavaScript,
The method must be decorated with “JSInvokable” attribute.
The method must be public.
The method may either be static or instance-level (this is only supported by Blazor 0.5.0 and above).
In Blazor, IJSRuntime interface is used to invoke a JavaScript
function from .NET.
Using the InvokeAsync<T> method of IJSRuntime abstraction, we can call the JavaScript function. This method takes the function name and function parameters as the argument.
The
method CallJSMethod will
call JS function JSMethod by using
the JSRuntime.InvokeAsync method.
Important notes
Do not write your JS code in the .cshtml file.
This is not allowed in Blazor and the compiler will throw an error. Always put
your JS code in the wwwroot/index.html file.
Always add your custom <script> tag after “<script
src=”_framework/blazor.webassembly.js”> </script>” in the
<body> section of the index.html file. This is to ensure that your
custom script will execute after loading the “blazor.webassembly.js” script.
Currently, Blazor doesn’t provide any direct way to access the browser’s DOM or APIs. But there is an option to invoke/call JavaScript functions via JS Interop, thereby letting Blazor access the DOM and its APIs. In the below example we have accessed the button’s DOM element in the script by using javascript interop.
[_Host.cshtml/index.html]
<script>
function accessDOMElement() {
var btn;
// access DOM here
btn = document.getElementById('btn');
btn.innerText = "Button Textchanged";
}
</script>
You have to refer to the JavaScript method
implemented JS (external-script.js) file in index.html properly and then call the function from .NET using IJSRuntime.
The InvokeAsync accepts only params object[] args, so the array of objects is parsed as a single, top-level entry in args. You have to pass the array of objects as a single object by casting. The following code only passes the single array object.
await JSRuntime.InvokeAsync<object>("debugOut", new Person[] {
new Person{FirstName=" Nancy",LastName=” Davolio”},
new Person{FirstName=" Andrew", LastName=” Fuller”}
});
By casting the array into an object, it retrieves all the values.
await JSRuntime.InvokeAsync< object >("debugOut", (object) new Person[] {
new Person{FirstName=" Nancy",LastName=” Davolio”},
new Person{FirstName=" Andrew", LastName=” Fuller”}
});
To use existing JavaScript libraries with Blazor, you can utilize JavaScript Interop, which allows you to call JavaScript functions from your C# code and vice versa.
Here are the general steps:
Include the JavaScript library in your project either by downloading it and placing it in your project directory or by using a package manager like npm.
Create a JavaScript file (e.g. mylibrary.js) that references the library and contains JavaScript functions that you want to use in your Blazor component.
In your Blazor component, inject the IJSRuntime service:
@inject IJSRuntime jsRuntime
4. Create a C# method that calls the JavaScript function. Use the InvokeAsync method of the IJSRuntime service to invoke the JavaScript function:
In the example above, myLibrary refers to the JavaScript library and myFunction is the name of the JavaScript function that you want to call. arg1 and arg2 are the arguments that you want to pass to the JavaScript function.
Note that the first argument to the InvokeAsync method specifies the name of the JavaScript function that you want to call, followed by any arguments that you want to pass to the function.
5. You can then call the CallMyLibraryFunction method in your component’s Razor markup or C# code.
No, the NavigateTomethod in theUriHelperclass of Blazor does not have built-in support for opening a URL in a new tab. It is primarily used to navigate within the same browser tab.
To open a URL in a new tab or window, you can use JavaScript interop in Blazor. Here’s an example of how you can achieve this: