Ctrl + Key Combination – Simple Jquery Plugin

In a recent web application I was working on, I had a need for the “Ctrl + S” hotkey to save an entry to the database. Being a an avid jquery fan, I immediately searched the plugin repository for any plugin that fits the bill. I was not very surprised to find a very comprehensive jshotkeys plugin. It was feature rich and addressed all the requirements for hotkeys in a jquery powered application and obviously my requirement was fulfilled as well.

But the basic issue (and advantage too) with any plugin is that it is written for a wide range of audience. So, although my requirement was only for a “Ctrl + key” combination, I had to part with my bandwidth for all other features this plugin offered. Like my famous jCarouselLite plugin, I like my javascript code kept to the minimum. So, I decided and wrote a short yet sweet plugin that would solve only the problem I have at hand. Unsurprisingly, the plugin code turned out to be only 195 bytes (minified). Given below is the code for the same…

$.ctrl = function(key, callback, args) {
    var isCtrl = false;
    $(document).keydown(function(e) {
        if(!args) args=[]; // IE barks when args is null
        
        if(e.ctrlKey) isCtrl = true;
        if(e.keyCode == key.charCodeAt(0) && isCtrl) {
            callback.apply(this, args);
            return false;
        }
    }).keyup(function(e) {
        if(e.ctrlKey) isCtrl = false;
    });        
};

This is how it works:

1. You want to execute a function when the user presses a “Ctrl + key” combination.
2. You as a developer should call the plugin method and pass in 3 parameters.
3. 1st Param: The “key” user should press while he is pressing Ctrl.
4. 2nd Param: The callback function to be executed when the user presses “Ctrl + key”.
5. 3rd Param: An optional array of arguments, that will be passed to the callback function.

In the code given below, when the user presses the “Ctrl + S” key combination, the anonymous callback function passed in as the second parameter is called.

$.ctrl('S', function() {
    alert("Saved");
});

Here, when the user presses the “Ctrl + S” key combination, the anonymous callback function passed in as the second parameter is called with the arguments passed in as the third parameter.

$.ctrl('D', function(s) {
    alert(s);
}, ["Control D pressed"]);

Thats it. I feel it is simple yet effective and solves a common requirement in modern web applications.

What do you think?

Update

A comment provided by “A Nony Mouse” in this blog entry clarified that, we don’t have to store a boolean called “isCtrl” to check if the “Ctrl” key is down while another key is being pressed. It is enough to check for e.ctrlKey as it will return true if the “Ctrl” key is down even if another key is being pressed along with Ctrl. Based on that input the “Ctrl + Key” plugin has been updated. Take a look at the updated code below. For archiving purposes, I am leaving the original version of the code above without any changes.

$.ctrl = function(key, callback, args) {
    $(document).keydown(function(e) {
        if(!args) args=[]; // IE barks when args is null 
        if(e.keyCode == key.charCodeAt(0) && e.ctrlKey) {
            callback.apply(this, args);
            return false;
        }
    });        
};

Ganeshji Marwaha

I spend my days as the Director of Technology for Mobility practice and help my clients design enterprise and consumer mobile strategies. Mobile Payments, Digital Wallet and Tokenization technologies are my areas of specialization

  • i think it is great. i wish more and more people took to simplifying like you u do. good work Ganeshji!

  • kurotsuto

    Simply spectacular. 195 bytes?!?!?! AMAZING.

  • dobi

    hi~ It is so great.

    When I tested this code in Chrome, work well.

    But when I tried this in IE, there was some error that I didn’t know.
    So didn’t work…

    Please test in IE, and let me know how to resolve this problem.

  • Dobi

    %ps – Version of IE is 8.

  • Ganeshji Marwaha

    @Dobi #3, #4: You are right. There was an error in IE. IE throws an error when your callback function doesn’t have any args. I have FIXED the code and updated it in the blog entry. Kindly take the latest code from the blog entry and check if it works for you. I checked it in IE 6 and 7, but not in IE 8. So, kindly lemme know if it works for you.

  • A Nony Mouse

    In my experience e.ctrlKey is true if the control key is down, not just if it is the key that was pressed. You could remove isCtrl and replace it with e.ctrlKey. Also watch out, some browsers (at least IE and chrome) will send back different character code for the enter key if ctrl is held down. not a problem if you are just using it for CTRL-S

  • Ganeshji Marwaha

    @A Nony Mouse #6: Thanks for your input. I have updated the plugin based on your input. It does make the plugin look a lot cleaner and now it is a lot smaller.

  • thanks so much

  • dk4r

    When I use this plug in in FF, I press Ctrl + S, FF show me the Save dialog, how can I disable it, mean when I click Ctrl + S, my page save content, It doesn’t fire the FF save dialog. Like gmail, if I’m focus on textbox, press Ctrl+S, it shows me Saving…, if I leave the textbox and press Ctrl+S again, it shows me the FF Save Dialog. Thank you and waiting for your reply.

  • It is enough to check for e.ctrlKey as it will return true if the “Ctrl” key is down even if another key is being pressed along with Ctrl.

  • Cool plugin! I wrote something pretty similar recently that adds a new event that you can bind called “keystrokes”. Check it out!
    http://boedesign.com/blog/2009/12/30/keystrokes-for-jquery/

  • krishna

    Hi this is krishna i need help from you when i am calling javascript function Ctrl+D event has to be fire can you please give me solution pleeeez

  • David S

    This worked great, although I did need to tweak it slightly as I needed to modify Ctrl+Insert, which required a keycode.

    This is how I modified the code:

    $.ctrl = function(key, callback, args) {
    var isCtrl = false;
    $(document).keydown(function(e) {
    if(!args) args=[]; // IE barks when args is null

    if(e.ctrlKey) isCtrl = true;
    var kc = parseInt(key);
    if((!isNaN(kc) && kc > 0 && e.keyCode == key || isNaN(kc) && e.keyCode == key.charCodeAt(0)) && isCtrl) {
    callback.apply(this, args);
    return false;
    }
    }).keyup(function(e) {
    if(e.ctrlKey) isCtrl = false;
    });
    };

    $.ctrl(45, function() { alert(‘custom functionality goes here’); return false; });

  • Tony

    Hi, is there a way to invoke the Ctrl+F key combo from a simple hyperlink using jquery, to bring up the “find in page” box in all browsers?

  • Pingback: syava()

  • Ctrl” key is down even if another key is being pressed along with Ctrl.

  • Ctrl” key is down even if another key is being pressed along with gallr

  • Thanks

  • thanks for codes

  • Great Plugin! Thanks

  • YoyoMOMMA

    I’ve stumbled across your blog before while google-fu-ing. This is exactly what i wanted. A nice side-effect of your code vs jshotkeys is that, in jshotkeys (as far as i can tell) if you have two binds like ctrl+a and ctrl+b, both functions will get fired on keypress and keydown. your code doesn’t do that. i like that.

  • very helpful and easy thanks

  • I think I may have come across a bug. I disabled Ctrl+A and Ctrl+C with the following code:

    $.ctrl(‘A’, function() { return false; });
    $.ctrl(‘C’, function() { return false; });

    My page has text fields on it. To reproduce the problem, do the following:

    1.) Use the above code in a HTML page with a textbox and regular text
    2.) Click on the text box and type “abc”. // This should work fine
    3.) Now click on text outside the textbox.
    4.) Quickly press Ctrl+A (make sure you release Ctrl and A keys at the same time).
    5.) Now click on the text box again and type “abc”. // The letters A and C don’t work.

    * NOTE: If the A & C keys still work after doing the above. Try it several times. I think it depends on how quickly the keys are pressed/released.

    I have a feeling it has something to do with the keyup event occuring before the keydown event has completely finished.

    I’ve been able to reproduce the problem in Google Chrome, Firefox 3 and IE8. I’ve only tested it with jQuery 1.2.6. I’ll try newer versions of jQuery in a little bit and see if this corrects the problem.

  • To add onto the problem I described previously. I just tested it with jQuery 1.4.3 and it’s doing the same thing.

  • seems deliou. like my cupcakes

  • Very helpful. Nice job.. Thanks for sharing

  • 1360

    You may want to consider allowing the callback to define whether or not to override the default behavior, otherwise you will disable ctrl key combos that might need to be kept intact ie. ctrl+(c,x,v). I modified you code to include this little snippet.
    var ret = callback.apply(this, args);
    return (ret!=undefined && ret !=false)?true:false;

  • Zod

    I am having a similar problem to David S.

    It has happened in chrome and firefox. To me it appears (using firebug) that during the keyup function on the ctrl key, e.ctrlKey is false.

    As such isCtrl is never set to false. Pressing ‘s’ causes my call back function to be called regardless of whether ctrl is down or not.

    My call back function simply ‘clicks’ the save button, however I have some javascript validation on the page (actually asp.net validators), which use javascript to prevent a submit if the page is invalid (which it was not when I first pressed ctrl+s). Consequently, the page is not saved, and the ‘s’ key becomes unusable.

  • Zod

    Double negative in the post above. The page WAS invalid first time I tried ctrl+s.

  • an

    Hello! It support for arrow keys? ctrl + arrow down for example?

    $.ctrl(‘??????’, function() {
    alert(“Saved”);
    });

  • Orelus

    Modified version :
    $.ctrl = function(key, callback, args) {
    var isCtrl = false;
    $(document).keydown(function(e) {
    if(!args) args=[]; // IE barks when args is null

    if(e.ctrlKey) isCtrl = true;
    if(e.keyCode == key.charCodeAt(0) && isCtrl) {
    callback.apply(this, args);
    isCtrl = false;
    return false;
    }
    else{
    isCtrl = false;
    }
    });
    };

    The previous version was bug when you press Ctrl+Key twice.

  • Sanya

    Added Ctrl+space support
    Also you can set key by code

    $.ctrl = function(key, callback, args) {
    var isCtrl = false;
    var codes = {space: 32};

    $(document).keydown(function(e) {
    if(!args) args=[]; // IE barks when args is null

    if(e.ctrlKey) isCtrl = true;
    var keyCode = null;
    switch (true) {
    case typeof codes[key] == ‘number’:
    keyCode = codes[key];
    break;
    case typeof key == ‘number’:
    keyCode = key;
    break;
    default:
    keyCode = key.charCodeAt(0);
    }
    if(e.keyCode == keyCode && isCtrl) {
    callback.apply(this, args);
    return false;
    }
    }).keyup(function(e) {
    if(e.ctrlKey) isCtrl = false;
    });
    };

    $.ctrl(‘space’, function(s) {
    alert(s);
    }, [“Control+Space pressed”]);

  • Sanya
  • Ganeshji Marwaha

    @Sanya – Excellent. Thanks for your amendment. Others who cross this path will definitely find it useful.

  • Ganeshji Marwaha

    @Orelus – Thanks for the fix dude. Others who stumble here will definitely find it useful.

    Others who have enquired about Ctrl+down arrow etc, I guess you can take a look at @Sanya #35 and #36 comments. That amendment should get you working. Just that this time you should be using the key code instead of the actual character itself.

  • Thanks for small advices. I really like your site and posts!

  • thank you very much! this piece of code is really useful and works!

  • steve

    This is great stuff and very much what i required! Thanks

    However,
    when using Cntrl S, how do we surpress the bubble cntrl S deifned in the browser.
    If i alert as by your example of cntrl S , I get the Alert fine but proceeding it i get the save page functionality

    Cheers
    Steve

  • Morris

    Your script needs to also check !event.metaKey && !event.altKey

    otherwise for example CTRL-ALT-S, CTRL-SHIFT-S and CTRL-ALT-SHIFT-S will act the same as CTRL-S.

  • Ganesh ….
    salut ..wonderfully done my friend. simple yet so flexible & extensive

    love it

  • @sanya & @Orelus

    respec’ … wonderfully done

  • Ganesh ….
    salut ..wonderfully done my friend. simple yet so flexible & extensive

    love it

  • this is something i was searching for quite a time now.

    i’m gonna give it a try and see how it works !

  • Pingback: e.which codes for CTRL + A and CTRL + E - Programmers Goodies()

  • Yup, I’m using it too. Very useful.

  • Pingback: 15 Keyboard Event Plugins | jQuery4u()

  • simple yet very effective. nice step-by-step tutorial

  • you’re right.

    not only the js-hotkeys program is to heavy, but also it bans some additional functions. I’m a Chinese user and I can’t input chinese with keyboard in the sample.

  • Jan

    This reminds me a bit of Perl… nearly a one-liner-solution. Elegant!

  • You may demand to consider allowing the callback to define whether or not to override the default behavior, otherwise you will disable ctrl key combos that force indispensability to be kept intact ie. ctrl+(c,x,v). I modified you code to include this little snippet.