Prevent input type=“number” from getting more than one dot in its value and limit decimals numbers

為{幸葍}努か 提交于 2020-06-07 07:38:45

问题


Inbefore: I know this question has been asked more than once on this forum. I know I could post my answer on these other posts. My issue is that the users who asked those questions did it 3 - 4 years ago, and looking at their autors profile, they do not seem very active and I beleive the questions would never be marked as solved.

So I've been looking around every where to find help on doing exactly that, with no simple solutions allowing to limit the user from typing more than one dot in an input type=“number”. It is important to keep the input type="number" as it may affect the keyboard on certain mobile devices.

I know it might seem limitative to prevent a keyboard event, and some might argue that the field should only be evaluated on submit or on change or on blur. I say the input type="number" already limits the effects of certain keypresses that are anything but numbers or "e" or ".", and that happens on the fly.

On top of it, some solutions made it impossible to limit the amount of floats allowed.


回答1:


You can find very detailed explainations in this Codepen

This solution is simple and will only allow one dot in the number field. It doesn't prevent from clicking back in the number and adding numbers before the ".". It doesn't prevent from executing browser keyboard shortcuts like refresh, copy and pasting (as long as the pasted value is a valid number) and others. It will allow to add "." withing the body of the number, but will remove any exceeding floats over the set limit.

The only behavior that I still can't prevent is if you press the dot key at the end of the input repeatedly, the dot will blink on and off. This happens because a typed value of "13." is a valid number and returns "13" and a typed value of "13.." is not and returns "". In my solution, if a value returns "" without the press of backspace or delete, it gets rolled back to the last valid value, wich is "13", obtained from the typed value "13.".

I've tried solutions where if a dot was pressed once, it was prevented to be triggered a second time, but every time I managed to get stuck with pressing the dot right after an already existing dot followed by nothing and then get stuck with not being able to type a dot unless I pressed any other key first.

I think the blinking on multiple press is the best solution for ther's no way a user would type a dot and nothing happens.

let lastValidInputValue;
let selectedDot = false;


const onKeypress = (e) => {
  if (e.key === "." && e.target.value.indexOf(".") !== -1 && !selectedDot) e.preventDefault();
  selectedDot = false;

  if (e.key === "e") e.preventDefault();
};


const onInput = (e) => {
  if (
    e.target.value.indexOf(".") < e.target.value.length - e.target.getAttribute("data-toFixed") - 1 &&
    e.target.value.indexOf(".") !== -1
  ) {
    let newValue;
    newValue = e.target.value.slice(
      0,
      e.target.value.indexOf(".") +
        parseInt(e.target.getAttribute("data-toFixed")) +
        1
    );
    newValue = parseFloat(newValue);
    e.target.value = newValue;
  }
  if (e.target.value !== "") {
    lastValidInputValue = e.target.value;
  } else if (e.inputType.match(/delete/g)) {
    lastValidInputValue = "";
  } else {
    e.target.value = lastValidInputValue;
  }
};

 const onSelect = (e) => {
   if(window.getSelection().toString().indexOf(".") > -1) selectedDot = true;
 }
<input type="number" id="myNumber" name="myNumber" data-toFixed="2" step="any" onkeypress="onKeypress(event)" oninput="onInput(event)" onselect="onSelect(event)">


来源:https://stackoverflow.com/questions/62070691/prevent-input-type-number-from-getting-more-than-one-dot-in-its-value-and-limi

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