Let's say I am appending a new div every time I submit a form to a parent div. How would I loop through all of those newly created div elements? For example:
const parentDiv = document.querySelector("div")
form.addEventListener("submit", function formSubmit(e) {
e.preventDefault()
let newDiv = document.createElement("div")
newDiv.classList.add("new-Div")
parentDiv.append(newDiv)
})
How could I loop through every newDiv element? I am trying something similar on a project I am working on and can't seem to find a solution. I have tried looping through using a for of loop but saying it is not iterable. Any help would be great!
If you tried looping through the parentDiv then yes it is not an iterable object. However, one solution could be just appending the new divs you create to a list and looping through the list like normal.
You can use getElementsByClassName()method, that will give you an array like object that you can iterate and access each element by their index like this
const newDiv = document.getElementsByClassName("new-Div");
for (let i = 0; i < newDiv.length; i++) {
console.log(newDiv[i]);
//do whatever
}
Related
This question already has an answer here:
Why does "appendChild" moves a node?
(1 answer)
Closed last month.
I have a module where I have an object and I append some elements depending how long is that object.
Now I want to set different ID's for all elements.
Here's my code:
Items.map(item =>{
var ParentDiv = document.getElementById('parentDiv');
var headerH1 = document.createElement('h1')
headerH1.setAttribute('id','header1')
ParentDiv.appendChild(headerH1);
})
What I have tried:
for(var i=0;i<=50;i++)
{
headerH1.setAttribute('id','header'+i)
ParentDiv.appendChild(headerH1);
}
I thought this would work but it just appends 50 elements but their ID will all be the same, "header50".
Can you tell me what am I missing me? Much appreciated.
Each createElement represents its own DOM element, and you need to interact with each element independently:
const parentDiv = document.getElementById('parentDiv');
Items.forEach((item, i) => {
const newItem = document.createElement('h1');
newItem.setAttribute('id', `header${i}`);
parentDiv.appendChild(newItem);
});
Also, while not required, I switched your map to a forEach since map should really only be used to create a new list, not as a function to just iterate over a list, which is what forEach is for.
Also, it's 2023, use let/const instead of var :)
I've got a task to do - to do list. I have a problem because i don't know how to move elements from parent "priority" to parent "standard".
My code of button to move is:
moveToStandardButton.addEventListener('click', function() {
const allListElements = document.querySelectorAll('[data-id="move"]');
for (let i = 0; i < allListElements.length; i++) {
let toClone = allListElements[i].checked;
}
})
toClone shoud have all list elements which are checked by user and then after click button it should move this elements to parent "standard". I've tried to do it like this but i can't use cloneNode at toClone or toClone[i].
If you log toClone, it is probably a boolean (true or false), as it is pulling whether the element is checked.
Try the following:
moveToStandardButton.addEventListener('click', function() {
// Get all elements that have a data-id of move
// I'm assuming these elements are the ones that need to move ;)
const allListElements = document.querySelectorAll('[data-id="move"]');
// iterate through the elements that need to move
for (let i = 0; i < allListElements.length; i++) {
let toClone = allListElements[i]; // Note that 'checked' isn't involved
if(!toClone.checked) continue; // If the element isn't checked, move to next element.
const clonedEl = toClone.cloneNode(true);
document.querySelector('#myOtherList').appendChild(clonedEl);
}
})
So after reading your question, I would recommend you watch or read some guides on JavaScript. You have some glaring issues that will become very apparent once you spend some time learning.
That said, I can lend some help to point you in the right direction.
1) It is not recommended to use data attributes as element identifiers. I would instead use a class, rather than data-id="move"
2) Your line let toClone is defined inside the for loop, and is scoped as such. It will not be available outside of the for loop.
3) Try creating an array outside of your for loop, and storing each checked element inside of it, and then operating on them after your loop.
I am adding table rows dynamically to a table using Javascript.
Is there a reason why items.length doesn't increase when I add a row?
I am also trying to sum the numbers contained in each row. But this doesn't work either. The dynamically added rows are completely ignored for some reason.
I am coming from jQuery where things like these used to work.
I am probably missing something really fundamental here. Thanks for any pointers.
document.addEventListener("DOMContentLoaded", function() {
var form = document.querySelector("#form");
var items = form.querySelectorAll(".item");
form.addEventListener("click", function(event) {
if (event.target.className == ".add_item") {
addFields(event);
}
});
function addFields(event) {
var item = document.createElement("template");
item.innerHTML = fields.trim();
items[items.length - 1].insertAdjacentElement("afterend", item.content.firstChild);
console.log(items.length);
event.preventDefault();
}
})
querySelector and querySelectorAll returns NodeList where as getElementsByClassName returns HTMLCollection.
The difference is, NodeList is a static copy but HTMLCollection is a live copy. So if element is modified, like in your case, a new row is added, HTMLCollection will work but NodeList will not.
So changing
var items = form.querySelectorAll(".item")
to
var items = form.getElementsByClassName("item")
might solve the problem.
Pointers
You cannot have a selector in getElementsByClassName. It expects a className, you cannot use composite selector like #form .item.
Reference:
Difference between HTMLCollection, NodeLists, and arrays of objects
You only query the items once here:
var items = form.querySelectorAll(".item");
form.addEventListener(
//you call addItem here
)
function addItem(){
//you access items.length here
}
You need to keep re-query-ing the selectors every time you add an item.
var items = form.querySelectorAll(".item"); //i got queried for the 1st time
function addFields(event) {
items = form.querySelectorAll(".item"); //get items again
//...
}
Or just don't query outside addFields() all in all. Put var items = ... in the function. There's no need to put it outside.
Read up #Rajesh's answer why this is so.
Basicly i have two buttons one who will create divs with the class "TargetDummy" and another who should be able to remove the created "TargetDummy".
The problem is i cant seem to edit the "TargetDummy"divs since they don't have an ID and i can't give them one since there are several of them.
I am looking for a solution in javascript only. My code for creating the "TargetDummy"divs is below
var Div = document.createElement("div");
document.body.appendChild(Div).className = "TargetDummy";
I thought something like
var Dummies = document.getElementsByClassName("TargetDummy");
Dummies.className = "something";
or
Dummies.remove();
would do it, but unfortunately not. I am still learning Javascript so go easy on me :)
If you want to simply hide the Divs, you could loop through them and give them a new class via the className property.
Example JS:
var Dummies = document.getElementsByClassName("red");
function addNewClass() {
for(var i = 0; i < Dummies.length; i++) {
Dummies[i].className = "newClass";
Dummies[i--].className = "newClass"
}
}
http://codepen.io/anon/pen/OPZNJN
I’m trying to add five new list items to the end of the unordered list #myList. My approach was to do the following:
const $newItem = $("<li>New Item</li>");
const $ul = $("#myList");
for(let i = 0; i < 5; ++i){
$newItem.appendTo($ul);
}
However this doesn’t work as it only inserts one list item into the list, not five.
In R. Murphy’s jQuery Fundamentals (in the Manipulation exercises in the jQuery Basics section), the solution provided by the author is very close to mine, the only difference being she doesn’t store the new list item in a variable, but rather uses an HTML string:
const $ul = $("#myList");
for(let i = 0; i < 5; ++i){
$("<li>List item " + i + "</li>").appendTo($ul);
}
It seems like my approach should work also, so I’m struggling to understand why it doesn’t. Why is this?
Your approach creates a single li element outside of the loop and tries to append the same thing to the ul five times. But since you hold a reference to a single li, each time you append it, it actually removes it from where it is and re-adds it there..
In the solution the li is created inside the loop so it is a new li element each iteration.
You could change your own to use the .clone() docs method
for (var i=0;i<5;i++){
$newItem.clone().appendTo($ul);
};
This way it will create a copy and you then add that to the ul.
you can also repalce the pointer
$newItem
into the loop
example:
var $ul = $('#myList');
for (var i=0;i<5;i++)
{
var $newItem = $('<li>New Item</li>');
$newItem.appendTo($ul);
};