I can't seem to get local storage to work. The goal is to keep the todo list items on the page upon refresh. Every time I refresh the page it goes poof. The syntax seems right.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TODO LIST</title>
<link rel="stylesheet" href="./styles/style.css">
</head>
<body>
<main id="main">
<h1>THE TO-DO LIST:</h1>
<form action="" id="add-task">
<label for="todo">Add Task:</label>
<input type="text" id="todo">
<button>Add Task</button>
</form>
<p class="center">To complete task, click on text.</p>
<ul id="task-list">
<li class="task-complete">example_1 <button>Remove Task</button></li>
</ul>
</main>
<script src="./script/index.js"></script>
</body>
</html>
const form = document.querySelector('#add-task');
const input = document.querySelector('#todo');
const taskList = document.querySelector('#task-list');
let taskID = 0;
taskList.addEventListener('click', function(e) {
if (e.target.tagName === 'BUTTON') {
e.target.parentElement.remove();
let inputTask = document.getElementById('todo');
localStorage.setItem('email', inputTask.value);
} else if (e.target.tagName === 'LI') {
e.target.classList.toggle('task-complete');
}
});
form.addEventListener('submit', function(e) {
e.preventDefault();
console.log(input.value);
const newTask = document.createElement('li');
const removeBtn = document.createElement('button');
let savedInput = input.value;
removeBtn.innerText = 'Remove Task';
newTask.innerText = input.value;
newTask.appendChild(removeBtn);
taskList.appendChild(newTask);
input.value = '';
console.log(localStorage);
});
.task-complete {
text-decoration: line-through;
}
Joshua, here are a few things from looking at your sample:
First, you're setting the localStorage to a single item, with the current input value, not a collection of tasks like an array
It also seems that you're not getting the saved data on page reload, that's why nothing happens when page reloads
Remember that you can only save strings to localStorage, in a todo list you might want to save an array (a collection of todos), but since you can't do it you need to convert it to a string while saving (JSON.stringify(yourArray) will help you with that), and parse it back to an Array when loading (JSON.parse)
const form = document.querySelector('#add-task');
const input = document.querySelector('#todo');
const taskList = document.querySelector('#task-list');
let taskID = 0;
let tasks = [] // here will hold your current todos collection
// a function that will retrieve the saved todos from local storage
//
// note that 'tasks' can be any string identifier that you want — 'todos'
// would also work — but you need to use the same for localStorage.getItem
// and localStorage.setItem
function getTasksFromLocalStorage(){
// it will return `null` if nothing's there
tasks = localStorage.getItem('tasks') || []
if (tasks) {
// convert it to an array so you can loop over it
tasks = JSON.parse(tasks)
}
}
function addTask(text) {
// CREATE DOM ELEMENTS
const newTask = document.createElement('li');
const removeBtn = document.createElement('button');
removeBtn.innerText = 'Remove Task';
// set the text to the provided value
newTask.innerText = text;
// append the remove button
newTask.appendChild(removeBtn);
// append it to the dom so we can see it
taskList.appendChild(newTask)
}
// on page load get tasks from local storage
// then loop over it, create the DOM elements and append them to
// the taskList
document.addEventListener('DOMContentLoaded', function() {
getTasksFromLocalStorage()
// if we have saved tasks, loop over them and render to the dom
tasks.forEach(function(savedTaskText) {
addTask(savedTaskText)
})
})
// then on your code, you need to update to push
// the current inputed `task` to the `tasks` collection (Array)
// then save the entire collection to the local storage
// then add the new task to the DOM
// and finally reset the input
form.addEventListener('submit', function(e) {
e.preventDefault();
console.log(input.value);
// save it to the current holding list
tasks.push(input.value)
// save a copy of the updated list to the localStorage, so when you
// reload the page you get saved items!
localStorage.setItem('tasks', tasks)
// add it to DOM
addTask(input.value);
// reset the input
input.value = '';
});
There's more things you need to do, if you want tasks to have unique ids (since, so you can remove them later), but the code was simplified for brevity of explanation (and yet you got a long answer anyways).
Here's so docs and suggested reading:
MDN Docs for LocalStorage
MDN Docs for JSON (parse and stringify)
There's plenty vanilla javascript tutorials (written and youtube) for "creating a todo lists using localStorage", that go into more detail than we can go in a SO answer, I suggest you skim through those as well!
Good luck and Happy coding ✌️
There are 2 problems with your code.
First, you are not saving each to-do task entered by user upon form submit. If you want to save each to-do task entered by user in localStorage, then modify the form submit handler as below:
form.addEventListener('submit', function(e) {
e.preventDefault();
const newTask = document.createElement('li');
const removeBtn = document.createElement('button');
let savedInput = input.value;
removeBtn.innerText = 'Remove Task';
newTask.innerText = input.value;
newTask.appendChild(removeBtn);
taskList.appendChild(newTask);
localStorage.setItem('Task'+taskID, input.value);
taskID++;
input.value = '';
});
Second, you are not utilizing the previously saved data in localStorage to show the list of to-dos that were entered by user before the page was loaded. You can achieve that by using below function code:
function showSavedToDos() {
const keys = Object.keys(localStorage);
let i = keys.length;
while (i--) {
const newTask = document.createElement('li');
const removeBtn = document.createElement('button');
removeBtn.innerText = 'Remove Task';
newTask.innerText = localStorage.getItem(keys[i]);
newTask.appendChild(removeBtn);
taskList.appendChild(newTask);
}
}
showSavedToDos();
You are not using de localStorage API, please take a look to this example. here I am using template to display the tasks. In the html file is the only change
<main id="main">
<h1>THE TO-DO LIST:</h1>
<form action="" id="add-task">
<label for="todo">Add Task:</label>
<input type="text" id="todo" />
<button>Add Task</button>
</form>
<p class="center">To complete task, click on text.</p>
<ul id="task-list">
<li class="task-complete">example_1 <button>Remove Task</button></li>
</ul>
</main>
<template id="task">
<li class="task-complete">
<span></span>
<button>Remove task</button>
</li>
</template>
In JavaScript I create a render function that will collect the task stored in localstorage. Populated when calling store(input.value) in the submit handler
const form = document.querySelector("#add-task");
const input = document.querySelector("#todo");
const taskList = document.querySelector("#task-list");
let taskID = 0;
taskList.addEventListener("click", function (e) {
if (e.target.tagName === "BUTTON") {
e.target.parentElement.remove();
let inputTask = document.getElementById("todo");
localStorage.setItem("email", inputTask.value);
} else if (e.target.tagName === "LI") {
e.target.classList.toggle("task-complete");
}
});
form.addEventListener("submit", function (e) {
e.preventDefault();
console.log(input.value);
const newTask = document.createElement("li");
const removeBtn = document.createElement("button");
let savedInput = input.value;
removeBtn.innerText = "Remove Task";
newTask.innerText = input.value;
newTask.appendChild(removeBtn);
taskList.appendChild(newTask);
store(input.value);
input.value = "";
console.log(localStorage);
});
function getTasks() {
return localStorage.tasks ? JSON.parse(localStorage.tasks) : [];
}
function store(task) {
const tasks = getTasks();
tasks.push(task);
localStorage.setItem("tasks", JSON.stringify(tasks));
}
function render() {
const tasks = getTasks();
tasks.forEach((task) => {
const newTask = createTask(task);
taskList.appendChild(newTask);
});
}
function createTask(task) {
const template = document.querySelector("#task");
const taskNode = template.content.cloneNode(true);
taskNode.querySelector("span").innerText = task;
return taskNode;
}
render();
The render function run every first render of the page, so tasks list will be populated
Related
i am trying to get a event planner app to show some user input and subsequently allow them to delete it when needed.
i have the input part working, but i can't figure out how to get a button with "delete" added to the same li when the user presses Enter.
this is my JS so far: (what do i need to add to get the button included in the li)
function todoList(){
const item: string = (<HTMLInputElement>document.getElementById('todoInput')).value;
const text = document.createTextNode(item)
const newItem = document.createElement('li')
const button: any = document.createElement("button")
button.innerHTML = 'Delete';
newItem.appendChild(text)
// #ts-ignore
}
const form = (<HTMLInputElement>document.getElementById('todoForm'))
form.addEventListener("submit", (e) => {
e.preventDefault();
})
<h1 class="title">todos</h1>
<form id="todoForm" onsubmit="todoList()" >
<button id="scrolldown-menu-toggle">˅</button>
<input type="text" id="todoInput" placeholder="Fill in your plan">
</form>
<ol id="todoList">
</ol>
You need to append the button into the <li> as well.
So you would want to do this -
function todoList(){
const item: string =
(<HTMLInputElement>document.getElementById('todoInput')).value;
const text = document.createTextNode(item)
const newItem = document.createElement('li')
const button: any = document.createElement("button")
button.innerHTML = 'Delete';
newItem.appendChild(text)
newItem.appendChild(button) // <--- Add this line
// #ts-ignore
}
This seems to work:
function todoList() {
// <HTMLInputElement> removed as the snippet will not run otherwise.
// This does however not seem to affect the execution of the code.
// Read the input text into variable:
const item: string = (document.getElementById('todoInput')).value;
// Create text-node:
const text = document.createTextNode(item);
// Create list item:
const newItem = document.createElement('li');
// Create button:
const button: any = document.createElement("button");
// Create button text node and append it to button:
const btnText = document.createTextNode('Delete');
button.appendChild(btnText);
// Add handler to actually delete the entry:
button.addEventListener('click', e => newItem.remove());
// Append text and button to the list item:
newItem.appendChild(text);
newItem.appendChild(button);
// Append list item to the ordered list:
document.getElementById('todoList').appendChild(newItem);
// #ts-ignore
}
const form = (document.getElementById('todoForm'))
form.addEventListener("submit", (e) => {
e.preventDefault();
})
<h1 class="title">todos</h1>
<form id="todoForm" onsubmit="todoList()">
<button id="scrolldown-menu-toggle" type="submit">˅</button>
<input type="text" id="todoInput" placeholder="Fill in your plan" />
</form>
<ol id="todoList">
</ol>
I am trying to make the tasks that have been created save to the user's local storage within the browser. Is it also possible to show me how to make the delete button remove the created task?
/************************************
* creates an object of elements needed *
************************************/
const elements = {
form: document.querySelector("#new-task-form"),
input: document.querySelector("#new-task-input"),
list: document.querySelector("#tasks"),
cal: document.querySelector("#calendar")
}
/****************************
* Generates an ID for task *
****************************/
const createId = () => `${Math.floor(Math.random() * 10000)}-${new Date().getTime()}`
/**********************************************
* function that creates the HTML elements *
**********************************************/
const createTask = () => {
const id = createId()
const task = elements.input.value;
const date = elements.cal.value;
if(!task && !date) return alert("Please fill in task and select date");
if(!task) return alert("Please fill in task");
if(!date) return alert("Please select date");
const tasks = document.createElement("div");
tasks.innerHTML = `
<button class = "sort">Sort</button>
<div class="task" data-id = "${id}">
<div class="content">
<input type ="checkbox" class="tick">
<input type ="text" class = "text" id = "text" value="${task}" readonly>
<label class = "due-date" for ="text">${date}</label>
<input type ="date" class = "date" id = "date">
</div>
<div class = "actions">
<button class="edit" data-id="${id}">Edit</button>
<button class="delete" data-id="${id}">Delete</button>
</div>
</div>
`
elements.list.appendChild(tasks)
listen()
return tasks
}
/********************************************
* Marks tasks as complete with checkbox *
********************************************/
function listen(){
let allCheckboxes = document.querySelectorAll('.tick')
allCheckboxes.forEach(checkbox =>{
checkbox.addEventListener('change',(e)=>{
let parentElem=e.target.parentElement
if(e.target.checked){
parentElem.style.textDecoration = "line-through"
}
else{
parentElem.style.textDecoration = "none"
}
});
});
}
/**************************************************************
* Event that listens for the edit,save and delete buttons *
**************************************************************/
elements.list.addEventListener('click',event => {
const {target} = event;
const {id} = target.dataset;
const task = id ? document.querySelector(`[data-id="${id}"]`):null;
const type = {
edit: event.target.classList.contains('edit'),
delete: event.target.classList.contains('delete')
}
const isFromSaveLabel = target.innerText.toLowerCase() === 'save'
//Checking to see if buttons are pressed
if(task && type.edit && isFromSaveLabel){
const text = task.querySelector('text')
target.innerText = 'Edit'
text.setAttribute('readonly', true)
return
};
if(task && type.edit){
const text = task.querySelector('text')
target.innerText = 'save'
text.removeAttribute('readonly')
text.focus()
return
};
if(task && type.delete){
return
}
});
/*******************************************************************
* Submits the HTML elements to have the lists submited and created*
*******************************************************************/
const submitHandler = (event) =>{
event.preventDefault();
createTask();
}
elements.form.addEventListener("submit", submitHandler);
The end result that I would like to achieve is to make the created list local storage so that if the page refreshes the tasks remain. and having the task delete when clicking the delete button
You can find the jsfiddler here: https://jsfiddle.net/blaze92/seLvzd1h/2/
I Had Done The Exact Same Project In The Past My Project. So How You Can Do It Can Be Like The Following:
Since You Already Have A Method For Creating A Task createTask. modify this function in a way such that you can pass custom parameters. This allows you to create a method to add notes from the localstorage to your page.
Then You Need To Take All The Tasks get their info using document.getElementByClassName or document.getElementByID and then add it to a JSON Object/Array.
Then You Can Convert this JSON Object/Array Into String Using JSON.Stringify. Now You Can Store This String Into Localstorage using localStorage.setItem()
Now You Can Add A Event Listener To Detect Page Load and then get this String from localhost as localStorage.getItem() and then convert it back to a JSON Object.
Then Create A For Loop Which Iterates Through all the elements of this object/array and call the method to createTask with the parameters from the object.
I was making a simple to-do list. You submit itens from an input and they go to the To-DO section. When you click over them they go to the 'Done' section. And when you click on them again, they vanish forever. It was all working fine.
But I realized the doneItens array kept growing in length, which I wanted to optimize. So I came up with this line of code
doneItens.splice(i, 1);
which goes inside an onclick event, which you can see in the code inside the deleteDone function.
That gives the error, though,
Error:{
"message": "Uncaught TypeError: doneItens.splice is not a function"
If I put it outside and below the onclick event it also doesn't work. How can I do it?
var input = document.getElementById('play');
var toDo = document.getElementsByTagName('ol')[0];
var done = document.getElementById('done');
function handleSubmit(event) {
event.preventDefault();
const newItem = document.createElement('li');
newItem.setAttribute('class', 'item');
newItem.append(input.value);
toDo.append(newItem);
input.value='';
deleteItem();
}
function deleteItem() {
const toBeDone = document.getElementsByClassName('item');
for(let i = 0; i < toBeDone.length; i++) {
toBeDone[i].onclick = () => {
appendItemDone(toBeDone[i]);
toBeDone[i].style.display = 'none';
deleteDone();
}
}
}
function appendItemDone(item) {
const newDone = document.createElement('li');
newDone.setAttribute('class', 'feito')
newDone.append(item.innerText);
done.append(newDone);
}
function deleteDone() {
const doneItens = document.getElementsByClassName('feito');
console.log('done length', doneItens.length)
for (let i = 0; i < doneItens.length; i++) {
doneItens[i].onclick = () => {
doneItens[i].style.display = 'none';
doneItens.splice(i, 1);
}
}
}
<div id='flex'>
<form class='form' onsubmit='handleSubmit(event)'>
<input placeholder='New item' type='text' id='play'>
<button>Send</button>
</form>
<div id='left'>
<h1 id='todo' >To-do:</h1>
<p class='instruction'><i>(Click over to mark as done)</i></p>
<ol id='here'></ol>
</div>
<div id='right'>
<h1>Done:</h1>
<p class='instruction'><i>(Click over to delete it)</i></p>
<p id='placeholder'></p>
<ol id='done'></ol>
</div>
</div>
With the use of JavaScript DOM API such as Node.removeChild(), Element.remove() and Node.parentNode, your task can be solved with this code:
const input = document.getElementById('play');
const todo = document.getElementById('todo');
const done = document.getElementById('done');
function handleSubmit(event) {
event.preventDefault();
// create new "todo" item
const newTodo = document.createElement('li');
newTodo.textContent = input.value;
todo.append(newTodo);
// clean the input field
input.value = '';
// listen to "click" event on the created item to move it to "done" section
newTodo.addEventListener('click', moveToDone);
}
function moveToDone(event) {
// remove "click"-listener to prevent event listener leaks
event.target.removeEventListener('click', moveToDone);
// move clicked todo-element to "done" section
const newDone = event.target.parentNode.removeChild(event.target);
done.append(newDone);
// listen to "click" event on the moved item to then completely delete it
newDone.addEventListener('click', removeFromDone);
debugElementsLeak();
}
function removeFromDone(event) {
// remove "click"-listener to prevent event listener leaks
event.target.removeEventListener('click', removeFromDone);
// complete remove clicked element from the DOM
event.target.remove();
debugElementsLeak();
}
function debugElementsLeak() {
const todoCount = todo.childElementCount;
const doneCount = done.childElementCount;
console.log({ todoCount, doneCount });
}
<div id="flex">
<form class="form" onsubmit="handleSubmit(event)">
<input placeholder="New item" type="text" id="play">
<button>Add item</button>
</form>
<div id="left">
<h1>To-do:</h1>
<p class="instruction"><em>(Click over to mark as done)</em></p>
<ol id="todo"></ol>
</div>
<div id="right">
<h1>Done:</h1>
<p class="instruction"><em>(Click over to delete it)</em></p>
<p id="placeholder"></p>
<ol id="done"></ol>
</div>
</div>
You'll want to use splice,
and then rather than use hidden, 'refresh' the done element by adding all elements in the spliced array.
I've commented my code where I've made changes and why
var input = document.getElementById('play');
var toDo = document.getElementsByTagName('ol')[0];
var done = document.getElementById('done');
function handleSubmit(event) {
event.preventDefault();
const newItem = document.createElement('li');
newItem.setAttribute('class', 'item');
newItem.append(input.value);
toDo.append(newItem);
input.value='';
deleteItem();
}
function deleteItem() {
const toBeDone = document.getElementsByClassName('item');
for(let i = 0; i < toBeDone.length; i++) {
toBeDone[i].onclick = () => {
appendItemDone(toBeDone[i].cloneNode(true));
toBeDone[i].style.display = 'none';
deleteDone();
}
}
}
function appendItemDone(item) {
const newDone = document.createElement('li');
newDone.setAttribute('class', 'feito')
newDone.append(item.innerText);
done.append(newDone);
}
function deleteDone() {
var doneItens = document.getElementsByClassName('feito');
for (let i = 0; i < doneItens.length; i++) {
doneItens[i].onclick = () => {
var splicedArray = spliceFromArray(doneItens,doneItens[i]);// NEW BIT -CALL NEW SPLICE FUNCTION
done.innerHTML=""; // NEW BIT - SET OVERALL DONE TO BLANK ON DELETE
for(var index in splicedArray){// NEW BIT - fOR EACH RETURNED ELEMENT IN THE SPLICE, ADD IT TO THE OVERALL DONE ELEMENT
done.appendChild(splicedArray[index]);
}
}
}
}
function spliceFromArray(arrayInput,element){// NEW BIT - SPLICE FUNCTION THAT RETURNS SPLICED ARRAY
var array = Array.from(arrayInput);
var index = array.indexOf(element);
if(index!=-1){
if(array.length==1 && index == 0){
array = [];
}
else{
array.splice(index,1);
}
}
return array;
}
<div id='flex'>
<form class='form' onsubmit='handleSubmit(event)'>
<input placeholder='New item' type='text' id='play'>
<button>Send</button>
</form>
<div id='left'>
<h1 id='todo' >To-do:</h1>
<p class='instruction'><i>(Click over to mark as done)</i></p>
<ol id='here'></ol>
</div>
<div id='right'>
<h1>Done:</h1>
<p class='instruction'><i>(Click over to delete it)</i></p>
<p id='placeholder'></p>
<ol id='done'></ol>
</div>
</div>
<?php foreach ($communities as $community) { ?>
<div class="community-container">
<p><?php echo $community->Title ?></p>
<button class="del-btn" data-id="<?php echo $community->ID ?>">Delete</button>
</div>
<?php } ?>
<Script>
const deleteBtns = document.getElementsByClassName('del-btn');
var deleteBtnsArray = Array.from(deleteBtns);
deleteBtnsArray.map(deleteBtn => {
deleteBtn.addEventListener('click', () => {
const delRequest = new XMLHttpRequest();
let params = [];
params = `deleteCommunity=true&communityID=${deleteBtn.dataset.id}`;
delRequest.open('POST', '/ajax/delete-community');
delRequest.onreadystatechange = function() {
if (delRequest.responseText === 'success') {
deleteBtn.parentElement.remove();
}
}
delRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
delRequest.send(params);
})
})
</Script>
I have communities list on my page and each community item has a delete button. Now when I click on a delete button I want to delete related community item.
But...
I can inspect these delete buttons from the browser and change it's data-id value to something else(if a data-id of a delete button is 10, I can change it to 1000). Then when I click on that delete button after changing its data-id value from the client side, it will delete some other community instead correct one. (If a community exists with that changed data-id value) because buttons data-id is changed and JavaScript code takes that value to make AJAX request. I can't stop user changing data-id from the client-side. Therefore, How can I handle this situation if user changed data attributes from client side?
Extra information
$communities is a array of community objects and each community item has a Name and ID.
You could read the data- prop(s) after the page loads. Store them in an array or whatever and then delete the data- prop(s) from the elements.
Be aware that validation should probably happen somewhere on the server side instead of client side
// Wrap everything in an IIFE so we don't create global variables
(() => {
const ID_MAP = new WeakMap();
const onClickAction = ({ currentTarget }) => {
// Exit if there is no ID stored
if(!ID_MAP.has(currentTarget)) return;
// Retrieve and log ID
const id = ID_MAP.get(currentTarget);
console.log(id);
}
const btns = document.querySelectorAll('button');
for(const btn of btns) {
// Skip if it doesn't have an ID
if(!btn.dataset.id) continue;
// Store and hide `data-id` attribute
ID_MAP.set(btn, btn.dataset.id);
btn.removeAttribute('data-id');
// Add event listener
btn.addEventListener('click', onClickAction, false);
}
})();
<button data-id="001">id: 001</button>
<button data-id="002">id: 002</button>
<button data-id="003">id: 003</button>
<button data-id="004">id: 004</button>
<button data-id="005">id: 005</button>
EDIT: using suggestions from comments (event delegation)
// Wrap everything in an IIFE so we don't create global variables
(() => {
const ID_MAP = new WeakMap();
const onClickAction = ({ target }) => {
// Exit if it's not a button
if(target.nodeName !== 'BUTTON') return;
// Exit if there is no ID stored
if(!ID_MAP.has(target)) return;
// Retrieve and log ID
const id = ID_MAP.get(target);
console.log(id);
}
const btns = document.querySelectorAll('button');
for(const btn of btns) {
// Skip if it doesn't have an ID
if(!btn.dataset.id) continue;
// Store and hide `data-id` attribute
ID_MAP.set(btn, btn.dataset.id);
btn.removeAttribute('data-id');
}
// Add event listener, instead of `document` you can also use a common parent container
document.addEventListener('click', onClickAction, false);
})();
<button data-id="001">id: 001</button>
<button data-id="002">id: 002</button>
<button data-id="003">id: 003</button>
<button data-id="004">id: 004</button>
<button data-id="005">id: 005</button>
I've made a start to a to do list. I've got it adding an item when you submit an item.
I want to now add local storage when you refresh the page so the items are saved in the browser.
I obviously need to save all the times when the page is refreshed but because my items only update on click I'm not sure how to grab that function data outside the function and save the items.
Any ideas?
Cheers
JS Fiddle:
https://jsfiddle.net/x1bj8mfp/
// When submit item
var submit = document.getElementById('form');
submit.addEventListener('submit', addItem);
var items = [];
var itemValues = document.getElementById('items');
var listContainer = document.createElement('ul');
itemValues.appendChild(listContainer);
// Add item
function addItem(e) {
e.preventDefault();
var item = this.querySelector('[name=item]');
var itemValue = item.value;
items.push(itemValue);
item.value = '';
// Output items
var listItems = document.createElement('li');
listItems.innerHTML = itemValue;
listContainer.appendChild(listItems);
}
You could write the whole array to local storage whenever you add an item:
localStorage.setItem('items', JSON.stringify(items));
Then on page load you would read from local storage the array and assign it back to your variable, or set it to [] (like now), if nothing is in local storage, and then display these items:
var items = JSON.parse(localStorage.getItem('items')) || [];
items.forEach(function (itemValue) {
var listItems = document.createElement('li');
listItems.textContent = itemValue;
listContainer.appendChild(listItems);
});
This updated JSFiddle has that code included.
Of course, you will need some function to delete items as well, otherwise you can only grow your list.
Here's a full solution for you. Note that the code snippet won't work here, due to the cors and sandbox. Just paste it into your code editor.
var submit = document.getElementById('form');
submit.addEventListener('submit', addItem);
var items = [];
var itemValues = document.getElementById('items');
var listContainer = document.createElement('ul');
itemValues.appendChild(listContainer);
//retrieve data after reload
window.onload = function() {
if (localStorage.userData != undefined) {
var userData = JSON.parse(localStorage.getItem('userData'));
for (var i = 0; i < userData.length; i++) {
var listItems = document.createElement('li');
listItems.innerHTML = userData[i];
listContainer.appendChild(listItems);
items = userData;
}
}
}
// Add item
function addItem(e) {
e.preventDefault();
var item = this.querySelector('[name=item]');
var itemValue = item.value;
items.push(itemValue);
item.value = '';
// Output items
var listItems = document.createElement('li');
listItems.innerHTML = itemValue;
listContainer.appendChild(listItems);
localStorage.setItem('userData', JSON.stringify(items));
}
<main>
<form id="form">
<input class="form-input" type="text" name="item" placeholder="Add item">
<input class="btn btn-block" type="submit" value="Submit">
</form>
<div id="items"></div>
<div id="completed"></div>
</main>
Here some helpful small example for local storage
function save() {
var fieldvalue = document.getElementById('save').value;
localStorage.setItem('text', fieldvalue);
}
function load() {
var storedvalue = localStorage.getItem('textfield');
if (storedvalue) {
document.getElementById('textfield').value = storedvalue;
}
}
function remove() {
document.getElementById('textfield').value = '';
localStorage.removeItem('textarea');
}
<body onload="load()">
<input type="textarea" id="textfield">
<input type="button" value="Save" id="save" onclick="save()">
<input type="button" value="remove" id="remove" onclick="clr()">
</body>
<!--save& run this in local to see local storage-->