gleysen
gleysen

Reputation: 33

for loop to add click function to multiple input fields in jQuery not working as expected

I have multiple checkboxes that need to behave as radio buttons. The number of checkbox fields can vary so I tried to use a for loop to go over them.

When I use the following code everything works ok

$("input[name='item_meta[221][0][253][]']").on('click', function() {$("input[name='item_meta[221][0][253][]']").not(this).attr('checked', false)});
$("input[name='item_meta[221][1][253][]']").on('click', function() {$("input[name='item_meta[221][1][253][]']").not(this).attr('checked', false)});
$("input[name='item_meta[221][0][268][]']").on('click', function() {$("input[name='item_meta[221][0][268][]']").not(this).attr('checked', false)});
$("input[name='item_meta[221][1][268][]']").on('click', function() {$("input[name='item_meta[221][1][268][]']").not(this).attr('checked', false)});

However, this would mean that if I have 10 of these checkbox groups, that I would need to write 10 lines for each. So I tried doing the same with a for loop like this:

for (i=0; i < 1; i++){
     $("input[name='item_meta[221][" + i + "][253][]']").on('click', function() {$("input[name='item_meta[221][" + i + "][253][]']").not(this).attr('checked', false)});
     $("input[name='item_meta[221][" + i + "][268][]']").on('click', function() {$("input[name='item_meta[221][" + i + "][268][]']").not(this).attr('checked', false)});
}

But when I use this, it doesn't work?! So what am I missing??

Upvotes: 3

Views: 411

Answers (2)

Pranav Rustagi
Pranav Rustagi

Reputation: 2721

Give it a try with let.

Explanation : The variable i in the code, is a global variable (declared with var). Unlike let, var do not support block scopes. The click event is actually binded when the button is clicked first time, not when the for loop executes. As i was a global variable, it had iterated through the loop and its value had become 10. When the button was clicked, the button was bind to input[name='item_meta[221][10][268][]'] which was not present. That is why, let is used because it supports block scope, and preserves its value for binding event.

for (let j = 0; j < 10; j++) {
  $("input[name='item_meta[221][" + j + "][253][]']").on('click', function() {
    $("input[name='item_meta[221][" + j + "][253][]']").not(this).attr('checked', false)
  });
  $("input[name='item_meta[221][" + j + "][268][]']").on('click', function() {
    $("input[name='item_meta[221][" + j + "][268][]']").not(this).attr('checked', false)
  });
}

Upvotes: 3

You have to use closure, or else you will get the last value of I only. Either use .forEach instead or make an anonymous function call with I as the only parameter, like

for(var i=0;i <8; i++) {
  (function(k) {
    //Do stuff with k as i replacement
  })(i)
}

Upvotes: 1

Related Questions