Tag Archives: browser

Override “Print Background Colors and Images” Option in Browser

Internet Explorer and Firefox, to name a few, have an option that allows for the printing of background colors and images. The user can check this option to override the print style sheet and print the backgrounds that were removed to increase legibility, protect copyright, or whatever other reason was necessary.

By default, this option is off in browsers and the user has to manually check a box. In IE it is under Tools, Internet Options, Advanced, Printing. In Firefox it is in Page Setup of the Print Preview window.

Here is what is looks like in FF:
Firefox print settings
To prevent the browser from printing backgrounds when this is checked, add the following to your print style sheet:

* {
  background-color: white !important;
  background-image: none !important;
  }

Now, I’m not one to take all control away from the user, but there are situations when you must.

Session Timeout Warning PHP Example with jQuery/JS

Updated 11-Jan-2010: Improved ability to adjust timeouts and simplified code a bit.

Detecting and warning a user of their session timing out can come in handy and, in some cases, may be necessary. Here is one way of doing this with jQuery/javascript and PHP. There may be a better way to do this, so take this as an example.
There is a post on a ColdFusion session timeout warning that works in a similar manner.

Session Defined: Start to Finish

A session is defined as when a user begins and ends using or visiting a web site. It can be unlimited in length or strictly defined by a timeout period. If the site requires a log in or accesses sensitive data, it should time out after a period of inactivity. They can end a session by logging out or closing the browser.

Inactivity means the user has done nothing, made no requests of the web server, during a specified time. Ajax requests usually do not count. There are other posts out there that detail how to check for session expiration with Ajax requests.

Demo

The session time left is determined by the server, and, if you want to poll the server with an Ajax request, go for it. This demo uses javascript to keep track of the time left in the session.

The demo uses a simple log in with session timing handled by jquery and javascript. When the session expiration approaches, the user is warned and given an opportunity to restart the session. If the session time limit is reached, the user is prompted to log in again. If they ignore that prompt, the page automatically redirects to the log in form. In the demo this sequence of events takes 40 seconds to complete and is broken down as follows:

  1. Session timeout: 30 seconds
  2. Timeout warning: 20 seconds
  3. Session expired warning: 10 seconds
  4. Redirect to log in page: 10 seconds

Interrupting the User

The user’s attention can be diverted away from other open windows to the eminent session expiration by using a javascript alert in place of the jquery dialog box. Personal preference.

Code Breakdown

The log in page checks for a query string variable called ‘expired’ and sets the loggedin cookie to false. This is there because the code is going to control the expiration of the session eliminating the need to compensate for browser latency. The actual session start time the time the page loads can differ by several seconds. To avoid having to add time to the session or any other fancy guesswork, when the allotted session time has expired according to the javascript timer on the page, they are done – session over.

If they are logged in, they get bumped to the index page. The rest is the logic that handles the log in form.

Note: I would not recommend handling a log in form this way. This is for demonstration only.

//if query string contains expired var & it = true, set loggedin cookie as false
//else if loggedin cookie exists and is set to true, send to index page
if (isset($_GET['expired']) && $_GET['expired'] == 'true')
    {
        setcookie("loggedin", "false", time()+30);
    }
elseif (isset($_COOKIE['loggedin']) && $_COOKIE['loggedin'] == 'true')
    {
        header("Location: index.php");
        exit;
    }
//log in logic
if (isset($_POST['username']) && isset($_POST['pw']) && $_POST['username'] == "session" && $_POST['pw'] == "test")
    {
        setcookie("loggedin", "true", time()+30);
        header("Location: index.php");
        exit;
    }

Other than the log in form and a message for the user, that’s all there is to the log in page.

Handling Session Timeout

The index page handles the session timeout code. This could be a separate javascript included in every page. The first block simply determines if they are logged in. If they are not, send them to the login page. If they are, refresh the cookie timeout by resetting it.

if (!isset($_COOKIE['loggedin']) || (isset($_COOKIE['loggedin']) && $_COOKIE['loggedin'] == 'false'))
    {
        header("Location: login.php");
        exit;
    }
elseif (isset($_COOKIE['loggedin']) && $_COOKIE['loggedin'] == 'true')
    {
    //user is logged in, page was refreshed or reloaded to restart session so reset cookie
    setcookie("loggedin", "true", time()+30);
    }
?>

Now the time variables are set and the a javascript timer is set to check the session every 10 seconds.
Javascript uses milliseconds so for clarity the time intervals multiply the number of seconds by 1,000. You could put 10000 in for 10 seconds but I think 10*1000 helps me determine that it is 10 seconds quite a bit faster. Do what is comfortable for you.

Also, a flag is set to determine if the warning dialog box has been opened and the countdown has begun.

//event to check session time variable declaration
var checkSessionTimeEvent;

$(document).ready(function() {
	//event to check session time left (times 1000 to convert seconds to milliseconds)
    checkSessionTimeEvent = setInterval("checkSessionTime()",10*1000);
});

//Your timing variables in number of seconds

//total length of session in seconds
var sessionLength = 30;
//time warning shown (10 = warning box shown 10 seconds before session starts)
var warning = 10;
//time redirect forced (10 = redirect forced 10 seconds after session ends)
var forceRedirect = 10; 

//time session started
var pageRequestTime = new Date();

//session timeout length
var timeoutLength = sessionLength*1000;

//set time for first warning, ten seconds before session expires
var warningTime = timeoutLength - (warning*1000);

//force redirect to log in page length (session timeout plus 10 seconds)
var forceRedirectLength = timeoutLength + (forceRedirect*1000);

//set number of seconds to count down from for countdown ticker
var countdownTime = warning;

//warning dialog open; countdown underway
var warningStarted = false;

The checkSessionTime function is what gets fired off every 10 seconds by the timer. It does a time comparison and opens the dialog boxes that warn the user.

function checkSessionTime()
{
	//get time now
	var timeNow = new Date(); 

	//event create countdown ticker variable declaration
	var countdownTickerEvent; 	

	//difference between time now and time session started variable declartion
	var timeDifference = 0;

	timeDifference = timeNow - pageRequestTime;

    if (timeDifference > warningTime && warningStarted === false)
        {
            //call now for initial dialog box text (time left until session timeout)
            countdownTicker(); 

            //set as interval event to countdown seconds to session timeout
            countdownTickerEvent = setInterval("countdownTicker()", 1000);

            $('#dialogWarning').dialog('open');
            warningStarted = true;
        }
    else if (timeDifference > timeoutLength){
    		//close warning dialog box
            if ($('#dialogWarning').dialog('isOpen')) $('#dialogWarning').dialog('close');

            $('#dialogExpired').dialog('open');

             //clear (stop) countdown ticker
            clearInterval(countdownTickerEvent);
        }

    if (timeDifference > forceRedirectLength)
     	{
           //clear (stop) checksession event
            clearInterval(checkSessionTimeEvent);

            //force relocation
            window.location="login.php?expired=true";
        }
}

The countdownTicker function provides a countdown inside the warning dialog box to prompt the user to act now. It uses a timer that fires every second for a 5,4,3,2,1 effect inside the dialog box.

function countdownTicker()
{
	//put countdown time left in dialog box
	$("span#dialogText-warning").html(countdownTime);

	//decrement countdownTime
	countdownTime--;
}

And, the dialog boxes either allow the user to reload the page or, if they did nothing when the warning popped up, it logs them out by redirecting to the log in page with the expired variable in the query string. Also, thanks to scube’s debugging, it now redirects to the log in if they hit the close button on the dialog box rather than the Login button.

$(function(){
                // jQuery UI Dialog
                $('#dialogWarning').dialog({
                    autoOpen: false,
                    width: 400,
                    modal: true,
                    resizable: false,
                    buttons: {
                        "Restart Session": function() {
                            location.reload();
                        }
                    }
                });

                $('#dialogExpired').dialog({
                    autoOpen: false,
                    width: 400,
                    modal: true,
                    resizable: false,
                    close: function() {
                            window.location="login.php?expired=true";
                        },
                    buttons: {
                        "Login": function() {
                            window.location="login.php?expired=true";
                        }
                    }
                });
});

The dialog box contents are at the bottom of the page but they could be just about anywhere in the body.

<!--Dialog box contents-->
<div id="dialogExpired" title="Session (Page) Expired!"><p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 0 0;"></span> Your session has expired!<p id="dialogText-expired"></p></div>

<div id="dialogWarning" title="Session (Page) Expiring!"><p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 0 0;"></span> Your session will expire in <span id="dialogText-warning"></span> seconds!</div>

Remember, this is just one example. There are other ways to do this. Use this, improve this, or roll your own.

Usual recommended jQuery and PHP reading:

Demo

Download zip of all files

Internet Explorer (IE) Not Submitting Form on Enter

While working on a ColdFusion application, I noticed that the login form was not submitted when enter was pressed in Internet Explorer. Other browsers, Firefox and Chrome specifically, did not have this issue. There are many methods used to fix this error if you Google it, but I found that the simplest solutions are usually the best. No javascript, no funky CSS to hide fields, yada, yada, yada.

The Situation

This app had a form with a single text field and a submit button. The form submitted back to its own page were the logic executed if form.submit (the submit button itself) came back with the form variables collection.

When you pressed the enter button, IE did not send the input type=submit field back with the form vars and the form logic did not execute. The page appeared to refresh and you started over again.

The Solution

All that was necessary was to add a hidden input field that the form logic used instead.

<input type="hidden" name="login" value="loginSubmit" />

If form.login and form.login = ‘loginSubmit’, the form logic executes and the user is logged in.

So, from now on, I am not going to rely on the input submit button to check for form submission. Call me crazy, but I think IE has the right idea here; the input submit should not be part of the form variables collection.

ColdFusion Dropping, Losing, or Resetting Session Variables and CFID/CFTOKEN

Actually, this is not ColdFusion’s fault; it is a browser issue. Here’s what happens:

A user logins into your application, navigates through it, and then, inexplicably, gets booted out or not recognized. Sometimes it is just one page that seems to be the problem, sometimes several. Sometimes it is one browser, say IE, and not another, say FF.

What is crazy about this is that the application has, for all intents and purposes, worked correctly up to this point. The problem seemed to occur out of the blue. (Personally, I think it happened at the same time said user switched to IE7, but that is just my opinion.) And, what is also wonderful about this is that oftentimes you cannot recreate it. The user just screams and screams while you pull your hair out.

If and when you can recreate it, when you output the CFID and CFTOKEN tags you notice that they are different for the same user. They should not be. They never left the application.

For me the solution was simple. My application was using ‘www’ in the domain name on some pages and not on others as in www.mysite.com vs. mysite.com. The browser interpreted this as two different sites and made no association with the CFID/CFTOKEN cookies set by the application.cfm. So, ColdFusion reset them and bye-bye went my session variables.

Now, if this happens between http and https sites I do not know since this was not using a certificate. So, for that, you will have to figure it out.

This really frustrated me and I hope it helps someone else.

Test Drivin’ Safari 4

I gave Safari 4 a whirl on both Mac and PC. I like it. It brings much of the cool stuff from iTunes into the browser. Cover flow is fun and fresh in a browser. The Top Sites with the page previews is an upscale rip off of Chrome and, really, it’s a good feature for any browser.

Cover Flow
Safari Cover Flow
Top Sites
Safari Top Sites

Safari 4 is great for casual browsing and general perusing of the code but web development work stills needs the robustness of the Firefox plugins. Firefox is so ahead of the curve for web developers and I’m so used to it’s fantastic toolbars and debuggers that I don’t know if anyone will catch up. Granted the Safari 4 Web Inspector on the pre-packed Developer toolbar is nifty. Gotta love the ‘Resources’ tab. Nice visual of the weight of each loaded item. The included scripts debugger is handy and a much needed accessory in every browser.

Did I mention Safari 4 is fast? It is. That my biggest complaint with Firefox. It can be slow to render. Maybe that will improve with FF 3.5. Still, the trade off at this point is worth it. Bottom line is Safari 4 is great for browsing and the Web Inspector is a must ‘once over’ tool for developers.

FYI, Lifehacker has a great article on the latest browser speed tests.