A. Z.
A. Z.

Reputation: 736

Issue with variable and if statement in jQuery

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

Answers (4)

iambriansreed
iambriansreed

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

Denys S&#233;guret
Denys S&#233;guret

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

BLSully
BLSully

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

bjorn
bjorn

Reputation: 56

I suspect your issue has root in weak typing and type conversion. try this:

 if(parseInt(val) > 10) { ...

Upvotes: -1

Related Questions