erichynds

Me!

Welcome to my online development portfolio and blog. I'm Eric Hynds, a 23 year old website developer living outside of Boston, Massachusetts, and I'm passionate about developing functional, standard-compliant, and user-friendly websites.

Archive for November, 2009

jQuery Related (Dependent) Selects Plugin

Wednesday, November 11th, 2009

I’ve finally gotten around to writing & releasing a jQuery plugin that allows you to create any number of related/dependent select boxes in a form. I’ve yet to find a decent solution and needed something that was fairly customizable and could retrieve data using AJAX/JSON, so here she is.

From the GitHub docs:

jQuery Related Selects is a plugin that allows you to create any number of select boxes whose options are determined upon the selected value of another. You pass an array or object of select box names, and the select boxes will depend on each other in the order in which they are passed in.

When a select box is changed an AJAX request is sent to the file specified in the onChangeLoad property, passing the selected value of each select box as parameters. For now the data must be returned in JSON format. An <option> must have a legitimate value in order to trigger the script. An <option> where the value is blank (value="") is used for the defaultOptionText option (see below).

This script provides a high level of customization. You can set the options once for each select to use, or set the options on a select-by-select basis. You can also start your markup with pre-populated options and selected values.

Usage

A basic example. Changing the "stateID" select updates the "countyID" select and so on. The values of all four select boxes are serialized and passed to datasupplier.php, which returns data for the next select box in JSON format.

<form>
	<select name="stateID">
	<option value="">Choose State</option>
	<option value="MA">Massachusetts</option>
	<option value="VT">Vermont</option>
	</select>
	<select name="countyID"><option value="">Choose County</option></select>
	<select name="townID"><option value="">Choose Town</option></select>
	<select name="villageID"><option value="">Choose Village</option></select>
</form>
$("form").relatedSelects({
	onChangeLoad: 'datasupplier.php',
	selects: ['stateID', 'countyID', 'townID', 'villageID']
});

Options

selects

Required. An array or object of select boxes you want to be dependent. Each one will depend on each other in the order in which they are passed in. If you want to override any of the options below on a select-by-select basis you can pass this as an object. See examples.

onChangeLoad

Required. The file to call to retrieve data when a select box is changed. Data must be returned in JSON format for now.

loadingMessage

Optional. The text to change the sibling select box to during the AJAX request.

defaultOptionText

Optional. The text inside the default <option> tag after AJAX populates a select box. This is typically the text where you instruct the user to choose an option. If this option is not provided and an <option> tag with a blank value attribute exists in your markup, that text will be used.

onLoadingStart

Optional. A callback to fire when the AJAX call starts.

onLoadingEnd

Optional. A callback to fire when the AJAX call ends.

onChange

Optional. A callback to fire when a select box is changed.

11-18-2009: Bug fix & new features update

I’ve fix a bug where refreshing the page makes all selects become active, and added a new option and callback:

disableIfEmpty

Set this option to true to keep the next select disabled if the previous does not return any results.

onEmptyResult

Optional. A callback to fire when no results are returned after changing a select.

12-2-2009: Update: Return data in HTML format

Data can now be returned in HTML format by using the new dataType option. Set it to either ‘html’ or ‘json’ (default).

Creating a Mint.com Style Idle Logout Timer Using jQuery

Tuesday, November 3rd, 2009

One of our real estate applications allows agents to write up e-mails and send MLS property listings to prospective buyers. One problem we ran into was sometimes agents would take a long, long time to write their e-mails. Somewhere in the middle of writing, the agent’s session would expire, so when the form was finally submitted, s/he was brought back to the login page and the e-mail was lost. While this probably should be been fixed server-side, I thought this would be a perfect opportunity to re-create Mint.com’s idle timeout functionality in jQuery.

Essentially, if a user is considered idle after a certain period of time, a message appears informing him/her that the session is about to timeout and offers a link to continue the session. "Idle" is a state where the following events have not been fired after a specified period of time: mousemove, keydown DOMMouseScroll, mousewheel, and mousedown. If the user clicks on the link to continue, an AJAX request is fired off that will keep the session alive. I am not sure about other programming languages, but in ColdFusion calling a .cfm or .cfc file will reset Java’s internal session timeout clock back to zero.

jQuery Idle Timeout

The code is fairly straightforward thanks to Paul Irish’s idleTimer plugin which I use to handle the idle detection. The rest involves interacting with the idle state and recovering from it when the user is no longer idle.

You can see an example here.

The (heavily commented) code:

$(function(){
 
	var $bar = $("#idletimeout"), // id of the warning div
		$countdown = $bar.find('span'), // span tag that will hold the countdown value
		redirectAfter = 30, // number of seconds to wait before redirecting the user
		redirectTo = 'timeout.htm', // URL to relocate the user to once they have timed out
		keepAliveURL = 'keepalive.php', // URL to call to keep the session alive, if the link in the warning bar is clicked
		expiredMessage = 'Your session has expired.  You are being logged out for security reasons.', // message to show user when the countdown reaches 0
		running = false, // var to check if the countdown is running
		timer; // reference to the setInterval timer so it can be stopped
 
	// start the idle timer.  the user will be considered idle after 2 seconds (2000 ms)
	$.idleTimer(2000);
 
	// bind to idleTimer's idle.idleTimer event
	$(document).bind("idle.idleTimer", function(){
 
		// if the user is idle and a countdown isn't already running
		if( $.data(document,'idleTimer') === 'idle' && !running ){
			var counter = redirectAfter;
			running = true;
 
			// set inital value in the countdown placeholder
			$countdown.html( redirectAfter );
 
			// show the warning bar
			$bar.slideDown();
 
			// create a timer that runs every second
			timer = setInterval(function(){
				counter -= 1;
 
				// if the counter is 0, redirect the user
				if(counter === 0){
					$bar.html( expiredMessage );
					window.location.href = redirectTo;
				} else {
					$countdown.html( counter );
				};
			}, 1000);
		};
	});
 
	// if the continue link is clicked..
	$("a", $bar).click(function(){
 
		// stop the timer
		clearInterval(timer);
 
		// stop countdown
		running = false;
 
		// hide the warning bar
		$bar.slideUp();
 
		// ajax call to keep the server-side session alive
		$.get( keepAliveURL );
 
		return false;
	});
});

The idleTimer plugin fires a custom event called idle.idleTimer which this plug-in binds to. As long as the countdown is not already running, the countdown value is set (starts at 30), the warning bar slides down, and a timer is created using setInterval. This timer fires every second until either the link is clicked to stop it, or the counter reaches 0 and the user is redirected. If the link is clicked, the timer is stopped, the warning bar slides back up, and a server-side file is called that will actually keep the session alive.

Again, you can see a demo here and view source to see the structure/styling of the warning bar.