I have created a webview in Android in which i am loading my html file.At the time of clicking a button i am displaying a pop up like alert dialog which is developed in html itself.
Now problem is as soon as i press back button on android phone,application is returning to previous page.But with identical behavior only dialog should be closed and application should be on same page.
How can i achieve it?
Thanks
I think you do not need the JavascriptInterface (as #Henil posted). I would do it like so:
in Java - onBackPressed:
if (webView.getUrl.equals("yourPopupUrl.com")) {
webView.loadUrl("javascript:goAwayPopup();");
return;
}
in JS:
function goAwayPopup() {
var popUp = document.getElementById("popUp"); // in my case popUp is just a <div>
var isVisible = popUp .offsetWidth > 0 || popUp .offsetHeight > 0;
if (isVisible) {
popUp.style.display = 'none';
}
}
EDIT:
Solution with JavascriptInterface:
in JS - function which is called when dialog popups:
function popUp() {
if (typeof Android != "undefined"){
if (Android.popUp!= "undefined") {
Android.popUp();
}
}
}
in Java:
define a inner class and a boolean field in your Activity
declare the bridge to your webview
override onBackPressed
private boolean isPopUpVisible = false;
// some code...
webView.addJavascriptInterface(new MyJavascriptBridge(), "Android");
// some code...
class MyJavascriptBridge {
public void popUp() {
if (isPopUpVisible)
isPopUpVisible = false;
else
isPopUpVisible = true;
}
}
onBackPressed:
if (isPopUpVisible) {
webView.loadUrl("javascript:goAwayPopup();");
return;
}
JS, again:
function goAwayPopup() {
// close alert here...
popUp(); // sets isPopUpVisible to false
}
Here is a post of closing a alert: How to "auto close" Alert boxes
Use java script interface and handle html page from that interface
Related
I have a cordova (android) app with window popout using window.open javascript that override with cordova inAppBrowser when device is ready refer to the code below:
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
window.open = cordova.InAppBrowser.open;
}
Then i want to set an event when user press phone back button or press "x" button to close the popout a dialog will pop out and asked "Are you sure? Y/N" before closing window popout. The code look like this:
var newwindow;
newwindow = window.open('something', '_self ', 'location=no');
newwindow.addEventListener('exit', function(event){ Exit() });
function Exit(){
navigator.notification.confirm(
'Are you sure?',
function(i){
if(i==2)
{
//exit the window popout
}
},
'App Name',
'Cancel,Exit'
);
But it doesn't work as i wanted, the popout window closed then dialog is prompt to user...How can i show a dialog and decides whether to close popout window.
Note: Sorry for bad grammar, i try my best to explain my problem.
I have found a fairly easy solution (android) for simple prompt like "Are you sure" "yes/no?" by editing the inappbrowser.dialog.java file. This solution is only prompting for confirmation before closing inappbrowser, which is suitable for my case.
Modify the java file InAppBrowserDialog.java in this location:
[your cordova project]/platforms/android/src/org/apache/cordova/inappbrowser/
ADD REQUIRED IMPORTS:
import android.content.DialogInterface;
MODIFY THE onBackPressed() FUNCTION
FROM:
public void onBackPressed () {
if (this.inAppBrowser == null) {
this.dismiss();
} else {
// better to go through the in inAppBrowser
// because it does a clean up
if (this.inAppBrowser.hardwareBack() && this.inAppBrowser.canGoBack()) {
this.inAppBrowser.goBack();
} else {
this.inAppBrowser.closeDialog();
}
}
}
TO:
public void onBackPressed() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context)
.setTitle("Exit")
.setMessage("You are about to exit, are you sure?")
.setPositiveButton("Exit", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
if (inAppBrowser == null) {
dismiss();
}
else {
// better to go through the in inAppBrowser
// because it does a clean up
if (inAppBrowser.hardwareBack() && inAppBrowser.canGoBack()) {
inAppBrowser.goBack();
} else {
inAppBrowser.closeDialog();
}
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
dialog.cancel();
}
});
alertDialogBuilder.create();
alertDialogBuilder.show();
}
I basically just create an alert dialog on top of checking for inappbrowser when back button is pressed.
I've been printing my page using the code below:
window.print();
An image below is what the print preview in Google chrome browser looks like. It has two main buttons: print and cancel.
I want to know if the user has clicked the print or cancel buttons. What I did uses jquery:
HTML Code of the Print Preview:
<button class="print default" i18n-content="printButton">Print</button>
<button class="cancel" i18n-content="cancel">Cancel</button>
Jquery Code:
$('button > .cancel').click(function (e) {
alert('Cancel');
});
$('button > .print').click(function (e) {
alert('Print');
});
I tried the code above with no luck. What am I missing?
You can not access Chrome's internal windows (printing dialog in this case) directly from a regular web page.
(function () {
var beforePrint = function () {
alert('Functionality to run before printing.');
};
var afterPrint = function () {
alert('Functionality to run after printing');
};
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function (mql) {
//alert($(mediaQueryList).html());
if (mql.matches) {
beforePrint();
} else {
afterPrint();
}
});
}
window.onbeforeprint = beforePrint;
window.onafterprint = afterPrint;
}());
Or, If you want to do something when the print preview gets opened, you can try below:
$(document).bind("keyup keydown", function (e) {
if (e.ctrlKey && e.keyCode == 80) {
setTimeout(function () { CallAfterWindowLoad();}, 5000);
return true;
}
});
function CallAfterWindowLoad()
{
alert("Open and call");
}
Reference:
How to capture the click event on the default print menu called by Javascript window.print()
Maybe if you provide your requirements for this two buttons click event, we can provide you an alternate solution.
it is very easily possible:
<body onafterprint="myFunction()">
The myFunction() that you can define within a tag will be fire when either the printing job is done or the cancel button was pressed.
As far as I know, the print preview is not part of any document your JS can access. These might interest you:
Detecting browser print event
ExtJS 4 - detecting if the user pressed "Print" on the print dialog that was called programatically
<script>
window.print();
onafterprint = function () {
window.location.href = "index.html";
}
</script>
This should do the trick. I've used jQuery v2.2.0 which is included in the html file.
$("#print").click(function() { // calls the id of the button that will print
document.body.style.visibility = 'hidden'; //code for hiding the body
document.getElementById('printthis').style.visibility = 'visible'; // div to be printed
document.getElementById('printthis').style.position = 'absolute'; //some code/css for positioning. you can adjust this
document.getElementById('printthis').style.top = '40px';
document.getElementById('printthis').style.left = '0px';
if (print()) { // shows print preview.
} else { // else statement will check if cancel button is clicked.
document.body.style.visibility = 'visible';
document.getElementById('printthis').style.position = '';
document.getElementById('printthis').style.top = '';
document.getElementById('printthis').style.left = '';
alert("Print Canceled");
}
});
I guess this might as well be used as a way to print certain divs in your html. Just hide the body element and only show the div that you want to print with some positioning css. Hope it works in yours. I've tried it and I can say that it worked for me.
I have an unexpected behavior of two JS which get called when I click on a control.
These JS are supposed to be called only when the button in the Tree list is clicked under specific conditions.
Right now the JS "message alert" is called even if a click on any of the node of the tree list when the conditions apply.
The other JS, which open a window, also opens when a node of the tree list is clicked, but after having opened and closed it at least one time.
protected void RadTreeList1_ItemCommand(object sender, TreeListCommandEventArgs e)
{
string idMessage = "";
if (e.CommandName == "Select")
{
if (e.Item is TreeListDataItem)
{
TreeListDataItem item = e.Item as TreeListDataItem;
idMessage = item.GetDataKeyValue("MessageID").ToString();
}
}
addMessage(idMessage);
}
private void addMessage(string idMessage)
{
if (Label1.Text =="" || Label1.Text==null )
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "Message", "alert('You shall be logged-in to post and replay to messages');", true);
}
else
{
{
Session["fatherMessageID"] = idMessage;
string script = "<script language='javascript' type='text/javascript'>Sys.Application.add_load(ShowWindow);</script>";
ClientScript.RegisterStartupScript(this.GetType(), "showWindow", script);
}
}
}
Function which opens the window:
function ShowWindow() {
var oWnd = window.radopen('Window1.aspx', 'window1');
}
Function which close the window from inside the window:
function GetRadWindow() {
var oWnd = null;
if (window.radWindow) oWnd = window.radWindow;
else if (window.frameElement.radWindow) oWnd = window.frameElement.radWindow;
return oWnd;
}
function CloseWindow() {
var oWnd = GetRadWindow();
oWnd.close()
}
Function which calls the CloseWindow inside the window page:
finally
{
string script = "<script language='javascript' type='text/javascript'>Sys.Application.add_load(CloseWindow);</script>";
ClientScript.RegisterStartupScript(this.GetType(), "CloseWindow", script);
}
How can I fix this issue?
Alert Issue:
you need to place addMessage(idMessage); inside if (e.Item is TreeListDataItem) condition
Dialog Issue:
not sure whether window.radopen('Window1.aspx', 'window1') is correct or not. if you are using RadWindow then showwindow function should be something like this var oWnd = window.radopen(null, "[RadWindowID]");
I have a webapplication which have call to showModalDialog but due to some reason this is not supported by chrome and I did search on for a work around but without any success.
The showModalDialog displays a aspx page with search field and a grid will be displayed with all the depts when user select on any deptname link the name should display in paren window textbox.
function DisplayDept()
{
var Object = window.showModalDialog('../DeptList.aspx', null, 'location=0,center:yes,status=0,scrollbars=1,width=500,height=500');
if (Object != null)
{
document.getElementById("<%=hdnDept.ClientID%>").value = Object.id;
if(document.getElementById("<%=txtDname.ClientID%>").value!=Object.name)
{
document.getElementById("<%=txtDname.ClientID%>").value=Object.name;
__doPostBack(document.getElementById("<%=txtDname.ClientID%>").name,'');
}
}
}
function LinkSelected(intCD, strName)
{
var obj=new Object();
obj.id=intCD;
obj.name=strName;
window.returnValue = obj;
window.close();
}
Tried with window.open method but unable to assing the selected field from open window to parent window control, wondering what would be ideal solution for this as I ma using asp.net web. application. Any suggestin/help on this would be of gr8 help.
For now I have resolved using windows.open as below.
function DisplayDept()
{
var Object = window.open('../DeptList.aspx', null, 'location=0,center:yes,status=0,scrollbars=1,width=500,height=500');
}
followed by
function SetDept(Object) {
if (Object != null)
{
document.getElementById("<%=txtDname.ClientID%>").value=Object.name;
__doPostBack(document.getElementById("<%=txtDname.ClientID%>").name,'');
}
}
And in the child windows
function SelectIt(intTypeCD, strTypeName)
{
var obj=new Object();
obj.id=intCD;
obj.name=strName;
window.opener.SetDept(obj);
window.close();
}
I have a webview that shows a message to confirm an user interaction. That message should fade out after any user interaction somewhere else on that page. To do this I detect any onTouchEvent and inject back a call to the webpage to trigger the message to fade out.
This works well for the first time but if I do it a second time (the webpage is not reloaded but the message is shown again through javascript by setting opacity back to 1 and display to "block") the message appears again but then fades out immediately w/o any user interactions. From the log statement I can see that the onTouchEvent does not get triggered and I do not inject the javascript.
I suspect that the loadURL creates some resilient call in the webpage that sticks around and somehow activates again.
Is there any way to clear this and see this executed only once ?
I catch the onTouchEvent in my WebView like this:
final class MyWebView extends WebView {
...
#Override
public boolean onTouchEvent(MotionEvent event) {
Log.v(TAG,"onTouchEvent");
if (mUndoActive && (event.getAction() == MotionEvent.ACTION_DOWN)) {
mUndoActive = false;
mLastAction = LAST_ACTION_NONE;
Log.v(TAG,"send hide message");
handler.sendEmptyMessageDelayed(CLICK_ON_WEBVIEW, 300);
}
return super.onTouchEvent(event);
}
}
In the parent activity I override the handleMessage and inject a javascript to my webview to trigger the javascript that fades out a message element like this:
#Override
public boolean handleMessage(Message msg) {
Log.v(TAG,"handleMessage triggered");
if (msg.what == CLICK_ON_WEBVIEW){
Log.v(TAG,"handle message registerd click from stack view web page");
webview.loadUrl("javascript:hideMessage()");
return true;
}
return false;
}
and the javascript in the webview is:
function hideMessage() {
var message = document.getElementById("message");
if (message != null) {
if (!message.style.opacity) {
message.style.opacity = 1;
}
var fader = setInterval(function(){
message.style.opacity -= .02;
if (message.style.opacity <= 0) {
clearInterval(fader);
message.style.display = "none";
}
}, 25);
}
}
I found a soulution myself: Preceding the 2 Interval calls with window, ie. window.clearInterval(fader) did fix the issue. I don't quite understand why but it looks like the interval timer did keep running permanently and was not properly turned off.