views:

199

answers:

2

I need to detect whether the user has pressed the dot key in the numeric keypad. I've written this first draft that works for me:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;
<html>
<head><title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript"><!--
(function($){
    var knownCodes = [
        [110, 46], // Firefox, IE, Chrome
        [78, 46] // Opera
    ];
    var pressedCodes = [null, null];

    $.fn.coma = function(){
        this.live("keydown", function(e){
            pressedCodes = [e.which, null];

        }).live("keypress", function(e){
            pressedCodes[1] = e.which;

            for(var i=0, len=knownCodes.length; i<len; i++){
                if(pressedCodes[0]==knownCodes[i][0] && pressedCodes[1]==knownCodes[i][1]){
                    $("#log").append("<li>Decimal key detected</li>");
                    break;
                }
            }
        });

        return this;
    };
    $(function(){
        $('<ol id="log"></ol>').appendTo("body");
    });
})(jQuery);

jQuery(function($){
    $(".coma input:text, .coma textarea").css("border", "1px solid black").coma();
});
//--></script>
</head>
<body>

    <form action="" method="get" class="coma" size="20">
        <p><input type="text"></p>
        <p><textarea rows="3" cols="30"></textarea></p>
    </form>

</body>
</html>

However, I can only test it in a Windows XP box with a Spanish keyboard. My questions are:

  1. Is it safe to read from e.which? I'm using it because both e.keyCode and e.charCode return undefined in at least one browser.

  2. Does the operating system affect these numeric codes in some manner or it's only a browser stuff?

  3. Do these codes depend on the keyboard layout?


Background info: I couldn't find a jQuery plugin to remap numeric keypad so I'm writing my own.

Update

I'll explain my exact need. Spanish keyboards that have a numeric keypad feature a . key. However, the decimal separator in Spanish is ,. That makes it annoying to type numbers in web applications. Some desktop apps like MS Excel remap this key so it inserts a coma. I'm trying to mimic that.

I've adapted a little script I've been using to post it here. That's how I got the values for the knownCodes arrays:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;
<html>
<head><title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript"><!--
(function($){
    $.fn.showKeyCodes = function(){
        var log = function(e){
            $("<li></li>").text(e.type + "(): [keyCode, charCode, which]=[" + e.keyCode + ", " + e.charCode + ", " + e.which + "]").appendTo("#log");
        }

        this.live("keydown", function(e){
            log(e);

        }).live("keypress", function(e){
            log(e);

        }).live("keyup", function(e){
            log(e);

        });

        return this;
    };
    $(function(){
        $('<ol id="log"></ol>').appendTo("body");
    });
})(jQuery);

jQuery(function($){
    $(".showKeyCodes input:text, .showKeyCodes textarea").css("border", "1px solid black").showKeyCodes();
});
//--></script>
</head>
<body>

    <form action="" method="get" class="showKeyCodes" size="20">
        <p><input type="text"></p>
        <p><textarea rows="3" cols="30"></textarea></p>
    </form>

</body>
</html>

Type the . key in your numeric keypad (or whatever key replaces it in your keyboard layout) and the key that corresponds to the same character in the alphabetical keypad. The goal is to detect you clicked the first one and not the second one.

+1  A: 

Your code doesn't do anything on my end, so I'd say it probably does depend on keyboard layout. A quick check confirms that the output on my finnish qwerty keyboard is keycode 44, instead of the expected 46.

Jani Hartikainen
Hmm... I get `[keyCode, charCode, which]=[0, 44, 44]` with my regular coma key. Does your Finish keypad feature a coma key?
Álvaro G. Vicario
Keydown: 110,0,110 for numpad, 188, 0, 188 for normal comma. In keypress: 44,44,44 for both numpad and normal comma
Jani Hartikainen
A: 

Is it safe to read from e.which?

Normally in IE no, you only get keyCode (though on keypress it's actually a character code not a key code). Your code can read which because behind the scenes jQuery copies the keyCode value into which on IE. Without jQuery, you need property-sniffing code to know which one to pick. (You can't always read keyCode on keypress because it's not guaranteed to be provided and it's 0 on Firefox.)

Please note I don't want to detect a character: I want to detect a key.

You can't do that in keypress, which only gives you a character code (46, ASCII for .). You would instead have to trap keydown, which gives you access to a real key code (in the keyCode property, and also in browsers that aren't IE, in which).

The keyCode reported for the numeric keypad ./, button is 110 (ASCII for lower-case N). Except on opera where it's 78, ASCII for upper-case N and thus indistinguishable from pressing the N button.

So you could claim the keydown event and store a flag when key 110 or 78 was being depressed, then claim keypress. If the flag from the last keydown was set and the which (charCode) property is 46, return false to prevent the keypress going through, and then insert a , at the focus point instead. (This isn't quite reliable if there are multiple keys being pressed at once and autorepeat going on, though.)

Note that inserting a character at focus is itself non-trivial; see many previous questions here. You'll need branching code for IE (document.selection.createRange().text=...) and other modern browsers (changing the input's value based on selectionStart/selectionEnd). Older and mobile or niche browsers may not support either method of editing, so detect the lack of these properties and leave the keyboard alone if you can't do it.

Does the operating system affect these numeric codes in some manner or it's only a browser stuff? Do these codes depend on the keyboard layout?

In general yes, though not in a way that will affect you here. Key events are in general still hugely variable cross-browser, cross-keyboard and cross-platform; they are best avoided if you can.

Personally I think the proper solution to a bad keyboard layout choice like Spanish's numpad decimal point would be to modify the layout using MSKLC.

bobince