Remove one item from an array when clicked by only js - javascript

I am new to JavaScript. I have a small code that creates list from input and then adds it to an array. I am able to remove one item from the DOM when the item is clicked, but I couldn't remove it from the array.
I tried to use array.splice(item, 1)
lists.addEventListener("click", function (e) {
e.target.closest("li").remove();
userInputArr.splice(item, 1);});
But it removes the entire array sometime, and sometime removes the last item. when I console log the code, it looks like I clicked 3 or 4 times on the list even though I just clicked once. I have no idea what's wrong. this is the entire code:
const lists = document.querySelector(".lists");
const userInput = document.querySelector(".add-note");
const addBtn = document.querySelector(".add-btn");
const item = document.querySelectorAll(".list");
userInputArr = [];
function addNote() {
if (userInput.value < 1) {
return;
}
lists.insertAdjacentHTML(
"afterbegin",
`<li class='list'>${userInput.value}</li>`
);
userInputArr.push(lists);
lists.addEventListener("click", function (e) {
e.target.closest("li").remove();
userInputArr.splice(item, 1);
});
userInput.value = "";
}
addBtn.addEventListener("click", function () {
addNote();
});

Code is totally meaningless
1)
userInputArr.push(lists)
why you push the same element all the time? As lists refers to the first and the only element with class 'lists'?
2)
userInputArr.splice(item, 1)
please watch carefully what splice does? The first argument is number, but you pass a collection of elements with class 'list'. But i camn not even suggest which element should be removed as it contains the same element as i mentioned in first point
3) You do not need this array at all
So right approach is something like this
const lists = document.querySelector(".lists");
// just once create listener, no need to do it each time
lists.addEventListener("click", function (e) {
// if you want to remove clicked item then
if (e.target.tagName === 'LI') e.target.remove();
// but if you want to remove the first one then uncomment line
// if (this.children[0]) this.children[0].remove()
});
const userInput = document.querySelector(".add-note");
const addBtn = document.querySelector(".add-btn");
///////////////////////////////////////////////////
// item is meaninglee here, so delete this line
// const item = document.querySelectorAll(".list");
//////////////////////
// array is useless too, delete this line
// userInputArr = [];
function addNote() {
// check if it is number
if (isNaN(userInput.value) || Number(userInput.value < 1)) {
return;
}
lists.insertAdjacentHTML(
"afterbegin",
`<li class='list'>${userInput.value}</li>`
);
userInput.value = "";
}
addBtn.addEventListener("click", function () {
addNote();
});

const items = (() => {
const _items = {};
let key = 0;
return {
put(value) {
_items[key++] = value;
console.log("Added", this.all());
return key - 1;
},
remove(key) {
delete _items[key++];
console.log("Removed", this.all());
},
all(asArray = true) {
return asArray ? Object.values(_items) : { ..._items
};
}
}
})();
const inputEl = document.querySelector(".input");
const itemsEl = document.querySelector(".items");
const addBtn = document.querySelector(".btn-add");
addBtn.addEventListener("click", () => {
const value = inputEl.value.trim();
if (!value.length) return;
const key = items.put(value);
const li = document.createElement("li");
li.textContent = value;
li.dataset.key = key;
itemsEl.append(li);
inputEl.value = "";
});
itemsEl.addEventListener("click", (e) => {
const li = e.target.closest("li");
items.remove(li.dataset.key);
li.remove();
});
<input type="text" class="input">
<button class="btn-add">Add</button>
<ul class="items"></ul>
Run code & View in full screen.

use shift() userInputArr.shift()
you are also getting double clicks because your addNote() function contains an event listener lists.addEventListener and it's executed by another event listner addBtn.addEventListener you should probably move
lists.addEventListener out of the addNote function

Related

Problem with sessionStorage: I am not displaying the first item correctly

I am having a problem with sessionStorage; in particular, I want the id of the ads to be saved in the session where the user puts the like on that particular favorite article.
However, I note that the array of objects that is returned contains the ids starting with single quotes, as shown below:
['', '1', '7']
but I want '1' to be shown to me directly.
While if I go into the sessionStorage I notice that like is shown as:
,1,7
ie with the leading comma, but I want it to start with the number directly.
How can I fix this?
function likeAnnunci(){
let likeBtn = document.querySelectorAll('.like');
likeBtn.forEach(btn => {
btn.addEventListener('click', function(){
let id = btn.getAttribute('ann-id');
//sessionStorage.setItem('like', [])
let storage = sessionStorage.getItem('like').split(',');
//console.log(storage);
if(storage.includes(id)){
storage = storage.filter(id_a => id_a != id);
} else {
storage.push(id);
}
sessionStorage.setItem('like', storage)
console.log(sessionStorage.getItem('like').split(','));
btn.classList.toggle('fas');
btn.classList.toggle('far');
btn.classList.toggle('tx-main');
})
})
};
function setLike(id){
if(sessionStorage.getItem('like')){
let storage = sessionStorage.getItem('like').split(',');
if(storage.includes(id.toString())){
return `fas`
} else {
return `far`
}
} else {
sessionStorage.setItem('like', '');
return`far`;
}
}
The main issue you're having is that you're splitting on a , instead of using JSON.parse().
Also, you've got some other code issues and logical errors.
Solution:
function likeAnnunci() {
const likeBtn = document.querySelectorAll('.like');
likeBtn.forEach((btn) => {
btn.addEventListener('click', function () {
let id = btn.getAttribute('ann-id');
//sessionStorage.setItem('like', [])
let storage = JSON.parse(sessionStorage.getItem('like') || '[]');
//console.log(storage);
if (!storage.includes(id)) {
storage.push(id);
}
sessionStorage.setItem('like', JSON.stringify(storage));
console.log(JSON.parse(sessionStorage.getItem('like')));
btn.classList.toggle('fas');
btn.classList.toggle('far');
btn.classList.toggle('tx-main');
});
});
}
More modular and optimal solution:
const likeBtns = document.querySelectorAll('.like');
// If there is no previous array stored, initialize it as an empty array
const initLikesStore = () => {
if (!sessionStorage.getItem('likes')) sessionStorage.setItem('likes', JSON.stringify([]));
};
// Get the item from sessionStorage and parse it into an array
const grabLikesStore = () => JSON.parse(sessionStorage.getItem('likes'));
// Set a new value for the likesStore, automatically serializing the value into a string
const setLikesStore = (array) => sessionStorage.setItem('likes', JSON.stringify(array));
// Pass in a value.
const addToLikesStore = (value) => {
// Grab the current likes state
const pulled = grabStorage();
// If the value is already there, do nothing
if (pulled.includes(value)) return;
// Otherwise, add the value and set the new array
// of the likesStore
storage.push(value);
setLikesStore(pulled);
};
const likeAnnunci = (e) => {
// Grab the ID from the button clicked
const id = e.target.getAttribute('ann-id');
// Pass the ID to be handled by the logic in the
// function above.
addToLikesStore(id);
console.log(grabLikesStore());
btn.classList.toggle('fas');
btn.classList.toggle('far');
btn.classList.toggle('tx-main');
};
// When the dom content loads, initialize the likesStore and
// add all the button event listeners
window.addEventListener('DOMContentLoaded', () => {
initLikesStore();
likeBtns.forEach((btn) => btn.addEventListener('click', likeAnnunci));
});

Local storage - wrong list items appear on refresh

I've created a to-do list with local storage. If you create three list items and delete the second one, the deleted list item will reappear in place of the third item on refresh.
Edit: I'm not sure whether it's to do with local storage or with the original todo array. In the code below, I'm trying to remove the relevant value from the array, but I suspect this isn't working (logging the array to the console produces no result).
Although it has nothing to do with local storage, I think the issue lies with the following code:
function removeItem() {
let item = this.parentNode.parentNode;
let parent = item.parentNode;
let id = parent.id;
console.log(id)
let value = parent.textContent;
todo.splice(todo.indexOf(value, 1));
this.parentNode.parentNode.removeChild(this.parentNode);
saveTodos();
}
Edit: Here is the code I used to store the list items:
function saveTodos() {
let jsonstr = JSON.stringify(todo);
localStorage.setItem('todo', jsonstr);
}
function getTodos() {
localStorage.getItem('todo')
let jsonstr = localStorage.getItem("todo");
todo = JSON.parse(jsonstr);
if (!todo || !todo.length) {
todo = [];
}
else {
renderTodoList();
}
}
Here is a link to the codepen: https://codepen.io/david-webb/pen/yLeqydK
Can you help?
This is because the current code seems to be removing the wrong item.
See scenario:
Localstorage: ["t","1", "2"];
-> Remove item #2 ("t")
Localstorage: ["t", "1"];
Output:
As you can see, the output shows ["t", "2"] thought the localstorage array is ["t", "1"].
This is because of the flawed logic in the removeItem function.
Try with this, instead.
//remove list item on click
function removeItem() {
const item = this.parentNode;
const value = this.parentNode.lastChild.textContent;
todo = todo.filter(t => t !== value);
this.parentNode.parentNode.removeChild(item);
saveTodos();
}
fiddle:
<input type = "text" style="font-size:25px;" id = "input" placeholder="Write here">
<button id = "addBtn" >Add item</button>
<ul id = "myUL">
</ul>
<script>
let todo = [];
renderTodoList();
document.getElementById('addBtn').addEventListener('click', function () {
let value = document.getElementById('input').value;
if (value) {
todo.push(value);
saveTodos()
addInput(value);
}
});
input.addEventListener("keypress", function(event) {
// Number 13 is the "Enter" key on the keyboard
if (event.keyCode === 13) {
// Trigger the button element with a click
document.getElementById("addBtn").click();
}
});
function addInput(text) {
//add list item on click
let listItem = document.createElement('li');
let list = document.getElementById('myUL');
let input = document.getElementById('input').value;
let textNode = document.createTextNode(text);
//create and append remove button
let removeBtn = document.createElement("BUTTON");
list.appendChild(removeBtn);
removeBtn.className = "removeBtn";
removeBtn.innerHTML = "Remove item";
listItem.appendChild(removeBtn);
list.appendChild(listItem);
listItem.appendChild(textNode);
document.getElementById("input").value = "";
removeBtn.addEventListener('click', removeItem);
console.log(todo);
}
//remove list item on click
function removeItem() {
const item = this.parentNode;
const value = this.parentNode.lastChild.textContent;
todo = todo.filter(t => t !== value);
this.parentNode.parentNode.removeChild(item);
saveTodos();
}
function renderTodoList() {
if (!todo) return
for (let i = 0; i < todo.length; i++) {
let value = todo[i];
addInput(value);
console.log(value);
}
}
function saveTodos() {
let jsonstr = JSON.stringify(todo);
localStorage.setItem('todo', jsonstr);
}
function getTodos() {
localStorage.getItem('todo')
let jsonstr = localStorage.getItem("todo");
todo = JSON.parse(jsonstr);
if (!todo || !todo.length) {
todo = [];
}
else {
renderTodoList();
}
}
//cross out text on click
/*document.addEventListener('click', function (ev) {
if (ev.target.tagName === 'LI') {
ev.target.classList.toggle('checked');
}
});*/
//renderTodoList();
getTodos();
</script>
I think the problem is the usage of splice and indexOf.
For splice -- pass index, how may delete, new item
var todo = ["a", "b", "c"];
var value = "b"
// your code
todo.splice(todo.indexOf(value, 1));
console.log(todo)
var todo = ["a", "b", "c"];
var value = "b"
// correct way to delete
todo.splice(todo.indexOf(value), 1);
console.log(todo)
This line has the error todo.splice(todo.indexOf(value, 1));
The reason is when you apply let item = this.parentNode.parentNode; you the UL element in the variable.
Fix:
While adding the item in addInput() create a span and put the text inside the span rather than creating textNode.
when removing from todo then you should use the innerText inside SPAN tag
todo.splice(todo.indexOf(value, 1));
In the value variable you should have the todo item name.

Array containing objects is not updating

I am new in programming. I am trying to update cart items. On instance of click "OK" in modal, the One_item object is updated. Then this object is passed on to Cart_Item array, which contains the total items.
I tried to write the logic in Listval() function in the Menu component. The One_Item is updated properly.
But the if condition at the bottom of the Listval(), is adding , but not updating. Also the first click gives an empty object.
Please see the sandbox:
https://codesandbox.io/s/hardcore-stallman-98o58
Relevant function to look into:
Listval() {
let ll = "$" + this.state.listvalue.replace(/[^0-9]/g, "");
let ll2 = this.state.listvalue.replace(/\d+/g, "");
let ll3 = ll2.replace(/\$/g, "");
let ll4 = ll.replace(/\$/g, "");
let ll5 = this.state.Select_Quantity;
let ll6 = parseFloat(ll4) * ll5;
let ll7 = this.state.Total_Item || [];
ll7.push(ll3);
ll7 = [...new Set(ll7)];
this.setState(
{
Select_Price: ll,
Select_Item: ll3,
Select_Item_TotalPrice: ll6,
Total_Item: ll7
},
() => {
// CHANGE: Use callback function to send data to the parent component
this.props.updateTotalItems(this.state.Total_Item.length);
}
);
// append new object This is where problem starts, the new object pushes at second click
if (this.state.Item !== this.state.Select_Item) {
let xx = {
Price: ll,
Item: ll3,
Quantity: this.state.Select_Quantity,
Total_Item_Price: ll6
};
// const Cart_Item = Object.assign(xx, this.state.Cart_Item);
let yy = this.state.Cart_Item || [];
yy.push(xx);
this.setState({ Cart_Item: yy });
}
//else try to update object based on property value
// This is not working at all. it keeps on adding objects instead of updating
else {
for (var i in this.state.Cart_Item) {
if (this.state.Cart_Item[i].value === this.state.Select_Item) {
this.state.Cart_Item[i].Price = ll;
this.state.Cart_Item[i].Item = ll3;
this.state.Cart_Item[i].Quantity = this.state.Select_Quantity;
this.state.Cart_Item[i].Total_Item_Price = ll6;
// }
break; //Stop this loop, we found it!
}
}
// i tried below logic as well but it didnt work
// this.setState({
// Cart_Item:this.state.Cart_Item.filter(v => v.this.state.Select_Item.includes(this.state.Item))
// .concat([ xx ])
// });
}
console.log(this.state.Cart_Item);
}

How would I use local storage for a to do list?

I am being asked to have a to do list and save each task (that the user supplies as well as original) through local storage. My teacher did a very simple demo on something completely different and I spent a few hours trying to figure it out. When I looked at the solution, I honestly cannot figure it out. It looks really complicated, and I don't even know where to start. If anyone can give me any hints, that would be awesome!
My code:
let ul = document.querySelector('ul');
let newItem = document.querySelector('input[type=text]');
let checkbox = document.createElement('input');
checkbox.setAttribute('type', 'checkbox');
function output() {
let newTodo = document.createElement('li');
newTodo.innerText = newItem.value;
newTodo.classList.add('todo');
let ulAppend = ul.append(newTodo);
ul.append(newTodo);
let checkboxAppend = newTodo.append(checkbox);
newTodo.append(checkbox);
newItem.value = '';
}
let button = document.querySelector('.btn');
button.addEventListener('click', output);
ul.addEventListener('click', function(e) {
if (e.target.tagName === 'LI') {
e.target.remove();
} else if (e.target.tagName === 'INPUT') {
e.target.parentElement.classList.toggle('finished');
}
});
My teacher's code/local storage solution:
const todoForm = document.getElementById("newTodoForm");
const todoList = document.getElementById("todoList");
// retrieve from localStorage
const savedTodos = JSON.parse(localStorage.getItem("todos")) || [];
for (let i = 0; i < savedTodos.length; i++) {
let newTodo = document.createElement("li");
newTodo.innerText = savedTodos[i].task;
newTodo.isCompleted = savedTodos[i].isCompleted ? true : false;
if (newTodo.isCompleted) {
newTodo.style.textDecoration = "line-through";
}
todoList.appendChild(newTodo);
}
todoForm.addEventListener("submit", function(event) {
event.preventDefault();
let newTodo = document.createElement("li");
let taskValue = document.getElementById("task").value;
newTodo.innerText = taskValue;
newTodo.isCompleted = false;
todoForm.reset();
todoList.appendChild(newTodo);
// save to localStorage
savedTodos.push({ task: newTodo.innerText, isCompleted: false });
localStorage.setItem("todos", JSON.stringify(savedTodos));
});
todoList.addEventListener("click", function(event) {
let clickedListItem = event.target;
if (!clickedListItem.isCompleted) {
clickedListItem.style.textDecoration = "line-through";
clickedListItem.isCompleted = true;
} else {
clickedListItem.style.textDecoration = "none";
clickedListItem.isCompleted = false;
}
// breaks for duplicates - another option is to have dynamic IDs
for (let i = 0; i < savedTodos.length; i++) {
if (savedTodos[i].task === clickedListItem.innerText) {
savedTodos[i].isCompleted = clickedListItem.isCompleted;
localStorage.setItem("todos", JSON.stringify(savedTodos));
}
}
});
Even though my code is more simpler (at least from what I can tell), it works exactly as his code does.
Local storage saves a JSON object to the user's computer. You should create an array of todos, append that array with every new todo, then set that item to local storage.
let ul = document.querySelector('ul');
const savedTodos = JSON.parse(localStorage.getItem("todos")) || []; // Retrieves local storage todo OR creates empty array if none exist
let newItem = document.querySelector('input[type=text]');
let checkbox = document.createElement('input');
checkbox.setAttribute('type', 'checkbox');
function output() {
let newTodo = document.createElement('li');
newTodo.innerText = newItem.value;
newTodo.classList.add('todo');
ul.append(newTodo);
newTodo.append(checkbox);
savedTodos.push({task: newItem.value, isCompleted: false}); // Appends the new todo to array
localStorage.setItem("todos", JSON.stringify(savedTodos)); //Converts object to string and stores in local storage
newItem.value = '';
}
I've annotated the solution you posted with some comments to help you step through it.
// Retrieve elements and store them in variables
const todoForm = document.getElementById("newTodoForm");
const todoList = document.getElementById("todoList");
// Get data stored in localStorage under the key "todos".
// The data type will be a string (local storage can only store strings).
// JSON is a global object that contains methods for working with data represented as strings.
// The `||` syntax is an OR operator and is used here to set an empty array as a fallback in case `localStorage` is empty
const savedTodos = JSON.parse(localStorage.getItem("todos")) || [];
// Create a loop the same length as the list of todos
for (let i = 0; i < savedTodos.length; i++) {
// Create an <li> element in memory (does not appear in the document yet)
let newTodo = document.createElement("li");
// Set the inner text of that new li with the contents from local storage.
// The savedTodos[i] is accessing data in the localStorage array.
// The [i] is a different number each loop.
// The `.task` is accessing 'task' property on the object in the array.
newTodo.innerText = savedTodos[i].task;
// Create a new property on the element called `isCompleted` and assign a boolean value.
// This is only accessible in code and will not show up when appending to the DOM.
newTodo.isCompleted = savedTodos[i].isCompleted ? true : false;
// Check the value we just set.
if (newTodo.isCompleted) {
// Create a style for the element if it is done (strike it out)
newTodo.style.textDecoration = "line-through";
}
// Actually append the new element to the document (this will make it visible)
todoList.appendChild(newTodo);
}
// `addEventListener` is a function that registers some actions to take when an event occurs.
// The following tells the browser - whenever a form is submitted, run this function.
todoForm.addEventListener("submit", function(event) {
// Don't try to send the form data to a server. Stops page reloading.
event.preventDefault();
// Create a <li> element in memory (not yet visible in the document)
let newTodo = document.createElement("li");
// Find element in the document (probably a input element?) and access the text value.
let taskValue = document.getElementById("task").value;
// Set the text of the <li>
newTodo.innerText = taskValue;
// Set a property on the <li> call `isCompleted`
newTodo.isCompleted = false;
// Empty out all the input fields in the form
todoForm.reset();
// Make the new <li> visible in the document by attaching it to the list
todoList.appendChild(newTodo);
// `push` adds a new element to the `savedTodos` array. In this case, an object with 2 properties.
savedTodos.push({ task: newTodo.innerText, isCompleted: false });
// Overwrite the `todos` key in local storage with the updated array.
// Use the JSON global object to turn an array into a string version of the data
// eg [1,2,3] becomes "[1,2,3]"
localStorage.setItem("todos", JSON.stringify(savedTodos));
});
// This tells the browser - whenever the todoList is clicked, run this function.
// The browser will call the your function with an object that has data about the event.
todoList.addEventListener("click", function(event) {
// the `target` of the event is the element that was clicked.
let clickedListItem = event.target;
// If that element has a property called `isCompleted` set to true
if (!clickedListItem.isCompleted) {
// update the styles and toggle the `isCompleted` property.
clickedListItem.style.textDecoration = "line-through";
clickedListItem.isCompleted = true;
} else {
clickedListItem.style.textDecoration = "none";
clickedListItem.isCompleted = false;
}
// The code above changes the documents version of the data (the elements themselves)
// This loop ensures that the array of todos data is kept in sync with the document
// Loop over the array
for (let i = 0; i < savedTodos.length; i++) {
// if the item in the array has the same text as the item just clicked...
if (savedTodos[i].task === clickedListItem.innerText) {
// toggle the completed state
savedTodos[i].isCompleted = clickedListItem.isCompleted;
// Update the localStorage with the new todos array.
localStorage.setItem("todos", JSON.stringify(savedTodos));
}
}
});
Keep in mind, there are 2 sources of state in your todo list. One is how the document looks, and the other is the array of todos data. Lots of challenges come from making sure these 2 stay in sync.
If somehow the document showed one of the list items as crossed out, but your array of data shows that all the todos are not completed, which version is correct? There is no right answer here, but state management will be something you might consider when designing apps in the future. Redux is a good js library with a well understood pattern that helps solve this problem. Hope this last comment doesn't confuse too much. Best of luck!
The important part is in (de)serializing the data. That means:
reading from localStorage (JSON.parse(localStorage.getItem("todos")) || [])
We add the default [] because if the todos key does not exist, we will get null and we expect a list
saving to localStorage (localStorage.setItem("todos", JSON.stringify(savedTodos)))
We need JSON.parse and its complementary operation JSON.stringify to parse and save strings because localStorage can store only strings.
In your case you need to read the data from localStorage and render the initial list. To save it to localStorage, again, you have to serialize the data. See the below snippets (link to working JSFIDDLE, because the below example does not work in the StackOverflow sandbox environment):
let ul = document.querySelector('ul');
let newItem = document.querySelector('input[type=text]');
const Store = {
serialize () {
return [].slice.call(document.querySelectorAll("li")).map(c => {
return {
text: c.textContent,
finished: c.querySelector("input").checked
}
})
},
get () {
return JSON.parse(localStorage.getItem("todos")) || []
},
save () {
return localStorage.setItem("todos", JSON.stringify(Store.serialize()))
}
}
const firstItems = Store.get()
firstItems.forEach(it => {
output(it.text, it.finished)
})
function output(v, finished) {
let newTodo = document.createElement('li');
newTodo.innerText = v || newItem.value;
newTodo.classList.add('todo');
let ulAppend = ul.append(newTodo);
ul.append(newTodo);
// Create a checkbox for each item
let checkbox = document.createElement('input');
if (finished) {
checkbox.checked = true
}
checkbox.setAttribute('type', 'checkbox');
let checkboxAppend = newTodo.append(checkbox);
newTodo.append(checkbox);
newItem.value = '';
}
let button = document.querySelector('.btn');
button.addEventListener('click', () => {
output()
Store.save()
});
ul.addEventListener('click', function(e) {
if (e.target.tagName === 'LI') {
e.target.remove();
} else if (e.target.tagName === 'INPUT') {
e.target.parentElement.classList.toggle('finished');
}
// Update the value in localStorage when you delete or add a new item
Store.save()
});
<ul></ul>
<input type="text" /> <button class="btn">Submit</button>
I have added the Store variable to simplify the way you get and set the data in localStorage.
The serialize method will read the TODOs from the list. document.querySelectorAll("li") returns a NodeList, but by doing [].slice.call(...) we convert it to an Array.

localStorage remove one value and keep existing values

I am trying to store two type of lists (add, remove) into localStorage. By default, I will add some values. And then user can remove that name if they don't want it. Once they remove the name from #notneeded list it will add into #needed list. I have done that case too.
JsBin Link
Default Case:
Problem is Here:
Now, you can see. I clicked EEE from second list. In visual screen it works fine. EEE removed from second list and added into first list. In localStorage first list is working fine as expected.
add => ["AAA","BBB","EEE"]
But, In second list I am expecting it should update like this
remove => ["CCC","DDD","FFF","GGG"]
instead of this
["CCC","DDD","EEE","FFF","GGG","\n\t\tCCCDDDFFFGGG"]
What I am doing wrong here?
Javascript
const selected = document.getElementById('needed');
const unselect = document.getElementById('notneeded');
//selected lists onload event
window.addEventListener('load', function(e){
var getLists = localStorage.getItem("add");
if (getLists === null) {
const defaultLists = [ 'AAA', 'BBB' ];
const unselectedLists = [ 'CCC', 'DDD', 'EEE', 'FFF', 'GGG' ];
defaultLists.forEach(item => {
liMaker(0, item);
});
unselectedLists.forEach(item => {
liMaker(1, item);
});
localStorage.setItem('add', JSON.stringify(defaultLists));
localStorage.setItem('remove', JSON.stringify(unselectedLists));
} else {
const defaultLists = JSON.parse(localStorage.getItem('add'));
const unselectedLists = JSON.parse(localStorage.getItem('remove'));
defaultLists.forEach(item => {
liMaker(0, item);
});
unselectedLists.forEach(item => {
liMaker(1, item);
});
}
});
//unselected lists onclick event
unselect.addEventListener('click', function(e){
const tgt = e.target;
let liArray = JSON.parse(localStorage.getItem('add')) || [];
liMaker(0, tgt.innerHTML);
liArray.push(tgt.innerHTML);
localStorage.setItem('add', JSON.stringify(liArray));
if(tgt.tagName.toUpperCase() == "LI") {
e.target.parentNode.removeChild(tgt);
}
const unselect = document.getElementById('notneeded').innerHTML;
let uliArray = JSON.parse(localStorage.getItem('remove')) || [];
uliArray.push(unselect);
console.log(uliArray);
localStorage.setItem('remove', JSON.stringify(uliArray));
});
const liMaker = (num, text) => {
const li = document.createElement('li');
li.textContent = text;
if(num === 0) {
selected.appendChild(li);
} else if(num === 1) {
unselect.appendChild(li);
}
}
HTML
<ul id="needed">
</ul>
<ul id="notneeded">
</ul>
Problem is here
const unselect = document.getElementById('notneeded').innerHTML;
This returns string, not actual values you expect
const unselect = document.getElementById('notneeded')
const badValues = unselect.innerHTML
const goodValues = [].map.call(unselect.children, (e) => e.textContent) // using .call
const goodValues2 = [...unselect.children].map(e => e.textContent) // using spread operator
console.log(badValues)
console.log(goodValues)
console.log(goodValues2)
<ul id='notneeded'>
<li>one</li>
<li>two</li>
</ul>
You are appending the innerHtml of the ul to the uliArray
const unselect = document.getElementById('notneeded').innerHTML;
let uliArray = JSON.parse(localStorage.getItem('remove')) || [];
uliArray.push(unselect);

Categories

Resources