I've tried to create a new window and print it from current one in maui application. I invoke the printPage() method from Index.razor. The problem is that I use js code to open it and it throws an exception that created window is null. Is it possible to create new window in such a way or there is another method?
I know that if I call just a window.print() in script, the print dialog will pop up. However, it'll print a current page and I want some specific page. (In the example it's just a blank page)
Index.razor
#page "/"
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
#inject IJSRuntime JS
<button class="btn btn-primary" #onclick="Print">Print</button>
#code {
private async void Print()
{
await JS.InvokeVoidAsync("printPage");
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
<title>MauiApp11</title>
<base href="/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/app.css" rel="stylesheet" />
<link href="MauiApp11.styles.css" rel="stylesheet" />
</head>
<body>
<div class="status-bar-safe-area"></div>
<div id="app">Loading...</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
Reload
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webview.js" autostart="false"></script>
<script>
function printPage() {
var i = window.open("", "", "height=452,width=1024,tabbar=no");
i.document.write(`<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>Template</h1>
<p>This is a blank template for a web page.</p>
</body>
</html>`);
i.document.close();
i.focus();
i.print();
}
</script>
</body>
</html>
How to call filter function JavaScript in blazor server-side
I am using Blazor server-side with Asp.net core I don't know how to call this script to my page.razor in #code{}
<script> $(document).ready(function(){
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase(); $("#myTable tr").filter(function(){
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1) }); }); });
</script>
Index.razor
#page "/"
#inject IJSRuntime JsRuntime
<button class="btn btn-primary" #onclick="Test">Test</button>
#Result
#code
{
private bool Result { get; set; } = false;
private async Task Test()
{
Result = await JsRuntime.InvokeAsync<bool>("Test.testFunc");
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>BlazorApp3</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
<div id="blazor-error-ui">
An unhandled error has occurred.
Reload
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script>
var Test = new function () {
this.testFunc = function () {
console.log("testFunc");
return true;
};
};
</script>
</body>
You can check that source code for more Javascript for Blazor https://github.com/ShadyNagy/Blazor.JavaScriptUtilities
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?
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.
Works fine for me like this, to add datepicker from jquery ui:
Razor component file.
#code {
protected override async void OnAfterRender(bool firstRender)
{
await jsRuntime.InvokeVoidAsync("addDatePicker");
base.OnAfterRender(firstRender);
}
}
Global razor file:
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Magiro.Blazor</title>
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<app>
#(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
</app>
<script src="_framework/blazor.server.js"></script>
<script>
window.addDatePicker = () => {
$(".datepicker").datepicker();
}
</script>
</body>
</html>
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 most probable cause is timing. The jQuery function gets executed before the DOM elements exists.
You should register the JS code as an interop function and call that after in OnAfterRender event.
Normally you don't need any JQuery function like ready, you can simply put those all required code into your custom js function which should run on ON_LOAD of your component as said by #Sipke Schoorstra in above answer
I am trying to integrate jQuery ClockPicker into my react app, but it won't work.
I have possibly tried the all possible ways without success. jQuery itself works well, but the ClockPicker doesn't.
It gives me an error:
Uncaught TypeError: clockpicker.clockpicker is not a function
These are my HTML and CDN links:
<!DOCTYPE html>
<html lang="en">
<head>
<base href="/">
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="description" content="The Brring Web Client">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/clockpicker/0.0.7/bootstrap-clockpicker.min.css" integrity="sha256-lBtf6tZ+SwE/sNMR7JFtCyD44snM3H2FrkB/W400cJA=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-87DrmpqHRiY8hPLIr7ByqhPIywuSsjuQAfMXAE0sMUpY3BM7nXjf+mLIUSvhDArs" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clockpicker/0.0.7/jquery-clockpicker.min.js"></script>
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="js/app.js"></script>
</body>
</html>
This is the function where I initialize the ClockPicker:
import * as $ from "jquery";
class example {
... other staff
initializeTimePicker() {
jQuery(function($) {
let clockpicker = $(".clockpicker");
clockpicker.clockpicker();
});
}
}
export default new CallUtil();
And finally, I call this function in another component's componentDidMount lifecycle:
import CallUtil from 'some_folder'
componentDidMount(): void {
CallUtil.initializeTimePicker();
}
What have I done wrong?
package com.xxx.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class IndexController {
#GetMapping("/")
public String showIndexPage(){
return "index";
}
}
IndexController.java
<!DOCTYPE html>
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
xmlns:th="http://www.springframework.org/schema/data/jaxb" xmlns:layout="http://www.w3.org/1999/xhtml">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<link rel="stylesheet" th:href="#{/bower_components/bootstrap/dist/css/styles.less}"
href="../../bower_components/bootstrap/dist/css/styles.css"/>
<script th:src="#{/bower_components/less/dist/less.min.js}"
src="../../bower_components/less/dist/less.min.js"></script>
</head>
<body>
</div>
</div>
<script th:href="#{/bower_components/bootstrap/dist/js/bootstrap.min.js}"
src="../../bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
</div>
</body>
</html>
index.html
The JavaScript tag does not work on the index page. I tried many ways but I could not find a solution. rejoice if you help me
I am using Thymeleaf as a template engine