November 3rd in Articles by .

Keyboard Interaction With JavaScript And jQuery


A couple of days ago I read an article by David Walsh where he used keyboard interaction to save a form’s contents in the background with MooTools. I have read a bunch of his articles, and I am a big fan, and have always thought I want to emulate one of his articles using jQuery. Until now, he has beat me to the post.

This time however, I seem to have a longer window ;) With that I set forth to recreate what he did using jQuery but, in the end it ended up being more then a simple hat tip to his article. There are two specific properties to the event object that jQuery does not share, please let me know if I am wrong, and they are, from David’s blog:

event.control || event.meta

Because of that I had to go back to straight JavaScript, with a little help from jQuery, to emulate what David did. In the rest of this article we will go over binding to an HTML DOM object and I will follow this up with another article on creating a special/custom jQuery event.

Binding An Event To A DOM Object

To start of let’s set up our HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>JavaScript Keyboard Interaction</title>
		<script type="text/javascript" src="lib/jquery/jquery-1.3.2.js"></script>
		<script type="text/javascript" src="js/keyCodeMatcher.js"></script>
		<script type="text/javascript" src="js/saveForm.js"></script>
    </head>
    <body>
        <h1>JavaScript Keyboard Interaction</h1>

		<p>Once you start typing in the text area below pressing Ctrl + Shift + S will save the form data to the server. With focus anywhere pressing Alt + I will load the first four images tagged with monkey from Flickr. To remove the images use Alt + C</p>

		<p id="images"></p>

		<form method="post" id="edit-form" action="dummy.html">
			<fieldset>
				<legend>Your Life's Story</legend>
				<textarea rows="10" cols="40" name="content" id="content-box"></textarea><br />
				<input type="submit" id="save_button" value="Save And Continue" />
			</fieldset>
		</form>
    </body>
</html>

You will see that there is a lot more to this page then we need right now but, we will get to all of this in time. The first script deals with key masks. These are the keys such as CTRL, Shitft etc. that are used in combination with another key to initiate a task.

For this our first step is to import jQuery, whether you do this via Google or not is up to you, I simply included it here from a local copy. We next need to create our JavaScript file. Create your js folder and create a new JavaScript file, I called it main.js. I then created a separate JavaScript file to hold my specific methods called keyCodeMatcher.js, you can choose to do the same or include all in the same main file.

Detecting the Key Mask

Our first step is to detect what is called the mask keys. These are the ctrl, alt and shift keys. Mask keys as they are use along with another key to trigger some functionality in an application. Add the following to your chosen js file

var detectKeyMask = function(event) {
	var _result = {
		is_mask:"false",
		key_value:""
	}

	if(event.shiftKey) {
		_result['is_mask'] = 'true';
		_result['key_value'] = 'shift';
	} else if(event.ctrlKey || event.metaKey) {
		_result['is_mask'] = 'true';
		_result['key_value'] = 'ctrl';
	} else if(event.altKey) {
		_result['is_mask'] = 'true';
		_result['key_value'] = 'alt';
	} else {
		_result['is_mask'] = 'false';
	}
	return _result;
}

First we set up a JavaScript Object literal with two values, one to hold whether a mask key was pressed and the other the mask key that was pressed. The rest of the function is self explanatory. Let’s test this out.

$(document).ready(function() {

	$("#content-box").keydown(function(event) {

		isKeyMask = detectKeyMask(event);

		alert(isKeyMask['is_mask']);

		mask = "";
	});

});

With this function we are attaching the keydown event to the ‘content-box’ HTML object, which is our text area, and we will then pop an alert whenever a key is pressed and print either true or false based on whether a key mask was pressed or not. Go ahead and try it out in the browser.

Having confirmed that the key mask detection is working as expected, we can move on. Let’s add an if statement to test whether a key mask was detected and if it was we can store the key value in a variable. Change the above method to reflect the following:

$(document).ready(function() {

	$("#content-box").keydown(function(event) {

		isKeyMask = detectKeyMask(event);

		if(isKeyMask['is_mask'] == "true") {
			mask = isKeyMask['key_value'];
		}

		mask = "";
	});
});

Knowing that a key mask was pressed and having the value allows us to be more specific with what we want to do with this knowledge however, just knowing which key mask was pressed alone is not really of much value, we also want to know which other key was used in combination with the key mask.

Reading the Standards Key Pressed

To get the key that was pressed we can use a built in method of JavaScript:

String.fromCharCode(_keyCode);

There is, as should come as no surprise, a slight difference in how Internet Explorer and other browsers expose this, with IE exposing it as event.charCode and other browsers as event.keyCode. With this I decided to create a small utility method, that simply accepts the event object and then reads the key code from the event based on which value is defined and return it:

var getKey = function(event) {
	_keyCode = "";

	if(event.keyCode != undefined) {
		_keyCode = event.keyCode;
	} else if(event.charCode != undefined) {
		_keyCode = event.charCode;
	}
	return String.fromCharCode(_keyCode);
}

With this we can now expand our code from above to test for the key mask and key combination that was pressed:

$(document).ready(function() {

	$("#content-box").keyup(function(event) {

		isKeyMask = detectKeyMask(event);

		if(isKeyMask['is_mask'] == "true") {
			mask = isKeyMask['key_value'];
		}
		keyPressed = mask + getKey(event);

		if(keyPressed.toLowerCase() == "shifts") {
			alert("Saving form....");
		}

		mask = "";
	});
});

Looking at the code above you can see that I am testing for the combination of the Shift mask and the s key to be pressed and will then pop an alert, in the real world we would do some funky Ajax stuff to actually save the content of the text area to the server but for now, we simply pop an alert.

If you tested it now it would work, well sort off… The problem with using the Shift + S combination is that it will trigger the save but, it will also add a capital S to the text area and that is not what we want. To overcome this problem, simply use the Ctrl, or meta key on the Mac, in combination with Shift + S and hey presto! It works!

Performance Optimization WordPress Plugins by W3 EDGE