Preventing user from entering negative numbers in input elements with number type

10,395

Solution 1

You were only adding the event listeners to the first number input.

https://jsfiddle.net/tpsbnp9q/5/

var myInput = document.querySelectorAll("input[type=number]");

function keyAllowed(key) {
  var keys = [8, 9, 13, 16, 17, 18, 19, 20, 27, 46, 48, 49, 50,
    51, 52, 53, 54, 55, 56, 57, 91, 92, 93
  ];
  if (key && keys.indexOf(key) === -1)
    return false;
  else
    return true;
}

myInput.forEach(function(element) {
  element.addEventListener('keypress', function(e) {
    var key = !isNaN(e.charCode) ? e.charCode : e.keyCode;
    if (!keyAllowed(key))
      e.preventDefault();
  }, false);

  // Disable pasting of non-numbers
  element.addEventListener('paste', function(e) {
    var pasteData = e.clipboardData.getData('text/plain');
    if (pasteData.match(/[^0-9]/))
      e.preventDefault();
  }, false);
})

Solution 2

Usually just using the min="0" attribute on a type="number" field should be enough.

<input type="number" min="0" step="0.1" name="whatever" />

If you need to stick to <input type="text" /> or support very old browsers or want to make sure users dont enter negative numbers via keyboard (possible with min="0" on some browsers), with jQuery you can overwrite negative values on focusOut for all inputs having a specific class attribute with the following code:

$(document).ready(function(){
    $("body").on('focusout', '.my-input-number-positive', function(){
        if($(this).val() < 0){
            $(this).val('0'); // alternatively show a hint – or whatever
        }
    });
});

This does not replace server side validation!

Share:
10,395
mcclosa
Author by

mcclosa

Updated on July 22, 2022

Comments

  • mcclosa
    mcclosa almost 2 years

    I have got the following code from another question on here on how to prevent users from entering negative numbers, however it covered all inputs. I have 2 number type input elements and 2 text type input elements. I obviously want to allow the user to add any character to the text fields but want to prevent users entering negative numbers/non number content to the number inputs.

    My code below works for one input with the number type and not the other. How would I go about changing my code to allow it for the other number input? Any help would be greatly appreciated.

    HTML

    <div class="cpNewTemplateDetailsWrap">
        <div class="col-sm-3">
            <label>Course Id</label>
        </div>
        <div class="col-sm-9">
            <input id="courseIdInput" type="text" class="form-control input-lg" placeholder="e.g. CT001" />
        </div>
        <div class="col-sm-3">
            <label>Course Description</label>
        </div>
        <div class="col-sm-9">
            <input id="courseDescInput" type="text" class="form-control input-lg" placeholder="e.g. Cadet Training" />
        </div>
        <div class="col-sm-3">
            <label>Course Duration <small>(Days)</small>
            </label>
        </div>
        <div class="col-sm-9">
            <input id="courseDurationInput" type="number" min="0" class="form-control input-lg" placeholder="5" />
        </div>
        <div class="col-sm-3" id="courseDemandTitle">
            <label>Course Demand</label>
        </div>
        <div class="col-sm-9">
            <input id="courseDemandInput" type="number" min="0" class="form-control input-lg" placeholder="5" />
        </div>
    </div>
    

    Javascript

    var myInput = document.querySelectorAll("input[type=number]")[0];
    myInput.addEventListener('keypress', function(e) {
      var key = !isNaN(e.charCode) ? e.charCode : e.keyCode;
      function keyAllowed() {
        var keys = [8,9,13,16,17,18,19,20,27,46,48,49,50,
                    51,52,53,54,55,56,57,91,92,93];
        if (key && keys.indexOf(key) === -1)
          return false;
        else
          return true;
      }
      if (!keyAllowed())
        e.preventDefault();
    }, false);
    
    // Disable pasting of non-numbers
    myInput.addEventListener('paste', function(e) {
      var pasteData = e.clipboardData.getData('text/plain');
      if (pasteData.match(/[^0-9]/))
        e.preventDefault();
    }, false);
    

    JS Fiddle Here!

    Edit

    With some of the duplicate questions, they cover just one input or all inputs. I just want to prevent negative numbers of 2 inputs. And if I wanted to add more input elements with a number type, I don't want to repeat code for each iteration. For example if I had 12 more inputs, I don't want to use that code 12 more times.

    • Dylan Meeus
      Dylan Meeus over 7 years
      Keep in mind that preventing the user from this client-side is not a guarantee that they will not be entered. You'll also need server-side checks for this. (The users can mess with anything on their client, including your javascript)
    • mcclosa
      mcclosa over 7 years
      @DylanMeeus I do have server-side checks for this, would just also like to prevent it on the front end too
    • gcampbell
      gcampbell over 7 years
      You've already set a min attribute.
    • Pugazh
      Pugazh over 7 years
    • mcclosa
      mcclosa over 7 years
      @gcampbell This only prevents a user from not selecting a negative number using the arrow keys, a user can still enter -1 into the input
    • Manoj
      Manoj over 7 years
      This question hav been answered here. stackoverflow.com/questions/31575496/…
    • epascarello
      epascarello over 7 years
      If you want to have it attached to all inputs, than you need to attach the code to all the inputs.
    • mcclosa
      mcclosa over 7 years
      @ManojYadav I had looked at the question previously, however like most others, it covers all/just one input(s) and not a selected few which is what I am having problems with
    • DANIEL
      DANIEL over 7 years
      @mcclosa I post another solution for you, see if its what you want. good luck!
  • mcclosa
    mcclosa over 7 years
    Yeah, I was trying to avoid the repeated code, I did see this as the issue. Is there no method of selecting all of the inputs in my document with a type of number?
  • ManFox
    ManFox over 7 years
    The first line does exactly that and then selects one of them, if you remove the [0] then it will return an array of all the number inputs on the page.
  • mcclosa
    mcclosa over 7 years
    When I do remove the [0] it allows me to enter -1 into both inputs
  • ManFox
    ManFox over 7 years
    Well yes it will, you would have to take the array and loop through it adding event listeners to each element. (I feel like there is certainly a better way to do that, but it is one way)
  • mcclosa
    mcclosa over 7 years
    Yeah, that's what I'm doing at the minute, but say if I had 4 more number type inputs, it will get a little messy, hopefully I will find a better resolution for this but adding event listeners to each statement will do for now
  • Hafenkranich
    Hafenkranich almost 7 years
    Thanks for throwing in addEventListener('paste', function(){});