Home > OS >  How to avoid 'NaN' message in html input
How to avoid 'NaN' message in html input

Time:06-07

Right now I have the following code implemented:

$(document).ready(function() {   
    let maximumFractionDigits = 2;
    var valueInput = $("#exampleInput");
    
    const formatNumber = (value) => {
      return parseFloat(value.replace(/,/g,'')).toLocaleString('en-US', { maximumFractionDigits });
    }
    
    valueInput.on('input', function() {
      if (!this.value || (maximumFractionDigits && this.value.endsWith('.'))) {
        return
      }
      $(this).val(formatNumber(this.value));
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="exampleInput"  aria-label="Grant Amount" type="text" placeholder="0" name="price" required="">

It works fine and does what I want: when the user enters more than 3 digits the thousand comma separator is added and two decimal places are allowed (USD format).

However, if the user enters some number in another charset, for example with a Japanese keyboard, or any unexpected char the following message appears:

'NaN'

Expected outcome:

If the user enters an invalid character, it should not appear in the input (I want to avoid NaN message), for example if I enter 'a' nothing will appear in the input.

What I've tried:

Somehow I tried to use the isNaN function but my approach is definitely wrong.

const formatNumber = (value) => {
  if (isNaN(value)){
    return 0;
  } else{
    return parseFloat(value.replace(/,/g,'')).toLocaleString('en-US', { maximumFractionDigits });
  }
}

If anyone could help me I would really appreciate it

CodePudding user response:

Well the solution is simple you must check the character right before the input event, which is the keypress event.

valueInput.keypress(
    /**
     * Handle the keypress event on valueInput.
     * 
     * Used to filter in only the numbers. 
     */
    function(e) {
        var keyCode = e.which
        if ((keyCode >= 32 && keyCode <= 43) 
           || keyCode == 45
           || keyCode == 47
           || (keyCode >= 58 && keyCode <= 126))
            return false
    }
);

keyCode is just the ASCII code of the key that is pressed:

  • from 32 to 47 these are all symbols. (44 is , character and 46 is . character)
  • from 58 to 126 these are all other symbols, letters, and parentheses.

Finally, by returning false when a non-number character is typed in, you basically tell jQuery to refuse it as input. Thus, not firing the input event and your problem is solved.

CodePudding user response:

Firstly, you need to remove all character except number and point,and remove redundant point. Finally, remove parseFloat because parseFloat('')'s value is NaN.

$(document).ready(function() {
  let maximumFractionDigits = 2;
  var valueInput = $("#exampleInput");

  const formatNumber = (value) => {
    const parsedValue = value.replace(/[^\d.]/gi, '').replace(/(?<!^[\d-] )\./g, '');
    return parsedValue ? ( parsedValue).toLocaleString('en-US', {
      maximumFractionDigits
    }) : '';
  }

  valueInput.on('input', function() {
    if (!this.value || (maximumFractionDigits && this.value.endsWith('.'))) {
      return
    }
    $(this).val(formatNumber(this.value));
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="exampleInput"  aria-label="Grant Amount" type="text" placeholder="0" name="price" required="">

CodePudding user response:

I found a potential solution:

const formatNumber = (value) => {
  var result = parseFloat(value.replace(/,/g,'')).toLocaleString('en-US', { maximumFractionDigits });
  const withoutCommas = result.replace(/,/g, '');
  if (isNaN(withoutCommas)){
    return
  }
  return result;
}

Basically, if after parsing the Float and removing the ',' isNaN=True, then return, if it's a number I can just return the result as expected. Might not be the most elegant solution but it works.

  • Related