I am currently attempting to build a list app in which the user inputs an item to the list, and the item entered displays on the page as well as gets pushed into an array called "items".
The part where the item is displayed on the page and gets pushed to the array works just fine, as well as removing the item from the page. Where I've been running into trouble is removing from the array. What happens is that when the item is removed from the DOM, the corresponding array element is not always removed.
It appears that simultaneously removing items from the page and the array is not so easy. And I need to push the items to an array, as this array will be used for something else, which I have already figured out.
Currently, I am attempting to use splice but that doesn't seem to work too well.
I have also tried re-writing this program to where the item gets pushed to the array first, and then, using a for loop, iterate over the array and have the items appear on the page.
The link below leads to a live version of the app in question. It's hosted on my Neocities account.
Thank you to anyone who can help!
https://chillaxin-cyborg.neocities.org/ListApp.html
Here is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#myList {
list-style: none;
}
li {
padding: 10px;
max-width: 300px;
background-color: rgb(186, 255, 129);
font-size: larger;
font-weight: bold;
border-style: double;
border-radius: 10px;
text-align: center;
margin: 5px;
}
.remove-btn {
float: right;
background-color: red;
color:black;
}
#itemAdd {
padding: 10px;
font-size: larger;
text-align: center;
}
#itemName {
padding: 10px;
max-width: 300px;
font-size: larger;
font-weight: bold;
border-style: double;
text-align: center;
}
</style>
</head>
<body>
<div >
<form action="" method="post">
<input type="text" id="itemName">
<button onclick="addItem()" id="itemAdd">ADD</button>
</form>
<div>
<ul id="myList">
</ul>
</div>
</div>
<script>
let items = [];
const addItem = () => {
event.preventDefault();
let myList = document.getElementById('myList');
let listItem = document.createElement('li');
listItem.innerText = itemName.value " ";
myList.append(listItem);
let removeButton = document.createElement('button');
removeButton.innerText = "-";
removeButton.className = "remove-btn"
removeButton.addEventListener('click', removeItem);
listItem.append(removeButton);
items.push(itemName.value);
document.forms[0].reset();
}
const removeItem = () => {
let item = event.currentTarget.parentNode;
item.remove();
let itemIndex = items.indexOf(item);
items.splice(itemIndex, 1);
}
</script>
</body>
</html>
CodePudding user response:
I'm programming blindly here, so bare with me if the code isn't flawless.
What's wrong is the line let itemIndex = items.indexOf(item);
where you search an array of string with a node (sort of DOM object).
Instead, add a data-*
attribute to your <li>
element, where you add what the user types, and extract that via the dataset property. Then use that string to search through your list
array.
I took the liberty of refactoring some of your code to make it more readable.
let items = [];
var createListItem = (text) => {
let listItem = document.createElement('li');
listItem.innerText = text;
listItem.setAttribute('data-value', text); // adding a data attribute
return listItem;
}
var createRemoveButton() {
let removeButton = document.createElement('button');
removeButton.innerText = "-";
removeButton.className = "remove-btn"
removeButton.addEventListener('click', removeItem);
return removeButton;
}
const addItem = () => {
event.preventDefault();
let userInput = itemName.value.trim();
let myList = document.getElementById('myList');
let listItem = createListItem(userInput);
listItem.append(createRemoveButton());
myList.append(listItem);
items.push(userInput);
document.forms[0].reset();
}
const removeItem = (event) => {
let item = event.currentTarget.parentNode;
let userInput = item.dataset.value; // extracting the data attribute
item.remove();
let itemIndex = items.indexOf(userInput);
items.splice(itemIndex, 1);
}