Search code examples
javascriptfirefoxsafariparsefloat

FireFox or Safari + JavaScript Parses an Input Field Type Number Incorrectly


If you have a form field type of number and use that value in JavaScript, the results are not always consistent (with FireFox and Safari so far.)

A value of 10.0 in the input field will parse correctly as the floating number 10.0. However, if you have a "naked" decimal (e.g. 10.) it will parse as NaN.

While this question is similar, it does not address the contextual help I would like to use with reportValidity() and checkValidity(). My intended eventual use is to leverage .on('input change', function (e) {//do processing here});.

I have included a Fiddle of an MRE as an example:

https://jsfiddle.net/lbussy/rv0swbox/

In FF and Safari:

  • 1 parses as 1
  • 1. parses as NaN
  • 1.0 parses as 1

And pointing this out again: I do not want to use a text field and then parse it to a number because it eliminates the functionality inherent in the number type.

So, I want to use a number field for the functionality (and this should work!) I will also recalculate other fields as the user types, so there will be an .on('input change') handler. All of which means not using a text field unless I re-write a lot of the functionality I'd be losing if I treat the field as text instead of as a number.


Solution

  • As I shared in some of the comments, according to real math and JavaScript the following are true:

    • (1 == 1.)
    • (1 === 1.)
    • ((1 + 1.) = 2)

    @nbk pointed out that according to the HTML standard, 1. is not a floating point number.

    HTML is not capable of math - for this, we rely on JS. JS believes 10. is a real number, and a user will expect NOT to get an error if entered - just as it would be a real number on a calculator, or C++, or any other programming language. Therefore I believe the HTML standard is "at fault" here, although I suppose someone has had this argument before me. (now I can't wait for the people taking umbrage at my use of "at fault.")

    This is an issue if, like me, you are running keydown or change or some other method to do a running calculation based on the value of that field. If you must enter 10.1 once you get to 10. your script will bomb out with unplanned errors.

    What I did was save a global variable and, if the value in the text field was valid, update the global and do calculations. If the value is invalid, I skip reassignment and continue using the last value. This does mean if you backspace over 10.1, you will get the value of 10. If this is an issue, you can conditionally use rounding on the floating point number.

    I do appreciate @nbk pointing me to the HTML standard. I do not believe, as they do, that this is proper since the standards appear to conflict. It might be "as planned," but it does create issues. I'd have a better chance of a hot date with Jessica Alba than getting someone to change a standard as fully entrenched as HTML, so I'll leave this here as a note to the next pour soul who hits it.