4

I have this jQuery which stops the enter key from being pressed and I have prepared it to accept an array of disallowed keypresses..

    $('.form input').bind('keypress', function(e) {
        var keys = [13];
        for (var i = keys.length; i--;){
            if(e.keyCode===keys[i]){
                return false;
            }
        }
    });

I want to do similar thing with the | character, but since it is shift of 220 and I don't need to stop \ from being entered into the form, how do I restrict that character or use a modifier key? (will also be processing it out server-side, of course).

I'm also aware that keyboard layout for special characters may differ from keyboard to keyboard with different localization, so it may be necessary to focus on the resulting character rather than the key itself (not entirely sure on that), but I don't want to introduce a large amount of overhead

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Damon
  • 10,493
  • 16
  • 86
  • 144
  • 3
    There are special keys for shift. e.shiftKey. http://stackoverflow.com/questions/3781142/jquery-or-javascript-how-determine-if-shift-key-being-pressed-while-clicking-an – dweiss May 01 '12 at 14:20
  • As far as I know, the pipe (|) is `124` while backslash (\\) is `92`. – kapa May 01 '12 at 14:23
  • you could use regular expressions instead? – Piotr Kula May 01 '12 at 14:26
  • you can set the max-length for input when you want to stop them. – Chinook May 01 '12 at 14:30
  • There are special keys for shift. For your purposes, you could use e.shiftKey. This SO Q+A explains using shift: http://stackoverflow.com/questions/3781142/jquery-or-javascript-how-determine-if-shift-key-being-pressed-while-clicking-an. You can combine e.shiftKey with the keycode check for \, where \ plus shift = |. As others are stating, this would only work on standard US layouts and whatever other keyboards support shift+\=| and these codes. – dweiss May 01 '12 at 14:20
  • Depends on the keyboard. – kapa May 01 '12 at 14:21

5 Answers5

6

The keypress event is about characters, not keys. You can just compare keyCode to the character code for "|" ("|".charCodeAt(0)) directly, no need to worry about the shift key being down (and it may not be on all keyboards).

Example - live copy | source:

HTML:

<p>Try to type | in the box below.</p>
<input id="theInput" type="text" size="80">

JavaScript:

jQuery(function($) {

  var keys = [13, "|".charCodeAt(0)];
  $("#theInput").keypress(function(e) {
    var index;

    for (index = 0; index < keys.length; ++index) {
      if (keys[index] === e.keyCode) {
        display("Denied!");
        return false;
      }
    }
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }
});

Or as bažmegakapa points out, since you're already using jQuery, you can use its inArray function:

jQuery(function($) {

  var keys = [13, "|".charCodeAt(0)];
  $("#theInput").keypress(function(e) {
    if ($.inArray(e.keyCode, keys) !== -1) {
      display("Denied!");
      return false;
    }
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }
});
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 3
    I've never heard of character.charCodeAt(0), but that's brilliant. Saves so much time and is incredibly easier to read as code than trying to look at a bunch of numerical keycodes. – dweiss May 01 '12 at 14:52
  • 1
    Should be `$.inArray(e.keyCode, keys) >= 0` since it returns `-1` if not found. – kapa May 01 '12 at 15:10
4

The keycode for the pipe is 124 so this should simply work:

$('.form input').bind('keypress', function(e) {
    var keys = [13, 124];
    for (var i = keys.length; i--;){
        if(e.keyCode===keys[i]){
            return false;
        }
    }
});​

Check out the demo

If you are using jQuery anyways, you could make use of the inArray() method:

$('.form input').bind('keypress', function(e) {
    var keys = [
        13, // enter
        124 // |
    ];
    return $.inArray(e.keyCode, keys) === -1;
});​
kapa
  • 77,694
  • 21
  • 158
  • 175
  • thanks! I didn't see the pipe on the keycode lists I found and concluded that it must be because it required a modifier key. Where did your keycode list come from, would like to have that on hand! – Damon May 01 '12 at 14:43
  • @Damon To be honest, I created a jsFiddle that simply logs the keycodes for the keys I press to the console :). – kapa May 01 '12 at 14:45
0

In conclusion the best solution ever would be:

var keys = [13, "|".charCodeAt(0)];
$(".form input").keypress(function(e) {
    return $.inArray(e.keyCode, keys) === -1;
});
noob
  • 8,982
  • 4
  • 37
  • 65
-2

You can check if e.shiftKey is true, but that'll require you to modify your array. Personally I'd use something like:

var mod = {
    NONE:0,
    SHIFT:1,
    CTRL:2,
    ALT:4
};
var keys = [
    [13,mod.NONE], // enter, no mod
    [220,mod.SHIFT] // \ with Shift = |
];
for( var i=keys.length; i--;) {
    if( e.keyCode === keys[i][0] && (e.shiftKey + 2*e.ctrlKey + 4*e.altKey) === keys[i][1]) {
        return false;
    }
}
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 2
    Writing code only for a specific keyboard layout does not seem to be a good idea. – kapa May 01 '12 at 14:26
-2

If you are simply looking to not include a specific character (or even set of characters), I think a better way is to remove any restricted characters from the form value.

$('.form input').keyup(function(e){ $(this).val( $(this).val().replace("|", "" ) ); });

kinadian
  • 238
  • 1
  • 3
  • 11
  • this causes an incredibly bad user experience, in my opinion. – jbabey May 01 '12 at 14:32
  • 1
    For several reasons, not least that the cursor jumps around when you replace the value. So typing a | puts you at the beginning or the end, etc. Just not good UX. When there's a *dramatically* better way, why not use it? – T.J. Crowder May 01 '12 at 14:56
  • Yeah, that wouldn't be a good interface. Just to note, that didn't happen to me when I tested this out using Firefox. The cursor remained where the | character was before being removed. – kinadian May 01 '12 at 15:01