Reputation: 79
I am practising on a todolist. I would like to remove the items from the list with a button in one go . When I click the button Clear
the second if
of containerList.addEventListener
manages to delete all the items from the local storage. Unfortunately I can't manage to target the <li>
in the DOM and remove the same items there too, unless I refresh...
How to target and remove them? I have also tried to target `list.children.remove()' but there is an error saying "it is not a function". Plese help. Thank you
const addForm = document.querySelector('.add');
const list = document.querySelector('.todos');
const clearAll = document.querySelector('.bottomForm');
const containerList = document.querySelector('.containerList');
// salvato gli items dal local storage in una variabile
let storedItems = localStorage.getItem('tasks');
const generateTemplate = todo => {
const html = `
<li class="newList">
<div class="tick">
<input type="checkbox" id="" name="" value="">
</div>
<div class="content">
<span>${todo}</span>
<i class="fas fa-times delete"></i>
</div>
</li>`
list.innerHTML += html;
}
if (!storedItems) {
storedItems = [];
} else {
storedItems = JSON.parse(storedItems);
storedItems.forEach(item => {
generateTemplate(item);
});
}
addForm.addEventListener('submit', e => {
const todo = addForm.add.value.trim();
e.preventDefault();
if (todo.length) {
generateTemplate(todo);
storedItems.push(todo);
localStorage.setItem('tasks', JSON.stringify(storedItems))
addForm.reset();
console.log(`${todo} has been added to html list`)
console.log(`Local storage now contains ${storedItems}`)
document.getElementById("numberItems").innerHTML = `${storedItems.length} item(s) `; //counting element when added
console.log(`aftr adding, now the items are ${storedItems.length}`)
}
});
/*Removing item*/
containerList.addEventListener('click', e => {
console.log(e.target);
if (e.target.classList.contains('delete')) {
e.target.parentElement.parentElement.remove();
let removedItem = e.target.parentElement.firstElementChild.innerText;
//console.log(`${removedItem} has been removed from the html list`);
//console.dir(e.target.parentElement.firstElementChild.innerText);
//console.log(storedItems)
const newArr = storedItems.filter(item => item !== removedItem)
//console.log(newArr)
storedItems = newArr
localStorage.setItem('tasks', JSON.stringify(storedItems))
document.getElementById("numberItems").innerHTML = `${storedItems.length} item(s) `; //counting element when deleted
//console.log(`Local storage now contains ${storedItems} `)
//console.log(`after removing, now the items are ${storedItems.length}`)
}
if (e.target.classList.contains('clears')){
window.localStorage.removeItem('tasks');
console.log('clear button has been pushed')
document.getElementsByClassName("newList").innerHTML = ''
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- displays site properly based on user's device -->
<link rel="icon" type="image/png" sizes="32x32" href="./images/favicon-32x32.png">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<title>Frontend Mentor | Todo app</title>
<!-- Feel free to remove these styles or customise in your own stylesheet 👍 -->
<!-- <style>
.attribution { font-size: 11px; text-align: center; }
.attribution a { color: hsl(228, 45%, 44%); }
</style> -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!--
Todo
items left
All
Active
Completed
Clear Completed
Drag and drop to reorder list -->
<div class="mainTitle">
<h1>TO DO</h1>
</div>
<form action="" class="add">
<div class="inputE">
<input type="text" id="name" name="add" placeholder="Enter name here">
</div>
<div class="containerList">
<ul class="todos"></ul>
<div class="bottomForm">
<div class="itemsLeft">
<p><span id="numberItems"></span> left</p> <!--use if for items or item !-->
</div>
<div class="allItems">
<button onclick="myFunction()">All</button>
</div>
<div class="activeItems">
<button onclick="myFunction()">Active</button>
</div>
<div class="completedItems">
<button onclick="myFunction()">Completed</button>
</div>
<div class="clear">
<button onclick="" class="clears">Clear</button>
</div>
<div class="completedItems">
<button onclick="myFunction()">Completed</button>
</div>
</div>
</div>
</div>
</form>
<!-- <div class="attribution">
Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>.
Coded by <a href="#">Your Name Here</a>.
</div> -->
<script src="app.js"></script>
</body>
</html>
Upvotes: 0
Views: 662
Reputation: 79
The challenge was to target and remove all the children of .list
. list.children.remove()
did not work because
the children properties holds a HTMLCollection of elements, which does not support remove()
as @Julian Adler stated.
So I have used childNodes
property in the for loop
to remove all the items of the list (
in reality all the nodes, including white spaces and <i>
):
`for (let i= list.childNodes.length -1; i>=0; i--) {
list.childNodes[i].remove()
}`
const addForm = document.querySelector('.add');
const list = document.querySelector('.todos');
const containerList = document.querySelector('.containerList');
let storedItems = localStorage.getItem('tasks');
const generateTemplate = todo => {
const html = `
<li class="newList">
<div class="tick">
<input type="checkbox" id="" name="" value="">
</div>
<div class="content">
<span>${todo}</span>
<i class="fas fa-times delete"></i>
</div>
</li>`
list.innerHTML += html;
}
if (!storedItems) {
storedItems = [];
} else {
storedItems = JSON.parse(storedItems);
storedItems.forEach(item => {
generateTemplate(item);
});
}
addForm.addEventListener('submit', e => {
const todo = addForm.add.value.trim();
e.preventDefault();
if (todo.length) {
generateTemplate(todo);
storedItems.push(todo);
localStorage.setItem('tasks', JSON.stringify(storedItems))
addForm.reset();
console.log(`${todo} has been added to html list`)
console.log(`Local storage now contains ${storedItems}`)
document.getElementById("numberItems").innerHTML = `${storedItems.length} item(s) `; //counting element when added
console.log(`aftr adding, now the items are ${storedItems.length}`)
}
});
/*Removing item*/
containerList.addEventListener('click', e => {
console.log(e.target);
if (e.target.classList.contains('delete')) {
e.target.parentElement.parentElement.remove();
let removedItem = e.target.parentElement.firstElementChild.innerText;
const newArr = storedItems.filter(item => item !== removedItem)
storedItems = newArr
localStorage.setItem('tasks', JSON.stringify(storedItems))
document.getElementById("numberItems").innerHTML = `${storedItems.length} item(s) `; //counting element when deleted
${storedItems.length}`)
}
if (e.target.classList.contains('clears')){
window.localStorage.removeItem('tasks');
console.log('clear button has been pushed')
for (let i= list.childNodes.length -1; i>=0; i--) {
list.childNodes[i].remove()
}
}
})
Upvotes: 0
Reputation: 100
You were close with list.children.remove()
! The problem is, that the children properties holds a HTMLCollection
of elements, which does not support remove()
itself. You can iterate over that HTMLCollection
with a loop and call remove()
on every child element:
for (const child of list.children) {
child.remove()
}
Alternativly you could convert it to a array and use the typical array functions, if you are more familiar with those:
[...list.children].forEach(child => child.remove())
Upvotes: 1