use JSON variable in jQuery to display more JSON variables - javascript

This is somewhat pseudo code so EDIT away. I want to make it when the user clicks on a thumb inside #placeholder DIV thumb2 is then displayed inside #imageLoad DIV. NOTE: Thumb and thumb2 are JSON items. A lot of people are saying that this can't be done with getJSON because it's an asynchronous request. If that is the case, then how can I change my script to support the request? If I am going the wrong way, please provide alternate solutions.
$.getJSON('jsonFile.json', function (data) {
var image1 = "<ul>";
for (var i in data.items) {
image1 += "<li><img src=images/items/" + data.items[i].thumb + ".jpg></li>";
}
image1 += "</ul>";
document.getElementById("placeholder").innerHTML = output;
var image2 = "<img src=images/items/" + data.items[i].thumb2 + ".jpg>";
$('li').click(function () {
document.getElementById("imageLoad").innerHTML = output;
});
});
Here is the external JSON file below (jsonFile.json):
{"items":[
{
"id":"1",
"thumb":"01_sm",
"thumb2":"01_md"
},
{
"id":"2",
"thumb":"02_sm",
"thumb2":"02_md"
}
]}

You can try something like the following:
$.getJSON('jsonFile.json', function(data)
{
$("#placeholder").html("");
var ul = $('<ul></ul>');
$('#placeholder').append(ul);
var load = $("#imageLoad");
for(var i in data.items)
{
var li = $('<li></li>');
ul.append(li);
var img = $('<img>');
img.attr("src", "images/items/" + data.items[i].thumb + ".jpg");
img.click((function(x)
{
return function()
{
load.html("<img src=images/items/" + data.items[x].thumb2 + ".jpg>");
}
})(i));
li.append(img);
}
});
Main difference is that click-handler is assigned inside the loop, so every handler receives a closure with appropriate reference to thumb2.

I think this could do the trick:
var $placeholder = $('#placeholder'),
$imageLoad = $('#imageLoad');
$.getJSON('jsonFile.json', function(data) {
var html = '<ul>';
$.each(data.items, function(i,item){
html += '<li><img src=images/items/' + item.thumb + '.jpg></li>';
});
html += '</ul>';
$placeholder.html(html);
});
$placeholder.on('click','li',function(){
$imageLoad.html($(this).html());
});
I can't understand the use of output since you are not declaring it in anyway. The eventhandler for the click event will trigger on all current and future li elements of the $placeholder which contains the DOM object with an id of placeholder.

Related

jQuery Append with event bind

I am trying to append a number of Div's to a div with an id "list", and each div has an event so i make an array for each div to be appended.
here is my code.
var count = Object.keys(data.results).length;
var el = [];
for(var i=1; i<=count; i++){
el[i] = $('<div id="'+i+'">data.results[i].name</div>');
$("#list").append(el[i]);
el[i].click(function(){
alert(data.results[i].name);
$('#searchbox').modal('toggle');
});
}
the data in div's was successfully appended. but as a try to alert the data in the event i bind to each div, it doesn't alert the data in the div.
what I am trying to do is append names with a div within the div with id "list" and if i click on a name, it should alert the name itself.
You can simplify the logic here by using a delegated event handler on all the appended div elements, then using the text() method to retrieve the required value. Try this:
var data = {
results: {
foo: { name: 'foo_name' },
bar: { name: 'bar_name' }
}
}
var $list = $("#list").on('click', 'div', function() {
console.log($(this).text());
//$('#searchbox').modal('toggle');
});
Object.keys(data.results).forEach(function(key, i) {
$list.append('<div id="' + i + '">' + data.results[key].name + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="list"></div>
The problem is that by the time an element is clicked i is already set to the maximum value i = count. To fix that you'll have to create a closure. Try this:
var count = Object.keys(data.results).length;
var el = [];
function closure(index){
el[index].click(function(){
alert(data.results[index].name);
$('#searchbox').modal('toggle');
});
}
for(var i=1; i<=count; i++){
el[i] = $('<div id="'+i+'">data.results[i].name</div>');
$("#list").append(el[i]);
closure(i);
}

Jquery Loading news listings into dom

I want simply to load/display my top 500 news into my DOM.
I'm not sure why doesn't display it on my <div id="hackernewsrss" ></div>
And if there's any other better way to display this? or to code it? Perhaps I can learn.
var LoadNews = $("#hackernewsrss");
LoadNews.load(function(event) {
parseTopStories('https://hacker-news.firebaseio.com/v0/topstories', '#hackernewsrss');
});
function parseTopStories(url, container) {
var hackernewsAPI = "https://hacker-news.firebaseio.com/v0/topstories.json";
$.getJSON(hackernewsAPI, function(json) {
var requests = [];
for (var i = 0; i < 10; i++) {
requests.push($.getJSON('https://hacker-news.firebaseio.com/v0/item/' + json[i] + '.json'));
}
$.when.apply($, requests)
.done(function() {
var results = []
.slice.call(arguments);
var list = results.map(function(arr) {
var thetemplate = '<li>' + arr[0].title + '</li>';
return thetemplate;
});
$(container).html('<ol>' + list.join('') + '</ol>');
console.log(container); //logs #hackernewsrss
});
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hackernewsrss"></div>
Can anyone help please?
If you try:
$(function(){
parseTopStories('https://hacker-news.firebaseio.com/v0/topstories', '#hackernewsrss');
});
All goes well.
I am not sure why you have load event attached to the div. It is usually used to trigger when image is loaded or window:
JQuery reference

Click event on every item on populated list with jQuery

Here is how I populate my list:
function bingNetworksList(myList) {
var list = '';
for (i = 0; i < myList.length; i++) {
list += '<li>' + myList[i] + '</li>';
}
$('#myList').empty();
$('#myList').append(list);
}
Here is my html file:
<ul id="myList"></ul>
I want to add a click event for every item of list (without having separate ids):
$(function() {
$('#myList').click(function() {
var listItem = this.find('a').text();
console.log(listItem); // never logged
});
});
However, when I click at a list item, click event doesn't fire.
What am I doing wrong?
I can only assume there's a js error in your console.
I've created a working sample for you. We can use event delegation and then retrieve the DOM node that was clicked. You need to ensure you call the bingNetworksList [assume typo in here and meant binD ;)] function when the DOM ready event has fired.
function bingNetworksList(myList) {
var list = '';
for (i = 0; i < myList.length; i++) {
list += '<li>' + myList[i] + '</li>';
}
$('#myList').empty();
$('#myList').append(list);
}
$(function() {
var list = ["foo", "bar"]
bingNetworksList(list);
$('#myList').click(function(evt) {
var listItem = $(evt.target).text();
console.log(listItem); // never logged
});
});
You need to wrap this inside $ as like this:
$(function() {
$('#myList').click(function() {
var listItem = $(this).find('a').text();
console.log(listItem); // will always be logged
});
});

getElementsByTagName('img').length logs out to 0

I have read multiple posts on this, but still don't understand why document.getElemenstsByTagName('img').length prints out '0' but when you console log it shows you the right length.
To further explain my problem, part of my HTML looks like this
<div id="parent">
<div id="slider">
</div>
</div>
Now i am dynamically adding the elements as children to the #slider element.
In my javascript i have an object
var manualSlide = {
imageLength: document.getElementsByTagName('img').length,
//other properties
};
Why does the property 'imageLength' gets assigned '0' instead of the actual length?
Edit:
Here is my entire script
<script>
$.getJSON('data.json',function(data){
$.each(data.images, function(key){
setImages(data.images[key]);
});
});
function setImages(obj){
var imgTag = '';
imgTag += "<img src='" + obj.Url + "' style='width:800px;height:400px' alt ='"+ obj.Title +"' name='pics'/>";
$('#slider').append(imgTag);
}
$(document).ready(function(){
var slide = getManualSlide();
document.getElementsByClassName('left').onclick = function(){
slide.previousImg();
};
document.getElementsByClassName('right')[0].onclick = function(){
slide.nextImg();
};
function getManualSlide(){
var manualSlide = {
imageNum : 1,
imageLength: document.getElementsByTagName('img').length,
image: document.getElementsByTagName('img'),
previousImg: function(){
if(this.imageNum > 1){
this.imageNum --;
}
else{
this.imageNum = this.imageLength;
}
document.pics.src = this.image[this.imageLength - 1];
},
nextImg: function(){
if(this.imageNum > this.imageNum){
this.imageNum ++;
}
else{
this.imageNum = 1;
}
console.log(document.getElementsByTagName('img').length);
console.log(this.imageLength);
document.pics.src = this.image[this.imageLength - 1];
}
};
return manualSlide;
}
});
</script>
It's all about where or when your code gets executed.
You have to make sure your code gets executed after the image tags are parsed (added to the DOM tree).
To do that you could put your code either behind the img-tags in the body or you wait for the document to be loaded:
<script>
document.addEventListener("DOMContentLoaded", function(event) {
imageLength = document.getElementsByTagName('img').length;
console.log(imageLength);
});
</script>
You can read more about this event here.
If you are using jQuery you could also use
$(document).ready(function(){ /* your code goes here */ });
which does exactly the same.
Because the object was created when no img tags were in the document. The object data will not update with the document. If you want this behavior you should use events.
Instead create a function to return an updated object. See below:
function getManualSlide()
{
var imgLen = document.getElementsByTagName('img').length;
var manualSlide = {
imageLength: imgLen
};
return manualSlide;
}
http://jsfiddle.net/2akca0dg/2/

jQuery getting .preventDefault() to work on generated elements

I'm having a bit of a problem with getting the .preventDefault to work on some elements I am generating via JQuery.
I am getting a JSON file using the following code and putting the data into individual p elements:
$.getJSON(searchURL, function(data) {
$.each(data, function(key, value) {
if (typeof value === 'object') {
for (var i = 0; i < data.count; i++) {
var fullPlayerURL = "<p class='entry'>" + "<a href=" + playerURL + data.data[i].id + ">"
+ "Nickname - " + data.data[i].nickname + "</a>" + "</p>"
$('#results').append(fullPlayerURL);
}
}
});
}); //end getJSON
Then I'm using the following code to stop the link from redirecting when clicked (links to another JSON file):
$('.entry').click(function(event) {
event.preventDefault();
var linkClicked = $(this).attr("href");
console.log(linkClicked);
});
I don't know if it matters but #results is just an empty div.
Here's all the code if this isn't enough info (sorry it's such a mess).
You'll need delegated event handlers for dynamic elements
$('#results').on('click', '.entry', function(event){
event.preventDefault();
var linkClicked = $('a', this).attr("href");
console.log(linkClicked);
});
Sorry, I'm not allowed to comment on adeneo's answer.
For me var linkClicked = $('a', this).attr("href"); gives undefined.
I had to make var linkClicked = $(this).attr("href"); out of it.
Edit: Know it, I wanted to address the anchor.
$('#results').on('click', 'a', function(event) {
event.preventDefault();
var linkClicked = $(this).attr("href");
console.log(linkClicked);
});

Categories

Resources