I'm trying to output an array of items to a list. The problems is when I click submit it's adding all the array items to each list item instead of one each time.
JSFIDDLE:
https://jsfiddle.net/b7Lwbrof/
Thanks!
var itemList = [];
var container = document.getElementById('container');
// On click
document.getElementById('submit').addEventListener("click", function(){
var itemValue = document.getElementById('itemValue').value;
// Push to array
itemList.push(itemValue);
// Append to List
for(i=0; i<itemList.length; i++) {
var items = document.createElement("li");
document.getElementById('container').appendChild(items);
items.innerHTML = itemList[i];
}
})
You don't need loop then, just append the item after it has been push to the itemList.
document.getElementById('submit').addEventListener("click", function(){
var itemValue = document.getElementById('itemValue').value;
// Push to array
itemList.push(itemValue);
// Append to List
var items = document.createElement("li");
document.getElementById('container').appendChild(items);
items.innerHTML = itemList[itemList.length-1];
})
items.innerHTML = itemList[itemList.length - 1] // get the last
and NOT
items.innerHTML = itemList[i]
And remove the loop as #digit said .
Fiddle here
Related
var array = {
'Brazilians': ['Thalison', 'Allan'],
'Venezuelans': ['Jaime', 'Andres'],
}
I just learned how to display the array with this:
for (key in array) {
document.write(`${key}: ${array[key]}<br>`);
console.log(`${key}: ${array[key]}`);
}
I hope to get this result with
<ul>
<li>
Brazilians
<ul>
<li>Thalison</li>
<li>Allan</li>
</ul>.....
var array = {
'Brazilians': ['Thalison', 'Allan'],
'Venezuelans': ['Jaime', 'Andres'],
}
const createItem = (text) => {
const li = document.createElement('li')
li.innerText = text;
return li
}
for (key in array) {
const ul = document.createElement('ul')
const li = createItem(key)
li.style.fontWeight = 'bold'
ul.append(li)
array[key].forEach(item => {
const li = createItem(item)
ul.append(li)
})
document.body.append(ul)
}
First of: never use document.write. Even the documentation recommends against using it and gives some reason to why you shouldn't use it.
One way to create HTML in JavaScript is with document.createElement(). This function can create HTML elements, which you can then append to the DOM with the append() method that every HTML Element has.
In the example below I've used a for...of loop in combination with Object.keys(). While for...in can be used to iterate over objects, the for...of loop is recommended as it only loops over values that should be looped over. See the difference here.
Object.keys() turn all the property keys into an array of keys. So the result in this case would be ['Brazilians', 'Venezuelans'] where we in turn loop over.
Inside the loop we create a second loop where we loop over the names array of each property in the object.
var data = {
'Brazilians': ['Thalison', 'Allan'],
'Venezuelans': ['Jaime', 'Andres'],
}
// First create the outer list.
const list = document.createElement('ul');
// Loop over the keys of the object.
for (let key of Object.keys(data)) {
// Create a list item for every key.
const listItem = document.createElement('li');
listItem.textContent = key;
// Create the sub list.
const subList = document.createElement('ul');
// Loop over the nested array.
for (let name of data[key]) {
// Create a sub list item for every name.
const subListItem = document.createElement('li');
subListItem.textContent = name;
// Add the sub list item to the sub list.
subList.append(subListItem);
}
// Add the sub list to the list item.
listItem.append(subList);
// Add the list item to the list.
list.append(listItem);
}
// Add the list to the body.
document.body.append(list);
I have a button that creates two input fields on click. I want to add a unique id for each couple of inputs that is created so that I can delete them later. Currently when I add the inputs they all have the same id 0 and the index does not increment, why and how can I make it increment? Here is my code:
createNewPricedRoundShareholder() {
const mainParent = document.getElementById('main-parent');
var index = 0;
const newPlatformNameInput1 = document.createElement("input");
newPlatformNameInput1.id = index + '_first';
newPlatformNameInput1.value = index;
const newPlatformNameInput2 = document.createElement("input");
newPlatformNameInput2.id = index + '_second';
newPlatformNameInput2.value = index;
const deleteButton = document.createElement("button");
deleteButton.innerText = 'delete';
const wrapperParent = document.createElement('div');
wrapperParent.id = index + '_parent';
wrapperParent.appendChild(newPlatformNameInput1);
wrapperParent.appendChild(newPlatformNameInput2);
wrapperParent.appendChild(deleteButton); mainParent.appendChild(wrapperParent);
index++;
}
and my html:
<div id="main-parent"></div>
I know you said you want an ID so you can use it to delete your row later, but you don't actually need it. If you add this code to your function, you can delete the entire row without the need of using an ID. This code will allow you to target the specific button, then the parent of that button and remove it.
deleteButton.addEventListener("click",function(e){
e.preventDefault();
e.target.parentNode.remove();
});
I think that is because you increase the index at the end of your function but you should increase it after creating the first input and before creating the second one
[...]
const newPlatformNameInput1 = document.createElement("input");
newPlatformNameInput1.id = index + '_first';
newPlatformNameInput1.value = index;
index++;
const newPlatformNameInput2 = document.createElement("input");
newPlatformNameInput2.id = index + '_second';
[...]
I am building a Todo-List Project and i am stuck at looping through my newly created list items.
This is what i am doing:
Created an array.
Made li items for array's each element through looping so that array appears in a list manner.
And then looping through newly created li section to addEventListener on each of li's ( But this one is not working).
var arrList = ["play","learn","walk"];
var list = document.querySelectorAll("li");
var done = false;
//printing array in list manner
for(let i = 0; i < arrList.length; i++){
let el = document.createElement("li")
el.textContent = arrList[i];
document.querySelector("ul").appendChild(el);
}
//looping through each li's to apply if else statement
for(let i = 0; i < list.length; i++){
list[i].addEventListener("click",function(){
if(!done){
this.style.textDecoration = "line-through";
done = true;
}else{
this.style.textDecoration = "none";
done = false;
}
})
}
You're code is mostly correct, however there are a few issues that need to be addressed. First, consider replacing your for loop with iteration based on forEach() as shown below. Using forEach() in this way allows you to leverage "closure" which in this case will greatly simplify your code. For instance, you can use the closure feature to store the done state of each item in your list, rather than storing that state explicitly in an array.
The other issue I noticed was var list = document.querySelectorAll("li"); queries the document for li elements before any are added to your document - later in your script it seems you're iterating that empty query result and expecting it to contain the added li elements.
Here's a working snippet - hope this helps!
var arrList = ["play", "learn", "walk"];
// Iterate the list via forEach
arrList.forEach(function(arrItem) {
// We're now in a new "closure" for this list item
// so we can define some state like "done" that will
// be used exclusively for this list item
var done = false;
// Create li element for this list item as before
var el = document.createElement("li")
el.textContent = arrItem;
// Configure click event
el.addEventListener("click", function() {
// Notice we're able to use the done variable
// in this closure for this list item? The key
// thing to understand is that each list item
// will have it's own unique "done" variable
if (!done) {
el.style.textDecoration = "line-through";
done = true;
} else {
el.style.textDecoration = "none";
done = false;
}
})
document.querySelector("ul").appendChild(el);
});
<ul></ul>
It seems like you only have one done variable that is shared for every item on the todo list. Therefore if you click one of the items all of the items will be crossed out. You will need a boolean variable for every item in your to do list.
Add this line just above the second for loop and remove from the top.
var list = document.querySelectorAll("li");
You are assigning list the values even before they are created.
from the source code I see that the list li item is initialized before new li item been created,
it will cause the list li item not contains the new one,
due to that addEventListener will not working for the new item.
to fix this, just need move init list li item code after creation part :
var arrList = ["play","learn","walk"];
var done = false;
//printing array in list manner
for(let i = 0; i < arrList.length; i++){
let el = document.createElement("li")
el.textContent = arrList[i];
document.querySelector("ul").appendChild(el);
}
var list = document.querySelectorAll("li");
//looping through each li's to apply if else statement
for(let i = 0; i < list.length; i++){
list[i].addEventListener("click",function(){
if(!done){
this.style.textDecoration = "line-through";
done = true;
}else{
this.style.textDecoration = "none";
done = false;
}
})
}
Please, be simple...
var
arrList = ["play","learn","walk"],
UL_arrList = document.querySelector("ul")
;
arrList.forEach (arrItem => {
let el = document.createElement("li");
el.textContent = arrItem;
UL_arrList.appendChild(el);
el.onclick = function(e){
let deco = this.style.textDecoration || 'none';
this.style.textDecoration = (deco==='none') ? 'line-through': 'none';
}
});
<ul></ul>
I'm really sorry for I am aware similar questions have already been asked, but whenever I try to do it myself, none seem to apply or work. Basically when a user clicks on one of the elements, I am trying to get the following variables:
the id of the selected element
an array with all of the values prior to selected + selected one
an array with all of the values post-selected (selected not included)
the id of the element directly following the selected one
Thanks to your help in different posts, I have so far managed to complete the first two ones (in italic), but am unable to achieve the other two.
Would anyone know how to do so please? Thank you all in advance for your help!!
jQuery:
var days = ['#monday','#tuesday','#wednesday','#thursday','#friday','#saturday','#sunday'];
$('.days').on('click', function() {
var day = '#'+this.id;
var index = days.indexOf(day)+1;
var prev = days.slice(0, index);
var next = days.slice(index);
var above = days[index];
});
Should look more like this (though I really don't understand your code logic):
var dayIds = ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
$('.days').on('click', function() {
//get selected element id
var dayId = this.id;
//find selected position in array and delete all values after
var dayPos = dayIds.indexOf(dayId);
var daysBelow = dayIds.slice(0, dayPos + 1;
//find position of item directly after selected and get value
var dayAfterPos = dayIds.indexOf(dayId) + 1;
var dayAfter = dayIds[dayAfterPos]; //(not working)
//only keep values following selected one
...
console.log(floorsBelow, floorId);
});
This is how you need to slicing the array. I'm not sure all the requirements you have so I have just taken out a snippet to demonstrate how you can get your values.
var dayIds = new Array('#monday','#tuesday','#wednesday','#thursday','#friday','#saturday','#sunday');
const current = '#thursday';
const currentIndex = dayIds.indexOf(current)+1;
const prev = dayIds.slice(0, currentIndex);
const next = dayIds.slice(currentIndex);
console.log(current); //#thursday
console.log(prev); //[ '#monday', '#tuesday', '#wednesday', '#thursday' ]
console.log(next); // [ '#friday', '#saturday', '#sunday' ]
EDIT:
Added newVar to contain next value
var dayIds = new Array('#monday','#tuesday','#wednesday','#thursday','#friday','#saturday','#sunday');
const current = '#thursday';
const currentIndex = dayIds.indexOf(current)+1;
const prev = dayIds.slice(0, currentIndex);
const next = dayIds.slice(currentIndex);
const newVar = dayIds[currentIndex];
console.log(current); //#thursday
console.log(prev); //[ '#monday', '#tuesday', '#wednesday', '#thursday' ]
console.log(next); // [ '#friday', '#saturday', '#sunday' ]
console.log(newVar); // #friday
I am using dexie.js, which is an indexDB wrapper. Anywhoo, I have an array that is called from the user's local storage, and my function is supposed to iterate through every list item in the DB and show it. However, upon clicking on my Butane it only shows the most recent input of name.
Note: You can see the entire database by adding a few values in and checking your local storage.
My JsFiddle:
https://jsfiddle.net/enzp3zws/1/
my html:
<ul id="mane"></ul>
my js:
var db = new Dexie("TestDatabase");
db.version(1).stores({
friends: '++id, name, age'
});
var collection = db.friends;
var placement = document.getElementById('rainman');
var jacement = document.getElementById('rainboy');
var stacement = document.getElementById('mane');
var listed = document.createElement('li');
function addrain(){
collection.each(function(friend){
var element = [friend.name];
for (var i = 0; i < element.length; i++){
listed.textContent = element[i];
document.getElementById('mane').appendChild(listed);
//alert(element); <-- this call alerts all names in database.
}
});
}
Please excuse the randomness of some of these variable names. I don't know what sleep is anymore.
You need to create a new 'li' element each time:
//Remove var listed = ... line in header, then:
function addrain(){
collection.each(function(friend){
var element = [friend.name];
for (var i = 0; i < element.length; i++){
var listed = document.createElement('li');
listed.textContent = element[i];
document.getElementById('mane').appendChild(listed);
}
//alert(element); <-- this call alerts all names in database.
});
}
The reason your code did not work before is that you only created one li element, and repeatedly changed its text and re-inserted it at different locations.