I am making a todo list. Here is my function that builds my todo list item:
function createTodoElement(todo) {
//todo div
const todoDiv = document.createElement('div');
todoDiv.classList.add('todos');
//complete btn
const completeBtn = document.createElement('button');
completeBtn.setAttribute('data-id', todo.id);
completeBtn.classList.add('complete-btn');
completeBtn.innerText = ('o(-_-)o');
completeBtn.onclick = completeTodo;
//todo content
const todoContent = document.createElement('div');
todoContent.innerText = todo.content;
todoContent.classList.add('todo-content');
//delete button
const deleteBtn = document.createElement('button');
deleteBtn.setAttribute('data-id', todo.id);
deleteBtn.classList.add('todo-delete-btn');
deleteBtn.innerText = 'X';
deleteBtn.onclick = deleteTodo;
todoDiv.appendChild(completeBtn);
todoDiv.appendChild(todoContent);
todoDiv.appendChild(deleteBtn);
return todoDiv;
}
and I am trying to update the todo item's content to say 'done' and update the completed status as 'true' but it doesn't seem to be totally working out for me. here is my function:
function completeTodo(e) {
const btn = e.currentTarget;
btn.innerText = '\\(^_^)/';
let targetId = (btn.getAttribute('data-id'));
console.log(targetId);
let hasId = ls.getTodoList();
let item = hasId.find(obj => obj.id == targetId);
item.content = "done";
item.completed = 'true';
localStorage.setItem('content', JSON.stringify(item.content));
}
my object looks somewhat like this: array[{id: 23435352, content: 'make soup', completed: 'false'}, {id:48283749, content: 'study', completed: 'false'}]
everything seems to be working okay but the updating the new data to locale storage. I also want to save the new button inner text. what do I need to change in my function to make this happen?
Related
I am trying to add a check box when button is pressed and also delete the same checkbox when the delete is pressed. Unfortunatly the delete function cannot run as it seems that the newly created div doesn't exist yet. How can I get around this?
<script>
const list = document.getElementById("list");
const cli_form = document.getElementById("client-form");
let idz = 0;
function add_client(input) {
const div = document.createElement("div");
div.setAttribute("id", idz.toString())
const newCheckbox = document.createElement("input");
newCheckbox.setAttribute("type", 'checkbox');
newCheckbox.setAttribute("id", 'checkbox');
const newLabel = document.createElement("label");
newLabel.setAttribute("for", 'checkbox');
newLabel.innerHTML = input.value;
const br = document.createElement("br");
const del = document.createElement("input");
del.setAttribute("type", 'button');
del.setAttribute("value", idz.toString());
del.onclick = delete_item(document.getElementById(idz.toString()));
div.appendChild(newCheckbox);
div.appendChild(newLabel);
div.appendChild(del);
div.appendChild(br);
list.appendChild(div);
idz++;
}
function delete_item(item1) {
item1.remove();
}
</script>
You are assigning the result of the function delete_item which invoke immediately. Therefore, it is removing the item before it is being added to DOM.
You might use an arrow wrapper to avoid immediate invocation.
Like this :
del.onclick = () => delete_item(document.getElementById(idz.toString()));
I am using the NASA API which displays images, and when the image is clicked, it displays a modal with the images and details of the image.
However, in the tutorial, there is a save to favourites feature that adds the image and details to the favourites section into local storage.
My question is, how do I implement the add to favourites feature link into the modals, and then save the image and details to the local storage favourites section?
const resultsNav = document.getElementById("resultsNav");
const favoritesNav = document.getElementById("favoritesNav");
const imagesContainer = document.querySelector(".images-container");
const saveConfirmed = document.querySelector(".save-confirmed");
const loader = document.querySelector(".loader");
// NASA API
const count = 3;
const apiKey = 'DEMO_KEY';
const apiUrl = `https://api.nasa.gov/planetary/apod?api_key=${apiKey}&count=${count}`;
let resultsArray = [];
let favorites = {};
// Show Content
function showContent(page) {
window.scrollTo({
top: 0,
behavior: "instant"
});
if (page === "results") {
resultsNav.classList.remove("hidden");
favoritesNav.classList.add("hidden");
} else {
resultsNav.classList.add("hidden");
favoritesNav.classList.remove("hidden");
}
loader.classList.add("hidden");
}
// Create DOM Nodes
function createDOMNodes(page) {
const currentArray =
page === "results" ? resultsArray : Object.values(favorites);
currentArray.forEach((result) => {
// Card Container
const card = document.createElement("div");
card.classList.add("card");
// Link that wraps the image
const link = document.createElement("a");
// Get the modal
var modal = document.getElementById("myModal");
// Get the image and insert it inside the modal - use its "alt" text as a caption
var img = document.getElementById("myImg");
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
img.onclick = function() {
modal.style.display = "block";
modalImg.src = event.target.src;
captionText.innerHTML = event.target.alt;
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// Image
const image = document.createElement("img");
image.src = result.url;
// image.alt = "NASA Picture of the Day";
image.alt = result.title + "<br>" + result.explanation + "<br>" + ' ' + result.date;
image.loading = "lazy";
image.classList.add("card-img-top");
// Card Body
const cardBody = document.createElement("div");
cardBody.classList.add("card-body");
// Card Title
const cardTitle = document.createElement("h5");
cardTitle.classList.add("card-title");
cardTitle.textContent = result.title;
// Save Text
const saveText = document.createElement("p");
saveText.classList.add("clickable");
if (page === "results") {
saveText.textContent = "Add To Favorites";
saveText.setAttribute("onclick", `saveFavorite('${result.url}')`);
} else {
saveText.textContent = "Remove Favorite";
saveText.setAttribute("onclick", `removeFavorite('${result.url}')`);
}
// Card Text
const cardText = document.createElement("p");
cardText.textContent = result.explanation;
// Footer Conatiner
const footer = document.createElement("small");
footer.classList.add("text-muted");
// Date
const date = document.createElement("strong");
date.textContent = result.date;
// Copyright
const copyrightResult =
result.copyright === undefined ? "" : result.copyright;
const copyright = document.createElement("span");
copyright.textContent = ` ${copyrightResult}`;
// Append everything together
footer.append(date, copyright);
cardBody.append(cardTitle, saveText, cardText, footer);
link.appendChild(image);
card.append(link); // hide cardBody
// Append to image container
imagesContainer.appendChild(card);
});
}
// Update the DOM
function updateDOM(page) {
// Get favorites from local storage
if (localStorage.getItem("nasaFavorites")) {
favorites = JSON.parse(localStorage.getItem("nasaFavorites"));
}
imagesContainer.textContent = "";
createDOMNodes(page);
showContent(page);
}
// Get 10 images from NASA API
async function getNasaPictures() {
// Show Loader
loader.classList.remove("hidden");
try {
const response = await fetch(apiUrl);
resultsArray = await response.json();
updateDOM("results");
} catch (error) {
// Catch Error Here
}
}
// Add result to favorites
function saveFavorite(itemUrl) {
// Loop through the results array to select favorite
resultsArray.forEach((item) => {
if (item.url.includes(itemUrl) && !favorites[itemUrl]) {
favorites[itemUrl] = item;
// Show save confirmation for 2 seconds
saveConfirmed.hidden = false;
setTimeout(() => {
saveConfirmed.hidden = true;
}, 2000);
// Set Favorites in Local Storage
localStorage.setItem("nasaFavorites", JSON.stringify(favorites));
}
});
}
// Remove item from favorites
function removeFavorite(itemUrl) {
if (favorites[itemUrl]) {
delete favorites[itemUrl];
localStorage.setItem("nasaFavorites", JSON.stringify(favorites));
updateDOM("favorites");
}
}
// On Load
getNasaPictures();
An interesting question, I check the Nasa.api and i find that the sever will return you an array that contain object, so a good option is to use an array to store all the liked item and it will be easier for you display.
My suggestion for you is to directly store the info that nasa.api give to you to the array and store in localStorage. It will be easier for you to display later.
I also created an example for you that use nasa.api that you could use it since I doesn't have your full code and how you get the code/display it, but you could just see the part that how i modify the localStorage
So in the example I created, every time user click on the liked button, it will save to liked (array) and save to localStorage. Every second time, user click the button , we will delete the item from the liked array and update localStorage.
let source;
let xhr = new XMLHttpRequest();
let link = "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&count=5"
xhr.open('GET', link, true);
xhr.send();
let liked = JSON.parse(localStorage.getItem("likeditem"));
if (liked == null) liked = [];
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
source = JSON.parse(xhr.responseText);
create()
}
} //Check if liked is null, if it is, assign empty array value to it.
function create() {
for (let i = 0; i < source.length; i++) {
console.log(source[i])
document.body.innerHTML += `
<img src=${source[i].url}>
<div >${source[i].title}</div>
<div >Date: ${source[i].date}</div>
<div>Copyright: ${source[i].copyright}</div>
<div>Media_type: ${source[i].media_type}</div>
<div>Service_version: ${source[i].service_version}</div>
<div>Explanation: ${source[i].explanation}</div>
<button onclick='save(${i})'>Save to like</button>
`
//TO save/remove liked item from local Storage when button clicked
window.save = function(index) {
let thisbutton = document.querySelectorAll('button')[index]
if (thisbutton.textContent == 'Save to like') {
liked.push(source[index])
localStorage.setItem('likeditem', JSON.stringify(liked));
thisbutton.textContent = "Saved"
} else {
//Remove it from local storage when user click it every two times
liked.splice(liked.indexOf(source[index]), 1)
localStorage.setItem('likeditem', JSON.stringify(liked));
thisbutton.textContent = 'Save to like'
}
}
}
}
In term of how to display the element from localStorage, also an example.
We have already saved all the info about the image to localStorage before , so we just use the way we display the info from nasa.api.
let liked = JSON.parse(localStorage.getItem("likeditem"));
for (let i in liked){
//Immediately return the for loop if no value stored in loal storage
if(!liked) break;;
document.body.innerHTML += `
<img src=${liked[i].url}>
<div >${liked[i].title}</div>
<div >Date: ${liked[i].date}</div>
<div>Copyright: ${liked[i].copyright}</div>
<div>Media_type: ${liked[i].media_type}</div>
<div>Service_version: ${liked[i].service_version}</div>
<div>Explanation: ${liked[i].explanation}</div>
`
}
Update:
Save to localStorage:
Display from localStorage:
EDIT : This is edit to my previous answer. This piece of of code should help you. (NOTE: this code snippet wont work here, try it from your system as localStorage is not supported here.)
let nasaImages = [
{
id:1,
url:"https://example.com/image-url-1"
},
{
id:2,
url:"https://example.com/image-url-2"
},
{
id:3,
url:"https://example.com/image-url-3"
}
];
let favs = [];
//check if key exists in localstorage
if(localStorage.nasaFavs){
favs = JSON.parse(localStorage.nasaFavs)
}
renderImages();
function renderImages(){
$("#images").html(nasaImages.map(image => (
`<div>
id: ${image.id}
<img src='${image.url}'>
${favBtn(image.id)}
</div>`
)
).join(""));
}
//render the fav button
function favBtn(id){
if(favs.includes(id)){
return `<button onclick="favUnfav(false,${id})">Remove from fav</button>`;
}
else{
return `<button onclick="favUnfav(true,${id})">Add to fav</button>`;
}
}
function favUnfav(isFav=true, id=null){
//write your logic to add to fav or remove from fav
if(isFav){
favs.push(id);
}
else{
favs = favs.filter(e => e!=id);
}
//save in localstorage
localStorage.nasaFavs = JSON.stringify(favs);
//re render the DOM
renderImages()
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="images"></div>
As #ba2sik already posted, first get familiar with localStorage API.
You are already saving the whole favorites object into local storage under nasaFavorites key.
In order to read it, use JSON.parse(localStorage.getItem('nasaFavorites')) to deserialize the content every time you want to access it.
Just note that the code above doesn't handle edge cases or errors so you might want to handle it with try/catch.
After the categories and todo items for the corresponding category are deleted, the category name, task counter, and form with add button still show. In other words, the (now-empty) section on the page for that category's items still remain as if it was populated before being deleted. They need to be hidden. Right now they only go away on page refresh.
I tried putting those classes to display none in the code below, but the result is hiding them all the time. You can see what I tried commented out. I also am not sure if I am putting the logic in the right place.
Here is full code Here is a video demonstrating issue.
// Delete Category button maker
const buildDeleteCategoryButton = (category) => {
const deleteButton = document.createElement('button');
deleteButton.className = 'delete-button';
deleteButton.innerText = 'x';
deleteButton.addEventListener('click', function (e) {
const div = this.parentElement;
div.style.display = 'none';
categorys = categorys.filter((item) => item.id !== category.id); // Filter removed categories
addCategoryLocalStorage(categorys);
todos = todos.filter((item) => item.category !== category.id); // Filter todo lists of removed categories
addToLocalStorage(todos);
// input.style.display = 'none';
// addButton.style.display = 'none';
// categoryTitle.style.display = 'none';
// listCountElement.style.display = 'none';
});
return deleteButton;
};
As soon as the items are deleted, we can reload our page using window.location.reload() function so that our changes are reflected properly.
Sandbox Link: Fixed Code with suggestions
Changes made in the below Function:
// Delete Category button maker
const buildDeleteCategoryButton = (category) => {
const deleteButton = document.createElement("button");
deleteButton.className = "delete-button";
deleteButton.innerText = "x";
deleteButton.addEventListener("click", function (e) {
const div = this.parentElement;
categorys = categorys.filter((item) => item.id !== category.id); // Filter removed categories
addCategoryLocalStorage(categorys);
todos = todos.filter((item) => item.category !== category.id); // Filter todo lists of removed categories
addToLocalStorage(todos);
div.style.display = "none";
// Added the following code with some logic, that works fine in your case
let arrowBtn = deleteButton.previousSibling;
if (arrowBtn.style.backgroundColor === "red") {
window.location.reload();
}
});
return deleteButton;
};
You have a problem in declaring elements and curTodos in your .js.
I fixed your codesandbox here: https://codesandbox.io/s/great-noyce-cwq9w
I am a bit stuck and hoping someone can help me, please.
Basically I have coded a shopping cart and am currently trying to get the cart to display a message saying "Cart is empty" after all of the cart items have been removed.
Everything is working ok apart from the "Cart is empty" message being re-displayed after the cart is empty.
I have tried a few things but cannot seem to get the emptyCartMessage to display when removing the last cart item.
Just for extra context my cart items each have an independent 'remove' button attached to them.
My code is below.
Thank you for any help, I do appreciate it!
const currentCartItems = document.getElementsByClassName('cart-item');
const emptyCartMessage = document.createElement('p');
emptyCartMessage.innerHTML = 'Your cart is empty.';
// EMPTY CART ITEM DISPLAY MESSAGE
shoppingCart.appendChild(emptyCartMessage);
// SHOPPING AREA BUTTON EVENT LISTENER
for (var i = 0; i < addToCartButton.length; i++) {
addToCartButton[i].addEventListener('click', createCartItem);
}
function createCartItem(event) {
//CREATE CART LI ITEM
const newItem = document.createElement('li');
newItem.className = 'cart-item';
//newItem.innerHTML = event.target.value;
//GET AND SET SHOP/CART ITEM VALUE
const itemValue = document.createElement('p');
itemValue.innerHTML = event.target.value;
//CREATE CART ITEM DESCRIPTION
const p = document.createElement('p');
p.innerHTML = itemDescription;
//CREATE CANCEL CART ITEM BUTTON
const cancelItemImage = document.createElement('img');
cancelItemImage.className = "remove-button";
cancelItemImage.src = "images/cancel-icon.png";
cancelItemImage.alt = "red remove icon";
newItem.appendChild(itemValue);
newItem.appendChild(p);
newItem.appendChild(cancelItemImage);
shoppingCart.appendChild(newItem);
if (currentCartItems.length > 0) {
emptyCartMessage.className = 'hide-empty-cart';
} else if (currentCartItems.length <= 0) {
emptyCartMessage.classList.remove('hide-empty-cart');
}
}
// REMOVE CART ITEMS BUTTON
shoppingCart.addEventListener('click', (e) => {
if (e.target.className === 'remove-button'){
const li = e.target.parentNode;
const ol = li.parentNode;
ol.removeChild(li);
}
});
Please remove this line
const currentCartItems = document.getElementsByClassName('cart-item');
We will use this variable inside the function 'createCartItem' and inside 'removeCartItem' tha i just created.
So when calling createCartItem we can always show the cart items, because this function adds new items, so the cart is not empty.
Inside remove function first we getting the count of current items, then checking if it is less or equal 0 then we hide cart.
So the final version would be.
const emptyCartMessage = document.createElement('p');
emptyCartMessage.innerHTML = 'Your cart is empty.';
// EMPTY CART ITEM DISPLAY MESSAGE
shoppingCart.appendChild(emptyCartMessage);
// SHOPPING AREA BUTTON EVENT LISTENER
for (var i = 0; i < addToCartButton.length; i++) {
addToCartButton[i].addEventListener('click', createCartItem);
}
function createCartItem(event) {
//CREATE CART LI ITEM
const newItem = document.createElement('li');
newItem.className = 'cart-item';
//newItem.innerHTML = event.target.value;
//GET AND SET SHOP/CART ITEM VALUE
const itemValue = document.createElement('p');
itemValue.innerHTML = event.target.value;
//CREATE CART ITEM DESCRIPTION
const p = document.createElement('p');
p.innerHTML = itemDescription;
//CREATE CANCEL CART ITEM BUTTON
const cancelItemImage = document.createElement('img');
cancelItemImage.className = "remove-button";
cancelItemImage.src = "images/cancel-icon.png";
cancelItemImage.alt = "red remove icon";
newItem.appendChild(itemValue);
newItem.appendChild(p);
newItem.appendChild(cancelItemImage);
shoppingCart.appendChild(newItem);
// Always show because after every adding, we know that there is
// at least one item, so we always showing cart
emptyCartMessage.className = 'hide-empty-cart';
}
function removeCartItem(event){
if (event.target.className === 'remove-button'){
const li = e.target.parentNode;
const ol = li.parentNode;
ol.removeChild(li);
// Get cart's current items
const currentCartItems = document.getElementsByClassName('cart-item');
// If cart items less then or equal to 0 then hide
if (currentCartItems.length <= 0) {
emptyCartMessage.classList.remove('hide-empty-cart');
}
}
}
// REMOVE CART ITEMS BUTTON
shoppingCart.addEventListener('click', removeCartItem);
I am making a todo list, i have just about everything for it figured out but one area i am stuck on is my UL and Li.
Basically when you enter items into the list, you have the ability to click the checkbox beside said item when you complete the task, and it will put a line through the text.
But i also want it to move that item to the bottom of the list when it is clicked.
would anyone be able to help me with how i would go about doing that
code Below
// making event listener for adding item
let addBTN = document.getElementById('addBtn');
addBTN.addEventListener('click', addItem);
// this creates a new li based on the entered value in the text box that it gets when you hit the button
// Through Research found that setAttribute isn't really needed and i can just use .id , .type etc
function addItem() {
// Creating needed elements as well as getting text from textbox
let newLi = document.createElement("li");
let myLiValue = document.getElementById('textBoxAdd').value;
let liTextNode = document.createElement("label");
liTextNode.textContent = myLiValue;
// makes div for li
let newDivID = ('div_' + myLiValue);
let newDiv = document.createElement('div');
newDiv.id = newDivID;
// makes checkboxes for the li
let newCheckBoxID = ('checkbox_' + myLiValue);
let newCheckBox = document.createElement('input');
newCheckBox.type = 'checkbox';
newCheckBox.id = newCheckBoxID;
// makes delete button for the li
let newDeleteID = ('deleteButton_' + myLiValue);
let newDeleteButton = document.createElement("button")
newDeleteButton.type = 'button';
newDeleteButton.id = newDeleteID
newDeleteButton.textContent = 'Delete';
//newDeleteButton.setAttribute('onclick', 'deleteItem()');
newDeleteButton.innerHTML = 'Delete';
// appends it to my newDiv
newDiv.appendChild(newCheckBox);
newDiv.appendChild(liTextNode);
newDiv.appendChild(newDeleteButton);
// then appends my new div to the new Li
newLi.appendChild(newDiv);
// this just makes sure a user cant enter in a blank value
if (myLiValue == "") {
alert("Please Enter Something Before Hitting Add Item");
} else {
document.getElementById('theNewList').appendChild(newLi);
document.getElementById('textBoxAdd').value = "";
}
}
//creating event listener for checkbox line through text and moving item
let theList = document.getElementById('theNewList');
theList.addEventListener('click', checkedComplete);
// function that will target every check box in the list and if any get checked then it will add a line through the text
function checkedComplete(event) {
const checkboxElement = event.target;
if (checkboxElement.type === 'checkbox') {
if (checkboxElement.checked) {
checkboxElement.nextElementSibling.style.textDecoration = 'line-through';
// add in moving item
} else {
checkboxElement.nextElementSibling.style.textDecoration = 'none';
}
}
}
// adds deleteItem listener to the list
theList.addEventListener('click', deleteItem);
function deleteItem(event) {
const deleteButton = event.target;
if (deleteButton.type === 'button') {
const deleteParentNode = deleteButton.parentNode;
deleteParentNode.parentNode.removeChild(deleteParentNode);
}
}
You are going to have a storage of you todos, right? Even if you did not think about it, it can do all the work. Just create the array (you could use localStorage to prevent you data from disappearing after browser is restarted) containing your todos and their condition, like
const todos = [{todo:"watch the movie", completed: false}, {...}, {...}]
Now you can easily add or remove items with standard array methods pop&push, delete with splice, filter etc. After array is mdified, just update the page and build your list using Array.map.
You should just add the following logic where you have // add in moving item comment:
const theList = document.getElementById('theNewList');
const lastListItem = theList.children[theList.children.length - 1];
theList.insertBefore(lastListItem, checkboxElement.parentNode.parentNode);
We're selecting your ul and searching for its last li and then we're simply placing the li belonging to the checkboxElement after the last li.
Working example:
// making event listener for adding item
let addBTN = document.getElementById('addBtn');
addBTN.addEventListener('click', addItem);
// this creates a new li based on the entered value in the text box that it gets when you hit the button
// Through Research found that setAttribute isn't really needed and i can just use .id , .type etc
function addItem() {
// Creating needed elements as well as getting text from textbox
let newLi = document.createElement("li");
let myLiValue = document.getElementById('textBoxAdd').value;
let liTextNode = document.createElement("label");
liTextNode.textContent = myLiValue;
// makes div for li
let newDivID = ('div_' + myLiValue);
let newDiv = document.createElement('div');
newDiv.id = newDivID;
// makes checkboxes for the li
let newCheckBoxID = ('checkbox_' + myLiValue);
let newCheckBox = document.createElement('input');
newCheckBox.type = 'checkbox';
newCheckBox.id = newCheckBoxID;
// makes delete button for the li
let newDeleteID = ('deleteButton_' + myLiValue);
let newDeleteButton = document.createElement("button")
newDeleteButton.type = 'button';
newDeleteButton.id = newDeleteID
newDeleteButton.textContent = 'Delete';
//newDeleteButton.setAttribute('onclick', 'deleteItem()');
newDeleteButton.innerHTML = 'Delete';
// appends it to my newDiv
newDiv.appendChild(newCheckBox);
newDiv.appendChild(liTextNode);
newDiv.appendChild(newDeleteButton);
// then appends my new div to the new Li
newLi.appendChild(newDiv);
// this just makes sure a user cant enter in a blank value
if (myLiValue == "") {
alert("Please Enter Something Before Hitting Add Item");
} else {
document.getElementById('theNewList').appendChild(newLi);
document.getElementById('textBoxAdd').value = "";
}
}
//creating event listener for checkbox line through text and moving item
let theList = document.getElementById('theNewList');
theList.addEventListener('click', checkedComplete);
// function that will target every check box in the list and if any get checked then it will add a line through the text
function checkedComplete(event) {
const checkboxElement = event.target;
if (checkboxElement.type === 'checkbox') {
if (checkboxElement.checked) {
checkboxElement.nextElementSibling.style.textDecoration = 'line-through';
const theList = document.getElementById('theNewList');
const lastListItem = theList.children[theList.children.length - 1];
theList.insertBefore(checkboxElement.parentNode.parentNode, lastListItem.nextSilbing);
} else {
checkboxElement.nextElementSibling.style.textDecoration = 'none';
}
}
}
// adds deleteItem listener to the list
theList.addEventListener('click', deleteItem);
function deleteItem(event) {
const deleteButton = event.target;
if (deleteButton.type === 'button') {
const deleteParentNode = deleteButton.parentNode;
deleteParentNode.parentNode.removeChild(deleteParentNode);
}
}
<input id="textBoxAdd" type="text" />
<button id="addBtn" type="button">Add</button>
<ul id="theNewList"></ul>