简体   繁体   中英

Trying to prevent invalid keypushes (not numbers) and multiple decimal points

So far I use this to call the function:

 document.getElementById("dzCalculator").addEventListener("keydown", isNumberKey);
   function isNumberKey(txt, evt) {
      let charCode = (evt.which) ? evt.which : evt.keyCode;
      if (charCode == 46) {
          evt.preventDefault();
        //Check if the text already contains the . character
        if (txt.value.indexOf('.') === -1) {
          return true;
        } else {
          return false;
        }
      } else {
        if (charCode > 31 &&
          (charCode < 48 || charCode > 57))
          return false;
      }
      return true;
    }

But unfortunately I get errors: Uncaught TypeError: evt is undefined

I am still very much in the learning phase, so I am not seeing what I am missing yet. Thanks very much for your help.

The addEventListener passes only the event that triggered it to the passed callback so in your case txt is holding the event and evt is undefined.

You can extract the txt value of the input by using evt.target.value .

document.getElementById("dzCalculator").addEventListener("keydown", isNumberKey);
   function isNumberKey(evt) {
      let txt = evt.target.value;

      //...

As for the rest of your logic, there are some good answers already available:

HTML text input allow only numeric input


Since you are still looking for a solution to limit input I will offer this. Instead of controlling the keys allowed, you can validate the value after keyup. Using an input listener we can watch for changes and validate without seeing invalid characters show while also solving the overarching problem of maintaining expected functionality and accessibility without having to specify all key responses.

This snippet listens for changes using input . When triggered it extracts the current value using event.target.value and stores the current cursor position. It then recasts the string to an array using destructuring [...value] . This array is then filtered using filter() so that it only contains characters that appear in the validKeys string. It is then reduced back to a string using reduce() at which time it accounts for duplicate decimal points. If the resulting editedValue is different than the initial value the evt.target.value is updated and the cursor is set back to where it was (minus one because we have removed a character);

 document.getElementById("dzCalculator").addEventListener("input", isNumberKey); function isNumberKey(evt) { const validKeys = '1234567890.'; const cursorLocation = evt.target.selectionStart; const value = evt.target.value; let editedValue = [...value] .filter(char => validKeys.includes(char)) .reduce((acc, char) => { return acc.includes('.') && char === '.' ? acc : acc + char}, ''); if (editedValue !== value) { evt.target.value = editedValue; evt.target.selectionStart = cursorLocation-1; evt.target.selectionEnd = cursorLocation-1; } }
 <input id="dzCalculator" value="" />

To accomodate negative values you can adjust validKeys and the reduce() callback thus:

const validKeys = '-1234567890.';
  let editedValue = [...value]
    .filter(char => validKeys.includes(char))
    .reduce((acc, char, i) => { 
        if (acc.includes('.') && char === '.' || char === '-' && i !== 0) {
        return acc
      } else {
        return acc + char
      }
    }, '');

I have written pretty simple logic to allow only numerical input and restrict inputs with one dot only.

 document.getElementById("dzCalculator").addEventListener("keydown", isNumberKey); function isNumberKey(evt) { let passCode = '0123456789.' if (passCode.indexOf(evt.key)===-1 && evt.key !=='Backspace' && evt.key !== 'Tab'&& evt.key !=='Delete'){ evt.preventDefault(); return false; }else{ //contains numbers && dots if (evt.target.value.indexOf('.') >= 0 && (evt.key === ".")) { //check for multiple dots evt.preventDefault(); return false; } else return true; } }
 <input id='dzCalculator' type='text'>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM