2

I'm trying to concatenate a variable into a JQuery selector (which I understand to be fairly straightforward), but I'm running into some interesting behavior. My code is supposed to uncheck certain radio selectors along a y-axis.

for(var i = 1; i < 5; i++) {
    $("input[value='"+1+"']").each(function() {                     //<--
        $(this).on('change', function() {
            var that = this;
            $("input[value='"+1+"']").each(function() {             //<--
                if($(this).attr('name') != $(that).attr('name')) {
                    $(this).prop('checked', false);
                }
            });
        });
    });
}

Now, the code works as it is (selecting only inputs of value '1', that is) and works with the '1' included in the quotes as well. However, once I pass in either i or i.toString(), the code doesn't work. Ideally, I'd like to be able to pass in i to activate all my inputs. Is that going to be possible? I'm using JQuery from http://code.jquery.com/jquery-1.10.2.min.js.

HTML

<form method="POST" action="votes.php">
    <div style="border:black solid 1px;border-radius:5px;">
        <label>One</label>
        <input type="radio" name="one" value="1">
        <input type="radio" name="one" value="2">
        <input type="radio" name="one" value="3">
        <input type="radio" name="one" value="4">
    </div>
    <div style="border:black solid 1px;border-radius:5px;">
        <label>Two</label>
        <input type="radio" name="two" value="1">
        <input type="radio" name="two" value="2">
        <input type="radio" name="two" value="3">
        <input type="radio" name="two" value="4">
    </div>
    <div style="border:black solid 1px;border-radius:5px;">
        <label>Three</label>
        <input type="radio" name="three" value="1">
        <input type="radio" name="three" value="2">
        <input type="radio" name="three" value="3">
        <input type="radio" name="three" value="4">
    </div>
    <div style="border:black solid 1px;border-radius:5px;">
        <label>Four</label>
        <input type="radio" name="four" value="1">
        <input type="radio" name="four" value="2">
        <input type="radio" name="four" value="3">
        <input type="radio" name="four" value="4">
    </div>
</form>
6
  • Show relevant HTML code. Commented Jan 3, 2014 at 6:31
  • radio, unselect??? Can't you use a radiogroup (ie. same name on the radio belonging together)? Commented Jan 3, 2014 at 6:33
  • I am grouping them: along the x-axis. It's a grid of radios where each x and y axis is unique. Commented Jan 3, 2014 at 6:34
  • can you elaborate more? still it is confusing.. what are you trying to accomplish? Commented Jan 3, 2014 at 6:38
  • 5 rows of 5 radio buttons, each radio valued 1-5 (for questionnaire purposes). Every rating (1-5) has to be unique on each selection (eg there can't be more than 1 value of the same type selected). I'm already using groups (names) to organize the individual selections' radio buttons (along the x-axis), so I have to use JS to manage the value selections (along the y-axis). Plug in the HTML and you'll see. Commented Jan 3, 2014 at 6:43

2 Answers 2

2

This is the classic closure problem in JavaScript. In your code, replacing 1 with i (the second i, that's in the event handler) would not work since those event handlers maintain an actual link to the i variable itself, not the value that i held when the code was run

The solution is simple: break the closure by passing i as a parameter to a function:

for(var i = 1; i < 5; i++) {
    (function(i){
         $("input[value='"+ i +"']").each(function() {
            $(this).on('change', function() {
                var that = this;
                $("input[value='"+i+"']").each(function() {             //<--
                    if($(this).attr('name') != $(that).attr('name')) {
                        $(this).prop('checked', false);
                    }
                });
            });
         });
    })(i);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Wow, no way! That's it! I'd be interested in reading up a little more on it if you know of any good sources. Thanks!
0

I have changed 1 with i, now your code is like

for(var i = 1; i < 5; i++) {
    $("input[value='"+i+"']").each(function() {                     //<--
        $(this).on('change', function() {
            var that = this;
            $("input[value='"+i+"']").each(function() {             //<--
                if($(this).attr('name') != $(that).attr('name')) {
                    $(this).prop('checked', false);
                }
            });
        });
    });
}

There is no use in iterating the html elements within the change event because it has only one element. Also you're iterating only an individual group instead try to iterate the group like

var names = ["one", "two", "three", "four"];
for (var i=0; i< names.length; i++) {
  $("input[name='"+names[i]+"']").each(function() { 
.............
.............   

Comments

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.