matt _
matt _

Reputation: 25

JavaScript pass variable to inner click function not working

I can't seem to figure this out. It's working fine for the first section of the for loop, but then the var is lost on the inner click function I commented where it breaks...

Plus, there's probably a cleaner way to write it to begin with:

$(function () {
var a = "rgb(58,88,90)";
var b = "rgb(123,156,158)";
for (var c = 1; c <= 3; c++) {
    if ($("#select" + c).is(":checked")) {
        $("#select" + c + "-icon").css("background", a);
        var d = document.getElementById("select" + c + "_title").innerHTML;
        $("#Selection_" + c).val(d)
    } else {
        $("#select" + c + "-icon").css("background", b);
        $("#Selection_" + c).val("Off")
    }
    $("#select" + c).click(function () {
    // here's where it stops working... var c is no longer recognized...
        if ($("#select" + c).is(":checked")) {
        $("#select" + c + "-icon").css("background", a);
        var d = document.getElementById("select" + c + "_title").innerHTML;
        $("#Selection_" + c).val(d)
    } else {
        $("#select" + c + "-icon").css("background", b);
        $("#Selection_" + c).val("Off")
    }
    })
}
return false });

Here are the first pair of objects it's targeting:

<label for="select1"><aside id="select1-icon" class="icon-form right rounded"><img src="../common/images/icon-viewDemo.png" /></aside>
                <input type="checkbox" id="select1" name="select" checked="checked" class="view" /> <h5 id="select1_title">Watch Demo</h5></label>

And:

<input type="hidden" id="Selection_1" name="Selection_1" value=""/>

Upvotes: 0

Views: 612

Answers (2)

Raymond Chen
Raymond Chen

Reputation: 45172

You are capturing your loop variable, so when the for loop is finished, the variable c has the value 4, which is the value the function sees when it executes.

var x;
for (var c = 0; c <= 3; c++) {
  x = function() { alert(c); };
}
x();

This will alert 4 because by the time you call x(), the variable c has the value 4.

If you want to capture the value of c rather than the variable itself, you can give each function a separate copy. I split the handler into a separate local function for readability.

function createClickHandler(c) {
    return function() {
        if ($("#select" + c).is(":checked")) {
            $("#select" + c + "-icon").css("background", a);
            var d = document.getElementById("select" + c + "_title").innerHTML;
            $("#Selection_" + c).val(d)
        } else {
            $("#select" + c + "-icon").css("background", b);
            $("#Selection_" + c).val("Off")
        }
    }
};
$("#select" + c).click(createClickHandler(c));

You can learn more about this phenomenon on this Web page and in this earlier stackoverflow question.

Upvotes: 1

Robert Louis Murphy
Robert Louis Murphy

Reputation: 1628

c doesn't exist in the global scope so it doesn't exist when you click. If you made it global, it won't have the value you wanted when the click occurs. So use eval(); to replace the c with it's literal value, thus when clicked, you have the value you wanted.

$(
    function () {
        var a = "rgb(58,88,90)";
        var b = "rgb(123,156,158)";
        for (var c = 1; c <= 3; c++) {
            if ($("#select" + c).is(":checked")) {
                $("#select" + c + "-icon").css("background", a);
                var d = document.getElementById("select" + c + "_title").innerHTML;
                $("#Selection_" + c).val(d);
            } else {
                $("#select" + c + "-icon").css("background", b);
                $("#Selection_" + c).val("Off");
            }
            eval(
                '$("#select"' + c + ').click(function () {' +
                    'if ($("#select"' + c + ').is(":checked")) {' +
                        '$("#select"' + c + '"-icon").css("background", a);' +
                        'var d = document.getElementById("select"' + c +
                            '"_title").innerHTML;' +
                        '$("#Selection_"' + c + ').val(d)' +
                    '} else {' +
                        '$("#select"' + c + '"-icon").css("background", b);' +
                        '$("#Selection_"' + c + ').val("Off");' +
                    '}' +
                '});'
            );
        }
        return false;
    }
);

Upvotes: 0

Related Questions