Reputation: 736
Why code fragments that looks similar works in different ways?
<input data-value-max="10">
1. If script gets option
from attr
, it always updates input
with option
value:
$('input').keyup(function(e) {
var $this = $(this);
option = $this.attr('data-value-max');
val = $this.val();
if (val > option){ // ←---
e.preventDefault();
$this.val(option);
}
});
I mean that if I type 3
or 10
, script updates input to 10
.
2. The second variant works just as I expect—it replaces input value only if it is greater then a number in if
statement:
$('input').keyup(function(e) {
var $this = $(this);
option = $this.attr('data-value-max');
val = $this.val();
if (val > 10){ // ←---
e.preventDefault();
$this.val(option);
}
});
So I can't understand why the first variant replaces input value all the time?
Upvotes: 2
Views: 106
Reputation: 22271
Cleaner:
$('input').keyup(function(e) {
var max_value = $(this).data('value-max') * 1;
if( this.value * 1 > max_value )
this.value = max_value;
});
You are comparing strings in your first example and in your second you are comparing a string to an integer (10
). You want to convert your strings to an integer for your expected comparison. One method is the *1
I used above.
Finally e.preventDefault()
is not needed.
Upvotes: 1
Reputation: 382514
You don't parse the values and attributes.
You should know that "3" > "10"
but 3 < "10"
(in the latter case, "10"
is automatically converted for the comparison).
Use parseInt :
var option = parseInt($this.attr('data-value-max'), 10);
As your attribute has the data
prefix, you might also use jQuery data's auto conversion feature :
var option = $this.data('value-max');
But personally I try to avoid it (especially given the bugs in 1.7 version) and I prefer to be explicit. And it wouldn't work for any value that you can parse as numbers : only those that give the same exact string if toString
is called on the number (it would fail for "03"
or "+03"
for example).
Upvotes: 6
Reputation: 5939
Your second example is relying on JavaScript's type-coercion to compare.
What you are literally doing is testing if "3" > 10
which JS interpreter realizes you're trying to do a numeric comparison and converts it internally to 3 > 10
This is just fine if you understand what the interpreter will try and coerce....similar examples would be:
var x = 0;
if(x) { /* do stuff */ } //0 is a falsy (but not === false) value so the test will always fail
var y = "10";
console.log(y * 10) //outputs 100;
Upvotes: 0
Reputation: 56
I suspect your issue has root in weak typing and type conversion. try this:
if(parseInt(val) > 10) { ...
Upvotes: -1