Maui сhange navigation in BlazorWebView - javascript

How can I change a page in BlazorWebView using Maui? For example, the page '/' was opened and I need to open '/fetch'.
I found how to return to the previous link via js.
Created a Custom Navigation Manager:
public class CustomNavigationManager
{
private static IJSRuntime JSRuntime { get; set; }
public CustomNavigationManager(IJSRuntime jSRuntime)
{
JSRuntime = jSRuntime;
}
public static async Task Navigation(string url)
{
//Microsoft.Maui.Platform;
if (JSRuntime!= null)
{
await JSRuntime.InvokeVoidAsync("navigation", url);
}
}
}
Which calls the Js code. Which calls the Js code. Which I placed in wwwroot/index.html
<script type="text/javascript">
window.navigation = (url) => {
window.location.href = url; // Error: There is no content at fetch.
//history.back();
//window.location="https://0.0.0.0/fetch"; //Error: There is no content at fetch.
}
</script>
Registering a service
builder.Services.AddTransient<CustomNavigationManager>();
And inject in Shared/MainLayout.razor
#page "/"
#inject CustomNavigationManager navigation
And I use it in maui
await CustomNavigationManager.Navigation("/fetch");
If I use the js code history.back(); then everything works,
but if I want to redirect to /fetch using
window.location.href = url;
then I get an error: There is no content at fetch.
Fetch.razor page
#page "/fetch"
#page "/fetch/{id}"
<h1>Test!</h1>

Fetch.razor
#page "/fetch"
#page "/fetch/{text}"
<h3>#Text</h3>
#code
{
[Parameter]
public string Text { get; set; }
}
MainLayout.razor
#inherits LayoutComponentBase
#inject CustomNavigationManager navigation
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
About
</div>
<article class="content px-4">
#Body
</article>
<div>#Url</div>
</main>
</div>
#code
{
[Inject]
private NavigationManager MyNavigationManager { get; set; }
private string Url;
protected override void OnInitialized()
{
base.OnInitialized();
MyNavigationManager.LocationChanged += OnLocationChanges;
Url = MyNavigationManager.Uri;
}
private void OnLocationChanges(object sender, LocationChangedEventArgs e)
{
Url = e.Location;
StateHasChanged();
}
}
CustomNavigationManager.cs
public class CustomNavigationManager
{
private static NavigationManager _navigationManager;
public CustomNavigationManager(NavigationManager MyNavigationManager)
{
_navigationManager = MyNavigationManager;
}
public static void Navigation(string url)
{
if (_navigationManager!=null)
{
_navigationManager.NavigateTo(url);
}
}
}
Decided so: Subscribed to the navigation change event. Implemented the service, and called NavigateTo. It didn't work through Js. Note: BlazorWebView must already download the project, otherwise nothing will work)

Related

How to pass form FormData from a view to a controller without using a specific Model?

How to pass form data from data a view to a controller without using Model? .. the reason behind that I'm trying to build public bootstrap modal that can be rendered as a partial view and submitted whatever data is included.
I almost did everything but for the final step [fetching the form to the controller] I get this error
POST https://localhost:44357/Pages/Update 500
and here is my attempt
Modal View
#model Modal
<div class="modal fade" id="MessageModel" tabindex="-1" aria-labelledby="MessageModel" aria-hidden="true">
<div class="modal-dialog">
<diav class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">#Model.header</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div id="ModelForm" class="modal-body">
<form method="post" id="ModalForm" action="#Model.SubmitFormUrl">
#Html.Raw(Model.body)
</form>
</div>
<div class="modal-footer">
#switch (#Model.footer)
{
case fotterButtons.OneButton:
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
break;
case fotterButtons.TwoButtons:
<button type="button" onclick="submitModalForm()" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
break;
}
</div>
</div>
</div>
Modal Model
public class Modal
{
// header section
public string header { get; set; }
public string body { get; set; }
public fotterButtons footer { get; set; }
public string SubmitFormUrl { get; set; }
}
public enum fotterButtons
{
OneButton,
TwoButtons
}
JavaScript to submit Modal
function submitModalForm() {
var formElem = document.forms['ModalForm'];
/*var rslt = new FormData(formElem);*/
var page = new FormData(formElem);
//console.log([...page]);
fetch(formElem.getAttribute("action"), {
method: "POST",
//mode: 'cors',
//cache: 'no-cache',
//credentials: 'same-origin',
//headers: {
// "Content-type":"application/json;charset=utf-8"
//},
body: page
}).catch (function (erro) {
console.log(erro);
});
return false;
};
The usage of the Modal in view
#{
ViewData["saveForm"] =
#"
<h5 class='currentPage'></h5>
<input type='hidden' name='Id' id='pageID' />
<input type='hidden' name='pageHtmlContent' id='pageHtml' />
<input type='text' name='pageName' class='form-control' />
<textarea name='pageDescreption' class='form-control' ></textarea>
";
}
<partial name="_MessageBox"
model='new Modal() {
header = "Updating page content" ,
body = #ViewData["saveForm"].ToString(),
footer = fotterButtons.TwoButtons,
SubmitFormUrl = #Url.Action("Update", "Pages")
};' />
The targeted ViewModel to be submitted
public class VMPage
{
public List<Page> pages { get; set; }
public Page page { get; set; }
}
and the source Model of page looks like
public class Page
{
[Key]
public Guid Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] // for auto increment
public int Index { get; set; }
public string pageName { get; set; }
public string pageDescreption { get; set; }
public string pageHtmlContent { get; set; }
}
Finally the controller's action
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Update(FormCollection page)
{
//if (ModelState.IsValid)
//{
// try
// {
// context.Update(page);
// await context.SaveChangesAsync();
// }
// catch (DbUpdateConcurrencyException)
// {
// throw;
// }
// return RedirectToAction(nameof(Index));
//}
return RedirectToAction(nameof(Index));
}
Notice: Modal view is strongly typed with Modal, not with Page. I need to use this view by rendering it, using the partial tag helper, anywhere in my application to submit any Model "page as an example".
Another note: when I try to get formdata values it comeback with
var page = new FormData(formElem);
console.log([...page]);
0: (2) ["Id", "f1d7afc6-14a8-4b85-a1dd-02ec1ae9a1f8"]
1: (2) ["pageHtmlContent", ""]
2: (2) ["pageName", "fffffffffffffffffff"]
3: (2) ["pageDescreption", "vvvvvvvvvvvvvvvvvvvvv"]
But I'm not sure if reciving formdata is correct using FormCollection page

JS in blazor component

I am trying create an alert message in within a Blazor component. I have no idea how to do this. I am running ASP.NET Core 3.1 Blazor server-side. Here's what I've tried
Component function:
private async Task ShowAlert()
{
await JSRuntime.InvokeAsync<object>("ShowMsg");
}
Javascript Interop:
function ShowMsg() {
success = "Success!";
return success;
}
File host.cshtml:
<script src="~/BlazorInterop.js"></script>
#page "/"
<button #onclick="MessageBox">Show Message</button>
#code
{
[Inject] IJSRuntime JSRuntime { get; set; }
protected async Task MessageBox()
{
await JSRuntime.InvokeVoidAsync("exampleJsFunctions.ShowMsg",
"Hello Blazor");
}
}
Put the following script tag beneath <script src="_framework/blazor.server.js"></script> in the _Host.cshtml file, like this:
<script src="_framework/blazor.server.js"></script>
<script>
window.exampleJsFunctions =
{
ShowMsg: function (message) {
window.alert(message);
}
};
</script>

Spring boot AJAX POST request and knockout.js debug error from user interface

I have two java models as player and team. I have a controller class. I get an error when I send a post request via ajax from the user interface. I've solved errors like CORS. But there is an error I can't solve; The knockout.js debug error and the post request are not occurring. There is no change in my database. I shared the model classes, the controller class, the html and javascriptfiles.
What do I need to change? Could you help?
Player Model
#Entity
#Table(name = "player")
public class Player{
#Id
#GeneratedValue
#NotNull
#Column
private int id;
#NotNull
#Column
private String playerName;
#NotNull
#Column
private String playerSurname;
#Column
private int playerAge;
public String getPlayerName() {
return playerName;
}
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
public String getPlayerSurname() {
return playerSurname;
}
public void setPlayerSurname(String playerSurname) {
this.playerSurname = playerSurname;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getPlayerAge() {
return playerAge;
}
public void setPlayerAge(int playerAge) {
this.playerAge = playerAge;
}
}
Team Model
#Entity
#Table(name = "team")
public class Team {
#Id
#GeneratedValue
#NotNull
#Column
private int id;
#NotNull
#Column
private String teamName;
#Column
private String teamCountry;
public Team(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public String getTeamCountry() {
return teamCountry;
}
public void setTeamCountry(String teamCountry) {
this.teamCountry = teamCountry;
}
#ManyToOne
private Player player;
public Player getPlayer() {
return player;
}
public void setPlayer(Player player) {
this.player = player;
}
}
Controller
#CrossOrigin(origins = "http://localhost:8000/")
#RestController
public class TeamController {
#Autowired
PlayerRepository playerRepository;
#Autowired
TeamRepository teamRepository;
#RequestMapping("/")
public void main() {
//create players by manual
Player messi = new Player();
Player ronaldo = new Player();
Player ozil = new Player();
messi.setPlayerName("Lionel");
messi.setPlayerSurname("Messi");
messi.setPlayerAge(31);
ronaldo.setPlayerName("Cristiano");
ronaldo.setPlayerSurname("Ronaldo");
ronaldo.setPlayerAge(32);
ozil.setPlayerName("Mesut");
ozil.setPlayerSurname("Ozil");
ozil.setPlayerAge(29);
this.playerRepository.save(messi);
this.playerRepository.save(ronaldo);
this.playerRepository.save(ozil);
//create teams by manual
Team barcelona = new Team();
Team juventus = new Team();
Team arsenal = new Team();
barcelona.setTeamName("Barcelona");
barcelona.setTeamCountry("Spain");
barcelona.setPlayer(messi);
juventus.setTeamName("Juventus");
juventus.setTeamCountry("Italy");
juventus.setPlayer(ronaldo);
arsenal.setTeamName("Arsenal");
arsenal.setTeamCountry("England");
arsenal.setPlayer(ozil);
this.teamRepository.save(barcelona);
this.teamRepository.save(juventus);
this.teamRepository.save(arsenal);
}
//**PLAYER**
#GetMapping(value="/getAllPLayers")
public List<Player> getAllPlayers(){
return playerRepository.findAll();
}
#PostMapping(value="getPlayerByName")
public List<Player> getPlayerByName(#RequestParam("playerName") String playerName){
return playerRepository.findByPlayerName(playerName);
}
#PostMapping(value="getPlayerBySurname")
public List<Player> getPlayerBySurname(#RequestParam("playerSurname") String playerSurname){
return playerRepository.findByPlayerSurname(playerSurname);
}
#PostMapping(value="getPlayerByAge")
public List<Player> getPlayerByAge(#RequestParam("playerAge") int playerAge){
return playerRepository.findByPlayerAge(playerAge);
}
#PostMapping(value="createNewPlayer")
public Player createNewPlayer(#Valid #RequestBody Player player) {
return playerRepository.save(player);
}
//**TEAM**
#GetMapping(value="/getAllTeams")
public List<Team> getAllTeams(){
return teamRepository.findAll();
}
#PostMapping(value = "/getTeamsByName")
public List<Team> getTeamByName(#RequestParam("teamName") String teamName){
return teamRepository.findByTeamName(teamName);
}
#PostMapping(value = "/getTeamsByCountry")
public List<Team> getTeamByCountry(#RequestParam("teamCountry") String teamCountry){
return teamRepository.findByTeamCountry(teamCountry);
}
#PostMapping(value="/createNewTeam")
public Team createNewTeam(#Valid #RequestBody Player player,#RequestBody Team team) {
playerRepository.save(player);
team.setPlayer(player);
return teamRepository.save(team);
}
}
Config
#Configuration
#EnableWebMvc
public class WebConfig implements Filter,WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
System.out.println("WebConfig; "+request.getRequestURI());
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With,observe");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Expose-Headers", "Authorization");
response.addHeader("Access-Control-Expose-Headers", "USERID");
response.addHeader("Access-Control-Expose-Headers", "ROLE");
response.addHeader("Access-Control-Expose-Headers", "responseType");
response.addHeader("Access-Control-Expose-Headers", "observe");
System.out.println("Request Method: "+request.getMethod());
if (!(request.getMethod().equalsIgnoreCase("OPTIONS"))) {
try {
chain.doFilter(req, res);
} catch(Exception e) {
e.printStackTrace();
}
} else {
System.out.println("Pre-flight");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Access-Control-Expose-Headers"+"Authorization, content-type," +
"USERID"+"ROLE"+
"access-control-request-headers,access-control-request-method,accept,origin,authorization,x-requested-with,responseType,observe");
response.setStatus(HttpServletResponse.SC_OK);
}
}
}
Player Repo
public interface PlayerRepository extends JpaRepository<Player, Integer>{
List<Player> findByPlayerName(String playerName);
List<Player> findByPlayerSurname(String playerSurname);
List<Player> findByPlayerAge(int playerAge);
}
Team Repo
public interface TeamRepository extends JpaRepository<Team, Integer>{
List<Team> findByTeamName(String teamName);
List<Team> findByTeamCountry(String teamCountry);
}
POST HTML Page
<!DOCTYPE HTML>
<html>
<head>
<title>Team Management</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" />
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<script src="js/restGetPlayer.js"></script>
<script src="js/restGetTeam.js"></script>
<script src="js/postTeam.js"></script>
</head>
<body>
<div class="container">
<h3 style="color: darkolivegreen" align="center">Create a new team</h3>
<div class"main-block>
<form id="teamForm" class="form-inline" style="margin:20px 20px 20px 20px">
<div class="form-group">
<label for="playerName" style="margin-left:20px; margin-right:5px">Player Name:</label>
<input type="text" class="form-control" id="playerName" placeholder="Enter player name"/>
</div>
<br>
<div class="form-group">
<label for="playerSurname" style="margin-left:20px; margin-right:5px">Player Surname:</label>
<input type="text" class="form-control" id="playerSurname" placeholder="Enter player surname"/>
</div>
<div class="form-group">
<label for="playerAge" style="margin-left:20px; margin-right:5px">Player Age:</label>
<input type="text" class="form-control" id="playerAge" placeholder="Enter player age"/>
</div>
<br style="clear: both;">
<div class="form-group">
<label for="teamName" style="margin-right:5px">Team Name:</label>
<input type="text" class="form-control" id="teamName" placeholder="Enter team name"/>
</div>
<br>
<div class="form-group">
<label for="teamCountry" style="margin-left:20px; margin-right:5px">Team Country:</label>
<input type="text" class="form-control" id="teamCountry" placeholder="Enter team country"/>
</div>
<br>
<hr>
<button type="submit" class="btn btn-default" style="margin-left:20px; margin-right:5px" >Submit Team</button>
</form>
</div>
<div class="col-sm-7" style="margin:20px 0px 20px 0px">
<button id="getAllTeams" class="btn btn-primary">Get Team Information</button>
<div id="getResultDiv3" style="padding:20px 10px 20px 50px">
<ul class="list-group">
</ul>
</div>
</div>
</div>
<style>
.container {
max-width: 400px;
width: 100%;
margin: 0 auto;
position: relative;
}
#contact {
background: #F9F9F9;
padding: 25px;
margin: 150px 0;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
}
</style>
<script type="text/javascript" src="js/libs/require/require.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
AJAX POST
$( document ).ready(function() {
$("#teamForm").submit(function(event) {
event.preventDefault();
ajaxPost();
});
function ajaxPost(){
var formData = {
playerName : $("#playerName").val(),
playerSurname : $("#playerSurname").val(),
playerAge : $("#playerAge").val(),
teamName : $("#teamName").val(),
teamCountry : $("#teamCountry").val()
}
$.ajax({
type : "POST",
contentType : "application/json",
url : "http://localhost:8080" + "/createNewTeam",
data : JSON.stringify(formData),
dataType : 'json',
success: function(result){
alert("Teams loaded!");
console.log(result);
$('#getResultDiv3 ul').empty();
var tableTitle = "<h2><strong>Team List</strong></h2>";
var teamList = "<table border='1'>";
teamList += "<tr><td><strong>Team Name</strong></td><td><strong>Team Country</strong></td><td><strong>Player Name</strong></td><td><strong>Player Surname</strong></td><td><strong>Player Age</strong></td></tr>";
$.each(result, function(i, teams){
teamList +="<tr>";
teamList +="<td>"+teams.teamName +"</td>";
teamList +="<td>"+teams.teamCountry+"</td>";
teamList +="<td>"+teams.player.playerName+"</td>";
teamList +="<td>"+teams.player.playerSurname+"</td>";
teamList +="<td>"+teams.player.playerAge+"</td>";
teamList +="</tr>";
});
teamList +="</table>";
$('#getResultDiv3').append(tableTitle, teamList)
console.log("Success: ", result);
},
error : function(e) {
$("#getResultDiv3").html("<strong>Error</strong>");
console.log("ERROR: ", e);
}
});
resetData();
}
function resetData(){
$("#playerName").val("");
$("#playerSurname").val("");
$("#playerAge").val("");
$("#teamName").val("");
$("#teamCountry").val("");
}
})
MainController.js
/**
* #license
* Copyright (c) 2014, 2019, Oracle and/or its affiliates.
* The Universal Permissive License (UPL), Version 1.0
*/
/*
* Your application specific code will go here
*/
define(['ojs/ojresponsiveutils', 'ojs/ojresponsiveknockoututils', 'knockout', 'ojs/ojknockout'],
function(ResponsiveUtils, ResponsiveKnockoutUtils, ko) {
function ControllerViewModel() {
var self = this;
// Media queries for repsonsive layouts
var smQuery = ResponsiveUtils.getFrameworkQuery(ResponsiveUtils.FRAMEWORK_QUERY_KEY.SM_ONLY);
self.smScreen = ResponsiveKnockoutUtils.createMediaQueryObservable(smQuery);
// Header
// Application Name used in Branding Area
self.appName = ko.observable("Oracle JET + REST API");
// User Info used in Global Navigation area
self.userLogin = ko.observable("admin#oracle.com");
// Footer
function footerLink(name, id, linkTarget) {
this.name = name;
this.linkId = id;
this.linkTarget = linkTarget;
}
self.footerLinks = ko.observableArray([
new footerLink('About Oracle', 'aboutOracle', 'http://www.oracle.com/us/corporate/index.html#menu-about'),
new footerLink('Contact Us', 'contactUs', 'http://www.oracle.com/us/corporate/contact/index.html'),
new footerLink('Legal Notices', 'legalNotices', 'http://www.oracle.com/us/legal/index.html'),
new footerLink('Terms Of Use', 'termsOfUse', 'http://www.oracle.com/us/legal/terms/index.html'),
new footerLink('Your Privacy Rights', 'yourPrivacyRights', 'http://www.oracle.com/us/legal/privacy/index.html')
]);
}
return new ControllerViewModel();
}
);
Picture 1:
Adding Player
Picture 2:
ERROR log After add player
Picture 3:
MySQL player table did not any change
Answering your question, it is not doing anything because you are not sending the parameter Player (that must be valid) due you are using a form this is not the way you should do it. (request params are send via url and your form should do it via #RequestBody)
Check this post for information. Can I use #Requestparam annotation for a Post request?
I would do something like this:
On my controller due I can have only one #RequestBody but my form sends an object containing data for multiple types of an object I would do a Dto
Something like this:
#PostMapping(value="/createNewTeam")
public Team createNewTeam(#Valid #RequestBody PayloadDto payloadDto) {
final Player player = new Player();
player.setPlayerName(payloadDto.playerName);
// fill player information
final Team team = new Team();
// fill team information...
playerRepository.save(player);
return teamRepository.save(team);
}
Your PayloadDto object must contain all attributes you are sending..
public class PayloadDto{
#JsonProperty("playerName")
public String playerName;
#JsonProperty("playerSurname")
public String playerSurname;
// .. more player and team properties
}
Be sure that the jsonProperty("propertyName) holds the same name you are using when sending the information

Uncaught TypeError: window.HybridApp.setMessage is not a function error

I want to make an app for hybridApp but some errors occurred.
"Uncaught TypeError: window.HybridApp.setMessage is not a function error"
I tried to find the cause, but I could not.
proguard
-keepattributes JavascriptInterface
-keep public class com.test.crosswalkdemo2$AndroidBridge
-keep public class * implements com.test.crosswalkdemo2$AndroidBridge
-keepclassmembers class com.test.crosswalkdemo2$AndroidBridge {
<methods>;
}
-keepclassmembers class * {
#android.webkit.JavascriptInterface <methods>;
}
main
public class AndroidBridge {
#JavascriptInterface
public void setMessage(final String text) { // must be final
handler.post(new Runnable() {
public void run() {
mTextView.setText(text);
}
});
}
}
html
<script language="JavaScript">
function setMessage(arg) {
document.getElementById('textMessageFromApp').innerHTML = arg;
}
function sendMessage(msg){
window.HybridApp.setMessage(msg);
}
</script>
</head>
<body>
<h2>Hybrid App (WEB+APP)</h2>
<hr/>
<input type="text" id="textMessageFromWeb" value="Hello, Hybrid(WEB)!!"/>
<input type="button" value="Send" onclick="sendMessage(document.getElementById('textMessageFromWeb').value)"/>
please see my code and help.

What's the true purpose of setJavaScriptCanOpenWindowsAutomatically

According to Android document:
Tells JavaScript to open windows automatically. This applies to the JavaScript function window.open(). The default is false.
But I didn't see any different between use or not use this API in my code, window.open works fine in the both cases, so what's the true purpose of this API or my usage is not correct?
My code sample as below:
public class MainActivity extends Activity {
private WebView mWebView;
//private Context mContext
RelativeLayout mParent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mParent = new RelativeLayout(MainActivity.this);
setContentView(mParent);
mWebView = new WebView(MainActivity.this);
WebSettings settings = mWebView.getSettings();
settings.setSupportMultipleWindows(true);
settings.setJavaScriptCanOpenWindowsAutomatically(false);
settings.setJavaScriptEnabled(true);
mParent.addView(mWebView);
mWebView.loadUrl("file:///android_asset/create_window.html");
mWebView.setWebViewClient(new MyWebViewClient());
mWebView.setWebChromeClient(new WebChromeClient() {
#Override
public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, Message resultMsg) {
WebView newWebView = new WebView(view.getContext());
newWebView.getSettings().setUserAgentString("BBB");
//newWebView.getSettings().setJavaScriptEnabled(true);
//newWebView.setWebChromeClient(this);
newWebView.setWebViewClient(new MyWebViewClient());
//view.getSettings().setUserAgentString("CCC");
mParent.addView(newWebView);
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(newWebView);
resultMsg.sendToTarget();
return true;
}
#Override
public void onCloseWindow(WebView window) {
mParent.removeViewAt(mParent.getChildCount() - 1);
}
});
}
private class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
#Override
public void onPageFinished(WebView view, final String url) {
super.onPageFinished(view, url);
}
}
}
The content of create_window.html as below:
<html>
<!-- scripts -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Create Window</title>
<script>
function
openURL ()
{
alert ("opening window");
window.open ("http://www.whoishostingthis.com/tools/user-agent/", "_blank", "width=200,height=100");
}
</script>
</head>
<body>
<div>
<button onclick="openURL()">open website in new window</button>
</div>
</body>
</html>

Categories