im trying to print array elements with html li element in a dynamically created div but no errors showing and neither array elements just an empty div.
What could be wrong?
Here is my code:
var fruitsName, fruitsLists, numFruits, i;
fruitsName = ["Mango", "Apple", "Banana", "Strawberry", "Blackberry", "Blueberry"];
numFruits = fruitsName.length;
fruitsLists = "<ul>";
for (i = 0; i < numFruits.length; i++)
{
fruitsLists = "<li>" + fruitsName[i] + "</li>";
}
fruitsLists += "</ul>";
var myDiv = document.createElement('div');
myDiv.className = 'bookmarksHolder';
myDiv.id = 'randomItem';
document.getElementById('bookmarks_row').appendChild(myDiv);
document.getElementById('randomItem').innerHTML = fruitsLists;
Two problems: numFruits is already a length of array, so should be just i < numFruits. Second, in loop concatenate previous value with the current:
for (i = 0; i < numFruits; i++) {
fruitsLists += "<li>" + fruitsName[i] + "</li>";
}
Complete sample:
var fruitsName, fruitsLists, numFruits, i;
fruitsName = ["Mango", "Apple", "Banana", "Strawberry", "Blackberry", "Blueberry"];
numFruits = fruitsName.length;
fruitsLists = "<ul>";
for (i = 0; i < numFruits; i++) {
fruitsLists += "<li>" + fruitsName[i] + "</li>";
}
fruitsLists += "</ul>";
var myDiv = document.createElement('div');
myDiv.className = 'bookmarksHolder';
myDiv.id = 'randomItem';
document.getElementById('bookmarks_row').appendChild(myDiv);
document.getElementById('randomItem').innerHTML = fruitsLists;
<div id="bookmarks_row"></div>
You are assigning to fruitsLists in the loop, instead of appending. Also your array length is numFruits, so don't call .length of that. Change your loop to:
for (i = 0; i < numFruits; i++)
{
fruitsLists += "<li>" + fruitsName[i] + "</li>";
}
You can also give the ul as innerHTML to the div prior to attaching the div to the DOM. This will invoke the rendering engine only once, instead of twice, and you wouldn't have to find the div by ID:
var myDiv = document.createElement('div');
myDiv.className = 'bookmarksHolder';
myDiv.id = 'randomItem';
myDiv.innerHTML = fruitsLists;
document.getElementById('bookmarks_row').appendChild(myDiv);
Within the loop, you need to concatenate instead of updating entire value otherwise fruitsLists includes the last generated HTML of li. Although update the for loop condition since numFruits holds the length.
for (i = 0; i < numFruits; i++)
// ---------^^^---
{
fruitsLists += "<li>" + fruitsName[i] + "</li>";
// ---^^^---
}
Related
for a challenge, I am calling an the twitch TV API to get info and update my HTML.
Using a for loop, I succeeded to setAttributes for my divs and appendChilds. but when I want to update those childs, it is updating only the childs of the last div.
I need your help to update all my appended childs. Below is my code:
// variables declarations to update the DOM
var users = usersJson.data;
var i;
var usersIds = [];
var channels = document.getElementById("all").children;
console.log(channels);
// pushing channels ids into an array for a later
for (i = 0; i < users.length; i++) {
usersIds.push(users[i].id);
}
var channelImg = document.createElement("img");
var channelTitle = document.createElement("h3");
for (var i = 0; i < channels.length; i++) {
channels[i].setAttribute("id", users[i].id);
channels[i].setAttribute("class", "channelInfo" + (i + 1) + " " + "channel" + (i + 1));
channels[i].appendChild(channelTitle);
channels[i].appendChild(channelImg).setAttribute("id", "img-holder" + (i + 1));
channelTitle.innerHTML = users[i].display_name;
channelImg.setAttribute("src", users[i].profile_image_url);
}
https://jsfiddle.net/xpcz1r5k/1/
The creation of the elements needs to go in the for loop:
for (var i = 0; i < channels.length; i++) {
var channelImg = document.createElement("img");
var channelTitle = document.createElement("h3");
channels[i].setAttribute("id", users[i].id);
channels[i].setAttribute("class", "channelInfo" + (i + 1) + " " + "channel" + (i + 1));
channels[i].appendChild(channelTitle);
channels[i].appendChild(channelImg).setAttribute("id", "img-holder" + (i + 1));
channelTitle.innerHTML = users[i].display_name;
channelImg.setAttribute("src", users[i].profile_image_url);
}
When the creation is on the outside of the loop, appendChild only moves the element to the next parent. appendChild doesn't clone/duplicate the DOM elements. So you end up constantly updating the same DOM element and the last one ends up winning.
I've been stuck with this for several days and I can't solve it.
I've done it with jQuery with no problem, but I need it in pure JS.
This is how my list is generated.
function get_friends(items){
if(items != undefined){
if (items.length != 0){
var html_friends_list = "";
for(var count = 0; count < items.length; count++){
if(items[count].subscription == "both"){
var display_name = Strophe.getNodeFromJid(items[count].jid);
html_friends_list = html_friends_list + "<li style='font-size:19px' id='open_chat-" + items[count].jid + "'>" + "<a href='chat-js/index.html'>" + display_name + "<span class='block-list-label' id='" + items[count].jid + "_unread_messages" + "'>0</span><span class='block-list-label' id='" + items[count].jid + "_change_status" + "'></span></a></li>";
}
}
document.getElementById("friends-list").innerHTML = html_friends_list;
As a said I want to save the value of the text and the id of any li element clicked.
Regards
you haven't specified whether this is for a specific list or just any li on your page. The below will log the id and innerHTML components of any li on the page. Perhaps you may need to update the querySelector for your particular use case.
var list = document.querySelectorAll('li');
Array.prototype.slice.call(list).forEach(function(listItem){
listItem.addEventListener('click', function(e){
console.log(this.id);
console.log(this.innerHTML);
});
});
Here's a JSFiddle which I think demonstrates what you are trying to achieve.
Jsfiddle
Combination of james' answer and working example.
function get_friends(items) {
if (items != undefined) {
if (items.length != 0) {
var html_friends_list = "<ul>";
for (var count = 0; count < items.length; count++) {
if (items[count].subscription == "both") {
html_friends_list = html_friends_list + "<li id='open_chat-" + items[count].jid + "'>"+ items[count].display_name +"</li>";
}
}
html_friends_list = html_friends_list + '</ul>'
document.getElementById("friends-list").innerHTML = html_friends_list;
}
}
}
Note: you should trigger prototype after your dom element created.
This is a coin flipping randomizer. I need to print out 10 rows and 20 columns. This is where I am stuck. My code seems to randomize correctly every time I click my button, it displays 20 columns but I cannot seem to get it to print a second row. It may be something simple that I am just not catching. Anything will be appreciated.
Javascript Code
function toss()
{
var heads = "x ";
var tails = "o ";
var rows = 0;
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++)
{
var val = Math.floor( Math.random() * 2 );
if(val === 1)
{
arr[i] = " x";
}
else
{
arr[i] = " y";
}
document.getElementById("results").innerHTML = arr + "<br />";
}
delete arr;
rows++
}
}
HTML:
<html>
<head>
<title>Coin Flip</title>
<script src="Toss.js" type="text/Javascript"></script>
<style>
#results
{
display: block;
}
</style>
</head>
<body>
Push Button to Flip -> <input type="button" onclick="toss()" value=" Flip ">
<span id="results"></span>
</body>
</html>
The problem is you are replacing the entire results output each time you create a row with the new row. You need to append instead of replace. So change this:
document.getElementById("results").innerHTML = arr + "<br />";
To:
document.getElementById("results").innerHTML += arr + "<br />";
You also need to move the append of the result out of the inner for loop! If you leave the append within the for loop, you will see this behavior: http://jsfiddle.net/t1s93Lqz/3/
JSFiddle: http://jsfiddle.net/t1s93Lqz/2/
You are resetting the html inside the element each iteration through the loop
document.getElementById("results").innerHTML = arr + "<br />";
And while you could concatenate innerHTML each iteration to fix this:
document.getElementById("results").innerHTML += arr + "<br />";
This will cause the whole html for that element to be re-rendered. It would be better to either build the html string first and then set the element's innerHTML property or use DOM methods like appendChild/insertAdjacentHTML.
Build string first
var html = "";
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++) {
var val = Math.floor( Math.random() * 2 );
if(val === 1) {
arr[i] = " x";
} else {
arr[i] = " y";
}
}
//moved the concatenation out of the loop
//otherwise you will get a line each as the array is set
html += arr + "<br />";
rows++
}
document.getElementById("results").innerHTML = html;
Using insertAdjacentHTML
var element = document.getElementById("results");
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++) {
var val = Math.floor( Math.random() * 2 );
if(val === 1) {
arr[i] = " x";
} else {
arr[i] = " y";
}
}
element.insertAdjacentHTML('beforeend',arr+"<br />");
rows++
}
Demo
var rows = 0;
var element = document.getElementById("results");
while(rows < 10)
{
var arr = new Array(20);
for(var i = 0; i < arr.length; i++) {
var val = Math.floor( Math.random() * 2 );
if(val === 1) {
arr[i] = " x";
} else {
arr[i] = " y";
}
}
element.insertAdjacentHTML('beforeend',arr+"<br />");
rows++
}
<div id="results"></div>
Also note your delete statement won't do anything as delete works on object properties, if you console.log( delete arr ) you will see it will print false
You are only printing the last row. Replace
document.getElementById("results").innerHTML = arr + "<br />";
with
document.getElementById("results").innerHTML += arr + "<br />";
I am using the Google Feed API to pull four items from an RSS feed. I want to style the last item on the list (the fourth) differently from the first three. It seems like there must be a simple way--but I can't seem to figure it out. Here's what I've got:
google.load("feeds", "1");
function initialize() {
var feed = new google.feeds.Feed("http://the-url-of-my-feed");
feed.load(function(result) {
if (!result.error) {
var container = document.getElementById("joes-teaser");
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var li = document.createElement("li");
li.innerHTML = '<a href="' + entry.link + '" target="_blank">'
+ entry.title + '<span>More »</span></a>';
container.appendChild(li);
}
}
});
}
google.setOnLoadCallback(initialize);
That gives me a nice list of four li items, but I want the last, and only the last, to have a css id of something else--maybe joes-teaser-last or whatever.
In your loop you can check if i is the last one by comparing it to the entries' length.
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var li = document.createElement("li");
if (i == result.feed.entries.length - 1) {
li.className = "lastLi";
}
li.innerHTML = '' + entry.title + '<span>More »</span>';
container.appendChild(li);
}
I am trying to loop out a JSON object using Javascript (jQuery).
Each object in the array of the main JSON object got embedded arrays containing tags.
I want to loop trough all files in the main object and at the same time loop through the tags and output them together with the files. The object are parsed before looping.
This is the JSON object:
{
"result": [
{
"id": "4f26f21f09ab66c103000sd00e",
"file_url": "http://thefilesat.s3.amazonaws.com/81/0000/12.jpg",
"tags": [
"image",
"elephants"
]
},
{
"id": "4f2422c509ab668472000005",
"file_url": "http://thefilesat.s3.amazonaws.com/9d/0000/7.jpg",
"tags": [
"image",
"green",
"tree"
]
}
]
}
It tried this code but it does not work:
for (var i=0; i < parsed.result.length; i++) {
for (var j=0; j < parsed.result[i].tags.length; j++) {
tags = '<div class="tag">' + parsed.result[j].tags[j] + '</div>';
};
html = '<div class="file""><img src="' + parsed.result[i].file_url + '" /><div class="tags">' + tags + '</div></div>';
$("#files").append(html);
};
Your problem is that inside the tags loop, you're using the = operator; which is overwriting the variable your assigning to in each iteration.
Instead, try something like this;
var html = '';
for (var i = 0; i < parsed.result.length; i++) {
var tags = '';
for (var j = 0; j < parsed.result[i].tags.length; j++) {
tags += '<div class="tag">' + parsed.result[i].tags[j] + '</div>';
};
html += '<div class="file""><img src="' + parsed.result[i].file_url + '" /><div class="tags">' + tags + '</div></div>';
};
$("#files").append(html);
You also had parsed.result[j].tags[j] rather than parsed.result[i].tags[j].
I've also pulled the appending to $('#files') to be outside the loop so it only happens once, to reduce the amount of DOM lookups and DOM manipulation (as this is slow (in relative terms)).
With:
parsed.result[j].tags[j]
I think you meant:
parsed.result[i].tags[j]
Also, tags = should be tags +=, or you'll just overwrite the previous tag.
You have a typo, the 3rd line must be:
tags = '<div class="tag">' + parsed.result[i].tags[j] + '</div>';
(use result[i] rather than j)
When you're handling objects and arrays it's very cheap to store an extra reference to the array:
var result = parsed.result; // new
for (var i=0; i < result.length; i++) {
var tags = result[i].tags; // new
for (var j = 0; j < tags.length; j++) {
tags += '<div class="tag">' + tags[j] + '</div>';
}
html = '<div class="file""><img src="' + result[i].file_url + '" /><div class="tags">' + tags + '</div></div>';
$("#files").append(html);
};
at which point the fact that you inadvertently included the index i twice in your innermost dereference becomes impossible.
This actually performs better too, since the interpreter doesn't have to repeatedly dereference the entire chain of properties over and over.
FWIW, a cleaner jQuery way of writing this without using the .html() method would be:
var result = parsed.result; // new
for (var i=0; i < result.length; i++) {
var div = $('<div>', {'class': 'file'})
.append('<img>', {src: result[i].file_url });
var tags = result[i].tags; // new
for (var j = 0; j < tags.length; j++) {
$('<div>', {'class': 'tag', text: tags[j]}).appendTo(div);
}
$("#files").append(div);
};
which avoids all of the string concatenation, and quote mark escaping, and ensures that any HTML special characters in your tags are correctly escaped, etc.