Why does this for loop only print one element? - javascript

Could you help me with this problem I found on MDN?
var list = document.querySelector('.output ul');
var totalBox = document.querySelector('.output p');
var total = 0;
list.innerHTML = '';
totalBox.textContent = '';
var products = [
'Underpants:6.99',
'Socks:5.99',
'T-shirt:14.99',
'Trousers:31.99',
'Shoes:23.99'
];
for (var i = 0; i < products.length; i++) {
var subArray = products[i].split(':');
var name = subArray[0];
var price = Number(subArray[1]);
total += price;
itemText = name + ' — $' + price;
var listItem = document.createElement('li');
listItem.textContent = itemText;
list.appendChild(listItem);
}
totalBox.textContent = 'Total: $' + total.toFixed(2);
<div class="output">
<ul></ul>
<p></p>
</div>
I understand the logic but when I write only this part of the code below on my console, it returns only "Socks:5.99":
var products = [
'Underpants:6.99',
'Socks:5.99',
'T-shirt:14.99',
'Trousers:31.99',
'Shoes:23.99'
];
for (var i = 0; i < products.length; i++) {
var subArray = products[i].split(':');
var name = subArray[0];
var price = Number(subArray[1]);
}
And the subArray contains only that element. It seems like the for loop doesn’t work. Shouldn’t it give me an entire new Array with:
Underpants — $6.99
Socks — $5.99
T-shirt — $14.99
Trousers — $31.99
Shoes — $23.99

Your code works, you just have to store each iteration result somewhere, like in a new array. Here is an example:
var products = [
'Underpants:6.99',
'Socks:5.99',
'T-shirt:14.99',
'Trousers:31.99',
'Shoes:23.99'
];
var formattedProducts = [];
for (var i = 0; i < products.length; i++) {
var subArray = products[i].split(':');
var name = subArray[0];
var price = Number(subArray[1]);
formattedProducts.push(name + ' - $' + price);
}
console.log(formattedProducts);
Edit
In your first code example, the result was stored directly in your DOM, inside the .output ul list element:
var listItem = document.createElement('li');
listItem.textContent = itemText;
// list is defined outside the loop and will receive a new li element with the result of the iteration as textContent
list.appendChild(listItem);

Related

Having issues creating a for loop for a list created in JS

I'm trying to for loop the H1 object through a list 10 times. I'm not sure where I went wrong any help would be appreciated.
var headOne = document.createElement("H1");
headOne.textContent = "Hello World";
document.body.appendChild(headOne);
var newOrderedList = document.createElement('OL');
newOrderedList.setAttribute("id", "OLJS");
document.body.appendChild(newOrderedList);
var helloWorld = document.getElementById("OLJS");
for (var i = 0; headOne < 10; i++){
var listItems = document.createElement("li");
listItems.innerHTML = headOne[i];
helloWorld.append(listItems);
}
If you want to loop 10 times then do:
for (let i = 0; i < 10; i++) {
// Do something
}
And in your case if you are trying to access each letter of headOne element and append it to the helloWorld list then you can do the following:
for (let i = 0; i < headOne.textContent.length; i++) {
let listItems = document.createElement('li')
listItems.textContent = headOne.textContent[i]
helloWorld.append(listItems)
}
You might also want to read more about Loops and iteration
var headOne = document.createElement("H1");
headOne.textContent = "Hello World";
document.body.appendChild(headOne);
var newOrderedList = document.createElement('OL');
newOrderedList.setAttribute("id", "OLJS");
document.body.appendChild(newOrderedList);
//var helloWorld = document.getElementById("OLJS");
for (var i = 0; i < 10; i++) {
var listItems = document.createElement("li");
listItems.innerHTML = "order list item " + (i + 1);
newOrderedList.append(listItems);
}

How to use for loop to sum a numbers inserted by the user?

i'm trying to create a simple project where the user is prompted to enter how many numbers he would like to add(sum). then when he click the button, a javascript will create a number of input tags equal to the number he inserted and then he will fill them with a number and click another button to calculate the result of the summation and here is the problem. below is a simplified snippet explain what is the problem:
function CL(){
const items = document.getElementById("items");
for (var i = 1; i < 3; i++) {
const inpt = document.createElement("input");
inpt.setAttribute("type","text");
inpt.setAttribute("style","margin:5px;");
inpt.setAttribute("id","y"+i);
inpt.setAttribute("value","");
const newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline);
}
}
function Add(){
const y = 0;
const sum = 0;
var is;
for (var i = 1; i < 3; i++) {
is = i.toString();
y = Number(document.getElementById('y'+ is).value);
sum = sum + y;
}
document.getElementById("demo").innerHTML = sum;
}
in the for loop how can i use getElementById with variables id like item1,item2,item3,...,itemN??
is there other way to achieve what i want?
You can take all items with ID "y" + consecutive number prefix on this way document.getElementById('y' + i).value;
Do not use "Add" for function name and Functions do not have to start with capital letters!
calckStart();
function calckStart() {
const items = document.getElementById("items");
for (var i = 1; i < 3; i++) {
const inpt = document.createElement("input");
inpt.setAttribute("type", "text");
inpt.setAttribute("style", "margin:5px;");
inpt.setAttribute("id", "y" + i);
inpt.setAttribute("value", "");
const newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline);
}
var button = document.createElement('button');
button.innerHTML = 'ClickMe'
items.appendChild(button);
button.addEventListener('click', calculateVal);
}
function calculateVal() {
var res = 0;
for (var i = 1; i < 3; i++) {
res = res + +document.getElementById('y' + i).value;
}
var items = document.getElementById("items");
var result = document.createElement('div');
result.innerHTML = res;
items.appendChild(result);
}
<div id="items"></div>
A better way is ...
When you create elements, you can assign them a CLASS attribute that is one for all input elements. You can then take the values from all elements with this class.
Example:
calckStart();
function calckStart() {
const items = document.getElementById("items");
for (var i = 1; i < 3; i++) {
const inpt = document.createElement("input");
inpt.setAttribute("type", "text");
inpt.setAttribute("style", "margin:5px;");
// inpt.setAttribute("id", "y" + i);
inpt.setAttribute("value", "");
inpt.setAttribute("class", "numbers"); //<-- Set class
const newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline);
}
var button = document.createElement('button');
button.innerHTML = 'ClickMe'
items.appendChild(button);
button.addEventListener('click', calculateVal);
}
function calculateVal() {
var list = document.getElementsByClassName('numbers'); //<-- Get by class
var res = 0;
for (var i = 0; i < list.length; i++) {
res = res + +list[i].value;
}
var items = document.getElementById("items");
var result = document.createElement('div');
result.innerHTML = res;
items.appendChild(result);
}
<div id="items"></div>
You can use ...args to collect arguments and use .reduce to add the arguments together.
const items = document.getElementById("items");
for (var i = 0; i < 3; i++) {
var inpt = document.createElement("input");
inpt.setAttribute("type","number"); //replaced with number
inpt.setAttribute("style","margin:5px;");
inpt.setAttribute("id","y"+i);
inpt.setAttribute("value","");
var newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline); //added newline appending
}
function sum(...args) {
return args.reduce((a, b) => a+b); //reduce arguments
}
<div id="items"></div><br /><button onclick="document.getElementById('answer').textContent = 'answer: ' + sum(+y0.value, +y1.value, +y2.value)">Add</button><div id="answer"></div>

Unable to parse json using javascript

I have a json which i'm trying to parse it using javascript. Iteration count and the pages getting appended to it are going to be dynamic.
Expected Result
Just like the above image i'm able to take dynamic iteration keys from the below mentioned json.
Iteration.json
{
"count":[
{
"iteration1":[
{
"PageName":"T01_Launch"
},
{
"PageName":"T02_Login"
}
]
},
{
"iteration2":[
{
"PageName":"T01_Launch"
},
{
"PageName":"T02_Login"
}
]
}
]
}
When i click on iteration it has to populate the corresponding pagenames for that particular iteration as shown in expected result image. But what i get actually is (refer the image below):
Please find the code that i tried:
var pagenamearray = [];
$.getJSON("iteration.json", function(json) {
var hits = json.count;
var iterations, tnname, iteration;
for (var k in hits) {
var value;
if (hits.hasOwnProperty(k)) {
value = hits[k];
var iteratearray = [];
for (var j in value) {
if (value.hasOwnProperty(j)) {
j;
var check = value[j];
for (var i in check) {
if (check.hasOwnProperty(i)) {
var test = check[i];
for (var t in test) {
if (test.hasOwnProperty(t)) {
var pagename = JSON.stringify(t)
var arr = []
if (pagename.includes("PageName")) {
//alert("Key is " +pagename + ", value is" + JSON.stringify(test[t]));
for (var it = 0; it < hits.length; it++) {
if ((Object.keys(hits[it])).includes(j)) {
var pagenamevalue = test[t];
arr[it] = [];
arr.push(pagenamevalue);
}
}
}
//alert(arr)
}
pagenamearray.push(arr);
}
}
}
}
var row = document.createElement('div');
row.setAttribute("class", "row");
row.setAttribute("id", j)
var gridWidth = document.createElement('div');
gridWidth.setAttribute("class", "col-lg-12");
var panelRoot = document.createElement('div');
panelRoot.setAttribute("class", "panel panel-default");
var panelHeading = document.createElement('div');
panelHeading.setAttribute("class", "panel-heading");
var heading3 = document.createElement('a');
heading3.setAttribute("class", "panel-title");
var icon = document.createElement('i');
icon.setAttribute("class", "fa fa-long-arrow-right fa-fw");
heading3.appendChild(icon);
heading3.innerHTML = j;
heading3.setAttribute("onclick", "doit('" + j + "');");
panelHeading.appendChild(heading3);
/* var panelBody=document.createElement('div');
panelBody.setAttribute("class","panel-body");
panelBody.setAttribute("id","panellinks");*/
panelRoot.appendChild(panelHeading);
// panelRoot.appendChild(panelBody)
gridWidth.appendChild(panelRoot);
row.appendChild(gridWidth);
document.getElementById("analysis").appendChild(row);
}
}
}
});
function doit(value) {
var ul = document.getElementById(value);
if (ul != undefined) {
$("#" + "expandlinks").remove();
$("#" + value + value).remove();
}
var accordion = document.getElementById(value);
var panelBody = document.createElement('div');
panelBody.setAttribute("class", "panel-body");
panelBody.setAttribute("id", "expandlinks")
var tablediv = document.createElement('div')
var tablelink = document.createElement('a');
tablediv.appendChild(tablelink);
var graphdiv = document.createElement('div')
var graphlink = document.createElement('a');
graphdiv.appendChild(graphlink);
var recommndiv = document.createElement('div');
var recommendlink = document.createElement('a');
recommndiv.appendChild(recommendlink)
//alert(pagenamearray.length)
tablelink.innerHTML = pagenamearray;
/*graphlink.innerHTML="Timeline View";
recommendlink.innerHTML="Recommendations";*/
panelBody.appendChild(tablediv);
panelBody.appendChild(recommndiv);
panelBody.appendChild(graphdiv);
accordion.appendChild(panelBody);
}
Any advise on how to achieve this would be of great help. Thanks in advance.
I think the problem is how you assign the pagenamearray to tablelink.innerHTML. This converts the array to a string, converting all elements in the array to a string too and separating them by a comma each. However, your pagenamearray contains some empty arrays too; these will convert to an empty string in the process, but will still have a comma before and after them.
In your example code above, the pagenamearray will end up with a value of [[[],"T01_Launch"],[[],"T02_Login"],[null,[],"T01_Launch"],[null,[],"T02_Login"]] - when converted to a String, this will result in ",T01_Launch,,T02_Login,,,T01_Launch,,,T02_Login". So instead of assigning it to the innerHTML value directly, you'll first have to filter out the empty arrays and null values.

how to create new list and add list items to new list using javascript

I am trying to create a new list and add it to the DOM, and then add list items to new list along with text node to each list item.
This is what I have so far, after trying several ways to do this, but still not accomplishing goal. any help is appreciated.The first 4 lines of code is HTML snippet, the code below that is the JavaScript code. Again thank you for any help with this.
<body>
<div id="nav"></div>
<script src="js/script.js"></script>
</body>
var newList = document.createElement("ul");
var newListItem = document.createElement("li");
var stringArray = ["Home","About","Our Services","Contact Us"];
var newUL = document.getElementById("nav").appendChild(newList);
function buildList(){
for( var i = 0; i < stringArray.length; i++){
newUL.appendChild(newListItem);
}
var listItems = document.getElementsByTagName("li");
for( var i = 0; i < listItems.length; i++){
listItems[i].appendChild(stringArray[i]);
}
}
buildList();
Two problems:
You're appending the same li over and over. You need to create a new one for each item.
You can't append a string to a DOM element, but you can set its textContent:
var stringArray = ["Home","About","Our Services","Contact Us"];
function buildList(){
var newList = document.createElement("ul");
var newListItem;
document.getElementById("nav").appendChild(newList);
for( var i = 0; i < stringArray.length; i++){
newListItem = document.createElement('li');
newListItem.textContent = stringArray[i];
newList.appendChild(newListItem);
}
}
buildList();
<div id="nav"></div>
Slightly cleaner version with .forEach():
var stringArray = ["Home","About","Our Services","Contact Us"];
function buildList(){
var newList = document.createElement("ul");
document.getElementById("nav").appendChild(newList);
stringArray.forEach(function (title) {
var newListItem = document.createElement('li');
newListItem.textContent = title;
newList.appendChild(newListItem);
});
}
buildList();
<div id="nav"></div>
You need to create a text node and append it to the <li> element.
var newList = document.createElement("ul");
var stringArray = ["Home","About","Our Services","Contact Us"];
// Create a <ul> element
var newUL = document.getElementById("nav").appendChild(newList);
function buildList(){
for(var i = 0; i < stringArray.length; i++){
// Create a text node
var newTextNode = document.createTextNode(stringArray[i]);
// Create a list element
var newListItem = document.createElement("li");
// Append text node and list item
newListItem.appendChild(newTextNode);
newUL.appendChild(newListItem);
}
}
buildList();
<body>
<div id="nav"></div>
</body>
Just loop over the string array and add lis, like this:
var nav = document.querySelector("nav");
var list = document.createElement("ul");
var items = ["Home","About","Our Services","Contact Us"];
items.forEach(function(item) {
var li = document.createElement("li");
li.innerText = item;
list.appendChild(li);
})
nav.appendChild(list);
Codepen example here
If it's supposed to be a site navigation, you may want to add links. That's easy, too – just append <a> in the loop like this:
var nav = document.querySelector("nav");
var list = document.createElement("ul");
var items = [{
text: "Home",
url: "/home"
}, {
text: "About",
url: "/about"
}, {
text: "Our services",
url: "/services"
}, {
text: "Contact Us",
url: "/contact"
}]
items.forEach(function(item) {
var li = document.createElement("li");
var link = document.createElement("a");
link.innerText = item.text;
link.href = item.url;
li.appendChild(link);
list.appendChild(li);
})
nav.appendChild(list);
Codepen example here
In this case, I would contend that using innerHTML and Array#join is simpler and more readable than other alternatives:
var stringArray = ["Home", "About", "Our Services", "Contact Us"];
function buildList() {
document.getElementById('nav').innerHTML = '<ul><li>' + stringArray.join('</li><li>') + '</li></ul>'
}
buildList()
<nav id="nav"></nav>

For loop through Array only shows last value

I'm trying to loop through an Array which then uses innerHTML to create a new element for every entry in the array. Somehow my code is only showing the last value from the array. I've been stuck on this for a few hours and can't seem to figure out what I'm doing wrong.
window.onload = function() {
// Read value from storage, or empty array
var names = JSON.parse(localStorage.getItem('locname') || "[]");
var i = 0;
n = (names.length);
for (i = 0; i <= (n-1); i++) {
var list = names[i];
var myList = document.getElementById("list");
myList.innerHTML = "<li class='list-group-item' id='listItem'>"+ list + "</li>" + "<br />";
}
}
I have a UL with the id 'list' in my HTML.
Change your for loop:
for (i = 0; i <= (n-1); i++) {
var list = names[i];
var myList = document.getElementById("list");
myList.innerHTML += "<li class='list-group-item' id='listItem'>"+ list + "</li>" + "<br />";
}
Use += instead of =. Other than that, your code looks fine.
I suggest you to first make a div by create element. there you add your innerHTML and after that you can do the appendchild. That will work perfectly for this type of scenario.
function displayCountries(countries) {
const countriesDiv = document.getElementById('countriesDiv');
countries.forEach(country => {
console.log(country.borders);
const div = document.createElement('div');
div.classList.add('countryStyle');
div.innerHTML = `
<h1> Name : ${country.name.official} </h1>
<h2> Capital : ${country.capital} </h2>
<h3> Borders : ${country.borders} </h3>
<img src="${country.flags.png}">
`;
countriesDiv.appendChild(div);
});
}

Categories

Resources