3

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??

13
  • The value of i in the click callback will be the last iteration value (1 in this case) not the value inside the loop (0). See: stackoverflow.com/questions/111102/… Commented Aug 10, 2020 at 9:38
  • @freedomn in this case i will never be 1 Commented Aug 10, 2020 at 9:49
  • It seems like you only want 1 item from a group of common named checkboxes to be selected - if so, why not just use a radio input? Commented Aug 10, 2020 at 9:52
  • @bluejayke are you sure about that? it continues while i<1 so therefore breaks when i>=1 - a simple test will remind you how for loops work: var i;for (i=0; i < 1; i++){ };console.log(i) Commented Aug 10, 2020 at 9:55
  • @freedomn the code for that test has two {}s immediately following the for loop, with the console. Log statement outside of it completely... Try moving the console. Log inside the brackets and see if you get the same result Commented Aug 10, 2020 at 9:57

2 Answers 2

3

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)
  });
}

Sign up to request clarification or add additional context in comments.

4 Comments

Good answer, just explain it a bit!
if I use this, it works on item_meta[221][0][253][], but not on item_meta[221][1][253][]
Are you sure that, there is no i variable, declared with var, in code before that? That might be causing problem. Try using some other variable like j or k in this for loop in place of i.
ok, I think this indeed should work, however the second checkboxes (item_meta[221][1][253][]) is loaded after the page has been loaded and I was using the jQuery(document).ready(function and so it only works on the checkboxes that were loaded in the beginning... so I need to see how I can run the code everytime that DOM elements are being added.... I'll check this as a good answer for now ;-) Thx!
1

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)
}

3 Comments

if I use this, it works on item_meta[221][0][253][], but not on item_meta[221][1][253][]
this is the code I used: for(var i=0;i <10; i++) { (function(k) { $("input[name='item_meta[221][" + k+ "][253][]']").on('click', function() {$("input[name='item_meta[221][" + k + "][253][]']").not(this).attr('checked', false)}); $("input[name='item_meta[221][" + k + "][268][]']").on('click', function() {$("input[name='item_meta[221][" + k + "][268][]']").not(this).attr('checked', false)}); })(i) }
@gleysen ok then that must be a problem with that particular input field with that particular name existing in that particular context, which is impossible to troubleshoot without seeing the code for which those input fields were made,

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.