3

I'm having a strange issue with a small piece of jquery code when using a for loop to concatenate jquery selector:

NOT working:

for(j = 1; j <= myHypervisors.length; j++)
{
    $("#status_vm" + j + "_dev").hide();
        $("#title_hypervisor_" + j).toggle(function(){
        $("#status_vm" + j + "_dev").show();
        $("#show_hypervisor_" + j).toggleClass('icon-plus icon-minus');
    },function(){
        $("#status_vm" + j + "_dev").hide();
        $("#show_hypervisor_" + j).toggleClass('icon-minus icon-plus'); 
    });
}//for

myHypervisors.length == 2

WORKING:

$("#status_vm1_dev").hide();
    $("#title_hypervisor_1").toggle(function(){
    $("#status_vm1_dev").show();
    $("#show_hypervisor_1").toggleClass('icon-plus icon-minus');
 },function(){
    $("#status_vm1_dev").hide();
    $("#show_hypervisor_1").toggleClass('icon-minus icon-plus');    
 });

$("#status_vm2_dev").hide();
    $("#title_hypervisor_2").toggle(function(){
    $("#status_vm2_dev").show();
    $("#show_hypervisor_2").toggleClass('icon-plus icon-minus');
 },function(){
    $("#status_vm2_dev").hide();
    $("#show_hypervisor_2").toggleClass('icon-minus icon-plus');    
 });

Regarding the DOM:

<h3 id="title_hypervisor_1"><i class="icon-plus" id="show_hypervisor_1"></i> Hypervisor : vm1-dev </h3>

<table class="table table-bordered" id="status_vm1_dev"></table>
...

Thank you in advance for your help

Virtuose
  • 173
  • 1
  • 6

1 Answers1

4

That's because j changes : when the callbacks are executed, its value is the one of end of loop. You may protect it with an immediately called function :

for(j = 1; j <= myHypervisors.length; j++){
   (function(j){
    $("#status_vm" + j + "_dev").hide();
    $("#title_hypervisor_" + j).toggle(function(){
        $("#status_vm" + j + "_dev").show();
        $("#show_hypervisor_" + j).toggleClass('icon-plus icon-minus');
    },function(){
        $("#status_vm" + j + "_dev").hide();
        $("#show_hypervisor_" + j).toggleClass('icon-minus icon-plus'); 
    });
   })(j);
}

And for people not liking functions created in a loop, here's another solution (as a bonus it's compatible with recent versions of jQuery) :

for(j = 1; j <= myHypervisors.length; j++) $("#status_vm" + j + "_dev").hide();
$('[id^="title_hypervisor_"]').click(function(){
   var j = this.id.slice('title_hypervisor_'.length);
   $("#status_vm" + j + "_dev").toggle();
   $("#show_hypervisor_" + j).toggleClass('icon-plus icon-minus');
});
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758