How to reload current page without losing added list items? - javascript

I'm creating something similar to a to-do-list project, but whenever I refresh the page I lose all the added items, I've tried using:
`
window.onbeforeunload = function () {
localStorage.setItem("list", $("#listItem").val());
};
window.onload = function () {
var name = localStorage.getItem("list");
if (name !== null) $("#listItem").val("list");
};
`
but still it doesn't work, I may have used it in the wrong place or wrong way. any help please?
here is my full code:
HTML:
`
<!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" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<link rel="stylesheet" href="style.css" />
<title>To Do List</title>
</head>
<body>
<section class="section-center">
<form class="todolist-form">
<h3>To Do List!</h3>
<div class="input-button">
<input type="text" id="items-input" placeholder="e.g. eggs" />
<input
type="button"
class="submit-btn"
onclick="addItems()"
value="Submit"
/>
</div>
<div class="added-items">
<ul id="faves"></ul>
</div>
</form>
</section>
<script src="main.js"></script>
</body>
</html>
`
Javascript:
`
function addItems() {
var li = document.createElement("LI");
li.setAttribute("id", "listItem");
var input = document.getElementById("items-input");
li.innerHTML = input.value;
input.value = "";
document.getElementById("faves").appendChild(li);
var deleteBtn = document.createElement("button");
deleteBtn.classList.add("delete-btn");
deleteBtn.innerHTML = "Delete";
deleteBtn.type = "button";
document.getElementById("faves").appendChild(deleteBtn);
var hrzBreak = document.createElement("br");
document.getElementById("faves").appendChild(hrzBreak);
/*********/
window.onbeforeunload = function () {
localStorage.setItem("list", $("#listItem").val());
};
window.onload = function () {
var name = localStorage.getItem("list");
if (name !== null) $("#listItem").val("list");
};
}
`
What am I doing wrong? I've included jQuery's CDN too, but still it doesn't work.

var texts = [];
function addItems() {
var input = document.getElementById("items-input");
createElement(input.value)
input.value = "";
}
function createElement(value) {
var li = document.createElement("LI");
li.setAttribute("id", "listItem");
li.innerHTML = value;
document.getElementById("faves").appendChild(li);
var deleteBtn = document.createElement("button");
deleteBtn.classList.add("delete-btn");
deleteBtn.innerHTML = "Delete";
deleteBtn.type = "button";
document.getElementById("faves").appendChild(deleteBtn);
var hrzBreak = document.createElement("br");
document.getElementById("faves").appendChild(hrzBreak);
texts.push(value)
}
window.onbeforeunload = function () {
// Store text array in storage
localStorage.setItem("list", JSON.stringify(texts));
};
window.onload = function () {
// get list grom storage
var list = localStorage.getItem("list");
if (list !== null) {
list = JSON.parse(list)
for (let index = 0; index < list.length; index++) {
const element = list[index];
// create your dom element
createElement(element)
}
}
};
Using an Array to manage the data flow. This will do the job but still a mess.

Try adding event listeners once and outside of your function
window.onbeforeunload = function () {
localStorage.setItem("list", $("#listItem").val());
};
window.onload = function () {
var name = localStorage.getItem("list");
if (name !== null) $("#listItem").val("list")
};
function addItems() {
...
}

Assuming that $("#listItem").val() will return the data you want, place below block outsite of the addItems() function
window.onbeforeunload = function () {
localStorage.setItem("list", $("#listItem").val());
};
window.onload = function () {
var name = localStorage.getItem("list");
if (name !== null) $("#listItem").val("list");
};

Related

How to store task in localstorage than onload make it appear in individual tasks

I am trying to make a To Do list but I have encountered a problem with storing it in local storage. I have tried storing the task in a var than it in localStorage but than when a new task is added it overwrites the variable and when I tried to store it in array and than when I tried to retrieve it from array all tasks appeared in a single task div. I want to store the tasks in local storage and have the task be edited, deleted, marked done also for localStorage too. I am providing the code.
<--JS-->
let tasksDiv = document.getElementById("tasks");
let oldTasksDiv = document.getElementById("old-tasks");
let input = document.getElementById('input');
var clear = document.getElementById('clear');
input.value = "What do you have planned?";
addBtn.addEventListener('click' , onclickBtn);
input.addEventListener('keypress' , function(){
if(event.keyCode === 13){
onclickBtn();
}
});
input.addEventListener('click' , function (){
if(input.value === "What do you have planned?"){
input.value ="";
}
})
clear.addEventListener('click' , function (){
input.value ="";
})
function onclickBtn(){
if(input.value.length !== 0){
var tasksName = document.createElement('div');
tasksName.classList.add("tasks-div")
var task = document.createElement('p');
task.innerText = input.value;
task.classList.add("task");
var del = document.createElement('button');
del.classList.add("del");
del.innerHTML = '<i class="fas fa-solid fa-trash"></i>';
var edit = document.createElement('button');
edit.classList.add("edit");
edit.innerHTML = '<i class="fas fa-solid fa-pen-to-square"></i>';
var save = document.createElement('button');
save.classList.add("save");
save.innerHTML = '<i class="fas fa-solid fa-floppy-disk"></i>';
var chkbox = document.createElement('input');
chkbox.classList.add("chkbox")
chkbox.type = "checkbox";
tasksName.appendChild(chkbox);
tasksName.appendChild(task);
tasksName.appendChild(del);
tasksName.appendChild(edit);
tasksName.appendChild(save);
tasksDiv.appendChild(tasksName);
chkbox.addEventListener('click' , function(){
if(chkbox.checked === true){
task.style.textDecoration = "line-through red";
edit.style.display = "none";
save.style.display = "none";
}
else{
task.style.textDecoration = "none";
edit.style.display = "block";
}
})
del.addEventListener('click' , function(){
tasksDiv.removeChild(tasksName);
})
edit.addEventListener('click' , function(){
task.contentEditable = true;
task.focus();
edit.style.display = "none";
save.style.display = "block";
})
save.addEventListener('click' , function(){
if(task.innerHTML === '<br>'){
alert('This task will be deleted');
tasksDiv.removeChild(tasksName);
}
task.contentEditable = false;
task.blur();
edit.style.display = "block";
save.style.display = "none";
})
}
else{
alert("Please enter a task");
}
}
<-- HTML -->
<!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>Tasks Keeper</title>
<link rel="stylesheet" href="./css/style.css">
<link rel="stylesheet" href="./css/resp.css">
<script src="https://kit.fontawesome.com/6bf6193572.js" crossorigin="anonymous"></script>
<script src="https://kit.fontawesome.com/9b41c17796.js" crossorigin="anonymous"></script>
</head>
<body>
<header>
<div class="brand-div">
<h1><span class="brand">Tasks Keeper</span></h1>
<span class="made-by">Made By Raghav Srvt</span>
</div>
<div class="input-div">
<div class="input-div-clear">
<input type="text" placeholder="What do you have planned?" id="input" value="What do you have planned?">
<i class="fa-solid fa-xmark" id="clear"></i>
</div>
<button type="submit" id="add-btn">Add</button>
</div>
</header>
<div id="tasks">
</div>
<script src = "./app.js"></script>
</body>
</html>
You can insert todos as object into an Array and store it on LocalStorage.
It is a Functionality that makes it Easy for you.
function LsHandling() {
return {
get: function (key) {
const item = localStorage.getItem(key);
if (item) {
return JSON.parse(item);
}
},
set: function (todo, key) {
const item = localStorage.getItem(key);
if (item) {
const itemToArray = [...JSON.parse(item)];
for (data in itemToArray) {
if (itemToArray[data].id === todo.id) {
return;
} else {
itemToArray.push(todo)
localStorage.setItem(key, JSON.stringify(itemToArray));
}
}
} else {
const defaultArray = [todo];
localStorage.setItem(key, JSON.stringify(defaultArray));
}
},
};
}
And you can use it Like This :
for getting the todosArray : LsHandling().get(yourKey)
for setting a todo in todosArray : LsHandling().set(todoObject, yourKey)
Note : for deleting or editing todos , you must define an id for each todo

Using PokeAPI to fetch data. Can't figure out why span element is not updating

So I'm using the PokeAPI to fetch the name of a Pokemon, then shuffling that name, and the user is supposed to guess what it is in the input. If they don't know then they can click the next button and it reshuffles a new mon. If they guess right they can press the same next button for a new mon. Each time they guess right the score increases by 1. That's working but I cant figure out why the out of/total games span isn't updating as well. Please excuse my terrible attempt at JS I'm very new if you can help me make my code look better that would be great.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="stylesheet" href="style.css" />
<title>Who's that Pkmn?</title>
</head>
<body>
<header>
<h1>Who's that Pokemon?!</h1>
</header>
<div id="jumble">?????</div>
<div class="container">
<input id="guess" type="text" placeholder="enter pkmn name" />
<button id="submit" class="btn" type="submit">go</button>
<button id="next" class="btn">next</button>
<p id="msg">unshuffle the letters</p>
</div>
<div id="scorekeepers">
<p>Score: <span id="score">0</span>
out of: <span id="gamesPlayed">0</span></p>
</div>
<script src="script.js"></script>
</body>
</html>
let jumbledName = document.querySelector("#jumble");
let guessInput = document.querySelector('#guess')
let submitButton = document.querySelector('#submit')
let nextButton=document.querySelector('#next')
let messageDisplay = document.querySelector('#msg')
let score = document.querySelector('#score')
let gamesPlayed = document.querySelector('#gamesPlayed')
score = 0;
gamesPlayed = 0;
let getPokemonName = function() {
fetch(`https://pokeapi.co/api/v2/pokemon/${Math.floor(Math.random()*151+1)}/`)
.then(function(response) {
return response.json();
})
.then(function(data) {
const pokeName = data.name;
const pokeNameJumbled = pokeName.shuffle();
displayInfomation(pokeName, pokeNameJumbled);
});
};
getPokemonName();
guessInput.value=''
// pokeNameJumbled=''
const displayInfomation = function(name, jumbledName) {
pokeName = name;
pokeNameJumbled = jumbledName;
jumble.textContent = jumbledName;
};
const displayMessage = function(message) {
document.querySelector("#msg").textContent = message;
};
const checkName = function () {
document.querySelector("#guess").textContent = guessInput;
const guess = document.querySelector("#guess").value.toLowerCase();
if (!guess) {
displayMessage("No guess entered!");
} else if (guess === pokeName) {
displayMessage(`Thats correct! It's ${pokeName}!`)
score++
document.querySelector("#score").textContent = score;
guessInput.value=''
} else if (guess != pokeName) {
displayMessage(`Wrong!`);
document.querySelector("#gamesPlayed").textContent = gamesPlayed;
}
};
submitButton.addEventListener('click', checkName)
nextButton.addEventListener('click',getPokemonName)
String.prototype.shuffle = function() {
var a = this.split(""),
n = a.length;
for (var i = n - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a.join("");
};

How to interact with an several appended childs

i am creating a todo list as a beginner exercise to train my JS skills but i hit a wall (again). As you can see in my code, i can create tasks that need doing and to each task i appended 2 buttons. Now i want both buttons to do the same thing (remove the task). I would like to create a addEventListener to those buttons but since i created them through JS and not HTML i don't now how to access them or their behavior (i don't know how to get their ID or if they even have one). So my question is this: how can i access those buttons through JavaScript? Thanks.
let b1 = document.getElementById('addItem');
let d1 = document.getElementById('resetList');
let content = document.getElementById('listItem').value;
let Liste = document.getElementById('laListe');
var addTask = function() {
var text = document.getElementById('listItem').value;
var li = document.createElement('li');
var buttons = document.createElement('button');
buttons.innerHTML = "X";
var buttons2 = document.createElement('button');
buttons2.innerHTML = "Done";
li.innerHTML = text;
li.append(document.createTextNode(" "));
document.getElementById('laListe').appendChild(li).appendChild(buttons);
li.append(document.createTextNode(" "));
li.append(buttons2);
}
document.getElementById('addItem').onclick = function(event) {
event.preventDefault()
};
b1.addEventListener('click', function() {
addTask();
});
d1.addEventListener('click', function() {
document.getElementById('laListe').innerText = " ";
});
document.getElementById('resetList').onclick = function(event) {
event.preventDefault()
};
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="Todo.css">
<title>ToDo App</title>
<script src='todo.js' defer></script>
</head>
<body>
<h1>To-Do List</h1>
<form id="Listcreator" name="itemAdd">
<input id="listItem" type="text">
<button id="addItem" type="submit"> Ajouter </button>
<button id="resetList" type="submit"> Tout Enlever</button>
</form>
<ul id="laListe"> </ul>
</body>
var buttons = document.createElement('button');
buttons.innerHTML = "X";
buttons.addEventListener("click", function(){
this.parentNode.remove();
});
var buttons2 = document.createElement('button');
buttons2.innerHTML = "Done";
buttons2.addEventListener("click", function(){
this.parentNode.remove();
});
You can add an event listener to your buttons when they are created.
https://jsfiddle.net/cnsxaL3b/
After adding event listeners, your code should look like below:
let b1 = document.getElementById('addItem');
let d1 = document.getElementById('resetList');
let content = document.getElementById('listItem').value;
let Liste = document.getElementById('laListe');
var addTask = function() {
var text = document.getElementById('listItem').value;
var li = document.createElement('li');
var buttons = document.createElement('button');
buttons.innerHTML = "X";
var buttons2 = document.createElement('button');
// Event listener for first button
buttons.addEventListener('click', function() {
alert('clicked button1');
});
// Event listener for first button
buttons2.addEventListener('click', function() {
alert('clicked button2');
});
buttons2.innerHTML = "Done";
li.innerHTML = text;
li.append(document.createTextNode(" "));
document.getElementById('laListe').appendChild(li).appendChild(buttons);
li.append(document.createTextNode(" "));
li.append(buttons2);
}
document.getElementById('addItem').onclick = function(event) {
event.preventDefault()
};
b1.addEventListener('click', function() {
addTask();
});
d1.addEventListener('click', function() {
document.getElementById('laListe').innerText = " ";
});
document.getElementById('resetList').onclick = function(event) {
event.preventDefault()
};

Trying to delete todo list but not working

var inputItem = document.getElementById("inputItem");
function addItem(list, input) {
var inputItem = this.inputItem;
var list = document.getElementById(list);
var listItem = document.createElement("li");
var deleteButton = document.createElement("button");
deleteButton.innerText = "delete";
deleteButton.addEventListener("click", function() {
//console.log("Delete");
//var ul=document.getElementById("list");
var listItem = list.children;
for (var i=0; i < listItem.length; i++) {
while(listItem[i] && listItem[i].children[0].checked) {
ul.removeChild(listItem[i]);
}
}
});
var checkBox = document.createElement("input");
checkBox.type = 'checkbox';
var label = document.createElement("label");
var labelText = document.createElement("span");
labelText.innerText = input.value;
label.appendChild(checkBox);
label.appendChild(labelText);
listItem.appendChild(label);
listItem.appendChild(deleteButton);
list.appendChild(listItem);
inputItem.focus();
inputItem.select();
return false;
}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>To-Do List</title>
</head>
<body>
<h1>To-Do List</h1>
<form onsubmit="return addItem('list', this.inputItem)">
<input type="text" id="inputItem">
<input type="submit">
</form>
<ul id="list">
</ul>
</body>
</html>
So first of all, there are a few little mistakes in the code:
var list = document.getElementById(list); - You're using the list as the parameter, not a string.
while(listItem[i] && listItem[i].children[0].checked) { - Not sure why you're using while here instead of if.
ul.removeChild(listItem[i]); - ul is commented a few lines above.
Besides these, the delete does not work because of the following line:
if(listItem[i] && listItem[i].children[0].checked) {
If you analyze the DOM, the list item contains a <label></label> that contains the input, which means children[0] is not what you expect it to be.
Therefore, fixing the issues mentioned above and replacing the check in the delete callback function with
if(listItem[i] && listItem[i].getElementsByTagName('input')[0].checked) {
list.removeChild(listItem[i]);
}
should be your fix.

Change css display of multiple elements using class in javascript

Fairly new to Javascript here. I have a to do list, and I am in the process of adding a feature to Hide all checked items (which have a class .checked).
The idea i have, is to add a display property to the class(that all checked items receive) but how do I do it? Is there any other way for me to be able to add a display property to all of the checked items?
Here's the code (didn't include the other css as it was unnecesary):
//ADD NEW ELEMENT SECTION
function newElement() {
var inputval = document.getElementById('inputnewlist').value;
var li = document.createElement('li');
var lichild = document.createTextNode(inputval);
li.appendChild(lichild);
if (inputval === '') {
alert('you must put something in the textbox!');
} else {
document.getElementById('mylist').appendChild(li);
}
document.getElementById('inputnewlist').value = "";
//REMOVE BUTTON SECTION
var button = document.createElement('button');
var buttonval = document.createTextNode('x');
button.classList.add("exit");
button.appendChild(buttonval);
li.appendChild(button);
var exit = document.querySelectorAll('.exit');
for (b = 0; b < exit.length; b++) {
exit[b].addEventListener('click', removeButtonParent);
}
}//end of create newelement function
var exit = document.querySelectorAll('.exit');
for (z = 0; z < exit.length; z++) {
exit.addEventListener('click', removeButtonParent);
}
function removeButtonParent() {
event.target.parentElement.remove();
}
//ENTER KEY PRESS-BUTTON PRESS
function enterfunction(event) {
var key = document.getElementById('inputnewlist');
if (event.keyCode === 13) {
event.preventDefault();
document.getElementById('addbutton').click();
}}
//CHECK BUTTON SECTION
var list = document.querySelector('ul');
list.addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
event.target.classList.toggle('checked');
}
}, false);
//HIDE CHECKED LIST ITEMS
function hideCheck() {
if (event.target.checked === true) {
var checkLI = document.querySelectorAll('.checked');
checkLI.style.display = "none";
}
else {
var checkliELSE = document.querySelectorAll('.checked');
checkLI.style.display = "";
}
}
.checked {
background-color: darkgrey;
text-decoration: line-through;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie-edge">
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght#500&display=swap" rel="stylesheet">
</head>
<body>
<div id="formcontainer">
<h1 class="title"> To Do List </h1>
<input type="text" name="inputnewlist" id="inputnewlist" placeholder="Add thing to do.." onkeydown="enterfunction(event)">
<button onclick="newElement()" class="addbutton" id="addbutton">Add</button>
</div>
<ul id="mylist">
</ul>
<input type="checkbox" id="hidecheck" onchange="hideCheck()"> <label for="hidecheck"> Hide the checked list items</label>
<script src="scripts.js"></script>
</body>
You can try the following code by adding the style 1 by 1.
function hideCheck() {
if (event.target.checked === true) {
var checkLIs = document.querySelectorAll('.checked');
for (let i = 0; i < checkLIs.length; i++){
checkLIs[i].style.display = "none";
}
}
}

Categories

Resources