I've never been good with JavaScript or jquery but my latest project has demanded that I get better. I'm trying to create a widget for a website. This widget uses ajax to access json data from another domain. This widget may have multiple instances on the same page, each with different settings.
I'm using JQuery to find all of the elements with a particular class which will identify where the widgets need to go. I'm using custom data- attributes to store the settings for each widget in what will be the container .
The problem I am having is this;
Because ajax request are asynchronous the results are coming in an effectively random order. The code Ihave so far is
<script>
var currentContainer;
$(document).ready(function(){
$($(".container")).each(function( index ){
currentContainer = this;
var url =
"http://example.com/json.php?iid="+$(this).data("owner_id")+
"&iid="+$(this).data("item_id")+
"&l="+$(this).data("layout")+
"&callback=?";
var request = $.get(url,function(data){
console.log(data)
display(data.oid,data.iid,data.l);
},"jsonp");
});
});
function display(oid,iid,l){
$(currentContainer).html("Owner Id = "+oid+" Item Id = "+iid+" Layout = "+l);
}
And in the body....
<div class="container" data-owner_id="George" data-item_id="car" data-layout="tidy">-</div>
<div class="container" data-owner_id="tim" data-item_id="computer" data-layout="allovertheplace">-</div>
<div class="container" data-owner_id="dee" data-item_id="hammer" data-layout="effingmess">-</div>
The result I get is random data in the last only. Any ideas much appreciated!
Don't use global variable in this case. Pass the currentContainer to the display function as an argument.
var currentContainer = this;
...
var request = $.get(url,function(data){
console.log(data)
display(currentContainer, data.oid,data.iid,data.l);
},"jsonp");
...
function display(currentcontainer, oid, iid, l) {
...
The problem is in the line:
$(currentContainer).html("Owner Id = "+oid+" Item Id = "+iid+" Layout = "+l);
When you loop through the divs with class container
($($(".container")).each
), you're assigning currentContainer
to the div you're working on. So at the end, currentContainer
refers to the last element with a class container
.
In display
, you want to select the div
to act on using its data
attribute. You can make this type of selection using jQuery's attribute selectors $("[attribute='val']")