0

I have a requirement where I have to fire click event on table header on click of other table header (2 different tables), but trigger is not fired on the table when in a loop. Although if I hardcode and bind the trigger to individual element, it works.

Currently, the JS looks like something like this:

var outsideHeaders = $("#header th");
var tableHeaders = $(".dataTable th");

for(var cnt = 0; cnt< outsideHeaders.length; cnt++)
{
    $(outsideHeaders[cnt]).bind('click',function(){
        $(tableHeaders[cnt]).trigger('click');
    });
}

Please provide solution for this!

Updated:
This is how my code looks now:

var outsideHeaders = $("#header th");
var tableHeaders = $(".dataTable th");

for(var cnt = 0; cnt< outsideHeaders.length; cnt++)
{
    (function(headerCnt){
        $(outsideHeaders[headerCnt]).bind('click',function(){
            $(tableHeaders[headerCnt]).trigger('click');
    });
  })(cnt);
}
5
  • You shouldn't be defining a function within a loop. Commented May 13, 2013 at 9:48
  • @DerekHenderson If you're going to make a statement that they shouldn't be doing something, the least you could do is bother to say why they shouldn't (and maybe even what they should do instead). Commented May 13, 2013 at 9:50
  • @AnthonyGrist, yes, you're right, since this site is about informing and educating, I should be more constructive. Commented May 13, 2013 at 9:58
  • The reason you shouldn't be defining a function within a loop is because an instance of the function is created in each iteration of the loop, not something you want to be doing. Instead, create the function outside the loop and reference it from inside the loop. Commented May 13, 2013 at 9:59
  • What is the alternative for not defining functions within the loop for the above scenario? My problem is trigger is not executed still ... i will change the code to have the function outside once i solve my core problem.. Thanks Commented May 13, 2013 at 10:37

3 Answers 3

2

The value of cnt inside the click event handler function is going to be equal to its last value in the for loop (in this case, whatever header.length was when the code executed) due to the way scoping in JavaScript works. You need to use a closure so that it maintains its value for that specific iteration:

$(document).ready(function() {
    var outsideHeaders = $("#header th");
    var tableHeaders = $(".dataTable th");

    for(var cnt = 0; cnt < outsideHeaders.length; cnt++)
    {
        (function(headerCount) {
            $(outsideHeaders[headerCount]).bind('click',function(){
                $(tableHeaders[headerCount]).trigger('click');
            });
        })(cnt);
    }
});

Note that I've wrapped the code in a $(document).ready() call. This will ensure that the elements exist when you try to select them.

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

10 Comments

Tried this but still not working.. Assuming that it is function(cnt) instead of function(headerCount) in the code you mentioned
@SomeswaraSiripuram You can name the parameter on the anonymous function whatever you like, but I went for something other than cnt to illustrate that it relates to what's passed to the function, not the counter for the for loop. Either way, the code should work - can you check that the click event handler being bound is actually executed; it might be running the code before the elements actually exist.
Thank you for replying quickly. But I am sorry I don't understand how will the parameter of the anonymous function will hold the current index of the for loop. Should we not assign the index and then pass to the anonymous function. I tried this (assigning index and using the same code above). Let me know If I have misunderstood or misssed something here. Also I have verified the click event is executed. As I mentioned, it works if I manually assign the counter by hardcoding the index for all instances, and does not work in a loop
@SomeswaraSiripuram You're immediately invoking the anonymous function and passing the value of cnt to it - then inside that anonymous function the value of headerCount will be whatever was passed to it. Difficult for me to tell you if you've gone wrong without seeing what you currently have.
This is how my code looks now: var outsideHeaders = $("#header th"); var tableHeaders = $(".dataTable th"); for(var cnt = 0; cnt< header.length; cnt++) { (function(headerCnt){ $(outsideHeaders[headerCnt]).bind('click',function(){ $(tableHeaders[headerCnt]).trigger('click'); }); })(cnt); }
|
2
var $outsideHeaders = $("#header th"),
    $tableHeaders = $(".dataTable th");

$outsideHeaders.on('click', function(){
   var i = $outsideHeaders.index(this);
   $tableHeaders.eq(i).trigger('click');
});

2 Comments

@SomeswaraSiripuram You should bind click handlers $tableHeaders.click(function(){ console.log('clicked') })
There is an action defined on click event of table header already. And I have checked that it is working by hardcoding the index and calling trigger.
1

No need in making iteration. I guess this could be the right way here:

outsideHeaders.on("click", function() {
    var cnt = outsideHeaders.index(this);
    tableHeaders.eq(cnt).trigger("click");
});

You simply bind click event to all outsideHeaders and trigger click event of the corresponding element of tableHeaders based on the index.

2 Comments

@SomeswaraSiripuram Then you don't bind it.
The click for tableHeaders is working. I have checked that. Also as I said, it is working if I hard code the index but not inside a loop....!!!!

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.