0

I have a block of HTML markup that looks something like this for a Course. This is predefined by the CMS my client's using

<ul class="box-3036">
  <li aria-selected="true">
    <a href="#" id="ui-id-5">Dentistry</a>
  </li>
</ul>

I have a bunch of courses, here's another example of this HTML block for another course.

<ul class="box-3032">
  <li aria-selected="true">
    <a href="#" id="ui-id-7">Pharmacy</a>
  </li>
</ul>

I am trying to write a jQuery code for all these courses. From the HTML block, here are the unique info

  • the <ul> class
  • the <a> id
  • and the <a> click will open up two course URLs

Here's the jQuery code I have now. The problem I am facing is that the URL vars is giving me undefined value

box = [
  ".box-3036",
  ".box-3032"
];  

uiid = [
  "a#ui-id-5",
  "a#ui-id-7"
];  

urlfirst = [
  "http://www.yahoo.com",
  "http://www.gmail.com"
];

urlsecond = [
  "http://www.google.com",
  "http://www.7senarai.com "
];   



for (var i = 0; i < box.length; i++) {
        $(box[i] + " " + uiid[i]).click(function() {

      var pid = $(this).parent().attr("aria-selected");
      if(pid == "true") { 
        //window.open(urlfirst[i], '_blank');
        //window.location.href = urlsecond[i];
        alert(urlfirst[i]);
        alert(urlsecond[i]);

      }
    });

}

Here's my jsfiddle

0

3 Answers 3

1

The issue is that the var i in the for loop's scope is above the function you pass to click, so you are getting the value of i AFTER the loop is finished which is 2 in this instance. You want the i to be scoped for your click function

 for (var i = 0; i < box.length; i++) {
    (function (i) {
            $(box[i] + " " + uiid[i]).click(function () {
          var pid = $(this).parent().attr("aria-selected");
          if(pid == "true") { 
            //window.open(urlfirst[i], '_blank');
            //window.location.href = urlsecond[i];
            alert(urlfirst[i]);
            alert(urlsecond[i]);

          }
        });
     })(i); // bring i into scope
 }
Sign up to request clarification or add additional context in comments.

1 Comment

You explained it better too!
1

I would suggest you use a forEach rather than a for loop so the i is scoped for each binding.

box.forEach(function(aBox, i){
  $(aBox + " " + uiid[i]).click(function() {
    var pid = $(this).parent().attr("aria-selected");
    if (pid == "true") {
      //window.open(urlfirst[i], '_blank');
      //window.location.href = urlsecond[i];
      console.log(i);
      console.log(urlfirst[i]);
      console.log(urlsecond[i]);
    }
  });
});

2 Comments

Thanks for your answer. Yeah I would love to learn how to use foreach for this too. Your code doesn't seem to work btw
Ohhhh yeah it did Taplar. My bad my bad, thanks so much! I might use forEach in the actual implementation coz it looks so cool and proper. Thanks so much! I wish I could pick 2 answers!
1

Use a closure around the content of the loop to preserve the value of i like so:

for (var i = 0; i < box.length; i++) {
     (function( i ) {
        $(box[i] + " " + uiid[i]).click(function() {

          var pid = $(this).parent().attr("aria-selected");
          if(pid == "true") { 
            //window.open(urlfirst[i], '_blank');
            //window.location.href = urlsecond[i];
            alert(urlfirst[i]);
            alert(urlsecond[i]);

          }
        });
    })( i );
}

DEMO

1 Comment

I picked your answer at first coz you had the demo, that's very convenient but Victory explained it better for a newbie like me to understand. Anyhow, you both rock! Thanks :)

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.