2

What is the best way to prevent users from entering negative values in an input text element?

Currently I am checking the field value on blur, but I am hoping somebody has a better solution.

$(".payment").blur(function() {
    var payment = getAmount($(this).val());
    if(!isNaN(payment) && amount >= 0) {
        $(this)
            .css("color", "black")
            .val(currency(payment));
    } else {
        if(amount < 0) showMessage("Negative amounts are not allowed", "error");
        $(this).css("color", "red");
    }
});

function getAmount(strAmount) {
    var amount = new String(strAmount).replace(/\$/g, "").replace(/,/g, "");
    return parseFloat(amount);
}
Sam Tyson
  • 4,496
  • 4
  • 26
  • 34
  • 2
    What does the `getAmount` function do? and where is the `amount` variable coming from? And did you mean `if(!isNaN(payment) && payment >= 0)` – Salman A Jun 04 '12 at 18:32
  • 1
    If it is working on blur, and your real question is at what point you should be validating the field, that depends on the situation. you can validate on keyup, on change, on blur, or on form submit. Each has it's own pros and cons. – Kevin B Jun 04 '12 at 18:33
  • I really don't know if it's the best way but you could use the `keyup event` and get the value then check if it's positive – Jorge Jun 04 '12 at 18:34
  • 1
    You need to listen to keystrokes. See: http://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input – Diodeus - James MacFarlane Jun 04 '12 at 18:34
  • 1
    It's more of a usability question, as a user I'd rather have it validate when I'm done with it (ie, on blur) rather than when I'm editing. If I fat finger `-` I don't want it to interrupt me before I get a chance to delete it. – Snuffleupagus Jun 04 '12 at 18:39
  • Thanks @Diodeus - I went with a solution based on keypress, and validating only number keys and a decimal point. – Sam Tyson Jun 04 '12 at 18:41

5 Answers5

9

You could use jQuery's .keypress() and prevent the default action for the - key. Example: http://jsfiddle.net/5cgXg/


$("#target").keypress(function(event) {
  if ( event.which == 45 || event.which == 189 ) {
      event.preventDefault();
   }
});
ayyp
  • 6,590
  • 4
  • 33
  • 47
  • Where are you coming up with 45? I get 109 when I press the dash key. Aside from that, the idea is the same. – Ashley Strout Jun 04 '12 at 18:39
  • Good solution. I would still validate on submit as well, in case they copy paste. – ToddBFisher Jun 04 '12 at 18:41
  • 1
    @David According to here it's 189: http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes According to here it's 45: http://api.jquery.com/keypress/ I feel like there may be multiple values for that key... – ayyp Jun 04 '12 at 18:41
  • Well, the only value I can come up with is 109. I pressed the dash next to the +/=, as well as my numpad dash with and without Num Lock on, and it stayed the same. Of course, that's just one guy with one US keyboard. – Ashley Strout Jun 04 '12 at 18:48
  • @David I did the same thing, on the jQuery site it gave 45, the other 189. I think some testing would need to be done, or some looking around to make sure that all key values are accounted for, – ayyp Jun 04 '12 at 18:49
  • i thought of the same solution, but it doesnt catch copy/paste – L. Monty Jun 04 '12 at 18:49
  • Regarding the key codes, how about using `fromCharCode` instead? – VisioN Jun 04 '12 at 18:50
2

This ought to do the trick:

$(".payment").keydown(function(event) {
    if (event.keyCode == 45 ) { event.preventDefault(); }   
});

This will prevent the keydown event from registering when the character code for "-" (45) is detected.

Andrew Odri
  • 8,868
  • 5
  • 46
  • 55
2

On the assumption you might not want to work with key-codes (e.which, e.keyCode and so on), here's one further option:

$('#a').blur(
    function(){
        var v = $(this).val(),
            t = parseInt(v,10),
            b = isNaN(t);
        if (b){
            $(this).val('');
        }
        else {
            $(this).val(Math.abs(t));
        }
    });​

JS Fiddle demo.

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
1

You can use jQuery's keypress or keydown events to test against the input on every key.

If you haveother fields that need validating as well, consider jQuery Validation plugin.

sachleen
  • 30,730
  • 8
  • 78
  • 73
0

Thanks for all of the answers.

Here is what I ended up with:

$("input.payment").keypress(function(e) {
    validateNumeric(e);
});

function validateNumeric(evt) {
   var theEvent = evt || window.event;
   var key = theEvent.keyCode || theEvent.which;
   key = String.fromCharCode( key );
   var regex = /[0-9]|\./;
   if( !regex.test(key) ) {
      theEvent.returnValue = false;
      if(theEvent.preventDefault) theEvent.preventDefault();
   }
}
Sam Tyson
  • 4,496
  • 4
  • 26
  • 34