How to disable "prevent this page from creating additional dialogs"? - javascript

I'm developing a web app that utilises JavaScript alert() and confirm() dialogue boxes.
How can I stop Chrome from showing this checkbox?
Is there a setting I can modify?
I know I could modify the source code, but I'd like it so that Chrome could still auto-update.
I don't need to worry about other browsers since the app only runs in Chrome.
I have admin access to the (Windows) machines that run the app.

You can't. It's a browser feature there to prevent sites from showing hundreds of alerts to prevent you from leaving.
You can, however, look into modal popups like jQuery UI Dialog. These are javascript alert boxes that show a custom dialog. They don't use the default alert() function and therefore, bypass the issue you're running into completely.
I've found that an apps that has a lot of message boxes and confirms has a much better user experience if you use custom dialogs instead of the default alerts and confirms.

This is what I ended up doing, since we have a web app that has multiple users that are not under our control...(#DannyBeckett I know this isn't an exact answer to your question, but the people that are looking at your question might be helped by this.) You can at least detect if they are not seeing the dialogs. There are few things you most likely want to change like the time to display, or what you are actually displaying. Remember this will only notify the user that they are have managed to click that little checkbox.
window.nativeAlert = window.alert;
window.alert = function (message) {
var timeBefore = new Date();
var confirmBool = nativeAlert(message);
var timeAfter = new Date();
if ((timeAfter - timeBefore) < 350) {
MySpecialDialog("You have alerts turned off");
}
}
window.nativeConfirm = window.confirm;
window.confirm = function (message) {
var timeBefore = new Date();
var confirmBool = nativeConfirm(message);
var timeAfter = new Date();
if ((timeAfter - timeBefore) < 350) {
MySpecialDialog("You have confirms turned off");
}
return confirmBool;
}
Obviously I have set the time to 3.5 milliseconds. But after some testing we were only able to click or close the dialogs in about 5 milliseconds plus.

I know everybody is ethically against this, but I understand there are reasons of practical joking where this is desired. I think Chrome took a solid stance on this by enforcing a mandatory one second separation time between alert messages. This gives the visitor just enough time to close the page or refresh if they're stuck on an annoying prank site.
So to answer your question, it's all a matter of timing. If you alert more than once per second, Chrome will create that checkbox. Here's a simple example of a workaround:
var countdown = 99;
function annoy(){
if(countdown>0){
alert(countdown+" bottles of beer on the wall, "+countdown+" bottles of beer! Take one down, pass it around, "+(countdown-1)+" bottles of beer on the wall!");
countdown--;
// Time must always be 1000 milliseconds, 999 or less causes the checkbox to appear
setTimeout(function(){
annoy();
}, 1000);
}
}
// Don't alert right away or Chrome will catch you
setTimeout(function(){
annoy();
}, 1000);

You should better use jquery-confirm rather than trying to remove that checkbox.
$.confirm({
title: 'Confirm!',
content: 'Are you sure you want to refund invoice ?',
confirm: function(){
//do something
},
cancel: function(){
//do something
}
});

You should let the user do that if they want (and you can't stop them anyway).
Your problem is that you need to know that they have and then assume that they mean OK, not cancel. Replace confirm(x) with myConfirm(x):
function myConfirm(message) {
var start = Number(new Date());
var result = confirm(message);
var end = Number(new Date());
return (end<(start+10)||result==true);
}

function alertWithoutNotice(message){
setTimeout(function(){
alert(message);
}, 1000);
}

Related

SWFObject event undefined in Chrome works in IE

I want to get the currentFrame of my Flash movie when it is loaded. I followed the the tutorial found here http://learnswfobject.com/advanced-topics/executing-javascript-when-the-swf-has-finished-loading/index.html and SWFOBJECT CurrentFrame Javascript. I am using SWFObject 2.3 beta. This works perfectly fine on Internet Explorer however it does not work on Google Chrome.
In Chrome I get the error
Uncaught TypeError: e.ref.currentFrame is not a function
Checking e it returns [object Object]
Checking e.ref returns [object HTMLObjectElement]
Checking e.ref.totalFrames returns undefined
var flashvars = {};
var params = {};
var attributes = {};
function mycall(e){
setInterval(function(){console.log("Frame: " + e.ref.currentFrame)},1000);
}
swfobject.embedSWF("notmyswf.swf", "course", "100%", "100%", "6.0.0", false, flashvars, params, attributes, mycall);
Why is this not working on Chrome but works well with IE? Is the event e not detected? Is there a work-around on how to make this work on Chrome?
The purpose of this is for me to create a check if the user is really using the course he has opened and not just leaving it idle. I have already added a code that will check idle but it is not enough. Most learners, have figured out a way to just open a course, leave it there to accumulate hours of training. Some even have a program running in their computers that will just move the mouse 1-pixel every few seconds so that the computer does not go to idle. If I can check the current frame of the Flash movie, I can create a function that will calculate the current page the user is viewing every 15 minutes. If he is stuck in the same page I can then show a prompt that the user must click in order to continue viewing the course or it will automatically close.
I suggest dropping the SWF-based currentFrame approach in favor of monitoring your calls to the database using JavaScript. (Based on your comments, it sounds like the DB calls are being sent by JS, so this shouldn't be a problem.)
If the course bookmark is auto-saved every 3 minutes (as described in your comments), you can cache the value in your page's JS and do a compare every time the save is performed. If the value hasn't changed in x number of minutes, you can display your timeout warning.
If you're using a SCORM wrapper (or similar), this is really simple, just modify the wrapper to include your timer code. Something like:
//Old code (pseudocode, not tested)
function setBoomark (val){
API.SetValue("cmi.core.lesson_location", val);
}
//New code (pseudocode, not tested)
var current_location = "";
var activityTimer;
function disableCourse(){
//do stuff to disable course because it timed out
}
function setBoomark (val){
API.SetValue("cmi.core.lesson_location", val);
if(val === current_location){
//do nothing, timer keeps ticking
} else {
//reset timer using new bookmark value
if(activityTimer){ clearTimeout(activityTimer); }
activityTimer = setTimeout(disableCourse, 15000);
//Update current_location value
current_location = val;
}
}
This is a rough sketch but hopefully you get the idea.
I feel stupid!
It did not work in Chrome and Firefox because I used the wrong casing for the functions but in IE11 it works no matter the case.
So the correct functions are:
e.ref.CurrentFrame() //I used currentFrame() which still works in IE11
e.ref.TotalFrames() //I used totalFrames() which still works in IE11
e.ref.PercentLoaded() //I used this correctly and was able to get the value

document.getElementById does not return null, but also does not do what I want. No error in javascript console

In this instance, I load a single paypal page, in which I am prompted to login. Once I login, the page changes, through the use of other javascripts on paypal's end. The address does not change on this transition, nor does the source code in any material way. I am trying to find a way to have my script wait long enough after the first click to be able to get the element that loads after. I thought I could do this fairly simple using the following:
document.getElementById("submitLogin").click();
window.onload = function() {
document.getElementById("continue").click();
};
When the script is executed, the first button is clicked, the page transitions, but it won't click the second button that loads. My javascript console does not report any errors, suggesting that it is able to "get" the element. Not sure why it won't click it though.
If nothing else, you could always poll for the existence of the "continue" element at some interval:
function clickContinue() {
var button = document.getElementById("continue");
return button ? button.click() : setTimeout(clickContinue, 100);
}
document.getElementById("submitLogin").click();
clickContinue();
If you go this route, you'll probably want to include a failsafe so it doesn't run too long, in case something unexpected happens. Something like this should work:
clickContinue.interval = 100; // Look for "continue" button every 0.1 second
clickContinue.ttl = 10000; // Approximate time to live: 10 seconds ~ 10,000 ms
clickContinue.tries = clickContinue.ttl / clickContinue.interval | 0;
function clickContinue() {
var button = document.getElementById("continue"),
interval = clickContinue.interval;
return button ? button.click() :
clickContinue.tries-- && setTimeout(clickContinue, interval);
}
// ...
Take a look at PayPal's API docs and see if they provide a way to set up a callback to handle this, though. This polling technique should probably only be used as a last resort.

How to Detect "prevent this page from creating additional dialogs"

QUESTION
How can I detect if a user has checked the box, "prevent this page from creating additional dialogs"?
WHY It's a problem
If the user has prevented the appearance of confirm boxes, the function confirm('foobar') always returns false.
If the user cannot see my confirmation dialogue boxes confirm('Are you sure?'), then the user can never perform the action.
CONTEXT
So, I use the code like if(confirm('are you sure?')){ //stuff... }. So an auto-response of false from the browser will prevent the user from ever doing stuff. But, if there was a way to detect that the user has checked the box, then I could execute the action automatically.
I think that if the user has disabled the dialogues, then the function should either throw an error, or return true. The function is meant to confirm an action that the user has requested.
As far as I know, this is not possible to do in any clean way as it's a browser feature, and if the browser doesn't let you know then you can't know.
However, what you could do is write a wrapper around confirm() that times the response time. If it is too fast to be human then the prompt was very probably suppressed and it would return true instead of false. You could make it more robust by running confirm() several times as long as it returns false so the probability of it being an über-fast user is very low.
The wrapper would be something like this:
function myConfirm(message){
var start = new Date().getTime();
var result = confirm(message);
var dt = new Date().getTime() - start;
// dt < 50ms means probable computer
// the quickest I could get while expecting the popup was 100ms
// slowest I got from computer suppression was 20ms
for(var i=0; i < 10 && !result && dt < 50; i++){
start = new Date().getTime();
result = confirm(message);
dt = new Date().getTime() - start;
}
if(dt < 50)
return true;
return result;
}
PS: if you want a practical solution and not this hack, Jerzy Zawadzki's suggestion of using a library to do confirmation dialogs is probably the best way to go.
I think you cannot change it - it's browser feature.
My first idea if you need workaround would be to change code from using system confirm to some js library alert (from e.g. jQuery UI)

How can I detect with JavaScript/jQuery if the user is currently active on the page?

I am needing to detect when a user is inactive (not clicking or typing) on the current page for more than 30 minutes.
I thinking it might be best to use event blubbling attached to the body tag and then just keep resetting a timer for 30 minutes, but I'm not exactly sure how to create this.
I have jQuery available, although I'm not sure how much of this will actually use jQuery.
Edit: I'm more needing to know if they are actively using the site, therefore clicking (changing fields or position within a field or selecting checkboxes/radios) or typing (in an input, textarea, etc). If they are in another tab or using another program, then my assumption is they are not using the site and therefore should be logged out (for security reasons).
Edit #2: So everyone is clear, this is not at all for determining if the user is logged in, authenticated or anything. Right now the server will log the user out if they don't make a page request within 30 minutes. This functionality to prevent the times when someone spends >30 minutes filling in a form and then submitting the form only to find out that they haven't been logged out. Therefore, this will be used in combination with the server site to determine if the user is inactive (not clicking or typing). Basically, the deal is that after 25 minutes of idle, they will be presented with a dialog to enter their password. If they don't within 5 minutes, the system automatically logs them out as well as the server's session is logged out (next time a page is accessed, as with most sites).
The Javascript is only used as a warning to user. If JavaScript is disabled, then they won't get the warning and (along with most of the site not working) they will be logged out next time they request a new page.
This is what I've come up with. It seems to work in most browsers, but I want to be sure it will work everywhere, all the time:
var timeoutTime = 1800000;
var timeoutTimer = setTimeout(ShowTimeOutWarning, timeoutTime);
$(document).ready(function() {
$('body').bind('mousedown keydown', function(event) {
clearTimeout(timeoutTimer);
timeoutTimer = setTimeout(ShowTimeOutWarning, timeoutTime);
});
});
Anyone see any problems?
Ifvisible.js is a crossbrowser lightweight solution that does just that. It can detect when the user switches to another tab and back to the current tab. It can also detect when the user goes idle and becomes active again. It's pretty flexible.
You can watch mouse movement, but that's about the best you're going to get for indication of a user still being there without listening to the click event. But there is no way for javascript to tell if it is the active tab or if the browser is even open. (well, you could get the width and height of the browser and that'd tell you if it was minimized)
I just recently did something like this, albeit using Prototype instead of JQuery, but I imagine the implementation would be roughly the same as long as JQuery supports custom events.
In a nutshell, IdleMonitor is a class that observes mouse and keyboard events (adjust accordingly for your needs). Every 30 seconds it resets the timer and broadcasts an state:idle event, unless it gets a mouse/key event, in which case it broadcasts a state:active event.
var IdleMonitor = Class.create({
debug: false,
idleInterval: 30000, // idle interval, in milliseconds
active: null,
initialize: function() {
document.observe("mousemove", this.sendActiveSignal.bind(this));
document.observe("keypress", this.sendActiveSignal.bind(this));
this.timer = setTimeout(this.sendIdleSignal.bind(this), this.idleInterval);
},
// use this to override the default idleInterval
useInterval: function(ii) {
this.idleInterval = ii;
clearTimeout(this.timer);
this.timer = setTimeout(this.sendIdleSignal.bind(this), ii);
},
sendIdleSignal: function(args) {
// console.log("state:idle");
document.fire('state:idle');
this.active = false;
clearTimeout(this.timer);
},
sendActiveSignal: function() {
if(!this.active){
// console.log("state:active");
document.fire('state:active');
this.active = true;
this.timer = setTimeout(this.sendIdleSignal.bind(this), this.idleInterval);
}
}
});
Then I just created another class that has the following somewhere in it:
Event.observe(document, 'state:idle', your-on-idle-functionality);
Event.observe(document, 'state:active', your-on-active-functionality)
Ifvisible is a nice JS lib to check user inactivity.
ifvisible.setIdleDuration(120); // Page will become idle after 120 seconds
ifvisible.on("idle", function(){
// do something
});
Using jQuery, you can easily watch mouse movement, and use it to set a variable indicating activity to true, then using vanilla javascript, you can check this variable every 30 minutes (or any other interval) to see if its true. If it's false, run your function or whatever.
Look up setTimeout and setInterval for doing the timing. You'll also probably have to run a function every minute or so to reset the variable to false.
Here my shot:
var lastActivityDateTime = null;
function checkActivity( )
{
var currentTime = new Date();
var diff = (lastActivityDateTime.getTime( ) - currentTime.getTime( ));
if ( diff >= 30*60*1000)
{
//user wasn't active;
...
}
setTimeout( 30*60*1000-diff, checkActivity);
}
setTimeout( 30*60*1000, checkActivity); // for first time we setup for 30 min.
// for each event define handler and inside update global timer
$( "body").live( "event_you_want_to_track", handler);
function handler()
{
lastActivityDateTime = new Date();
// rest of your code if needed.
}
If it's a security issue, doing this clientside with javascript is absolutely the wrong end of the pipe to be performing this check. The user could easily have javascript disabled: what does your application do then? What if the user closes their browser before the timeout. do they ever get logged out?
Most serverside frameworks have some kind of session timeout setting for logins. Just use that and save yourself the engineering work.
You can't rely on the assumption that people cannot log in without javascript, therefore the user has javascript. Such an assumption is no deterrent to any determined, or even modestly educated attacker.
Using javascript for this is like a security guard handing customers the key to the bank vault. The only way it works is on faith.
Please believe me when I say that using javascript in this way (and requiring javascript for logins!!) is an incredibly thick skulled way to engineer any kind of web app.
Without using JS, a simpler (and safer) way would simply be to have a lastActivity timestamp stored with the user's session and checking it on page load. Assuming you are using PHP (you can easily redo this code for another platform):
if(($_SESSION['lastAct'] + 1800) < time()) {
unset($_SESSION);
session_destroy();
header('Location: session_timeout_message.php');
exit;
}
$_SESSION['lastAct'] = time();
and add this in your page (optional, the user will be logged out regardless of if the page is refreshed or not (as he logs out on next page log)).
<meta http-equiv="refresh" content="1801;" />
You can add and remove classes to the document depending on the user active status.
// If the window is focused, a mouse wheel or touchmove event is detected
$(window).on('focus wheel touchmove', function() {
$( 'html' ).addClass('active').removeClass('inactive');
});
// If the window losses focus
$(window).on('blur', function() {
$( 'html' ).addClass('inactive').removeClass('active');
});
After that, you can check every while if the html has the "active" class and send an AJAX request to check the session status and perform the action you need:
setInterval( function() {
if ( $( 'html' ).hasClass('active') ) {
//Send ajax request to check the session
$.ajax({
//your parameters here
});
}
}, 60000 ); /* loops every minute */
If your concern is the lost of information for the user after a login timeout; another option would be to simply store all the posted information upon the opening of a new session (a new session will always be started when the older session has been closed/scrapped by the server) when the request to a page is made before re-routing to the logging page. If the user successfully login, then you can use this saved information to return the user back to where he was. This way, even if the user walk away a few hours, he can always return back to where he was after a successful login; without losing any information.
This require more work by the programmer but it's a great feature totally appreciated by the users. They especially appreciate the fact that they can fully concentrate about what they have to do without stressing out about potentially losing their information every 30 minutes or so.

Make browser window blink in task Bar

How do I make a user's browser blink/flash/highlight in the task bar using JavaScript? For example, if I make an AJAX request every 10 seconds to see if the user has any new messages on the server, I want the user to know it right away, even if he is using another application at the time.
Edit: These users do want to be distracted when a new message arrives.
this won't make the taskbar button flash in changing colours, but the title will blink on and off until they move the mouse. This should work cross platform, and even if they just have it in a different tab.
newExcitingAlerts = (function () {
var oldTitle = document.title;
var msg = "New!";
var timeoutId;
var blink = function() { document.title = document.title == msg ? ' ' : msg; };
var clear = function() {
clearInterval(timeoutId);
document.title = oldTitle;
window.onmousemove = null;
timeoutId = null;
};
return function () {
if (!timeoutId) {
timeoutId = setInterval(blink, 1000);
window.onmousemove = clear;
}
};
}());
Update: You may want to look at using HTML5 notifications.
I've made a jQuery plugin for the purpose of blinking notification messages in the browser title bar. You can specify different options like blinking interval, duration, if the blinking should stop when the window/tab gets focused, etc. The plugin works in Firefox, Chrome, Safari, IE6, IE7 and IE8.
Here is an example on how to use it:
$.titleAlert("New mail!", {
requireBlur:true,
stopOnFocus:true,
interval:600
});
If you're not using jQuery, you might still want to look at the source code (there are a few quirky bugs and edge cases that you need to work around when doing title blinking if you want to fully support all major browsers).
var oldTitle = document.title;
var msg = "New Popup!";
var timeoutId = false;
var blink = function() {
document.title = document.title == msg ? oldTitle : msg;//Modify Title in case a popup
if(document.hasFocus())//Stop blinking and restore the Application Title
{
document.title = oldTitle;
clearInterval(timeoutId);
}
};
if (!timeoutId) {
timeoutId = setInterval(blink, 500);//Initiate the Blink Call
};//Blink logic
Supposedly you can do this on windows with the growl for windows javascript API:
http://ajaxian.com/archives/growls-for-windows-and-a-web-notification-api
Your users will have to install growl though.
Eventually this is going to be part of google gears, in the form of the NotificationAPI:
http://code.google.com/p/gears/wiki/NotificationAPI
So I would recommend using the growl approach for now, falling back to window title updates if possible, and already engineering in attempts to use the Gears Notification API, for when it eventually becomes available.
My "user interface" response is: Are you sure your users want their browsers flashing, or do you think that's what they want? If I were the one using your software, I know I'd be annoyed if these alerts happened very often and got in my way.
If you're sure you want to do it this way, use a javascript alert box. That's what Google Calendar does for event reminders, and they probably put some thought into it.
A web page really isn't the best medium for need-to-know alerts. If you're designing something along the lines of "ZOMG, the servers are down!" alerts, automated e-mails or SMS messages to the right people might do the trick.
The only way I can think of doing this is by doing something like alert('you have a new message') when the message is received. This will flash the taskbar if the window is minimized, but it will also open a dialog box, which you may not want.
Why not take the approach that GMail uses and show the number of messages in the page title?
Sometimes users don't want to be distracted when a new message arrives.
you could change the title of the web page with each new message to alert the user. I did this for a browser chat client and most users thought it worked well enough.
document.title = "[user] hello world";
You may want to try window.focus() - but it may be annoying if the screen switches around
AFAIK, there is no good way to do this with consistency. I was writing an IE only web-based IM client. We ended up using window.focus(), which works most of the time. Sometimes it will actually cause the window to steal focus from the foreground app, which can be really annoying.
function blinkTab() {
const browserTitle = document.title;
let timeoutId;
let message = 'My New Title';
const stopBlinking = () => {
document.title = browserTitle;
clearInterval(timeoutId);
};
const startBlinking = () => {
document.title = document.title === message ? browserTitle : message;
};
function registerEvents() {
window.addEventListener("focus", function(event) {
stopBlinking();
});
window.addEventListener("blur", function(event) {
const timeoutId = setInterval(startBlinking, 500);
});
};
registerEvents();
};
blinkTab();
These users do want to be distracted when a new message arrives.
It sounds like you're writing an app for an internal company project.
You might want to investigate writing a small windows app in .net which adds a notify icon and can then do fancy popups or balloon popups or whatever, when they get new messages.
This isn't overly hard and I'm sure if you ask SO 'how do I show a tray icon' and 'how do I do pop up notifications' you'll get some great answers :-)
For the record, I'm pretty sure that (other than using an alert/prompt dialog box) you can't flash the taskbar in JS, as this is heavily windows specific, and JS really doesn't work like that. You may be able to use some IE-specific windows activex controls, but then you inflict IE upon your poor users. Don't do that :-(

Categories