Ensure a positive integer number in input

旧街凉风 提交于 2021-02-07 10:51:41

问题


I have an HTML input element for positive integer numbers. I need to evaluate this input field and ensure that only proper values are inserted.

function exampleFunction(event, element) {

  // If event is not backspace and Not a Number
  if (event.which != 8) {

    //If the event is Not a Number
    if (isNaN(String.fromCharCode(event.which))) {

      // Cancels the event
      event.preventDefault();
    }
    //If the length reached the limit
    else {

      var value = document.getElementById(element.id).value;
      var maxLength = document.getElementById(element.id).maxLength;
      var valueLength = document.getElementById(element.id).value.length;

      if (valueLength >= maxLength) {

        // Cancels the event
        event.preventDefault();
      } else {

        // Convert the value to a number and back to string. This means leading 0 will be gone.
        document.getElementById(element.id).value = Number(value);
      }
    }
  }

};
<input id="exampleInput" type="number" value="0" min="0" step="1" maxlength="5" onkeypress="exampleFunction(event, this)">

purposes:

  • default value is 0
  • only numbers shall be accepted
    • no decimal value .,
    • no other characters +-e
  • the input can come from:
    • typing
    • copy
  • backspace and delete can also modify the value
  • length of input shall also be limited for 5 character length
  • leading 0 shall be eliminated after a proper new value

Problems:

  • the default value is 0 and leading zeros are not immediately deleted, only after the second number is typed
  • with ctrl+v .,+-e characters can be inserted

Question: Is any better solution for my purposes? If it is jQuery related, it is also acceptable.

Maybe I am not using the proper event. I tried also to handle the input event but it is not possible to evaluate the input text. I am not sure if I make this too complicated, or the solution would be much more complex than I think.


回答1:


I suggest you to use .addEventListener() instead of the inline event handler.

So to the same input element, you can add more than one event. To do what you wish to do, there are three events implied:

  • keydown to prevent the not allowed keys
  • contextmenu for mouse pasting
  • input to parseInt the value

The below snippet is restricting the input to nubers only. No dot, minus sign, e or whatever except numbers are allowed.

Pasting can be done via [CTRL]+[v] or the mouse contextmenu. In both cases, I assume the previous value of the input should be squarely cleared.

I took the pasted negative numbers case in account using Math.abs().

// Get the element
let myInput = document.querySelector("#exampleInput")

// This event handler only allows numbers, backspace and [ctrl]+[v]
myInput.addEventListener("keydown", function(event) {

  console.log("Key:", event.key)

  // If this is to be a keyboard paste [CTRL]+[v],
  // squarely clears the input value before the paste is done
  if (event.ctrlKey && event.key === "v") {
    console.log("keyboard paste")
    this.value = ""
    return;
  }

  // If the key is not backspace, but is NAN, it is not a number.
  // In short, only a number OR a backspace is allowed at this point.
  if (event.key !== "Backspace" && isNaN(event.key)) {
    event.preventDefault();
    console.log(" --------- Event prevented")
  }

});

// This handler is for "mouse pastes"
// It squarely clears the input value before the paste is done
myInput.addEventListener("contextmenu", function(event) {
  this.value = ""
})

// This handler fixes the value length and parses as a positive integer
myInput.addEventListener("input", function(event) {

  console.log("Original value", this.value)

  // Get the maxlength attribute value
  var maxLength = parseInt(this.maxLength)

  // ParseInt the value (will remove any leading zero) and ensure it is positive
  // Then keep just the [maxlength] first characters.
  var value = Math.abs(parseInt(this.value)).toString().slice(0, maxLength)
  console.log("Fixed value", value)
  this.value = value;
});
<input id="exampleInput" type="number" value="0" min="0" step="1" maxlength="5">



回答2:


Here we go with a JQuery solution

Features:

  • Remove default "0" on focus.
  • Set maximum length to (5)
  • Allowed numeric content only and Backspace, Del, Home, End, Arrow-Left, Arrow-Right, ctrl+v, ctrl+c, ctrl+a buttons.
  • Check if the copied text contains any numeric value and collect it and remove non-numeric values.
  • Check if pasted text length + current value length are meeting maximum length

$(document).ready(function() {
  //Remove default "0" ONLY! when focus at the input.
  $("#exampleInput").on('focus', function() {
    var oldval = $("#exampleInput").val();
    if (oldval < 1) {
      $("#exampleInput").val("");
    }
  });
  /* SET CTRL+V , CTRL+C funciton */

  var ctrlprs = false,
    ctrlk = 17,
    mccmd = 91,
    vk = 86,
    ak = 65,
    ck = 67;
    
  $(document).keydown(function(e) {
    if (e.keyCode == ctrlk || e.keyCode == mccmd) ctrlprs = true;
  }).keyup(function(e) {
    if (e.keyCode == ctrlk || e.keyCode == mccmd) ctrlprs = false;
  });

  //Listen to the input in keydown

  $("#exampleInput").on('keydown', function(e) {
    var txt = $("#exampleInput").val();
    //exceptions for [b-space,end,home,left,right,del]
    var keys = [8, 35, 36, 37, 39, 46];
    var rgx = $.inArray(e.which, keys) < 0;
    var cnvrt = String.fromCharCode(e.which);
/* allow CTRL + "a or c or v" */
 if (ctrlprs && ((e.keyCode == ck) || (e.keyCode == ak) || (e.keyCode == vk))) {
 
    } else if ((txt.length == 5) || (cnvrt.match(/[^0-9]/)) || (e.shiftKey)) {
      if ((rgx)) {
        e.preventDefault();
            /* prevent all text except numbers, and set max input value length to (5) */
      }
    } 
  });

  /*Bind a paste function to check if clipboard data met with requirements or not.*/
  $("#exampleInput").on('paste', function(e) {
    var oldl = $("#exampleInput").val();
    var oldval = e.originalEvent.clipboardData.getData('text');
    if (oldval.match(/[0-9]{1,5}$\d/g)) {} else {
      //remove all non-numeric text from clipboard text.
      var newvar = oldval.replace(/\D/g, "");
      setTimeout(function() {
        //check if ( clipboard[Numeric only] + input value ) length equals or less than (5). 
        var totlen = oldl.length + newvar.length;
        if (newvar.length > 0 && totlen <= 5) {
          $("#exampleInput").val(oldl + newvar);
        } else {
          //if total length is more than (5) keep the input value before paste.
          console.log("total length is : " totlen);
          $("#exampleInput").val(oldl);
        }
      }, 1);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="exampleInput" type="number" value="0" min="0" step="1" maxlength="5">


来源:https://stackoverflow.com/questions/65970004/ensure-a-positive-integer-number-in-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!