2

I am trying to limit keyboard input in my text field to numbers [0-9] and the minus sign - only (no copy/paste, etc.) and the delete key obviously.

The code works for limiting to numbers and the delete key but it doesn't work for the minus sign - part.

The user should only be able to enter a minus sign - in front of their number, if they try to enter 1 then - it should not input the - but right now the - part doesn't work at all.

Fiddle: http://jsfiddle.net/7XLqQ/1/

I think this piece of code is the issue but it looks fine. It checks that the text input is blank and if so it input the minus sign -.

// Only enter the minus sign (-) if the user enters it first
if (unicode == 45 && input.value == "") {
    return true;
}

My full code:

<input type="text" maxlength="10" id="myInput">

<script>
var input = document.getElementById("myInput");

input.onkeypress = function(e) {
   var unicode = e.keyCode;

    if (unicode == 49 || unicode == 50 || unicode == 51 || unicode == 52 || unicode == 53 || unicode == 54 || unicode == 55 || unicode == 56 || unicode == 57 || unicode == 48) {
        return true;
    } else {
        return false;   
    }

    // Only enter the minus sign (-) if the user enters it first
    if (unicode == 45 && input.value == "") {
        return true;
    }
};
</script>
Lukkar
  • 111
  • 1
  • 9
user1822824
  • 2,478
  • 6
  • 41
  • 65

4 Answers4

1

Order of opperations, you are returning false on the 0-9 before you are ever asking about the minus sign. move the minus sign if block above the 0-9 if block and you are golden

<input type="text" maxlength="10" id="myInput">

<script>
var input = document.getElementById("myInput");

input.onkeypress = function(e) {
   var unicode = e.keyCode;

    // Only enter the minus sign (-) if the user enters it first
    if (unicode == 45 && input.value == "") {
        return true;
    }

    if (unicode == 49 || unicode == 50 || unicode == 51 || unicode == 52 || unicode == 53 || unicode == 54 || unicode == 55 || unicode == 56 || unicode == 57 || unicode == 48) {
        return true;
    } else {
        return false;   
    }


};
</script>
invertedSpear
  • 10,864
  • 5
  • 39
  • 77
1

I'd suggest:

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

input.onkeypress = function(e) {
    switch (e.keyCode){
        case 45:
            return this.value.length == 0 ? true : false;
            break;
        case 48:
        case 49:
        case 50:
        case 51:
        case 52:
        case 53:
        case 54:
        case 55:
        case 56:
        case 57:
            return true;
            break;
        default:
            return false;
            break;
    }
};

JS Fiddle demo.

The reason your original code failed is simply that you'd already returned from the function before the if condition could be assessed. In this version if the - key is pressed a ternary returns true if there is no current value (so the - will be the first character), or false if there is already a value (and therefore the - will not be the first character).

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • Thanks that worked for me but what is this expression called: this.value.length == 0 ? true : false; --- I know it's checking the length of input but what's the ? true : false part called --- I've seen it before but I couldn't find any info on it on the MDN JavaScript Reference website. – user1822824 Feb 21 '13 at 23:36
  • You're very welcome, and I'm glad to have helped. The expression you're asking about is a [ternary (conditional) operator](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Conditional_Operator). Effectively it evaluates the condition and, if it's true, assigns the first value or, if false, assigns the second; so in the following: `var x = 1 === 1 ? true : false;` the variable `x` will be assigned the value of `true`. – David Thomas Feb 21 '13 at 23:52
  • `this.value.length == 0` is already true or false, you don't need a ternary – James Feb 21 '13 at 23:53
  • @James: indeed, but I was trying to offer code that gave an insight into what I was doing or, at least, the thought processes behind what I was doing. Plus I (personally) find it more readable *as* a ternary, regardless of it being *necessary* to do it that way. A personal preference is all. – David Thomas Feb 21 '13 at 23:55
  • `keyCode` is the wrong property in all browsers except IE. You need `charCode` or `which` in other browsers. Using this you'll get character code instead and can use a regular expression to test the typed character. Also, `e` will be undefined in IE <= 8 and you'll need to reference `window.event` instead. – Tim Down Feb 21 '13 at 23:58
  • @Tim: ah? I tested in Chrome and it seemed to work as expected. I'll correct it tomorrow (or please feel free to edit/correct in the meantime), right now: I need sleep, sorry. =( (though I knew about `window.event`, I just assumed the OP had corrected for that elsewhere). – David Thomas Feb 22 '13 at 00:01
  • No problem. It's one of my pet subjects. I've added my own answer. – Tim Down Feb 22 '13 at 00:05
1

keyCode is the wrong property in all browsers except IE. You need charCode or which in other browsers. Using this you'll get character code instead and can use a regular expression to test the typed character. You also need to allow non-printable keypresses such as delete, backspace and arrow keys in browsers that fire keypress events for such keys.

Demo: http://jsfiddle.net/7XLqQ/3/

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

input.onkeypress = function(e) {
    e = e || window.event;
    var charCode = (typeof e.which == "number") ? e.which : e.keyCode;

    // Allow non-printable keys
    if (!charCode || charCode == 8 /* Backspace */ ) {
        return;
    }

    var typedChar = String.fromCharCode(charCode);

    // Allow numeric characters
    if (/\d/.test(typedChar)) {
        return;
    }

    // Allow the minus sign (-) if the user enters it first
    if (typedChar == "-" && this.value == "") {
        return;
    }

    // In all other cases, suppress the event
    return false;
};

There is one case that isn't considered here, which is when the user places the caret at the start of the input and types a minus sign. For that, you'd need to detect the caret position. Here's some cross-browser code to detect whether the caret is at the start of the input, adapted from this answer:

function isCaretAtTheStart(el) {
    if (typeof el.selectionEnd == "number") {
        // Modern browsers
        return el.selectionEnd == 0;
    } else if (document.selection) {
        // IE < 9
        var selRange = document.selection.createRange();
        if (selRange && selRange.parentElement() == el) {
            // Create a working TextRange that lives only in the input
            var range = el.createTextRange();
            range.moveToBookmark(selRange.getBookmark());
            return range.moveEnd("character", -el.value.length) == 0;
        }
    }
    return false;
}

Here's a revised demo: http://jsfiddle.net/7XLqQ/5/

Finally, my favourite resource on JavaScript key events, which will tell you everything you need to know: http://unixpapa.com/js/key.html

Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • Thanks for your response. I went through your code and understand everything but 2 lines. Could you explain what's happening in the first 2 lines? ( e = e || window.event; AND var charCode = (typeof e.which == "number") ? e.which : e.keyCode;) – user1822824 Feb 22 '13 at 00:23
  • I guess on line 1 you're setting e to e OR e to window.event. – user1822824 Feb 22 '13 at 00:24
  • @user1822824: Yes. The first line is for IE <= 8, which does not supply the event as a parameter to the event handler function and instead supplies it `window.event`, and uses the fact JavaScript's `||` operator returns the value of the first operand that is not [falsy](http://stackoverflow.com/a/4361614/96100). The second line is another thing for IE <= 8: those browsers do not have a `which` or `charCode` property on `keypress` events, instead providing the character code in the `keyCode` property, so the second line uses `which` in browsers where it exists and `keyCode` otherwise. – Tim Down Feb 22 '13 at 00:35
0

I'd suggest:

$(".class_name").keypress(function (e) {
   if (e.which != 8 && e.which != 0 && e.which != 45 && (e.which < 48 || e.which > 57)) {
      return false;
   }
});