AboutjQuery.hotkeys is a plugin that let you easily add and remove handlers for keyboard events anywhere in your code supporting almost any key combination. It is based on a library shortcut.js written by Binny V A. The syntax is as follows: $(expression).bind(<types>,<options>, <handler>);
$(expression).unbind(<types>,<options>, <handler>);
$(document).bind('keydown', 'Ctrl+a', fn);
// e.g. replace '$' sign with '€'
$('input.foo').bind('keyup', '$', function(){
this.value = this.value.replace('$', '€');
});
$('div.foo').unbind('keydown', 'Ctrl+a', fn);TypesSupported types are 'keydown', 'keyup' and 'keypress' OptionsThe options are 'combi' i.e. the key combination, and 'disableInInput' which allow your code not to be executed when the cursor is located inside an input ( $(elem).is('input') || $(elem).is('textarea') ). As you can see, the key combination can be passed as string or as an object. You may pass an object in case you wish to override the default option for disableInInput which is set to false: $(document).bind('keydown', {combi:'a', disableInInput: true}, fn);I.e. when cursor is within an input field, 'a' will be inserted into the input field without interfering. If you want to use more than one modifiers (e.g. alt+ctrl+z) you should define them by an alphabetical order e.g. alt+ctrl+shift Modifiers are case insensitive, i.e. 'Ctrl+a' == 'ctrl+a'. HandlerIn previous versions there was an option propagate which is removed now and implemented at the user code level. When using jQuery, if an event handler returns false, jQuery will call stopPropagation() and preventDefault() Live DemojQuery CompatibilityTested with jQuery 1.2.6 to jQuery 1.3.1 Browser support
If you happened to have a browser installed on a platform which I marked as '?', I will appreciate if you kindly run the demo and send over the results. Features added in this version (0.7.x)
Overriding jQueryThe plugin wraps the following jQuery methods:
Even though the plugin overrides these methods, the original methods will always be called. The plugin will add functionality only for the keydown, keyup and keypress event types. Any other types are passed untouched to the original 'bind()' and 'unbind()' methods. Moreover, if you call bind() without passing the shortcut key combination e.g. $(document).bind('keydown', fn) only the original 'bind()' method will be executed. I also modified the $.fn.find method by adding a single line at the top of the function body. here is the code: Plugin's Version jQuery.fn.find = function( selector ) {
// the line I added
this.query=selector;
// call jQuery original find
return jQuery.fn.__find__.apply(this, arguments);
};You can read about this at jQuery's User Group Overrides Browser Native Shortcuts (f5, Ctrl-l, etc)Firefox is the most liberal one in the manner of letting you capture all short-cuts even those that are built-in in the browser such as Ctrl-t for new tab, or Ctrl-a for selecting all text. You can always bubble them up to the browser by returning true in your handler. Others, (IE) either let you handle built-in short-cuts, but will add their functionality after your code has executed. Or (Opera/Safari) will not pass those events to the DOM at all. So, if you bind Ctrl-Q or Alt-F4 and your Safari/Opera window is closed don't be surprised. The following example omit the quick-search feature in firefox when typing '/' jQuery(document).bind('keydown', '/', function (evt){
alert("Hello Slash");
evt.stopPropagation( );
evt.preventDefault( );
return false;
});Note that I am calling preventDefault() and stopPropagation() inside the handler For some reason just returning false does not work. Current Version is: beta 0.7 | ||||||||||||||||||||||||
There's a way to manage Ctrl+click? Thank you
Great code! One question, what about combining accelerator keys? (Shift+Crtl+A, Alt+Shift+K, etc.)
Answering my own question, Ctrl+Shift+, etc. all seem to work for me now. They didn't when I first tried it ....
I'm having troubles in IE only (works in Safari, Firefox):
I test for $(this).attr("onclick"), and if so add function () {$(this).click();}
Works great in Firefox and follows the preexisting onclick javascript, but doesn't in IE. Anybody else seeing this?
can this plugin help with manage "Shift+click"?? it's need for multyple selection in list (select some item set, how it's works in windows).
Works great, except that, if i have the focus in a text box, i get an error saying Error: that.allelement? has no properties Source File: scripts/jquery.hotkeys.js Line: 78 Am i doing something wrong? Is it possible to get over this? Thanks
Works great. Can't use the backspace key without going back a page though (firefox/win). Works in the demo, just not on my screen.. I must be missing sthg.
Hi!
How can i make a toggle effect? For example. Shift+1 -> div->display: none; shift+1 again div->display: block;
Hi! For the number pad, I temporary fixed this problem adding the next code in the variable: 'this.special_keys' in the jquery.hotkeys.js
this.special_keys = {......., 96:'n0', 97:'n1', 98:'n2', 99:'n3', 100:'n4',101:'n5',102:'n6',103:'n7',104:'n8',105:'n9',........};
the keycodes 96 to 105 are the number pad keycodes. For use this solution,
jQuery.hotkeys.add('n0',function (){ /YOUR CODE/}); //For 0 in the number pad. jQuery.hotkeys.add('n1',function (){ /YOUR CODE/}); //For 1 in the number pad.
It works in my Iceweasel (Firefox). I hope it will help someone.
Hu! I've implemented Command key support for mac. I don't think that people would use combinations like "Command+a" but today the plugin is "stealing" the command key (if I bind "C", then Command+C stops working.
Hope it helps: Lines 65:74
var code = event.which, type = event.type, character = String.fromCharCode(code).toLowerCase(), special = that.special_keys[code], shift = event.shiftKey, ctrl = event.ctrlKey, alt= event.altKey, cmd= e.metaKey, propagate = true, // default behaivour mapPoint = null;Line 86:
if(!shift && !ctrl && !alt && !cmd) { // No ModifiersLine 95:
=)
@rafudu Thank you! That was driving me crazy.
It might be worth starting a comprehensive list of keys that can be safely captured on the various platforms -- or if anyone knows of such a thing that exists, link to it. I've wasted quite some time trying out keys in the various browsers, and it seems that most obvious key combos have at least one browser irrevocably binding them. In CodeMirror I'm capturing tab, ctrl-y, ctrl-z on all browsers except Safari, where I bind ctrl-backspace to undo, ctrl-and , and ctrl-enter.
Anyone tested this with jQuery 1.2.6?
seems to work fine in jquery 1.2.6 (we're using on a web site and with in Adobe AIR 1.1)
I want to bind different F1 functions to separate elements on the page. It only seems to want to bind to one.
$.hotkeys.add('f1',{target:$('#text1')[0]}, function(){alert('text1');}); $.hotkeys.add('f1',{target:$('#text2')[0]}, function(){alert('text2');});F1 only works in #text1, but shows text2 alert message. What's the point of the target if the hotkey can only be bound once? Am I missing something?
Just a comment to say thanks for putting this up! It really short-cut the work on a troublesome page I'm doing.
Is it possible to simply cycle different functions with a single same key?
Line 71: "alt = event.altKey," does not appear to work correctly in jQuery 1.2.6.
I'm using IE7/Windows and it always returns "undefined". However, in jQuery 1.2.2, it worked correctly.
OK, I found the solution to the "altKey" problem.
Change line 71 from: "alt = event.altKey," to:
alt = event.originalEvent.altKey,
Source: http://groups.google.com/group/jquery-en/browse_thread/thread/83e10b3bb1f1c32b/0f0cfd0be9409d12?show_docid=0f0cfd0be9409d12
var selectorId = ((this.prevObject && this.prevObject.query)
Using this code is not quite safe as this.prevObject (which should be this.end() ) returns the selector from only the last method of the chain. And many jQuery methods (not, filter, add,...) use the internal pushStack method that returns a new jQuery object and saves the former to this.prevObject. But in the next version of jQuery there will be 'Internal Selector State Tracking' which is I think is just what you want: http://docs.jquery.com/JQuery_1.3_Roadmap
I try this with the target is text input, but it doesn't work :
$.hotkeys.add('Ctrl+f', {target:$('#date')}, function (){ $("#panel_search").fadeIn("slow"); });or I miss something?
@xundertanktop, What version are you using? Try the latest (0.7.7) Note the with the new api it would be:
$('#date').bind('keydown', 'Ctrl+f', function(){$("#panel_search").fadeIn("slow"); });@Comment by thedandruff, Sep 01 (6 days ago):
planning to add this feature as it is a standard in jQuery which uses this.pushStack and let you bind many funciton to the same event at the same target.
expect it with in few days from now.
@Comment by thedandruff, Sep 01, 2008
It is possible now - check out version 0.7.8.
-Tzury
Will it ever be able to capture PrintScreen? ?!?
I've written a library that does basically the opposite of shortcut.js. Instead of taking a key description string and binding an event handler, it takes a keyboard event and outputs a string suitable for shortcut.js event binding:
http://jonathan.tang.name/code/js_keycode
It may be useful if you want to allow users to specify their own hotkeys with a keypress, and save those keys for later event binding.
Opera 9.62 does not always set event.crtlKey. When in a form field event.ctrlKey is always false. The Ctrl key does generate proper event.keyCode properties of '17'. This applies to the other modifier keys, as well. Firefox and Epiphnany work just fine as is. But for true portability, the code really must keep track of the keyup and keydown events from the modifier keys.
Hi, nice plugin! One problem, the following is not working in IE6/7: $('input').bind('keydown', 'return', function() { alert('test'); });
Although if I do $(document).bind... it works. Tested on version 0.7.8.
"Or (Opera/Safari) will not pass those events to the DOM at all."
Is there any way to get around this? Like, say suppressing the 'save as' window in opera for a ctrl+s?
ctrl + click would be nice...
I want execute set of statement on two even for example click or shortcut keys how I can I achieve that ?
click or Ctrl+s { do this; }
Nice plug-in! My ergo buddies will love this :)
One question/help needed:
Code Sample
`$(document).ready(function(){
});`Issue
The "disableinInput" isn't actually disabling my hotkey (e.g.ctrl+e). Is there any issue with my implementation?
P.S. Browser is IE6/7
the example above has a typo: 'disableinInput' should be 'disableInInput'
I spent hours trying to get this to work. The documentation needs to be updated with the spelling fix "disableInInput" as commented by chunzi.
Otherwise, great work.
Works great! I am now using it in a pirate game I am working on http://constantsail.com .
Thanks! Rob
Has anyone used this plugin with ASP.NET 3.5? When it is included on a normal aspx page, eg one with <form runat="server">, pressing the "Enter" key in a text box is still generating a postback. It is definitely coded in correctly.
Thanks, Mike
There's a small typo in "Options", the "i" ("in") in "disableinInput" should be uppercased ;-)
I have a textarea for the chat, I've added a shortcut for enter to send a message. But the new line gets into the text field. how can I say not to write new line into textarea?
Great plug-in... but if i add the following keys to your demo they don't work...
... jQuery(document).bind('keydown', ';',function (evt){jQuery('#other1').addClass('dirty'); return false; }); jQuery(document).bind('keydown', ':',function (evt){jQuery('#other2').addClass('dirty'); return false; }); ...
... <div id="_other1" class="eventNotifier">;</div> <div id="_other2" class="eventNotifier">:</div> ...
Unless there is something I am doing wrong I think you need to add some more keys to your test case (i.e. ';', ':', etc).
Cheers Anthony
Hi!
Is it possible to bind several keys to one action at once? I mean something like
$(document).bind('keydown', '1,2,3', function(){ alert('It works!'); });
Nice plugin by the way!
Is $(document).bind( "keydown", "a+a", fn ); supported? //press 'a' twice
Great job though!
Great job.
Great job, I have a problem though.. The disableInInput works in half. I doesnt fire the function, but it doesnt print the letter in input either...
This is realy great for webapplications! is there a way to get it to work with the jquery toggle function.
for example if i hit the f2 button a div wil appear and if i hit it again the div will disappear?
Great plugin, but i have one question. Is there any way of assigning my function to "ctrl+f" in Safari?
plain
$(document).bind(key_event, 'ctrl+f', function (evt) {
} works everywhere, but not in Safari 4.0.3 any thoughts?Guys, i really need help with Safari. Also preventDefault doesn't stop the default Safari's ctrl+p function.
Also, is there any way of assigning ctrl +/ ctrl - keys to user functions and preventing the default zooming?
Is there a way to enter the Konami Code with this plugin? Example (in order): up, up, down, down, left, right, left, right, b, a
Hi All. Can I associate 3 key combinations (Ctrl+q+c)? I'm creating hotkey for menu and say the above combination is for Quote -> Create. I tried a lot but it doesn't works. Please suggest. It would be a great help.
right button click mouse?
So, everybody knows nothing about Safari? great. what about ctrl+/- is it possible at all? also Opera's alt + arrows =)
Hi,
here is my code :
for (i = 1; i <= 9; i++) { $(document).bind('keydown', {combi : i+'', disableInInput : true }, function(evt) { // my function return false; }); }I want disable the hotkeys on my input with disableHotkeys css class.
I try this code :
$('input.disableHotkeys').unbind('keydown', {combi : ''+i, disableInInput : false }, function(){});but it does'nt work.
Could you help me please?
Thx,
Nicolas
can not unbind "Ctrl+(any)" "Shift+(any)" ,but can unbind "a","b" or any single key. why?
my testing code, can not unbind the function:
but this can work
function han(){ alert(1); } function bindhotkeys(){ $(document).bind("keydown", "a",function(){han(); return false;}); } function unbindhotkeys(){ $(document).unbind("keydown", "a",function(){han(); return false;}); }I got the same problem :/
try to write 'Shift' in lowercases
;lgk;lgkf
;lgk;lgkf
hi, i'm trying to simulate the behaviour of the "alt" key in office 2007/2010 on my site.
The "alt" key in office shows all the possible hotkeys in small boxes.
So, is there any way to bind the "alt" (just "alt", not "alt+anything") on jquery.hotkeys?
If you're using jQuery 1.4, you need the fork here (aka version 8.0): http://github.com/jeresig/jquery.hotkeys/
Thanks for that, trevor ;-)
So there is a problem with the current codebase. Namely if you bind more than one shortcut event to a dom element then those events will fire N numbers of times (where N is the number of events you assigned to an element).
For example:
$(document).bind('keyup', 'ctrl+t', handle_keyboard_add_command); $(document).bind('keyup', 'ctrl+a', handle_keyboard_add_action); $(document).bind('keyup', {combi:'up', disableInInput: true}, handle_keyboard_up); $(document).bind('keyup', {combi:'down', disableInInput: true}, handle_keyboard_down); $(document).bind('keyup', {combi:'right', disableInInput: true}, handle_keyboard_right); $(document).bind('keyup', {combi:'left', disableInInput: true}, handle_keyboard_left); $(document).bind('keyup', {combi:'home', disableInInput: true}, handle_keyboard_home); $(document).bind('keyup', {combi:'end', disableInInput: true}, handle_keyboard_end); $(document).bind('keyup', {combi:'return', disableInInput: true}, handle_keyboard_enter); $(document).bind('keyup', {combi:'space', disableInInput: true}, handle_keyboard_space);If you hit "ctrl-t" the handle_keyboard_add_command will fire 11 times. This is because in the hotkeys code in the hotkeys.handler there is no provision made to check WHERE the event came from. From my analysis of the code a map of shortcuts with a key of the dom_element from which the event can be fired. If that dom_element is found, then the code looks for a match for the specific shortcut combination, if it finds a match it fires the handler. However no where in that logic does it make sure that the shortcut combination corresponds to the even fired. This isn't hard to do, we have the comibination in event.data.combi, we just have to check it. I altered the code to do this:
// the event handler hotkeys.handler = function(event) { var target = hotkeys.findElement(event.currentTarget), jTarget = jQuery(target), ids = jTarget.attr('hkId'); if(ids){ ids = ids.split(';'); var code = event.which, type = event.type, special = hotkeys.specialKeys[code], // prevent f5 overlapping with 't' (or f4 with 's', etc.) character = !special && String.fromCharCode(code).toLowerCase(), shift = event.shiftKey, ctrl = event.ctrlKey, // patch for jquery 1.2.5 && 1.2.6 see more at: // http://groups.google.com/group/jquery-en/browse_thread/thread/83e10b3bb1f1c32b alt = event.altKey || event.originalEvent.altKey, mapPoint = null; for (var x=0; x < ids.length; x++){ if (hotkeys.triggersMap[ids[x]][type]){ mapPoint = hotkeys.triggersMap[ids[x]][type]; break; } } //find by: id.type.combi.options if (mapPoint){ var trigger; // event type is associated with the hkId if(!shift && !ctrl && !alt) { // No Modifiers if(mapPoint[special]) { trigger = mapPoint[special]; if(trigger && special != event.data.combi) { return; } } else if(character && mapPoint[character]) { trigger = mapPoint[character]; if(trigger && character != event.data.combi) { return } } } else{ // check combinations (alt|ctrl|shift+anything) var modif = ''; if(alt) modif +='alt+'; if(ctrl) modif+= 'ctrl+'; if(shift) modif += 'shift+'; // modifiers + special keys or modifiers + character or modifiers + shift character or just shift character trigger = mapPoint[modif+special]; // only continue if we match the combi key of the current event if(trigger && (modif+special) != event.data.combi) { return; } if (!trigger){ if (character){ if(mapPoint[modif+character]) { trigger = mapPoint[modif+character]; if(trigger && (modif+character) != event.data.combi) { return; } } else if(mapPoint[modif+hotkeys.shiftNums[character]]) { trigger = mapPoint[modif+hotkeys.shiftNums[character]]; if(trigger && (modif+hotkeys.shiftNums[character]) != event.data.combi) { return; } } else if(modif === 'shift+' && mapPoint[hotkeys.shiftNums[character]]) { trigger = mapPoint[hotkeys.shiftNums[character]]; if(trigger && hotkeys.shiftNums[character] != event.data.combi) { return; } } } } } if (trigger){ var result = false; for (var x=0; x < trigger.length; x++){ if(trigger[x].disableInInput){ // double check event.currentTarget and event.target var elem = jQuery(event.target); if (jTarget.is("input") || jTarget.is("textarea") || jTarget.is("select") || elem.is("input") || elem.is("textarea") || elem.is("select")) { return true; } } // call the registered callback function result = result || trigger[x].cb.apply(this, [event]); } return result; } } } };There is probably a cleaner way to do this, but this works.
met the same problem with james.ostheimer. (mac + firefox + hotkeys v0.7.9) After applying his solution, it works just fine. Thanks james.ostheimer.
Is there a way to make combo keybindings Gmail style, like "g, then i"? I have tried g+i and g,i and neither seems to work.
the github version is broken for azerty keyboard users. One need to type Shift+key to get numbers like 1 which is shift+&.
I am using IE8 64 bit on Windows 7 64 bit, and I can't seem to get the propagation/cancelBubble to stop the event hierarchy from firing. Out of the box the demo from github (test-static-01.html) will handle the correct key combination and update the html, but the browser still fires it shortcuts. Shortcuts like alt+h, alt+d, etc. Everything is A-OK in firefox. I am using jquery1.4.2, and the jquery-hotkeys version 0.8. I tried that demo because I was having the same thing happen with jq1.4.2 and 0.79 in my project's codebase. Another developer was seeing the same thing on his machine. Here is the current code I am using. But I have also tried the code posted by 'devil.tsc':
jQuery(document).bind('keydown', 'Alt+h',function (evt){ jQuery('#_Alt_h').addClass('dirty'); evt.cancelBubble=true; evt.returnValue=false; evt.keyCode=0; return false; }); });Any help greatly appreciated!
Hola, tambien tenia el mismo codigo tuyo, probe con todo, pero hoy como jugando puse esto y me funciona en IE8 pero no en FF:
jQuery(document).bind('keydown', 'Alt+h',function (evt){
});por ahi lei que esto:
evt = evt || window.event; servia para diferenciar de explorador, ya que en FF si le quito el "window.event.keyCode = 0;" me funciona, pero en IE8 no, haber si encuentras otra solucion y me la haces saber, gracias.
jQuery(document).bind('keydown', 'Alt+h',function (evt){
});
I'm trying to detect the "key" detected by the plugin:
var Letters = new Array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"); for (key in Letters ){ $(document).bind('keydown', 'Ctrl+Shift+'+Letters[key], function(){ RunActionsFor(".Ctrl_Shift_"+Letters[key]); }); }But doesn't work. Help please.
Hi all,
does anybody experimented conflits with popup blockers? I´m trying something like this:
$(document).bind('keydown', 'Ctrl+Y', function() {
});But popup blocker blocks the window. Does anybody knows how to solve this? If i add the site to the trusted sites settings works perfect, but i would not have to do that.
Thanks in advance,
If i wanted to bind something to a combination of characters like "N+C" (meaning pressing C while holding down N), how can i do this with this plugin, if at all?
Is it also possible to use the ' ? ' key ?
can i use this plugin if i'm using jquery-1.1.3.1.pack.js ? is it compatible because my code \
jQuery(document).bind('keydown', 'ctrl+t', function (evt){
alert("Hello Ctrr+t"); evt.stopPropagation( ); evt.preventDefault( ); return false; }); responds to each and every key! it binds all the key.. is there any solution for this??
It's working awesome! Thank you!