446

currently I have the following code

<input type="number" />

it comes out to something like this

enter image description here

The little selector things on the right allow the number to go into negative. How do I prevent that?

I am having doubts about using type="number", it is causing more problems than it is solving, I am going to sanity check it anyways, so should I just go back to using type="text"?

Arian Faurtosh
  • 17,987
  • 21
  • 77
  • 115
  • 4
    You'll still need to validate the value on the server. Anyone could override the field to send whatever content they want. – zzzzBov Oct 07 '13 at 19:54
  • 3
    @zzzzBov Yeah, I validate it with php, and also use prepare statements, the only thing left to worry about is users who barley know how to user a web browser. lol – Arian Faurtosh Oct 07 '13 at 19:56
  • 1
    Possible duplicate of [Is there any way to prevent input type="number" getting negative values?](https://stackoverflow.com/questions/7372067/is-there-any-way-to-prevent-input-type-number-getting-negative-values) – Vega Oct 26 '17 at 18:10

25 Answers25

894

Add a min attribute

<input type="number" min="0">
Álvaro González
  • 142,137
  • 41
  • 261
  • 360
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 107
    This works for the selector arrows, but allows typing a negative number – David Burton Mar 03 '16 at 12:51
  • 3
    Changing the attribute to `min="0.000001"` will help in most cases. More than 6 decimal places, JavaScript will convert it to exponent format. – MarkMYoung Jun 02 '16 at 20:32
  • By default, this only allows integers but not decimals. See [Allowing decimal values](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number#Allowing_decimal_values). – str Aug 02 '19 at 12:07
  • 1
    i tried running this .. but failing when you type this 98---89232-232 – Bh00shan Jul 16 '20 at 10:34
  • @Bh00shan — If you type something that is invalid, it will get picked up when the form's submit button is clicked and the user will be prompted to fix it. – Quentin Jul 16 '20 at 10:46
  • It should not allow by typing time itself why to wait till form submit.. Please provide updated solution. – Bh00shan Jul 16 '20 at 10:49
  • @Bh00shan — I'm not going to completely rewrite my answer because your needs are different to those of the person who asked the question. – Quentin Jul 16 '20 at 10:55
  • 2
    @DavidBurton Yes, this is correct but clicking at `Submit` button runs the validation and then the browser complains regarding the negative number and prevents the form to be submitted. But thank you for the comment as I tested it now explicitly because of it. – Peter VARGA Nov 14 '20 at 22:01
  • not all inputs are made to submit.. for example in a calculator app, we never submit; the user musn't be able to type negative numbers – Jack Casas Jul 06 '21 at 13:25
194

I have found another solution to prevent negative number.

<input type="number" name="test_name" min="0" oninput="validity.valid||(value='');">
Kushal
  • 2,605
  • 4
  • 22
  • 23
92

It depends on how precise you want to be. It you want to accept only integers, than:

<input type="number" min="1" step="1">

If you want floats with, for example, two digits after decimal point:

<input type="number" min="0.01" step="0.01">
Pavlo
  • 43,301
  • 14
  • 77
  • 113
  • It seems currently it works without a step="1"... should i still add it? – Arian Faurtosh Oct 07 '13 at 20:06
  • @Arian you may omit it as long as you don't specify `max` value. – Pavlo Oct 07 '13 at 20:12
  • 2
    Step 1 is the browser default, you're fine – Stephan Muller Oct 07 '13 at 20:12
  • 6
    This doesn't prevent typing in bad values still - if you omit the step value chrome reduces the validation it does when typing so you can enter non-numeric values. With step set it only lets you type in values outside of the min-max range - still wrong, but better. – David Burton Mar 03 '16 at 12:53
  • min="1" step="1" still allows me to type floating numbers like 1.2 How can I force integer only ? – Sam Jul 06 '16 at 10:10
  • This works; however, one can also type in a negative number. It does not stop one from typing the negative number. – Hello Universe Jun 07 '18 at 03:36
80

You can force the input to contain only positive integer by adding onkeypress within the input tag.

<input type="number" onkeypress="return event.charCode >= 48" min="1" >

Here, event.charCode >= 48 ensures that only numbers greater than or equal to 0 are returned, while the min tag ensures that you can come to a minimum of 1 by scrolling within the input bar.

Shubham Mittal
  • 1,545
  • 18
  • 21
34

You can turn negative input into a positive number by the following:

<input type="number" onkeyup="if(this.value<0){this.value= this.value * -1}">
10

You can use the following to make type="number" accept positive numbers only:

<input type="number" step="1" pattern="\d+">
Aliaksandr Sushkevich
  • 11,550
  • 7
  • 37
  • 44
Deepali
  • 97
  • 1
  • 5
  • 2
    Can you try to explain what your statement does and why it helps? Also, you have two different snippets. Which one is correct? – techfly Sep 28 '18 at 17:22
  • 2
    by adding step attribute, you restrict input to integer and adding the pattern ensures any use of a fractional portion gets the field marked as invalid but depends on browser implementations (Firefox marks the field as red upon the input losing focus whereas Chrome doesn't let you input disallowed values in the first place). One should validate this on the server/ client. – Deepali Sep 28 '18 at 19:33
  • 1
    This totally worked for me, but i think it only works for rounded numbers – WtFudgE Sep 11 '20 at 15:07
8

Try

<input type="number" pattern="^[0-9]" title='Only Number' min="1" step="1">

Rogerio de Moraes
  • 1,527
  • 18
  • 15
6

If you try to enter a negative number, the onkeyup event blocks this and if you use the arrow on the input number, the onblur event resolves that part.

<input type="number" 
    onkeyup="if(this.value<0)this.value=1"
    onblur="if(this.value<0)this.value=1"
>
Wictor Chaves
  • 957
  • 1
  • 13
  • 21
4

I cannot find the perfect solution as some work for inputting but not for copy&paste, some are the other way around. This solution works for me. It prevents from negative number, typing "e", copy&paste "e" text.

create a function.

<script language="JavaScript">

  // this prevents from typing non-number text, including "e".
  function isNumber(evt) {
    evt = (evt) ? evt : window.event;
    let charCode = (evt.which) ? evt.which : evt.keyCode;
    if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) {
      evt.preventDefault();
    } else {
      return true;
    }
  }
</script>

add these properties to input. this two prevent from copy&paste non-number text, including "e". you need to have both together to take effect.

<input type="number" oninput="validity.valid||(value='');" onpress="isNumber(event)" />

If you are using Vue you can refer this answer here. I have extracted it to a mixin which can be reused.

Arst
  • 3,098
  • 1
  • 35
  • 42
2

This solution might seem a little bit redundant, but takes care of every aspect.

In the form use this

<input type="number" min="0" (keypress)="onlyDigits($event)" >

and in the .ts define the function

onlyDigits(event) {
   let code = event.charCode;
   return (code >= 48 && code <= 57);
}

This ensures only positive numbers might be entered with the arrows. It also prevents typing of any non-digit char (including '-', '+' and 'e')

zeroquaranta
  • 392
  • 4
  • 16
  • But it doesn't prevent pasting content through mouse (right click). – AmigoJack Jan 08 '23 at 11:21
  • that is off topic – zeroquaranta Jan 09 '23 at 08:07
  • "_takes care of every aspect_" is misleading then: keyboard input is too restricted (what about the legal UP, DOWN, DELETE and BACKSPACE keys?) there are still possibilities to input non-numbers. Guarding more/other event handlers would be more effective and less overly restrictive. – AmigoJack Jan 09 '23 at 08:26
1

Other solution is to use Js to make it positive (min option can be disabled and is not valid when the user types smth) The negative if is not necessary and on('keydown') event can also be used!

let $numberInput =  $('#whatEverId');
$numberInput.on('change', function(){
    let numberInputText = $numberInput.val();
    if(numberInputText.includes('-')){
        $numberInput.val(Math.abs($numberInput.val()));
    }
});
Andres Paul
  • 1,020
  • 16
  • 18
  • `1e-3` is not a negative number despite having a minus ([scientific notation](https://stackoverflow.com/q/33132933/4299358)). – AmigoJack Jan 08 '23 at 11:19
1

If needing text input, the pattern works also

<input type="text" pattern="\d+">
ABDO
  • 130
  • 1
  • 6
1

Try this:

  • Tested in Angular 8
  • values are positive
  • This code also handels null and negitive values.
              <input
                type="number"
                min="0"
                (input)="funcCall()" -- Optional
                oninput="value == '' ? value = 0 : value < 0 ? value = value * -1 : false"
                formControlName="RateQty"
                [(value)]="some.variable" -- Optional
              />
1

The problem with type="number" and min="1" is that it allows typing or pasting the - sign, the e sign and the + sign.

The problem with the Math.abs(value) is that it replaces the whole typed in number with 0, which we don't want and is very frustrating.

The e.keyCode is very unreadable and deprecated.

The pure HTML method doesn't work in this case, you have to use JavaScript.

Remove the type="number" and do this:

function inputNumberAbs() {
  var input = document.getElementsByTagName("input")[0];
  var val = input.value;
  val = val.replace(/^0+|[^\d.]/g, '');
  input.value = val;
}
<input oninput="inputNumberAbs()">

Regex explanation:

^0+ removes all 0s from beginning

| OR operator

[^\d.] remove everything that is ^(NOT) a \d(NUMBER) or a .(PERIOD)

This prevents the user to type or paste any of the not defined characters, like e, -, +, and all other characters that are not numbers.

If you don't need decimal numbers just remove . from regex.

0

It depends on whether you want an int or float field. Here's what the two would look like:

<input type="number" name="int-field" id="int-field" placeholder="positive int" min="1" step="1">
<input type="number" name="float-field" id="float-field" placeholder="positive float" min="0">

The int field has the correct validation attached to it, since its min is 1. The float field accepts 0, however; to deal with this, you can add one more constraint validator:

function checkIsPositive(e) {
  const value = parseFloat(e.target.value);
  if (e.target.value === "" || value > 0) {
    e.target.setCustomValidity("");
  } else {
    e.target.setCustomValidity("Please select a value that is greater than 0.");
  }
}

document.getElementById("float-field").addEventListener("input", checkIsPositive, false);

JSFiddle here.

Note that none of these solutions completely prevent the user from trying to type in invalid input, but you can call checkValidity or reportValidity to figure out whether the user has typed in valid input.

Of course, you should still have server-side validation because the user can always ignore client-side validation.

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
0

I think using type text is best instead of number because using type=number, you will face some problems like arrow keys in input field and value change on up and down key.


<input type="text" onkeypress="return event.charCode>=48 && event.charCode<=57" />
Aman Bansal
  • 53
  • 1
  • 6
0

I created a directive in angular to force no '-' to be entered.

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

@Directive({
  selector: '[appPositiveNumber]'
})
export class PositiveNumberDirective {
  private regex = new RegExp(/^\d*[.,]?\d*$/g);
  private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', 'ArrowLeft', 'ArrowRight', 'Del', 'Delete'];

  constructor(private el: ElementRef) { }

  @HostListener('keydown', ['$event']) onKeyDown(event: KeyboardEvent) {
    if (!event.key.match(this.regex) && !this.specialKeys.includes(event.key)) {
      event.preventDefault();
      return;
    }
  }
}

So u can add it on the element like such:

<input type="number" appPositiveNumber min="0" step="1" max="9999"
      [(ngModel)]="value.employeeCount">
Hans Poppe
  • 323
  • 2
  • 10
0

Try this options and give min and max

 <input type="number" 
       pattern="\d+"    
       inputmode="numeric"                             
       value="123" 
       autocomplete="off" 
       maxlength="5"
       step="1" 
       min="0" 
       max="99999"
>
Ingo
  • 5,239
  • 1
  • 30
  • 24
  • Why `autocomplete`, `maxlength`, `step` and `max`? Nobody asked for those limitations and [a better answer was posted 5 years ago](https://stackoverflow.com/a/46334535/4299358) already. – AmigoJack Jan 08 '23 at 11:13
0

I have added this solution because it will save time for people

<input type=“number” onkeypress=“return (event.charCode>=48 && event.charCode<=57 || event.charCode==46) min=“0” >

The above code will restrict entering negative values and e letter In the above line we are allowing dot if you don’t need that you can remove OR condition code(|| event.charCode==46)

-1

<input type="number" min="1" step="1">
FRabbi
  • 135
  • 1
  • 6
-1

add this code in your input type;

onkeypress="return (event.charCode == 8 || event.charCode == 0 || event.charCode == 13) ? null : event.charCode >= 48 && event.charCode <= 57"

for example:

<input type="text" name="age" onkeypress="return (event.charCode == 8 || event.charCode == 0 || event.charCode == 13) ? null : event.charCode >= 48 && event.charCode <= 57" />
modsfabio
  • 1,097
  • 1
  • 13
  • 29
Sakawa Bob
  • 17
  • 3
-1

Use this.

onkeypress="return (event.charCode >= 48 && event.charCode <= 57 || event.charCode == 46)" 

You can enter whole numbers and decimal numbers.

-2

With text type of input you can use this for a better validation,

return (event.keyCode? (event.keyCode == 69 ? false : event.keyCode >= 48 && event.keyCode <= 57) : (event.charCode >= 48 && event.charCode <= 57))? true : event.preventDefault();
ANURAG GUPTA
  • 173
  • 1
  • 13
-3

(function ($) {
  $.fn.inputFilter = function (inputFilter) {
    return this.on('input keydown keyup mousedown mouseup select contextmenu drop', function () {
      if (inputFilter(this.value)) {
        this.oldValue = this.value;
        this.oldSelectionStart = this.selectionStart;
        this.oldSelectionEnd = this.selectionEnd;
      } else if (this.hasOwnProperty('oldValue')) {
        this.value = this.oldValue;
        //this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
      } else {
        this.value = '';
      }
    });
  };
})(jQuery);

$('.positive_int').inputFilter(function (value) {
  return /^\d*[.]?\d{0,2}$/.test(value);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="number" class="positive_int"/>

Above code works fine for all !!! And it will also prevent inserting more than 2 decimal points. And if you don't need this just remove\d{0,2} or if need more limited decimal point just change number 2

Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
-5

Try this:

Yii2 : Validation rule 

    public function rules() {
    return [
['location_id', 'compare', 'compareValue' => 0', 'operator' => '>'],
        ];
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129