How to create Ctrl+Key shortcuts in Javascript

Posted On Feb 22, 2008 at 4:34 am

Everybody loves shortcuts, so why should you deny your users of this guilty pleasure when it comes to your javascript-driven web application? Giving your users the ability to execute commands with simple shortcuts can make all the difference in the usability of your application.

Javacript Code

Here is the simple code that allows you to capture when a desired set of keys are pressed. In this example, we are focusing on CTRL+S, but it can be expanded easily with just a few lines of code per shortcut you wish to add.

var isCtrl = false; document.onkeyup=function(e){ if(e.which == 17) isCtrl=false; } document.onkeydown=function(e){ if(e.which == 17) isCtrl=true; if(e.which == 83 && isCtrl == true) { //run code for CTRL+S -- ie, save! return false; } }

jQuery Code

Here is an example of how to create a Ctrl+Key based shortcut within javascript using the jQuery Library.

var isCtrl = false; $(document).keyup(function (e) { if(e.which == 17) isCtrl=false; }).keydown(function (e) { if(e.which == 17) isCtrl=true; if(e.which == 83 && isCtrl == true) { //run code for CTRL+S -- ie, save! return false; } });

Explanation

This code is quite simple but let me explain it a little bit. Whenever a key is pressed down, we first check to see if its CTRL being pressed (key code 17). If it is CTRL, then we set isCtrl to true in order to keep track when CTRL is activated, and of course we return isCtrl back to false once CTRL is released via the keyup event. We must keep track of the CTRL activity with a variable because the event will fire on a per-key basis. When you press ctrl+S for example, the event fires twice with two different key codes - making it impossible to simply check for both keys in one swift action.

Now going back to the keydown event; after the CTRL key check, we can look to see if other keys are being pressed. In this example, key code 83 is for the S key, which in one example could be useful for allowing quick saving of a form. And lastly, the return false; plays a very important role in keeping the browser from picking up that particular key combination and acting on it. In the example above of using CTRL+S, normally when you press that the browser will prompt you to save the page - but with the return false, the browser backs down and stays quiet.

Additional Shortcut Examples

var isCtrl = false; document.onkeyup=function(e){ if(e.which == 17) isCtrl=false; } document.onkeydown=function(e){ if(e.which == 17) isCtrl=true; if(e.which == 83 && isCtrl == true) { //run code for CTRL+S -- ie, save! return false; } if(e.which == 79 && isCtrl == true) { //run code for CTRL+O -- ie, open! return false; } if(e.which == 84 && isCtrl == true) { //run code for CTRL+T -- ie, new tab! return false; } }

Library

As posted in the comments, there is a nice library to get this done over at openjs.com. If your looking for a simple solution that covers all angles, check out Handling Keyboard Shortcuts in JavaScript

Javascript Key Codes

Key Pressed Key Code
backspace 8
tab 9
enter 13
shift 16
ctrl 17
alt 18
pause/break 19
caps lock 20
escape 27
page up 33
page down 34
end 35
home 36
left arrow 37
up arrow 38
right arrow 39
down arrow 40
insert 45
delete 46
0 48
1 49
2 50
3 51
4 52
5 53
6 54
7 55
8 56
9 57
a 65
b 66
c 67
d 68
e 69
f 70
g 71
h 72
i 73
j 74
k 75
l 76
m 77
n 78
o 79
p 80
q 81
r 82
s 83
t 84
u 85
v 86
w 87
x 88
y 89
z 90
left window key 91
right window key 92
select key 93
numpad 0 96
numpad 1 97
numpad 2 98
numpad 3 99
numpad 4 100
numpad 5 101
numpad 6 102
numpad 7 103
numpad 8 104
numpad 9 105
multiply 106
add 107
subtract 109
decimal point 110
divide 111
f1 112
f2 113
f3 114
f4 115
f5 116
f6 117
f7 118
f8 119
f9 120
f10 121
f11 122
f12 123
num lock 144
scroll lock 145
semi-colon 186
equal sign 187
comma 188
dash 189
period 190
forward slash 191
grave accent 192
open bracket 219
back slash 220
close braket 221
single quote 222

This topic has the following tags:

Last 5 Linkbacks

Comments (20)

Vinay's Avatar

Vinay Feb 07, 2009

Use This For Ctrl S OR c OR t Like wise....



shortcut = {
'all_shortcuts':{},//All the shortcuts are stored in this array
'add': function(shortcut_combination,callback,opt) {
//Provide a set of default options
var default_options = {
'type':'keydown',
'propagate':false,
'disable_in_input':false,
'target':document,
'keycode':false
}
if(!opt) opt = default_options;
else {
for(var dfo in default_options) {
if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
}
}

var ele = opt.target;
if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
var ths = this;
shortcut_combination = shortcut_combination.toLowerCase();

//The function to be called at keypress
var func = function(e) {
e = e || window.event;

if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
var element;
if(e.target) element=e.target;
else if(e.srcElement) element=e.srcElement;
if(element.nodeType==3) element=element.parentNode;

if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
}

//Find Which key is pressed
if (e.keyCode) code = e.keyCode;
else if (e.which) code = e.which;
var character = String.fromCharCode(code);

if(code == 188) character=","; //If the user presses , when the type is onkeydown
if(code == 190) character="."; //If the user presses , when the type is onkeydown

var keys = shortcut_combination.split(" ");
//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
var kp = 0;

//Work around for stupid Shift key bug created by using lowercase - as a result the shift num combination was broken
var shift_nums = {
"`":"~",
"1":"!",
"2":"@",
"3":"#",
"4":"$",
"5":"%",
"6":"^",
"7":"&",
"8":"*",
"9":"(",
"0":")",
"-":"_",
"=":" ",
";":":",
"'":"\"",
",":"",
"/":"?",
"\\":"|"
}
//Special Keys - and their codes
var special_keys = {
'esc':27,
'escape':27,
'tab':9,
'space':32,
'return':13,
'enter':13,
'backspace':8,

'scrolllock':145,
'scroll_lock':145,
'scroll':145,
'capslock':20,
'caps_lock':20,
'caps':20,
'numlock':144,
'num_lock':144,
'num':144,

'pause':19,
'break':19,

'insert':45,
'home':36,
'delete':46,
'end':35,

'pageup':33,
'page_up':33,
'pu':33,

'pagedown':34,
'page_down':34,
'pd':34,

'left':37,
'up':38,
'right':39,
'down':40,

'f1':112,
'f2':113,
'f3':114,
'f4':115,
'f5':116,
'f6':117,
'f7':118,
'f8':119,
'f9':120,
'f10':121,
'f11':122,
'f12':123
}
var alpha = {
's':83,
't':84,
'c':67,
'a':65
}

var modifiers = {
shift: { wanted:false, pressed:false},
ctrl : { wanted:false, pressed:false},
alt : { wanted:false, pressed:false},
meta : { wanted:false, pressed:false} //Meta is Mac specific
};

if(e.ctrlKey) modifiers.ctrl.pressed = true;
if(e.shiftKey) modifiers.shift.pressed = true;
if(e.altKey) modifiers.alt.pressed = true;
if(e.metaKey) modifiers.meta.pressed = true;

for(var i=0; k=keys[i],i 1) { //If it is a special key

if(special_keys[k] == code) kp ;

} else if(opt['keycode']) {

if(opt['keycode'] == code) kp ;

} else { //The special keys did not match
if(character == k) {kp ;
}
else {

if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
character = shift_nums[character];

if(character == k) kp ;

}
if(alpha[keys[i]] == code) kp ;
}
}
}


if(kp == keys.length &&
modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
modifiers.shift.pressed == modifiers.shift.wanted &&
modifiers.alt.pressed == modifiers.alt.wanted &&
modifiers.meta.pressed == modifiers.meta.wanted) {
callback(e);

if(!opt['propagate']) { //Stop the event
//e.cancelBubble is supported by IE - this will kill the bubbling process.
e.cancelBubble = true;
e.returnValue = false;

//e.stopPropagation works in Firefox.
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
return false;
}
}
}
this.all_shortcuts[shortcut_combination] = {
'callback':func,
'target':ele,
'event': opt['type']
};
//Attach the function with the event
if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
else if(ele.attachEvent) ele.attachEvent('on' opt['type'], func);
else ele['on' opt['type']] = func;
},

//Remove the shortcut - just specify the shortcut and I will remove the binding
'remove':function(shortcut_combination) {
alert(shortcut_combination);
shortcut_combination = shortcut_combination.toLowerCase();
var binding = this.all_shortcuts[shortcut_combination];
delete(this.all_shortcuts[shortcut_combination])
if(!binding) return;
var type = binding['event'];
var ele = binding['target'];
var callback = binding['callback'];

if(ele.detachEvent) ele.detachEvent('on' type, callback);
else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
else ele['on' type] = false;
}
}


/**
shortcut.add("ctrl c",function() {
// alert("Hi there!");
popUpAdd('LookupConsginee.htm');
});
*/

Post Comment

You are replying to cancel reply

Your email address will not be visible to the public

Avatars by Gravatar. Join Gravatar for free to have your avatar shown everywhere you post.