2

I want to pass the 'y' variable to okayid but there seems to be a problem with the looping. The loop works fine with the first call of 'y' on okay.item(y) but it is not looping through okayid.item(y). It seemed to me like it was a scope problem but I am not sure.

var okay = document.getElementsByClassName("Okay");
var okayid = document.getElementsByClassName("OkayID");

var numberOkays = okay.length;

        for(y = 0; y <= numberOkays; y++){
            okay.item(y).onclick = function(){

                xmlhttp = new XMLHttpRequest();
                xmlhttp.onreadystatechange = function(){

                    if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
                        alert('vote Sent to picture with id = ' + okayid.item(y).innerHTML);
                    }
                };
                xmlhttp.open("GET", "ajax/vote.php", true);
                xmlhttp.send();
            };
        }

Here is the html ...

<a class="Link1A Okay" href="#"><span class="OkayID">[id]</span><div class="Vote1A">Okay</div></a>
FarrisFahad
  • 356
  • 1
  • 4
  • 17
  • `y` is a **global** variable, you didn't use the `var` keyword, so it's accessible everywhere ? – adeneo Dec 27 '14 at 16:11
  • 2
    Your issue is closures, scope and asynchronicity, and you should start here -> http://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue – adeneo Dec 27 '14 at 16:12
  • It should be noted that your issue could simply be solved by doing `this.innerHTML` instead ! – adeneo Dec 27 '14 at 16:15
  • I tried `this.innerHTML` but it returns HTML instead of [id]. @adeneo I think it's closures too, I tried returning the alert but It won't loop through 2nd function. – FarrisFahad Dec 27 '14 at 19:53
  • If you want the ID, just do `this.id` – adeneo Dec 27 '14 at 19:56
  • @adeneo I have identify the problem. When I pass 'y' to the first function it works but it does not iterate, it only passes the first result. So in this solution when I click on Okay, I only get the first OkayID. I will post the solution in the answer area ... – FarrisFahad Dec 28 '14 at 14:56

1 Answers1

1

You've got lots if issues.

  • in the for loop, you don't init y with var which could cause problems, as now y is part of the global scope.
  • in the for loop, you have y <= numberOkays which will cause an empty element to be retrieved at the end since numberOkays is the result of the array's length. So you'd get okay[y] is undefined at the end.
  • You don't need to retrieve the okays at the onset, you can just get the appropriate element in the onclick event.
  • After the loops are done y will be at the last index, so when the click event is fired you'd always get the last element when you refer to the Okay[y] (or in your case you'll just get undefined because of problem 2). Using this will refer to the element clicked which effectively what you intended with Okay[y].

Here's an updated version of your code, with a link to a working jsFiddle below:

var okay = document.getElementsByClassName("Okay");

for(var y = 0; y < okay.length; y++){
    okay[y].onclick = function(){  
        idElem = this.getElementsByClassName("OkayID")[0];

        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function(){

            if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
                alert('vote Sent to picture with id = ' + idElem.innerHTML);
            }
        };
        xmlhttp.open("GET", "ajax/vote.php", true);
        xmlhttp.send();
    };
}

jsFiddle

Daniel Gimenez
  • 18,530
  • 3
  • 50
  • 70
  • It works perfectly. But what I don't understand are these two things: 1. What does 'this' refer to? 2. And why did you set it's index to 0? not x for example – FarrisFahad Dec 28 '14 at 16:45
  • 1) in this context `this` refers to the element that was clicked. You should read about `this` as it isn't the same as it is in other languages. 2) I set it to 0, because I wanted to get the first element with className OkayID. `this` is the parent element with the `Okay` class. – Daniel Gimenez Dec 29 '14 at 13:59