** I want when to click on the active button if the checkbox is checked to add filtered class in HTML element but it doesn't work and give me an undefined error in this line check.parentElement.classList.add("filtered"); **
<ul class="ul-list"></ul>
</section>
</main>
<footer class="footer">
<button class="all footer-btn">All</button>
<button class="active footer-btn">Active</button>
<button class="complete footer-btn">Complete</button>
</footer>
let check = document.querySelectorAll(".complete-txt");
let complete_btn = document.querySelector(".complete");
let active_btn = document.querySelector(".active");
let all_btn = document.querySelector(".all");
let edit_list = document.querySelector(".edit-list");
let main_text = document.querySelector(".main-text");
let list_item = document.querySelector(".list-item");
let footer = document.querySelector(".footer");
const generateTemplate = (todo) => {
const html = `
<li class="list-item">
<input type="checkbox" class="complete-txt" name="" id="check"><span class="main-text">${todo}</span><div class="edit-list"></div><div class="delete-list"></div>
</li>
`;
list.innerHTML += html;
};
// add todos event
addForm.addEventListener("submit", (e) => {
e.preventDefault();
const todo = addForm.add.value.trim();
if (todo.length) {
generateTemplate(todo);
addForm.reset();
}
});
active_btn.addEventListener("click", function () {
let check_id = document.querySelector(".complete-txt");
// check.forEach(function () {
debugger;
if (check.checked !== "true") {
check.parentElement.classList.add("filtered");
console.log("hi");
}
// });
// console.log("hi");
console.log("hi");
// console.log(check.checked.value);
});
if the larger document fixes all other inconcistencies you should be able to change the eventlistener to
active_btn.addEventListener("click", function () {
let check_id = document.querySelector(".complete-txt");
if (check_id.checked !== "true") {
check_id.parentElement.classList.add("filtered");
}
});
BUT!!! this will not "fix" all of your errors, like defining let check before the checkbox is created with generateTemplate
Related
I called the function inside the backticks onclick of the input and lis and on fontawesome icon it is not calling the function but the onclick is working as it shows in console.
and here is the code.
let editId;
let isEditTask = false;
let todos = JSON.parse(localStorage.getItem('todo-list'));
function showTodo(filter) {
let liTag = '';
if (todos) {
todos.forEach((todo, id) => {
const completed = todo.status === 'completed' ? 'checked' : '';
if (filter === todo.status || filter === 'all') {
liTag += `<li class="task">
<label for="${id}">
<input onclick="updateStatus(this)" type="checkbox" id="${id}" ${completed}>
<p class="${completed}">${todo.name}</p>
</label>
<div class="settings">
<i onclick="showMenu(this)" class="uil uil-ellipsis-v"></i>
<ul class="task-menu">
<li onclick='editTask(${id}, "${todo.name}")'><i class="uil uil-pen"></i>Edit</li>
<li onclick='deleteTask(${id}, "${filter}")'><i class="uil uil-trash"></i>Delete</li>
</ul>
</div>
</li>`;
}
});
}
taskBox.innerHTML = liTag || '<span>You don\'t have any task here</span>';
const checkTask = taskBox.querySelectorAll('.task');
!checkTask.length ? clearAll.classList.remove('active') : clearAll.classList.add('active');
taskBox.offsetHeight >= 300 ? taskBox.classList.add('overflow') : taskBox.classList.remove('overflow');
}
showTodo('all');
filters.forEach((btn) => {
btn.addEventListener('click', () => {
document.querySelector('span.active').classList.remove('active');
btn.classList.add('active');
showTodo(btn.id);
});
});
function updateStatus(selectedTask) {
const taskName = selectedTask.parentElement.lastElementChild;
if (selectedTask.checked) {
taskName.classList.add('checked');
todos[selectedTask.id].status = 'completed';
} else {
taskName.classList.remove('checked');
// todos[selectedTask.id].status = "pending";
}
localStorage.setItem('todo-list', JSON.stringify(todos));
}
I tried to not use backticks and create each of them using createElement.
I am still working on that way
You could use event delegation here, sample example below, we target ul and then the click on particular li element and do whatever intended to do
Event delegation tutorial ...
const sample = document.querySelector("#sample");
const ul = document.createElement("ul");
sample.append(ul)
const fruits = ["apple","orange","grapes"];
let li = "";
fruits.forEach((fruit)=>{
li += `<li id=${fruit}>${fruit}</li>`;
ul.innerHTML= li;
})
ul.addEventListener("click",function(e){
if(e.target?.tagName === "LI"){
console.log(e.target.innerText)
}
})
<div id="sample"></div>
I was making a simple to-do list. You submit itens from an input and they go to the To-DO section. When you click over them they go to the 'Done' section. And when you click on them again, they vanish forever. It was all working fine.
But I realized the doneItens array kept growing in length, which I wanted to optimize. So I came up with this line of code
doneItens.splice(i, 1);
which goes inside an onclick event, which you can see in the code inside the deleteDone function.
That gives the error, though,
Error:{
"message": "Uncaught TypeError: doneItens.splice is not a function"
If I put it outside and below the onclick event it also doesn't work. How can I do it?
var input = document.getElementById('play');
var toDo = document.getElementsByTagName('ol')[0];
var done = document.getElementById('done');
function handleSubmit(event) {
event.preventDefault();
const newItem = document.createElement('li');
newItem.setAttribute('class', 'item');
newItem.append(input.value);
toDo.append(newItem);
input.value='';
deleteItem();
}
function deleteItem() {
const toBeDone = document.getElementsByClassName('item');
for(let i = 0; i < toBeDone.length; i++) {
toBeDone[i].onclick = () => {
appendItemDone(toBeDone[i]);
toBeDone[i].style.display = 'none';
deleteDone();
}
}
}
function appendItemDone(item) {
const newDone = document.createElement('li');
newDone.setAttribute('class', 'feito')
newDone.append(item.innerText);
done.append(newDone);
}
function deleteDone() {
const doneItens = document.getElementsByClassName('feito');
console.log('done length', doneItens.length)
for (let i = 0; i < doneItens.length; i++) {
doneItens[i].onclick = () => {
doneItens[i].style.display = 'none';
doneItens.splice(i, 1);
}
}
}
<div id='flex'>
<form class='form' onsubmit='handleSubmit(event)'>
<input placeholder='New item' type='text' id='play'>
<button>Send</button>
</form>
<div id='left'>
<h1 id='todo' >To-do:</h1>
<p class='instruction'><i>(Click over to mark as done)</i></p>
<ol id='here'></ol>
</div>
<div id='right'>
<h1>Done:</h1>
<p class='instruction'><i>(Click over to delete it)</i></p>
<p id='placeholder'></p>
<ol id='done'></ol>
</div>
</div>
With the use of JavaScript DOM API such as Node.removeChild(), Element.remove() and Node.parentNode, your task can be solved with this code:
const input = document.getElementById('play');
const todo = document.getElementById('todo');
const done = document.getElementById('done');
function handleSubmit(event) {
event.preventDefault();
// create new "todo" item
const newTodo = document.createElement('li');
newTodo.textContent = input.value;
todo.append(newTodo);
// clean the input field
input.value = '';
// listen to "click" event on the created item to move it to "done" section
newTodo.addEventListener('click', moveToDone);
}
function moveToDone(event) {
// remove "click"-listener to prevent event listener leaks
event.target.removeEventListener('click', moveToDone);
// move clicked todo-element to "done" section
const newDone = event.target.parentNode.removeChild(event.target);
done.append(newDone);
// listen to "click" event on the moved item to then completely delete it
newDone.addEventListener('click', removeFromDone);
debugElementsLeak();
}
function removeFromDone(event) {
// remove "click"-listener to prevent event listener leaks
event.target.removeEventListener('click', removeFromDone);
// complete remove clicked element from the DOM
event.target.remove();
debugElementsLeak();
}
function debugElementsLeak() {
const todoCount = todo.childElementCount;
const doneCount = done.childElementCount;
console.log({ todoCount, doneCount });
}
<div id="flex">
<form class="form" onsubmit="handleSubmit(event)">
<input placeholder="New item" type="text" id="play">
<button>Add item</button>
</form>
<div id="left">
<h1>To-do:</h1>
<p class="instruction"><em>(Click over to mark as done)</em></p>
<ol id="todo"></ol>
</div>
<div id="right">
<h1>Done:</h1>
<p class="instruction"><em>(Click over to delete it)</em></p>
<p id="placeholder"></p>
<ol id="done"></ol>
</div>
</div>
You'll want to use splice,
and then rather than use hidden, 'refresh' the done element by adding all elements in the spliced array.
I've commented my code where I've made changes and why
var input = document.getElementById('play');
var toDo = document.getElementsByTagName('ol')[0];
var done = document.getElementById('done');
function handleSubmit(event) {
event.preventDefault();
const newItem = document.createElement('li');
newItem.setAttribute('class', 'item');
newItem.append(input.value);
toDo.append(newItem);
input.value='';
deleteItem();
}
function deleteItem() {
const toBeDone = document.getElementsByClassName('item');
for(let i = 0; i < toBeDone.length; i++) {
toBeDone[i].onclick = () => {
appendItemDone(toBeDone[i].cloneNode(true));
toBeDone[i].style.display = 'none';
deleteDone();
}
}
}
function appendItemDone(item) {
const newDone = document.createElement('li');
newDone.setAttribute('class', 'feito')
newDone.append(item.innerText);
done.append(newDone);
}
function deleteDone() {
var doneItens = document.getElementsByClassName('feito');
for (let i = 0; i < doneItens.length; i++) {
doneItens[i].onclick = () => {
var splicedArray = spliceFromArray(doneItens,doneItens[i]);// NEW BIT -CALL NEW SPLICE FUNCTION
done.innerHTML=""; // NEW BIT - SET OVERALL DONE TO BLANK ON DELETE
for(var index in splicedArray){// NEW BIT - fOR EACH RETURNED ELEMENT IN THE SPLICE, ADD IT TO THE OVERALL DONE ELEMENT
done.appendChild(splicedArray[index]);
}
}
}
}
function spliceFromArray(arrayInput,element){// NEW BIT - SPLICE FUNCTION THAT RETURNS SPLICED ARRAY
var array = Array.from(arrayInput);
var index = array.indexOf(element);
if(index!=-1){
if(array.length==1 && index == 0){
array = [];
}
else{
array.splice(index,1);
}
}
return array;
}
<div id='flex'>
<form class='form' onsubmit='handleSubmit(event)'>
<input placeholder='New item' type='text' id='play'>
<button>Send</button>
</form>
<div id='left'>
<h1 id='todo' >To-do:</h1>
<p class='instruction'><i>(Click over to mark as done)</i></p>
<ol id='here'></ol>
</div>
<div id='right'>
<h1>Done:</h1>
<p class='instruction'><i>(Click over to delete it)</i></p>
<p id='placeholder'></p>
<ol id='done'></ol>
</div>
</div>
I have been working on a vanilla javascript TODO list with variou functionality like editing , adding deleting todos.
But I am failing to edit it because i cannot fetch the required HTML to the input tag.
Here is the relatede HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Grocery Bud</title>
<!-- font-awesome -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
/>
<!-- styles -->
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<section class="section-center">
<!-- form -->
<form class="grocery-form">
<p class="alert"></p>
<h3>Grocery Bud</h3>
<div class="form-control">
<input type="text" id="grocery" placeholder="e.g. eggs">
<button type="submit" class="submit-btn">
Submit
</button>
</div>
</form>
<!-- list -->
<div class="grocery-container">
<div class="grocery-list">
</div>
<!-- button -->
<button type="button" class="clear-btn">clear items</button>
</div>
</section>
<!-- javascript -->
<script src="app.js"></script>
</body>
</html>
And here is my javascript code.
// ****** SELECT ITEMS **********
const alert = document.querySelector('.alert');
const form = document.querySelector('.grocery-form');
const grocery = document.getElementById('grocery');
const submitBtn = document.querySelector('.submit-btn');
const container = document.querySelector('.grocery-container');
const list = document.querySelector('.grocery-list');
const clearBtn = document.querySelector('.clear-btn');
// edit option
let editElement;
let editFlag = false;
let editID = "";
// display alert
const displayAlert = (text,action)=>{
alert.textContent = text;
alert.classList.add(`alert-${action}`);
// remove alert
setTimeout(() => {
alert.textContent = '';
alert.classList.remove(`alert-${action}`);
}, 1000);
}
// clear item
const clearItems = () => {
const items = document.querySelectorAll('.grocery-item');
if (items.length > 0) {
items.forEach(item => {
list.removeChild(item);
})
}
container.classList.remove('show-container');
displayAlert('Empty list', 'danger');
setBackToDefault();
// localStorage.removeItem('list');
}
// remove from local storage item
const removeFromLocalStorage = (id) => {
}
// delete function
const deleteItem = e => {
// console.log("Item Deleted.");
const element = e.currentTarget.parentElement.parentElement;
const id = element.dataset.id;
list.removeChild(element);
if (list.children.length === 0) {
container.classList.remove('show-container');
}
displayAlert("Item removed", "danger");
setBackToDefault();
// remove from local storage
// removeFromLocalStorage(id);
}
// edit function
const editItem = (e) => {
// console.log("Item Edited.");
const element = e.currentTarget.parentElement.parentElement;
// set edit item
editElement = e.currentTarget.parentElement.previousElementSiblings;
// set from value
grocery.value = editElement.innerHTML;
editFlag = true;
}
// local storage
const addTolocalStorage = (id, value) => {
console.log('added to local storage.');
}
// set back to default
const setBackToDefault = () => {
// console.log('Setted back to default.');
grocery.value = "";
editFlag = false;
editID = "";
submitBtn.textContent = "submit";
}
// ****** FUNCTIONS **********
const addItem = (e) => {
e.preventDefault();
// console.log(grocery.value);
const value = grocery.value.trim();
const id = new Date().getTime().toString();
if (value && !editFlag) {
const element = document.createElement('article');
// add class
element.classList.add('grocery-item');
// add id
const attr = document.createAttribute('data-id');
attr.value = id;
element.setAttributeNode(attr);
element.innerHTML = ` <p class="title">${value}</p>
<div class="btn-container">
<button type="button" class="edit-btn">
<i class="fas fa-edit"></i>
</button>
<button type="button" class="delete-btn">
<i class="fas fa-trash"></i>
</button>
</div>`;
const deleteBtn = element.querySelector('.delete-btn');
const editBtn = element.querySelector('.edit-btn');
deleteBtn.addEventListener('click', deleteItem);
editBtn.addEventListener('click', editItem);
// append chiled
list.appendChild(element);
// display alert
displayAlert('item added to the list.', 'success');
// show container
container.classList.add('show-container');
// add to localstorage
addTolocalStorage(id, value);
// set back to default
setBackToDefault();
}
else if (!value && editFlag) {
console.log("Editing...");
}
else {
displayAlert('PLease enter velue...', 'danger');
}
}
// ****** EVENT LISTENERS **********
// submit form
form.addEventListener('submit', addItem);
// clear items
clearBtn.addEventListener('click', clearItems);
The arrow function named editItem has a line with innerHTML. Here i have to get the innerHTML in the input in order to edit it.
Please help meout someone.
// edit function
const editItem = (e) => {
// console.log("Item Edited.");
const element = e.currentTarget.parentElement.parentElement;
// set edit item
editElement = e.currentTarget.parentElement.previousElementSiblings;
// set from value
grocery.value = editElement.innerHTML;
editFlag = true;
}
If you are trying to get the value of an input try with this:
grocery.value = editElement.value
Just change the editElement to element.firstElementChild and youre good
const editItem = (e) => {
// console.log("Item Edited.");
const element = e.currentTarget.parentElement.parentElement;
// set edit item
editElement = element.firstElementChild;
// set from value
grocery.value = editElement.innerHTML;
editFlag = true;
}
I am doing a task list with an editable function for the each task item. What I expect is that when I update item's value, the value in LocalStorage update simultaneously. Currently, the value in LocalStorage can be updated, however, it only updates the last value of it no matter which item's value I modify. And the one should be changed does not be modified. How do I change correct localStorage value when I revise the task item?
const todo__input = document.querySelector(".todo__input")
const add__btn = document.querySelector(".add__btn")
const item__sector = document.querySelector(".item__sector")
function createToDoItem(toDoItem) {
const position = "beforeend"
const item = `
<div class="item">
<input type="checkbox" class="done__btn">
<input type="text" class="item__content" value="${toDoItem}" disabled>
<button class="edit__btn"><i class="far fa-edit"></i></button>
<button class="delete__btn"><i class="far fa-trash-alt"></i></button>
</div>
`
item__sector.insertAdjacentHTML(position, item)
return item__sector
}
// load todo item from localstorage when page is loaded
document.addEventListener("DOMContentLoaded", getLocalStorage)
// add item to the item sector
add__btn.addEventListener("click", e => {
e.preventDefault()
const input__value = todo__input.value
if (input__value.trim() === "") { return }
createToDoItem(input__value)
saveLocalStorage(input__value)
todo__input.value = ""
})
// keypress Enter
document.addEventListener("keypress", e => {
if (e.keyCode == 13) {
e.preventDefault()
const input__value = todo__input.value
if (input__value.trim() === "") { return }
createToDoItem(input__value)
saveLocalStorage(input__value)
todo__input.value = ""
}
})
// the function on item (done, edit, and delete)
item__sector.addEventListener("click", e => {
const parent = e.target.parentElement
// done
if (e.target.classList.contains("done__btn")) {
e.target.nextElementSibling.classList.toggle("done__color")
}
// edit the todo item
if (e.target.classList.contains("edit__btn")) {
if (e.target.previousElementSibling.disabled.disabled == true) {
e.target.previousElementSibling.disabled = !e.target.previousElementSibling.disabled
} else {
e.target.previousElementSibling.disabled = !e.target.previousElementSibling.disabled
e.target.previousElementSibling.setAttribute("value", e.target.previousElementSibling.value)
editLocalStorage(e.target.previousElementSibling)
}
}
// delete todo item
if (e.target.classList.contains("delete__btn")) {
parent.remove()
deleteLocalStorage(e.target.previousElementSibling.previousElementSibling)
}
})
// function for check todo status in the LocalStorage
function checkLocalStorage() {
let todos
if (localStorage.getItem("todos") === null) {
todos = []
} else {
todos = JSON.parse(localStorage.getItem("todos"))
}
return todos
}
// function for save localstorage
function saveLocalStorage(todo) {
const todos = checkLocalStorage()
todos.push(todo)
localStorage.setItem("todos", JSON.stringify(todos))
}
// function for get item and render to the screen from localstorage
function getLocalStorage() {
const todos = checkLocalStorage()
todos.forEach(todo => {
createToDoItem(todo)
})
}
// edit localStorage
function editLocalStorage(todo) {
const todos = checkLocalStorage()
const todoIndex = todo.getAttribute("value")
todos.splice(todos.indexOf(todoIndex), 1, todoIndex)
localStorage.setItem("todos", JSON.stringify(todos))
}
====
<body>
<div class="container">
<h1 class="title">My To-Do List</h1>
<form class="add__todo">
<input type="text" class="todo__input" placeholder="Add a task...">
<button class="add__btn">Add</button>
</form>
<div class="item__sector">
</div>
<div class="item__status">
<button class="all">All</button>
<button class="completed">COMPLETE</button>
<button class="incompleted">UNCOMPLETE</button>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
<script src="app.js"></script>
</body>
The reason that causes your solution to edit the last value is:-
The todoIndex variable inside the editLocalStorage function is referencing the new updated value from your input which is not yet stored inside the todos array in local storage therefore indexOf() returns -1 hence editing the last value.
I have rewritten the JS with a tweak to the functions item__sector.addEventListener, editLocalStorage and added a global variable edit__index
Code Snippet
const todo__input = document.querySelector(".todo__input")
const add__btn = document.querySelector(".add__btn")
const item__sector = document.querySelector(".item__sector")
let edit__index = -1
function createToDoItem(toDoItem) {
const position = "beforeend"
const item = `
<div class="item">
<input type="checkbox" class="done__btn">
<input type="text" class="item__content" value="${toDoItem}" disabled>
<button class="edit__btn"><i class="far fa-edit"></i></button>
<button class="delete__btn"><i class="far fa-trash-alt"></i></button>
</div>
`
item__sector.insertAdjacentHTML(position, item)
return item__sector
}
// load todo item from localstorage when page is loaded
document.addEventListener("DOMContentLoaded", getLocalStorage)
// add item to the item sector
add__btn.addEventListener("click", e => {
e.preventDefault()
const input__value = todo__input.value
if (input__value.trim() === "") { return }
createToDoItem(input__value)
saveLocalStorage(input__value)
todo__input.value = ""
})
// keypress Enter
document.addEventListener("keypress", e => {
if (e.keyCode == 13) {
e.preventDefault()
const input__value = todo__input.value
if (input__value.trim() === "") { return }
createToDoItem(input__value)
saveLocalStorage(input__value)
todo__input.value = ""
}
})
// the function on item (done, edit, and delete)
item__sector.addEventListener("click", e => {
const parent = e.target.parentElement
// done
if (e.target.classList.contains("done__btn")) {
e.target.nextElementSibling.classList.toggle("done__color")
}
// edit the todo item s
if (e.target.classList.contains("edit__btn")) {
if (e.target.previousElementSibling.disabled.disabled == true) {
e.target.previousElementSibling.disabled = !e.target.previousElementSibling.disabled
} else {
const todos = checkLocalStorage()
if (edit__index === -1) {
const valueBeforeEdit = e.target.previousElementSibling.getAttribute("value")
edit__index = todos.indexOf(valueBeforeEdit)
} else {
const valueAfterEdit = e.target.previousElementSibling.value
editLocalStorage(edit__index, valueAfterEdit)
edit__index = -1
}
e.target.previousElementSibling.disabled = !e.target.previousElementSibling.disabled
e.target.previousElementSibling.setAttribute("value", e.target.previousElementSibling.value)
}
}
// delete todo item
if (e.target.classList.contains("delete__btn")) {
parent.remove()
deleteLocalStorage(e.target.previousElementSibling.previousElementSibling)
}
})
// function for check todo status in the LocalStorage
function checkLocalStorage() {
let todos
if (localStorage.getItem("todos") === null) {
todos = []
} else {
todos = JSON.parse(localStorage.getItem("todos"))
}
return todos
}
// function for save localstorage
function saveLocalStorage(todo) {
const todos = checkLocalStorage()
todos.push(todo)
localStorage.setItem("todos", JSON.stringify(todos))
}
// function for get item and render to the screen from localstorage
function getLocalStorage() {
const todos = checkLocalStorage()
todos.forEach(todo => {
createToDoItem(todo)
})
}
// edit localStorage
function editLocalStorage(editIndex, editValue) {
const todos = checkLocalStorage()
todos.splice(editIndex, 1, editValue)
localStorage.setItem("todos", JSON.stringify(todos))
debugger
}
Note:
There is an edge case of having more than one todo item with the same value that you need to solve for.
I wrote a to do list in javascript but this code dose not work and show a deleteItem() is not defined error. I test it in codepen and it works correctly.
window.onload = function () {
let ourForm = document.getElementById("ourform");
let ourField = document.getElementById("todo");
let ourList = document.getElementById("list");
ourForm.addEventListener("submit", e => {
e.preventDefault();
createItem(ourField.value);
});
function createItem(x) {
let ourHtml = `<li>${x}<button onclick="deleteItem(this)">Delete</button></li>`;
ourList.insertAdjacentHTML("beforeend", ourHtml);
ourField.value = "";
ourField.focus();
}
function deleteItem(elementToDelete) {
elementToDelete.parentElement.remove();
}
}
<h1>NEED-TO-DO APP</h1>
<form id="ourform">
<input id="todo" type="text" autocomplete="off">
<button>Create Item</button>
</form>
<h3>Need To Do</h3>
<ul id="list">
</ul>
whats wrong with my script ..
Try copying the deleteItem function outside window.onload function as the scope is not accessible right now.
window.onload = function () {
let ourForm = document.getElementById("ourform");
let ourField = document.getElementById("todo");
let ourList = document.getElementById("list");
ourForm.addEventListener("submit", e => {
e.preventDefault();
createItem(ourField.value);
});
function createItem(x) {
let ourHtml = `<li>${x}<button onclick="deleteItem(this)">Delete</button></li>`;
ourList.insertAdjacentHTML("beforeend", ourHtml);
ourField.value = "";
ourField.focus();
}
}
function deleteItem(elementToDelete) {
elementToDelete.parentElement.remove();
}
Your code is correct
you can delete this line given under below
window.onload = function () {
then you code will work perfect
thank you