Matteo
Matteo

Reputation: 79

How to remove items on my todo list with local storage by clicking on one button

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

Answers (2)

Matteo
Matteo

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

Julian Adler
Julian Adler

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

Related Questions