Tomas Dohnal
Tomas Dohnal

Reputation: 2025

HTML number input min and max not working properly

I have type=number input field and I have set min and max values for it:

<input type="number" min="0" max="23" value="14">

When I change the time in the rendered UI using the little arrows on the right-hand side of the input field, everything works properly - I cannot go either above 23 or below 0. However, when I enter the numbers manually (using the keyboard), then neither of the restrictions has effect.

Is there a way to prevent anybody from entering whatever number they want?

Upvotes: 125

Views: 199875

Answers (22)

Ilker Aykut
Ilker Aykut

Reputation: 81

oninput="if(this.value>your_max_number) this.value=your_max_number;"

This works properly for me.

Upvotes: 5

Ali Sheikhpour
Ali Sheikhpour

Reputation: 11096

This code will remove the last digit enetered by user to keep the value in the range. In some cases it may be more helpful instead of jumping to MAX. For minimum I think still better to jump to MIN.

$(document).ready(function() {
  $('#minmax').on('keyup', function() {
    var inputValue = parseInt($(this).val());
    var minValue = parseInt($(this).attr('min'));
    var maxValue = parseInt($(this).attr('max'));

    if (inputValue < minValue) {
      $(this).val(minValue);
    } else if (inputValue > maxValue) {
      // Remove the last digit to bring the value within the range
      $(this).val(function(_, value) {
        return value.slice(0, -1);
      });
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="minmax" type="number" min="0" max="23" value="14" />

jquery compact form just in case:

$(document).ready(function(){$("#minmax").on("keyup",function(){var a=parseInt($(this).val()),b=parseInt($(this).attr("min")),c=parseInt($(this).attr("max"));a<b?$(this).val(b):a>c&&$(this).val(function(a,b){return b.slice(0,-1)})})});

Vanilla JS:

document.addEventListener("DOMContentLoaded",function(){document.getElementById("minmax").addEventListener("keyup",function(){var e=parseInt(this.value),t=parseInt(this.min),n=parseInt(this.max);e<t?this.value=t:e>n&&(this.value=this.value.slice(0,-1))})});

Upvotes: 0

Peter
Peter

Reputation: 2270

Had similar issue but in my case i had a save button as well.n People could enter a wrong number and after lost focus the value stays.

If the number was too low or too high then in that case the save button set it to its max or min value, (and then directly after that return, not yet saving it), i made save only work with valid values.

Not to save it was just a choice one could also directly save it. Its just another way how one can solve it.

As I didn't want to mix javascript (which can solve this) with typescript. I do understand angular typescript gets compiled to javascript but thats another topic.

Also i am aware that with angular based forms you can solve this differently. (in my case it had to be on a form but wasnt part, of it but had some relations with it, i'll spare the details or a rare case)

Upvotes: 0

Shubham Lohar
Shubham Lohar

Reputation: 51

You can use html keyup event for restriction

<input type="number" min="0" max="23" value="14" onkeyup="if(value<0) value=0;if(value>23) value=23;">

Upvotes: 2

Mohammad Komaei
Mohammad Komaei

Reputation: 9656

<input type="number" min="0" onkeyup="if(value<0) value=0;" />

Upvotes: 17

Vincent
Vincent

Reputation: 2169

Despite the HTML5 enforcement of min and max on the up/down arrows of type=number control, to really make those values useful you still have to use Javascript.

Just save this function somewhere and call it on keyup for the input.

function enforceMinMax(el) {
  if (el.value != "") {
    if (parseInt(el.value) < parseInt(el.min)) {
      el.value = el.min;
    }
    if (parseInt(el.value) > parseInt(el.max)) {
      el.value = el.max;
    }
  }
}
<input type="number" min="0" max="23" value="14" onkeyup=enforceMinMax(this)>

Upvotes: 31

Nitin Ramnani
Nitin Ramnani

Reputation: 312

You can compare keyCode and return false if those keys aren't numbers

for e.g

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
    <script>
      function handleKeyDown(e) {
        if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
          e.preventDefault();
          return false;
        }
      }
    </script>
  </head>

  <body>
    <input type="number" min="0" max="23" value="14" onkeydown="handleKeyDown(event)" />
  </body>
</html>

Upvotes: -1

Gon&#231;alo
Gon&#231;alo

Reputation: 13

$(function () {
  $("input").keydown(function () {
    // Save old value.
    if (!$(this).val() || (parseInt($(this).val()) <= 11 && parseInt($(this).val()) >= 0))
    $(this).data("old", $(this).val());
  });
  $("input").keyup(function () {
    // Check correct, else revert back to old value.
    if (!$(this).val() || (parseInt($(this).val()) <= 11 && parseInt($(this).val()) >= 0))
      ;
    else
      $(this).val($(this).data("old"));
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="number" min="0" max="23" value="14" />

Upvotes: 0

user2061057
user2061057

Reputation: 1022

In some cases pattern can be used instead of min and max. It works correctly with required.

Upvotes: 13

Carsten Massmann
Carsten Massmann

Reputation: 28206

Here is my Vanilla JS approach of testing against the set min and max values of a given input element if they are set.

All input.check elements are included in the input check. The actual input check is triggered by the change event and not by keyup or keydown. This will give the user the opportunity to edit their number in their own time without undue interference.

const inps=document.querySelectorAll("input.check");
inps.forEach(inp=>{
 // memorize existing input value (do once at startup)
 inp.dataset.old=inp.value;
 // Carry out checks only after input field is changed (=looses focus)
 inp.addEventListener("change",()=>{
   let v=+inp.value;
   // console.log(v,inp.min,inp.max,inp.dataset.old);
   if(inp.max!=""&&v>+inp.max || inp.min!=""&&v<+inp.min) inp.value=inp.dataset.old;
   else inp.dataset.old=inp.value;
 });
})
<input class="check" type="number" min="0.1" max="23.4" value="14" />

Upvotes: 0

Roberto Sep&#250;lveda
Roberto Sep&#250;lveda

Reputation: 415

Solution to respect min and max if they are defined on an input type=number:

$(document).on("change","input[type=number][min!=undefined]",function(){if($(this).val()<$(this).attr("min")) $(this).val($(this).attr("min"))})
$(document).on("change","input[type=number][max!=undefined]",function(){if($(this).val()>$(this).attr("max")) $(this).val($(this).attr("max"))})

Upvotes: 0

Ambuj Singh
Ambuj Singh

Reputation: 31

This works for me I think you should try this you change the pattern according to your need like you start from pattern 1

<input type="number" pattern="[0-9]{2}" min="0" max="23" value="14">

Upvotes: 3

SKLTFZ
SKLTFZ

Reputation: 950

Again, no solution truly solved my question. But combined the knowledge, it somehow worked

What I wanted is a true max/min validator (supporting int/float) for my input control without fancy html5 help

Accepted answer of @Praveen Kumar Purushothaman worked but its hardcoded min/max in the checking condition

@Vincent can help me dynamically validate the input field by max/min attributes but it is not generic and only validating the integer input.

To combine both answer Below code works for me

function enforceMinMax(el){
  if(el.value != ""){
    if(parseFloat(el.value) < parseFloat(el.min)){
      el.value = el.min;
    }
    if(parseFloat(el.value) > parseFloat(el.max)){
      el.value = el.max;
    }
  }
}

$(function () {
    $("input").keydown(function () {
        enforceMinMax(this);
    });
    $("input").keyup(function () {
        enforceMinMax(this);
    });
});

For the DOM

<input type="number" min="0" max="1" step=".001" class="form-control">

Afterwards all my inputs are truly responsive on the min max attributes.

Upvotes: 0

stefo91
stefo91

Reputation: 618

This work perfect for geographic coordinates when you have general function document EventListener "keydown" in my example i use bootstrap class.

<input type="text" name="X_pos" id="X_pos" class="form-control form-control-line" onkeydown="event.stopPropagation(); return(parseInt(event.key) >= 0 && parseInt(event.key) <= 9 && this.value+''+event.key <= 179 && this.value+''+event.key >= (-179)) || this.value.slice(-1) == '.' && parseInt(event.key) >= 0 && parseInt(event.key) <= 9 || event.keyCode == 8 || event.keyCode == 190 && String(this.value+''+event.key).match(/\./g).length <=1 || event.keyCode == 109 && String(this.value+''+event.key).length == 1 || event.keyCode == 189 && String(this.value+''+event.key).length == 1" style="width:100%;" placeholder="X" autocomplete="off">

If you want you can create a function with this code but i preferred this method.

Upvotes: 0

Pars
Pars

Reputation: 5272

One event listener, No data- attribute.

You can simply prevent it by using following script:

$(document).on('keyup', 'input[name=quantity]', function() {
  var _this = $(this);
  var min = parseInt(_this.attr('min')) || 1; // if min attribute is not defined, 1 is default
  var max = parseInt(_this.attr('max')) || 100; // if max attribute is not defined, 100 is default
  var val = parseInt(_this.val()) || (min - 1); // if input char is not a number the value will be (min - 1) so first condition will be true
  if (val < min)
    _this.val(min);
  if (val > max)
    _this.val(max);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" class="form-control" name="quantity" max="250" min="1" value="">

The only problem is: You can't type - to get negative numbers if your min is lower than 0

Upvotes: 3

$(document).on('keyup', 'input[type=number][min],input[type=number][max]', function () {
    var _this = $(this);
    if (_this.val() === "-")
        return;

    var val = parseFloat(_this.val());

    if (_this.attr("min") !== undefined && _this.attr("min") !== "") {
        var min = parseFloat(_this.attr('min'));

        if (val < min)
            _this.val(min);
    }
    if (_this.attr("max") !== undefined && _this.attr("max") !== "") {
        var max = parseFloat(_this.attr('max'));

        if (val > max)
            _this.val(max);
    }
});
$(document).on('change', 'input[type=number][step]', function () {
    var _this = $(this);

    var val = parseFloat(_this.val());

    if (_this.attr("step") !== undefined && _this.attr("step") !== "") {
        var step = parseFloat(_this.attr('step'));

        if ((val % step) != 0)
            _this.val(val - (val % step));
    }
});

Upvotes: 0

horiatu
horiatu

Reputation: 392

Forget the keydown or keyup: it won't let you enter like 15 or 20 if the min was set to 10! Use the change event since this is where the input value goes in your business logic (ViewModel):

private _enforceMinMax = (input:HTMLInputElement) => {
    console.log("input", input);
    const v = parseFloat(input.value);
    if(input.hasAttribute("min")) {
        const min = parseFloat(input.min);
        if(v < min) {
            input.value = min+"";
        }
    }
    if(input.hasAttribute("max")) {
        const max = parseFloat(input.max);
        if(v > max) {
            input.value = max+"";
        }
    }
}

private _distanceChange = (event) => {
    this._enforceMinMax(event.target);
    ...

Upvotes: 0

CreativeMinds
CreativeMinds

Reputation: 343

Use this range method instead of number method.

$(function () {
  $("#input").change(function () {
    // Save old value.
    $("#limit").val($("#input").val());
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text" id="limit" name="limit" value="14" readonly><br>
<input type="range" id="input" name="input" min="0" max="23" value="14"/>

Upvotes: 0

Antony
Antony

Reputation: 4364

$(document).ready(function(){
    $('input[type="number"]').on('keyup',function(){
        v = parseInt($(this).val());
        min = parseInt($(this).attr('min'));
        max = parseInt($(this).attr('max'));

        /*if (v < min){
            $(this).val(min);
        } else */if (v > max){
            $(this).val(max);
        }
    })
})

Here is my contribution. Note that the v < min is commented out because I'm using Bootstrap which kindly points out to the user that the range is outside the 1-100 but wierdly doesn't highlight > max!

Upvotes: 6

Praveen Kumar Purushothaman
Praveen Kumar Purushothaman

Reputation: 167212

With HTML5 max and min, you can only restrict the values to enter numerals. But you need to use JavaScript or jQuery to do this kind of change. One idea I have is using data- attributes and save the old value:

$(function () {
  $("input").keydown(function () {
    // Save old value.
    if (!$(this).val() || (parseInt($(this).val()) <= 11 && parseInt($(this).val()) >= 0))
    $(this).data("old", $(this).val());
  });
  $("input").keyup(function () {
    // Check correct, else revert back to old value.
    if (!$(this).val() || (parseInt($(this).val()) <= 11 && parseInt($(this).val()) >= 0))
      ;
    else
      $(this).val($(this).data("old"));
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="number" min="0" max="23" value="14" />

Upvotes: 18

autodidact
autodidact

Reputation: 84

if you still looking for the answer you can use input type="number".
min max work if it set in that order:
1-name
2-maxlength
3-size
4-min
5-max
just copy it

<input  name="X" maxlength="3" size="2" min="1" max="100" type="number" />

when you enter the numbers/letters manually (using the keyboard), and submit a little message will appear in case of letters "please enter a number" in case of a number out of tha range "please select a value that is no more/less than .."

Upvotes: -5

George Wilson
George Wilson

Reputation: 251

Maybe Instead of using the "number" type you could use the "range" type which would restrict the user from entering in numbers because it uses a slide bar and if you wanted to configure it to show the current number just use JavaScript

Upvotes: 21

Related Questions