views:

949

answers:

3

Hi!

I'm binding on the keydown event with jQuery to allow some specific characters in a textbox. I'm trying to make my code cross browser and platform compliant. My main issue is that I can't find a way to map the received key code to a valid char code, especially for key code coming from the numeric pad (decimal separator, is it a coma or a period, etc.).

Thanks in advance for helping, Fabian

+2  A: 

That is correct. There is no such mapping you can do; a keydown may not even correspond to a character being inserted. Or Caps Lock might change the meaning of the keypress, and you can't sniff for that. And various other wrinkles.

If you want to know the character code your only option is to use the keypress event.

bobince
This is also my conclusion. But, according to http://www.quirksmode.org/js/keys.html, it seems Firefox doesn't handle correctly the keypress event. I'm a bit stuck on this issue :-/
Fabian Vilers
One more thing about keypress, I get the same code for the period AND the delete key (not backspace): 46. This is a huge issue for me :(Using english Windows XP, english Firefox, belgian keyboard, belgian mapping.
Fabian Vilers
Firefox's keypress is fine, just use the usual `event.which` to get the character. Then add fallback for IE's charCode-in-keyCode behaviour. eg. `var c= 'which' in event? event.which : event.keyCode;`
bobince
And yeah, there are many keys that have odd keyCodes too. I'm not quite sure what you're trying to do, but if it's number validation keyboard events are the wrong place to be doing that.
bobince
I'm trying to filter input on a textbox to allow only a set of character. Currently, I'm working on the numeric filter (I'm allowing negative and/or decimal numbers).Bobince, any clue on how better doing this is welcome :)
Fabian Vilers
`onchange` is the traditional place to do filtering, so you can type anything you want but when you unfocus it updates. Otherwise you end up with problems like not being able to type a dot because the validation regex won't allow a trailing dot. And keypress filtering doesn't stop other forms of editing such as copy-and-paste, drag-and-drop, right-click-undo etc.
bobince
A: 

Well, if your problem is translation of the keycodes to characters, why not let the browser handle it for you? This might sound hideous, but you could simply allow the browser modify the text box (so that delete is a delete, and a period is a period), and then go back and edit it... Um... maybe something like this:

function hookEvents() {
    $('#myTextBox').oldValue = $('#myTextBox').value;
    $('#myTextBox').bind('keyup', function(event) {
        // Maybe nothing's changed?
        if (event.target.oldValue == event.target.value) {
            return;
        }

        var validInput = /(\-?[0-9]*(?:\.[0-9]*)?)/;
        var input = event.target.value;
        var result = validInput.exec(input);
        if (result.index != 0 || result[result.length-1] != input.length) 
        {
            event.target.value = result[0];
        }

        // update for later
        event.target.oldValue = event.target.value;
    });
}

The biggest problem with this approach is that every key pressed appears on screen for a moment. On the other hand, with the REGEX you have a lot more control over the format of the allowed input. In the example above, I only allow positive or negative numbers (with an optional decimal point). Such as: "123", "-123", "-123.456", "123.456".

I know this doesn't really answer your question, but it sidesteps the issue entirely!

scraimer
Interesting, but as you said, the character will first appaer on the textbox. This is something I don't want to have.
Fabian Vilers
A: 

Well, like I said in comments, the goal behind this question was to filter a textbox on numeric values. I managed to reach my goal using the keypress event.

I've published a jQuery plug-in for those who are interested in the solution.

Fabian Vilers