views:

301

answers:

2

Hi,

I'm attempting to do info validation against user text input in the process of keydown event. The reason that I am trying to validate in the keydown event is because I do not want to display the characters those that are considered to be illegal in the input box at the beginning.

The validation I am writing is like this,

function validateUserInput(){
   var code = this.event.keyCode;
    if ((code<48||code>57) // numerical
      &&code!==46 //delete
      &&code!==8  //back space
      &&code!==37 // <- arrow 
      &&code!==39) // -> arrow
   {
     this.event.preventDefault();        
    }
}

I can keep going like this, however I am seeing drawbacks on this implmentation. Those are, for example,

  1. Conditional statement become longer and longer when I put more conditions to be examined.
  2. keyCodes can be different by browsers.
  3. I have to not only check what is not legal but also have to check what are exceptionals. In above examples, delete,backspace, and arrow keys are exceptionals.

But the feature that I don't want to lose is having not to display the input in the textarea unless it passes the validation. (In case the user try to put illegal characters in the textarea, nothing should appear at all) That is why I am not doing validation upon keyup event.

So my question is,

  1. Are there better ways to validate input in keydown event than checking keyCode by keyCode?
  2. Are there other ways to capture the user inputs other than keydown event before browser displays it? And a way to put the validation on it?

Thanks for the help in advance.

+1  A: 

I don't think you need the preventDefault part. If you want to catch keys (by event.keyCode, or combinations using for example event.ctrlKey + event.keyCode), you check if the keyCode is allowed. If it is, simply return true, otherwise return false. If you return false, the key input will not be written to the input field, otherwise it will.

I can't think of better ways to then using keyCode. You can use String.fromCharCode([keyCode]) if you want to check for specific character values, but it keeps boiling down to some loop to check the keyCodes you want to validate. May be a switch ... case could offer a bit more readability.

Here's a piece of code from a keydown event handler I use (just for demonstration, it doesn't actually do anything):

function handleKey(e, thisFld) {
        thisFld = (thisFld || this);
              e = e || event;
    if (!e) {
      return true;
    }

    var isCtrl = e.ctrlKey,
        isShift = e.shiftKey,
        isAlt = e.altKey,
        kc = e.keyCode || e.which,
        codes = [27, 38, 40],
        keys = {
                 escape: 27,
                 up: 38,
                 down: 40,
                 ins: 45,
                 del: 46,
                 one: 49
                };

    if (isCtrl && kc === keys.del) { ... }
    if (isAlt && kc === keys.ins) { ... }
        //etc
    return true;
}
KooiInc
Thanks for the information. preventDefault wasn't necessary. Have applied String.fromCharCode too.
c411
+1  A: 

If you're checking a printable key, which is exactly what you seem to be doing, you should use the keypress event instead, since that's the only place you're going to be able to get reliable information about the character the keypress represents. You can't detect numeric keypresses reliably in the keydown event. Also, it's a bad idea to suppress arrow keys and delete/backspace keys. What do you gain from doing that?

There's also some errors: in Firefox, you'll need to get the Event object from the parameter passed into the event handler function, and if you're using a DOM0 event handler function rather than addEventListener() or attachEvent(), you should use return false; to suppress default behaviour. Here's my recommended code:

var input = document.getElementById("your_input_id");

input.onkeypress = function(evt) {
    evt = evt || window.event;
    var charCode = evt.which || evt.keyCode;
    var charStr = String.fromCharCode(charCode);
    if (/\d/.test(charStr)) {
        return false;
    }
};
Tim Down
Yes, onkeypress worked nicely. Thanks a lot!
c411