Is there any way to prevent input type="number" getting negative values?
Asked Answered
H

19

452

I want to get only positive values, is there any way to prevent it using only html
Please don't suggest validation method

Screenshot of input control

Hook answered 10/9, 2011 at 13:38 Comment(2)
This thread answers the same question in much better extent: #31575996Cresol
What about the user (and not the developer)? If I type -3 I get a 3, and that is not what I meant! Absolutely makes to sense! just leave the -3 there and give me an explanation error. How come most developers think this terrible behavior is user friendly? I hate it when a developer breaks my keyboard without telling me.Sebastien
P
862

Use the min attribute like this:

<input type="number" min="0">
Postbox answered 10/9, 2011 at 13:42 Comment(14)
Here's a more reliable reference source.Suspicious
This will block a negative number from being entered using the arrow buttons / spinner. However, the user can still manually enter in a negative number and have that field's value read as a negative number, thus bypassing the min attribute.Spaceport
@demaniak No. And how did this answer get so many upvotes when it half answers the question is a mysteryMoorman
@Postbox What if the data loaded with the -ve value in the form, it does not mark it as red.Wainwright
how to prevent even e from taking..can someone help quickly plzTypesetter
still copy past allowedTeniafuge
This doesn't work, the user can still enter a negative number manually.Cazzie
i just tried entering a negative number manually and it stopped it.... not sure why all the comments about this not working. could of course be user error :)Reichsmark
I can still copy paste negative values into the input field. I will look for another solution. This one doesn't work completely for me.Motherly
<input min='0' type="number" onkeypress="return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57"> https://mcmap.net/q/80318/-is-there-any-way-to-prevent-input-type-quot-number-quot-getting-negative-valuesCorpuscle
I was looking for upper bound. This answer guided me towards max=1000. (*upvoted) :-)Lawlor
I used this, when I entered negative number it let me in, but did not let me submit, so I would say the code works as it should.Jenn
@Postbox The answer should cover all corner cases. I am able to copy paste the -1 and able to type as well.Replacement
As others have said you can enter a negative number into the field but it will be considered invalid. The form will not be able to submit, a message is show at the field about the correct values.Deonnadeonne
V
230

For me the solution was:

<input type="number" min="0" oninput="this.value = Math.abs(this.value)">

Edit

As suggested on the comments with a minor change to work if 0 is the min value.

<input type="number" min="0" oninput="this.value = 
 !!this.value && Math.abs(this.value) >= 0 ? Math.abs(this.value) : null">
Valladolid answered 4/9, 2017 at 14:29 Comment(12)
Really best solution once you use pattern and noformvalidate with angular , since the model is not updated if not within the range. My case : <input ng-model="row.myValue" type="{{row.code == 1 ? 'text' : 'number'}}" min="0" ng-pattern="..." noformvalidate oninput="if (this.type=='text') this.value=Math.abs(this.value) ">Scumble
this works best when user knows the default value is 0. Other wise user get confused on backspace press why field is not clearing. Except this, it is best solution.+1Kimikokimitri
This one works best, and in case of using decimal also. I had used other answer above, it stopped working when decimal is to be allowed. Is there way we can move this answer to up so-that people can use this mostly.Bala
If you want to keep blank after filling (e.g. with backspace) you should use this this.value = Math.abs(this.value) > 0 ? Math.abs(this.value) : nullEtienne
I think ali6p's comment is the most useful. It's more user-friendly. Perhaps this answer can be updated with both versions.Symposium
The best solution!!Triplett
The only working solution with no negative inputs, no negative copy/paste, no negaive scroll.Amygdaloid
Brilliant. Also solves this style of input preventing .NET validation. Should be accepted answer.Delanos
edited version of this answer is the best solution ever.Mondrian
Tried to use this and its working with Chrome and Firefox but not in IE. Is there a way on how will it work with IE as well ? Thank you.Greenes
This prevents adding decimal to the value. For example, 0.00Exploitation
This is not allowing decimal values @renato machadoSkewness
E
158

I was not satisfied with @Abhrabm answer because:

It was only preventing negative numbers from being entered from up/down arrows, whereas user can type negative number from keyboard.

Solution is to prevent with key code:

// Select your input element.
var number = document.getElementById('number');

// Listen for input event on numInput.
number.onkeydown = function(e) {
    if(!((e.keyCode > 95 && e.keyCode < 106)
      || (e.keyCode > 47 && e.keyCode < 58) 
      || e.keyCode == 8)) {
        return false;
    }
}
<form action="" method="post">
  <input type="number" id="number" min="0" />
  <input type="submit" value="Click me!"/>
</form>

Clarification provided by @Hugh Guiney:

What key codes are being checked:

  • 95, < 106 corresponds to Numpad 0 through 9;
  • 47, < 58 corresponds to 0 through 9 on the Number Row; and 8 is Backspace.

So this script is preventing invalid key from being entered in input.

Electrolytic answered 14/1, 2016 at 7:1 Comment(11)
Upvoted but I think it would help to clarify what key codes are being checked: > 95, < 106 corresponds to Numpad 0 through 9; > 47, < 58 corresponds to 0 through 9 on the Number Row; and 8 is Backspace. So this script is preventing any key but those from being entered. It's thorough but I think it might be overkill for browsers that natively support number inputs, which already filter out alphabetical keys (except for characters like "e" which can have a numerical meaning). It would probably suffice to prevent against 189 (dash) and 109 (subtract). And then combine with min="0".Immigrant
@Electrolytic It restricts to copy and paste numbers using keyboard. And allows me to copy paste negative numbers using mouse.Lim
@Beniton Thanks giving this use case. Can you give me little idea about what you are doing.Always I can help you out. Please provide little runnable code or fiddle. You can have form Submit level validation for in your code. Although i always have check in Backend if i don't allow negative numbers.Electrolytic
Just copy-paste into the field basically. It's not really a special case or anything. Instead of handling the validation via keycode, it's probably better to do it onChange or focusOut and build a little validation function to catch any negative numbers.Pulsar
I support @HughGuiney's advice, especially since this answer prevents arrow keys from being used to move around input field.Guava
Added nice explanation provided by @HughGuiney. Many Thanks.Electrolytic
I went with Hugh Guiney's method but added e.preventDefault() as well which seemed to prevent onChange (React) from firing.Smaragd
@BenCreasy It will disable that event at all. Then you can't change the numbers from arrows.Electrolytic
the e.preventDefault() only applies when I'm returning false for dash and subtract per Hugh's method - wasn't working otherwise in my caseSmaragd
Condition for arrow key(37, 38, 39, 41) should also be put. || (e.keyCode>36 && e.keyCode<41) This does not allow user to increase/decrease number through up/down arrow and go right/left to edit number.Impale
Does this work if the user has some other way of putting in the value, such as pasting -15 from the clipboard?Mazel
P
44

This code is working fine for me. Can you please check:

<input type="number" name="test" min="0" oninput="validity.valid||(value='');">
Palomo answered 15/5, 2017 at 7:34 Comment(8)
This works but emptying the entire input after you try to type - is not really a good idea.Ellingston
@Ellingston Sounds like a fair punishment to the user trying to enter a negative in a field where common sense indicates there are no negatives.Granary
<input type="number" name="test" min="0" oninput="validity.valid||(value=value.replace(/\D+/g, ''))"> - this will remove all non-digit symbolsBobbitt
@Rexford I agree, But I have set min="0" so there are no nagatives. If you want to negative value then remove this attribute.Palomo
How can you do this in React?Korrie
I tried this but it also prevented numbers with decimal points from being entered.Irritable
It is not a good solution. it will break in decimal value. When you add 23.5 it automatically removed decimal and show 235 which is not ok.Ingressive
@Ingressive As per the question. I have answered this. Here is asking for an only a positive number.Palomo
D
27

Easy method:

<input min='0' type="number" onkeypress="return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57">
Disclosure answered 18/10, 2017 at 6:23 Comment(3)
Nice and easy ... but still, negative numbers can be pasted.Dedicated
Nice and easy. Doesn't work.Mazel
event.charCode is deprecated nowStegosaur
U
8

I wanted to allow decimal numbers and not clear the entire input if a negative was inputted. This works well in chrome at least:

<input type="number" min="0" onkeypress="return event.charCode != 45">
Unfeigned answered 14/10, 2018 at 12:31 Comment(3)
How can add more ascii number here. for eg. with 45 i wana add 46 also. How it can be done?Uncinariasis
@PradeepSingh "return [45, 46].indexOf(event.charCode) == -1"Unfeigned
Please think out of the box. Are you really sure a keypress is the only way one could enter a negative number into an input...Comportment
C
7

The @Manwal answer is good, but i like code with less lines of code for better readability. Also i like to use onclick/onkeypress usage in html instead.

My suggested solution does the same: Add

min="0" onkeypress="return isNumberKey(event)"

to the html input and

function isNumberKey(evt){
    var charCode = (evt.which) ? evt.which : event.keyCode;
    return !(charCode > 31 && (charCode < 48 || charCode > 57));
}

as a javascript function.

As said, it does the same. It's just personal preference on how to solve the problem.

Consuetudinary answered 15/2, 2017 at 11:52 Comment(0)
P
7

Here's an angular 2 solution:

create a class OnlyNumber

import {Directive, ElementRef, HostListener} from '@angular/core';

@Directive({
  selector: '[OnlyNumber]'
})
export class OnlyNumber {

  // Allow decimal numbers. The \. is only allowed once to occur
  private regex: RegExp = new RegExp(/^[0-9]+(\.[0-9]*){0,1}$/g);

  // Allow key codes for special events. Reflect :
  // Backspace, tab, end, home
  private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home'];

  constructor(private el: ElementRef) {
  }

  @HostListener('keydown', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    // Allow Backspace, tab, end, and home keys
    if (this.specialKeys.indexOf(event.key) !== -1) {
      return;
    }

    // Do not use event.keycode this is deprecated.
    // See: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
    let current: string = this.el.nativeElement.value;
    // We need this because the current value on the DOM element
    // is not yet updated with the value from this event
    let next: string = current.concat(event.key);
    if (next && !String(next).match(this.regex)) {
      event.preventDefault();
    }
  }
}

add OnlyNumber to declarations in app.module.ts and use like it like this anywhere in your app

<input OnlyNumber="true">
Piotrowski answered 29/8, 2017 at 7:55 Comment(1)
Is there a way of allowing Paste for this? Also I changed the regex to: /^-?[0-9]+(\.[0-9]*){0,1}$/g to allow negative numbers, but it doesn't seem to work?Sweettalk
P
5

Just for reference: with jQuery you can overwrite negative values on focusout with the following code:

$(document).ready(function(){
    $("body").delegate('#myInputNumber', 'focusout', function(){
        if($(this).val() < 0){
            $(this).val('0');
        }
    });
});

This does not replace server side validation!

Pirouette answered 3/10, 2016 at 17:53 Comment(1)
This works fine IF the user focuses out of the input field, however if they immediately press enter whilst still in the field; they can still enter a negative number.Superficies
C
4

simply use min="0"

<v-text-field
   v-model="abc"
   class="ml-1 rounded-0"
   outlined
   dense
   label="Number"
   type="number"
   min="0">
</v-text-field>
Christenson answered 6/10, 2021 at 5:26 Comment(0)
X
3
oninput="this.value=(this.value   < Number(this.min) || this.value   > Number(this.max))  ? '' : this.value;"
Xanthin answered 27/1, 2018 at 15:57 Comment(2)
While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.Hak
While this may be the correct answer, it lacks enough detail. Please explain why this works. When using Stack Overflow, consider that this is a living knowledge base, answers that don't share knowledge are far less useful.Farflung
A
3

Restrict the charcter (-) & (e) in type Number

<input type="number" onkeydown="return event.keyCode !== 69 && event.keyCode !== 189" />

Demo: https://stackblitz.com/edit/typescript-cwc9ge?file=index.ts

Arvid answered 22/10, 2020 at 8:9 Comment(2)
It still is accepting dash(negative) symbol on the numpad side of my keyboard. only restricting/blocking the dash(negative) symbol key on qwerty side of keyboard.Crosson
@Crosson if you want you can add the keycode for the dash in the numpad in validation. It's 109 (toptal.com/developers/keycode).Erection
C
2

Just adding another way of doing this (using Angular) if you don't wanna dirt the HTML with even more code:

You only have to subscribe to the field valueChanges and set the Value as an absolute value (taking care of not emitting a new event because that will cause another valueChange hence a recursive call and trigger a Maximum call size exceeded error)

HTML CODE

<form [formGroup]="myForm">
    <input type="number" formControlName="myInput"/>
</form>

TypeScript CODE (Inside your Component)

formGroup: FormGroup;

ngOnInit() { 
    this.myInput.valueChanges 
    .subscribe(() => {
        this.myInput.setValue(Math.abs(this.myInput.value), {emitEvent: false});
    });
}

get myInput(): AbstractControl {
    return this.myForm.controls['myInput'];
}
Chicky answered 16/7, 2019 at 8:44 Comment(0)
B
1

<input type="number" name="credit_days" pattern="[^\-]+" 
    #credit_days="ngModel" class="form-control" 
    placeholder="{{ 'Enter credit days' | translate }}" min="0" 
    [(ngModel)]="provider.credit_days"
    onkeypress="return (event.charCode == 8 || event.charCode == 0 || 
    event.charCode == 13) ? null : event.charCode >= 48 && event.charCode <= 
    57" onpaste="return false">
Benz answered 25/1, 2018 at 7:38 Comment(0)
P
1

The answer to this is not helpful. as its only works when you use up/down keys, but if you type -11 it will not work. So here is a small fix that I use

this one for integers

  $(".integer").live("keypress keyup", function (event) {
    //    console.log('int = '+$(this).val());
    $(this).val($(this).val().replace(/[^\d].+/, ""));
    if (event.which != 8 && (event.which < 48 || event.which > 57))
    {
        event.preventDefault();
    }
   });

this one when you have numbers of price

        $(".numeric, .price").live("keypress keyup", function (event) {
     //    console.log('numeric = '+$(this).val());
    $(this).val($(this).val().replace(/[^0-9\,\.]/g, ''));

    if (event.which != 8 && (event.which != 44 || $(this).val().indexOf(',') != -1) && (event.which < 48 || event.which > 57)) {
        event.preventDefault();
    }
   });
Passage answered 9/9, 2019 at 14:49 Comment(0)
E
0

This solution allows all keyboard functionality including copy paste with keyboard. It prevents pasting of negative numbers with the mouse. It works with all browsers and the demo on codepen uses bootstrap and jQuery. This should work with non english language settings and keyboards. If the browser doesn't support the paste event capture (IE), it will remove the negative sign after focus out. This solution behaves as the native browser should with min=0 type=number.

Markup:

<form>
  <input class="form-control positive-numeric-only" id="id-blah1" min="0" name="nm1" type="number" value="0" />
  <input class="form-control positive-numeric-only" id="id-blah2" min="0" name="nm2" type="number" value="0" />
</form>

Javascript

$(document).ready(function() {
  $("input.positive-numeric-only").on("keydown", function(e) {
    var char = e.originalEvent.key.replace(/[^0-9^.^,]/, "");
    if (char.length == 0 && !(e.originalEvent.ctrlKey || e.originalEvent.metaKey)) {
      e.preventDefault();
    }
  });

  $("input.positive-numeric-only").bind("paste", function(e) {
    var numbers = e.originalEvent.clipboardData
      .getData("text")
      .replace(/[^0-9^.^,]/g, "");
    e.preventDefault();
    var the_val = parseFloat(numbers);
    if (the_val > 0) {
      $(this).val(the_val.toFixed(2));
    }
  });

  $("input.positive-numeric-only").focusout(function(e) {
    if (!isNaN(this.value) && this.value.length != 0) {
      this.value = Math.abs(parseFloat(this.value)).toFixed(2);
    } else {
      this.value = 0;
    }
  });
});
Eyetooth answered 17/12, 2017 at 14:49 Comment(0)
C
0

Here is a solution that worked best of me for a QTY field that only allows numbers.

// Only allow numbers, backspace and left/right direction on QTY input
    if(!((e.keyCode > 95 && e.keyCode < 106) // numpad numbers
        || (e.keyCode > 47 && e.keyCode < 58) // numbers
        || [8, 9, 35, 36, 37, 39].indexOf(e.keyCode) >= 0 // backspace, tab, home, end, left arrow, right arrow
        || (e.keyCode == 65 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + A
        || (e.keyCode == 67 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + C
        || (e.keyCode == 88 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + X
        || (e.keyCode == 86 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + V
    )) {
        return false;
    }
Caa answered 22/3, 2018 at 16:21 Comment(0)
E
0

I tried the other answers, some had issues with decimal points while some failed when the values were pasted. Here is my take on it, as long as the user physically doesn't change the code in the developer console this should work just fine. Try breaking it, and let me know if it fails, I would love to modify it further.

Post Validation

Use the onfocusout event to perform the validation when the user is done inserting/correcting the full input.

function positiveDecimalInputValidate(e) {
  if (e.value == "") {
    e.value = "";
    return
  }
  e.value = Math.abs(e.value);
}
<input type="number" onfocusout="positiveDecimalInputValidate(this);">

The first if check is to empty the input field when user inputs invalid inputs like e10, 1-2+4 etc. (I don't know why HTML thinks these are valid numerics).

You can add a second if to alert the user using alert or some toast etc. To let them know that you have changed their input value. Or don't change it at all, i.e. set it to an empty string. You can also switch onfocusout with onblur based on your use case. Here is a good difference between the two functions.

This code is resilient against copy paste as well. But if you also want to prevent the users from typing a negative sign or other bad charecters, you can use the below code as well.

Pre-measures

To prevent these bad charecters like a dash (-), I have modified the code to use event.key so that all dashes (-) and plusses (+) are compared/treated equally (removed in our case).

function badCharForNumberInputValidate(event) {
  const badKeys = ['-', 'e', 'E', ',']
  if (badKeys.includes(event.key)) {
    event.preventDefault();
  }
}
<input type="number" onkeypress="badCharForNumberInputValidate(event)">

If the user inputs any badKeys, it won't be added into the input field, while keeping the rest of the input unchanged. You can also replace the onkeypress with onkeydown or onkeyup basd on your use case.

Combined

The following is the combined and minified code I ended up using for my use case -

function positiveDecimalInputValidate(e) {
  if (e.value == "") {
    e.value = "";
    return
  }
  const newVal = Math.abs(e.value);
  if (newVal != e.value) {
    e.value = newVal;
  }
}

function badCharForNumberInputValidate(event) {
  const badKeys = ['-', '+', 'e', 'E', ','];
  if (badKeys.includes(event.key)) {
    event.preventDefault();
  }
}
<input type="number" onfocusout="positiveDecimalInputValidate(this);" onkeypress="badCharForNumberInputValidate(event)">
Erection answered 16/3 at 7:6 Comment(0)
S
-1

If Number is Negative or Positive Using ES6’s Math.Sign

const num = -8;
// Old Way
num === 0 ? num : (num > 0 ? 1 : -1); // -1

// ES6 Way
Math.sign(num); // -1
Sinter answered 12/3, 2020 at 8:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.