4

I have an HTML input element and I'm trying to force a single decimal place into the input after the user changes the value. So, let's say the user enters "4", I run this code:

this.value = this.value.toFixed(1)

but then I get a JavaScript error saying "Object 4 has no method 'toFixed'".

It seems like JavaScript is trying to process a literal as a Number and failing but, er, why? And how do I avoid it?

Jeff Chausse
  • 51
  • 1
  • 1
  • 3

2 Answers2

26

this.value is a String when you get it from an input element. You need to cast it to a number before you can use a number's methods on it:

this.value = Number(this.value).toFixed(1);

Alternatively you can use the unary + operator to cast the string to a number:

this.value (+this.value).toFixed(1);

If you need to remove string suffixes, then you could use parseFloat:

this.value = parseFloat(this.value).toFixed(1);

However, it's worth noting that parseFloat does not handle hexadecimal formats while casting to Number does:

this.value = +'0xF'; //15
this.value = parseFloat('0xF'); //0
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • Thanks. That did it (though I alto took Ben Blank's "parseFloat" advice below). I guess I was used to JavaScript being more flexible about type casting... – Jeff Chausse Mar 16 '11 at 19:31
  • It's very flexible, but it can only look at the methods associated with the current object type. `toFixed` is useful if you need a specific precision, `parseFloat`/`parseInt` are useful for type/value conversion. – zzzzBov Mar 16 '11 at 19:40
  • — I think you misunderstood my suggestion; I'm advocating `this.value = parseFloat(this.value).toFixed(1);` – Ben Blank Mar 16 '11 at 20:48
3

convert to a Number first,

this.value = Number(this.value).toFixed(1);

this.value is a String, and a string does not have the toFixed method.

Anurag
  • 140,337
  • 36
  • 221
  • 257
  • Using the `Number` constructor is overkill for this; `parseFloat` is probably the better option. – Ben Blank Mar 16 '11 at 19:10
  • @Ben Blank, `Number()` isn't being used as a constructor, it's being used to cast. unlike server scripts, JS tends not to have as much of a performance requirement, and @Jeff Chausse did specify that a certain precision was desired, so casting to a number would be appropriate in this instance. If a numeric representation was desired without any precision, `parseFloat` would definitely be the way to go. – zzzzBov Mar 16 '11 at 19:45
  • 1
    @zzzzBov — Whether it's being *used* as a constructor isn't the issue; `parseFloat` is designed for the specific purpose of converting a string to a floating-point number and so many JS engines optimize it as such (e.g. by passing it directly to the underlying C function). `Number` doesn't benefit from such optimizations because it has a broader scope and must run through a number of checks first. I'm not sure what you mean by "without any precision"… this `Number` call will result in a call to the same internal method that `parseFloat` does. – Ben Blank Mar 16 '11 at 20:47