Reputation: 35
I know there is a similar post about displaying local storage data, but my structure wasn't quite like it and I wasn't able to figure out how could I do it. So here it goes.
P.S: There might be some syntax/logical mistakes regarding the ES6 (I'm still trying to get used to it)
So here is my JS File:
const list = document.getElementById("list");
const input = document.getElementById("new-todo");
let toDoList = [];
let toDoObj = {
toDoName: String,
toDoDone: Boolean,
toDoID: 0,
}
input.addEventListener("keyup", e => {
if (e.keyCode === 13) {
addToDo(input.value, toDoObj);
updateLocalStorage();
}
});
list.addEventListener("click", e => {
ulComp = e.target;
if(ulComp.id === "dltBtn") {
removeToDo(ulComp, toDoList);
updateLocalStorage();
}
else if (ulComp.classList.contains("todo-text")) {
doneToDo(ulComp, toDoList);
updateLocalStorage();
}
});
const addToDo = (newToDo, obj) => {
if(input.value) {
const toDoItem = `<li id="item"><i class="fas fa-trash-alt" data-text="${newToDo}" id="dltBtn"></i><span data-text="${newToDo}" class="todo-text">${newToDo}</span> </li>`;
list.insertAdjacentHTML("afterbegin", toDoItem );
obj = {
toDoName: newToDo,
toDoDone: false,
toDoID: toDoObj.toDoID++
};
toDoList.push(obj);
input.value = "";
}
else {
alert("Please Type In A To-Do!");
}
}
const doneToDo = (item, list) => {
item.classList.toggle("done");
for(let i = 0; i < list.length; i++) {
if (list[i].toDoName === item.getAttribute("data-text") && item.classList.contains("done")) {
list[i].toDoDone = true;
}
else if (list[i].toDoName === item.getAttribute("data-text")) {
list[i].toDoDone = false;
}
}
}
const removeToDo = (item, list) => {
for (let i = 0; i < list.length;i++) {
if (list[i].toDoName === item.getAttribute("data-text")) {
item.parentElement.remove();
list.splice(i,1);
console.log(list);
}
}
}
const updateLocalStorage = () => {
localStorage.setItem("TODOs", JSON.stringify(toDoList));
}
const loadLocalStorage = () => {
JSON.parse(window.localStorage.getItem('TODOs'));
}
So far I was able to update the data on certain actions and getting it back on refresh. But I couldn't figure out how to display it.
I've tried passing JSON.parse(window.localStorage.getItem('TODOs'));
attributes and values into the variable and call the addToDo()
function, but since it's taking input.value
and toDoObj
arguements, I couldn't get it working.
Basically, (if I have no other mistakes in my logic) I want to be able to show the items on my locally stored array on the page when the page is refreshed.
Any help is very much appreciated
P.S 2: I'm still a newbie, so I'm sorry the code is messy and if there are some logical mistakes. ( feedback on those are appreciated as well.
Thanks!
Snippet:
const list = document.getElementById("list");
const input = document.getElementById("new-todo");
let toDoList = [];
let toDoObj = {
toDoName: String,
toDoDone: Boolean,
toDoID: 0,
}
input.addEventListener("keyup", e => {
if (e.keyCode === 13) {
addToDo(input.value, toDoObj);
updateLocalStorage();
}
});
list.addEventListener("click", e => {
ulComp = e.target;
if(ulComp.id === "dltBtn") {
removeToDo(ulComp, toDoList);
updateLocalStorage();
}
else if (ulComp.classList.contains("todo-text")) {
doneToDo(ulComp, toDoList);
updateLocalStorage();
}
});
const addToDo = (newToDo, obj) => {
if(input.value) {
const toDoItem = `<li id="item"><i class="fas fa-trash-alt" data-text="${newToDo}" id="dltBtn"></i><span data-text="${newToDo}" class="todo-text">${newToDo}</span> </li>`;
list.insertAdjacentHTML("afterbegin", toDoItem );
obj = {
toDoName: newToDo,
toDoDone: false,
toDoID: toDoObj.toDoID++
};
toDoList.push(obj);
input.value = "";
}
else {
alert("Please Type In A To-Do!");
}
}
const doneToDo = (item, list) => {
item.classList.toggle("done");
for(let i = 0; i < list.length; i++) {
if (list[i].toDoName === item.getAttribute("data-text") && item.classList.contains("done")) {
list[i].toDoDone = true;
}
else if (list[i].toDoName === item.getAttribute("data-text")) {
list[i].toDoDone = false;
}
}
}
const removeToDo = (item, list) => {
for (let i = 0; i < list.length;i++) {
if (list[i].toDoName === item.getAttribute("data-text")) {
item.parentElement.remove();
list.splice(i, 1);
}
}
}
const updateLocalStorage = () => {
localStorage.setItem("TODOs", JSON.stringify(toDoList));
}
const loadLocalStorage = () => {
JSON.parse(window.localStorage.getItem('TODOs'));
}
.done {
text-decoration: line-through;
opacity: 0.5;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>To Do List</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="style.css">
<!-- FONT AWESOME -->
<script src="https://kit.fontawesome.com/b9a2aee93e.js" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<h1>To Do List</h1>
<input id="new-todo" type="text" name="todo">
<ul id="list">
</ul>
</div>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
Upvotes: 1
Views: 99
Reputation: 35
const localStorageLoad = () => {
const items = JSON.parse(window.localStorage.getItem('TODOs'));
items.forEach( (item) => {
addToDo(item.toDoName, item);
});
}
Editing localStorageLoad
function as above and calling the function on window load as below, made everything work perfectly.
window.addEventListener("load", (e) => {
localStorageLoad();
});
So Checking Aditya's answer. It was mostly the correct answer in terms of logic.
Upvotes: 0
Reputation: 801
I think you have to call addToDo()
for all the items in the retrieved array. You can do something like this.
const items = JSON.parse(window.localStorage.getItem('TODOs'));
items.forEach((item) => {
addTodo(item)
});
Upvotes: 1