Запретить input type = «number» в значении более одной точки и ограничить десятичные числа - PullRequest
0 голосов
/ 28 мая 2020

Перед: Я знаю, что этот вопрос задавали на этом форуме более одного раза. Я знаю, что могу опубликовать свой ответ в других сообщениях. Моя проблема в том, что пользователи, которые задавали эти вопросы, делали это 3-4 года go, и, глядя на профиль своих авторов, они не выглядят очень активными, и я верю, что вопросы никогда не будут отмечены как решенные.

Итак, я искал повсюду, чтобы найти помощь в том, чтобы сделать именно это, без простых решений, позволяющих ограничить пользователя от ввода более одной точки во входном поле type = «number». Важно сохранить input type = "number", так как это может повлиять на клавиатуру на некоторых мобильных устройствах.

Я знаю, что предотвращение события клавиатуры может показаться ограничивающим, и некоторые могут возразить, что поле должно оцениваться только при отправке, изменении или размытии. Я говорю, что input type = "number" уже ограничивает эффекты некоторых нажатий клавиш, которые не являются числами, или "e" или ".", И это происходит на лету.

Вдобавок к этому, некоторые решения сделал невозможным ограничение разрешенного количества операций с плавающей запятой.

1 Ответ

0 голосов
/ 28 мая 2020

Вы можете найти очень подробные объяснения в этом Codepen

Это простое решение, допускающее только одну точку в числовом поле. Это не мешает вернуться к номеру и добавить числа перед ".". Это не мешает запускать сочетания клавиш браузера, такие как refre sh, копировать и вставлять (если вставленное значение является допустимым числом) и другие. Это позволит добавить "." в тело числа, но удалит все превышающие установленный предел.

Единственное поведение, которое я все еще не могу предотвратить, - это если вы нажмете клавишу с точкой в конец ввода несколько раз, точка будет мигать и гаснет. Это происходит потому, что типизированное значение "13." является допустимым числом и возвращает "13", а типизированное значение "13.." не является и возвращает "". В моем решении, если значение возвращает "" без нажатия клавиши возврата или удаления, оно возвращается к последнему допустимому значению, которое составляет "13", полученному из введенного значения "13.".

Я пробовал решения, в которых, если точка была нажата один раз, ее нельзя было запустить во второй раз, но каждый раз мне удавалось застревать, нажимая точку сразу после уже существующей точки, за которой ничего не было а затем застрял в том, что не смог ввести точку, если сначала не нажал любую другую клавишу.

Я думаю, что мигание при многократном нажатии - лучшее решение, поскольку пользователь не набирает точку, и ничего не происходит .

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)">
...