I have a todo html element whose inner html i want to save in localstorage through use of html but i am unable to figure out how i would do it.
My javascript code
// Load everything
// get DOM Elements
let to_do_input = document.getElementById("todo-input");
let addBtn = document.getElementById("addBtn");
let display = document.getElementsByClassName("display")[0];
// Event Listeners
addBtn.addEventListener("click", () => {
// Add DOM ELements
let list = document.createElement("ul");
let todos = document.createElement("li");
let deleteBtn = document.createElement("button");
deleteBtn.innerText = "Delete";
// let saveBtn = document.createElement("button");
// saveBtn.innerText = "Save";
display.appendChild(list);
list.appendChild(todos);
list.appendChild(deleteBtn);
// list.append(saveBtn);
// Class names
list.classList.add("list");
todos.classList.add("todos");
deleteBtn.classList.add("deleteBtn");
// saveBtn.classList.add("saveBtn");
// Set values
todos.innerHTML = to_do_input.value;
to_do_input.value = null;
// delete todo
deleteBtn.addEventListener("click", () => {
list.innerHTML = null;
});
// SAVE todo
// saveBtn.addEventListener("click", () => {
// // let arr = [];
// let savedTodo = arr.push(todos.innerHTML);
// localStorage.setItem("todo", JSON.stringify(savedTodo));
// });
// Set saved todo
});
and my 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" />
<meta name="description" content="This web app provides you with accessibility of todo list" />
<title>Simple To-Do-List</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<h2>A Reliable To-Do-App</h2>
<div class="text-input center">
<input type="text" id="todo-input" placeholder="Write you task here.." />
<button type="button" id="addBtn" )>Add</button>
</div>
<div class="display"></div>
</div>
<script src="app.js"></script>
</body>
</html>
I have reviewed from other sites on how to do it but when i tried the array method , it returned numbers or when i tried to push todos into empty array , it didnt do anything. Also i dont know how i will convert the html element into an object to use it while making todo. Rest all the things work fine.
You need to set a array to save list,
So just edit your JS code to :
// Load everything
// get DOM Elements
let to_do_input = document.getElementById('todo-input')
let addBtn = document.getElementById('addBtn')
let display = document.getElementsByClassName('display')[0]
let todoArray = []
// Event Listeners
addBtn.addEventListener('click', () => {
// Add DOM ELements
let list = document.createElement('ul')
let todos = document.createElement('li')
let deleteBtn = document.createElement('button')
deleteBtn.innerText = 'Delete'
// let saveBtn = document.createElement("button");
// saveBtn.innerText = "Save";
display.appendChild(list)
list.appendChild(todos)
list.appendChild(deleteBtn)
// list.append(saveBtn);
// Class names
list.classList.add('list')
todos.classList.add('todos')
deleteBtn.classList.add('deleteBtn')
// saveBtn.classList.add("saveBtn");
// Set values
todos.innerHTML = to_do_input.value
todoArray.push(to_do_input.value)
to_do_input.value = null
// delete todo
deleteBtn.addEventListener('click', () => {
list.innerHTML = null
})
// SAVE todo
// saveBtn.addEventListener("click", () => {
// // let arr = [];
// let savedTodo = arr.push(todos.innerHTML);
// localStorage.setItem("todo", JSON.stringify(savedTodo));
// });
// Set saved todo
localStorage.setItem('todo', JSON.stringify(todoArray))
})
Related
I have found this very simple to do list. The inputs get stored as it should in the local storage, but I have problems with the "removing item" section in JS. The items are removed from the html but not from the local storage. So when it is refreshed the items I thought I removed are still there and I do not understand why. Also I do not understand firstElementChild and why it is there.
/*variables */
const addForm = document.querySelector('.add');
const list = document.querySelector('.todos');
// salvato gli items dal local storage in una variabile
let storedItems = localStorage.getItem('tasks');
const generateTemplate = todo => {
const html = `
<li>
<span>${todo}</span>
<i class="far fa-trash-alt delete"></i>
</li>`
list.innerHTML += html;
}
if (!storedItems) {
storedItems = [];
} else {
storedItems = JSON.parse(storedItems);
storedItems.forEach(item => {
generateTemplate(item);
});
}
addForm.addEventListener('submit', e => {
const todo = addForm.add.value.trim();
e.preventDefault();
if (todo.length) {
generateTemplate(todo);
storedItems.push(todo);
localStorage.setItem('tasks', JSON.stringify(storedItems))
addForm.reset();
console.log(`${todo} has been added to html list`)
console.log(`Local storage now contains ${storedItems}`)
}
});
/*Removing item*/
list.addEventListener('click', e => {
console.log(e.target);
if (e.target.classList.contains('delete')) {
e.target.parentElement.remove();
let removedItem = e.target.parentElement.firstElementChild.innerText;
console.log(`${removedItem} has been removed from the html list`);
console.log(storedItems)
const newArr = storedItems.filter(item => item !== removedItem)
console.log(newArr)
storedItems = newArr
console.log(`Local storage now contains ${storedItems} `)
}
})
<!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">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<title>Todolist</title>
</head>
<body>
<form action="" class="add">
<h1>To do list</h1>
<input type="text" id="name" name="add" placeholder="Enter name here">
<ul class="todos"></ul>
</form>
<script src="app.js"></script>
</body>
</html>
You are removing items from local array but not setting updated array to local storage. Just add
window.localStorage.setItem('tasks', JSON.stringify(storedItems))
after
storedItems = newArr
in your code. #TheBritishAreComing approach will work when you want to remove complete list instead of individual task
all this code is doing is manipulating the storedItems array, but it's not touching local storage.
if (e.target.classList.contains('delete')) {
e.target.parentElement.remove();
let removedItem = e.target.parentElement.firstElementChild.innerText;
console.log(`${removedItem} has been removed from the html list`);
console.log(storedItems)
const newArr = storedItems.filter(item => item !== removedItem)
console.log(newArr)
storedItems = newArr
console.log(`Local storage now contains ${storedItems} `)
}
You need to use, before you update your global array
localStorage.removeItem(removedItem);
Docs for localStorage.removeItem can be found here
Super new to all of this so this might be some beginner troubleshooting. The list seems to be working where I'm adding a list element to the UL with a checkbox and delete button. When checkbox is checked it puts a line through the text and when the delete button is clicked it deletes the list element. The assignment asks to save to localStorage so that when refreshed, the list items still remain, and I'm getting super confused by this. What I have now seems to be saving my list elements to an array but I don't understand how to get them to save and stay on the page.
const form = document.querySelector('form');
const input = document.querySelector('#todoInput');
const newElement = document.querySelector('ul');
const savedToDos = JSON.parse(localStorage.getItem('todos')) || [];
newElement.addEventListener('click', function(e) {
if(e.target.tagName === 'BUTTON') {
e.target.parentElement.remove()
}
})
function addToList(text) {
const li = document.createElement('li');
const checkbox = document.createElement('input');
const button = document.createElement('button');
button.innerText = "Delete";
checkbox.type = 'checkbox';
checkbox.addEventListener('change', function() {
li.style.textDecoration = checkbox.checked ? 'line-through' : 'none';
})
li.innerText = text;
li.insertBefore(checkbox, li.firstChild);
li.appendChild(button);
return li;
};
form.addEventListener('submit', function(e) {
e.preventDefault();
const newListItem = addToList(input.value);
input.value = '';
newElement.append(newListItem);
savedToDos.push(newListItem.innerText);
localStorage.setItem('todos', JSON.stringify(savedToDos));
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ToDo App</title>
<link rel="stylesheet" href="app.css">
</head>
<body>
<div>
<h1>Todo List</h1>
<form action="">
<input type="text" id="todoInput" placeholder="Add To Todo List">
<button class="add-button">Add</button>
</form>
<ul id="todoList">
</ul>
</div>
<script src="app.js"></script>
</body>
</html>
It looks like you're failing to populate the DOM when the page loads.
After you retrieve the items from local storage (which you're already doing), loop through the list and add each of them to the DOM:
// After this line, which you've already written:
const savedToDos = JSON.parse(localStorage.getItem('todos')) || [];
// Loop through savedToDos, and for each one, insert a new list:
savedToDos.forEach(function(value) {
const newListItem = addToList(value);
newElement.append(newListItem);
});
Every browser has local storage where we can store data and cookies. just go to the developer tools by pressing F12, then go to the Application tab. In the Storage section expand Local Storage.
this piece of code might help you
// Store Task
function storeTaskInLocalStorage(task) {
let tasks;
if(localStorage.getItem('tasks') === null){
tasks = [];
} else {
tasks = JSON.parse(localStorage.getItem('tasks'));
}
tasks.push(task);
localStorage.setItem('tasks', JSON.stringify(tasks));
}
I don't have coding experience, am in the process of learning.
I'm very very confuse as to what/how I should proceed setItem to localStorage and getItem from localStorage . So when webpage refresh, saved todo items would still be there.
I seen quite a few youtube videos and blog posts, but cant quite seem to understand .
I know I need to
-push input value into an array
-save that to localStorage with JSON.stringify
-when page refresh, check if there's data in localStorage
-if true, getItem from localStorage with JSON.parse
-if false, do nothing.
Can someone please explain like I'm five.
const toDoForm = document.querySelector('#todo-form');
const toDoInput = document.querySelector('#todo');
const ulList = document.querySelector('#ulList');
let dataArray = [];
toDoForm.addEventListener('submit', function (e) {
//stop submit event from refreshing
e.preventDefault();
//when submit -> create a element <li> link it with variable newLi
//Fill new <li>innerText</li> with toDoInput's value
const newLi = document.createElement('li');
newLi.innerText = toDoInput.value;
//when submit -> create a element <button></button> link it with variable btn
//<button>x</button>
//append <button>x</button> to newLi <li><button>x</button></li>
const btn = document.createElement('button');
btn.innerText = 'x';
newLi.appendChild(btn);
//add newLi <li><button>x</button></li> to ulList<ul></ul>
ulList.appendChild(newLi);
//push input into an empty array called dataArray
dataArray.push(toDoInput.value);
localStorage.setItem('localData', JSON.stringify(dataArray));
//when submit -> after all the above is done, we will set the input field to empty string
toDoInput.value = '';
});
ulList.addEventListener('click', function (e) {
if (e.target.tagName === 'BUTTON') {
e.target.parentElement.remove();
} else if (e.target.tagName === 'LI') {
e.target.classList.toggle('line');
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>TO DO LIST</h1>
<ul id="ulList">
</ul>
<form action="" id="todo-form">
<label for="todo">Write down things to do</label>
<input type="text" id="todo" name="todo">
<input type="submit">
</form>
<script src="app.js"></script>
</body>
</html>
You can extract the code to add a TODO item to a function and then call that function for each element in the array stored in localStorage if it is found.
let dataArray = localStorage.getItem('localData') ? JSON.parse(localStorage.getItem('localData')): [];
dataArray.forEach(addTodo);
function addTodo(todo){
const newLi = document.createElement('li');
newLi.innerText = todo;
//when submit -> create a element <button></button> link it with variable btn
//<button>x</button>
//append <button>x</button> to newLi <li><button>x</button></li>
const btn = document.createElement('button');
btn.innerText = 'x';
newLi.appendChild(btn);
//add newLi <li><button>x</button></li> to ulList<ul></ul>
ulList.appendChild(newLi);
}
toDoForm.addEventListener('submit', function (e) {
//stop submit event from refreshing
e.preventDefault();
addTodo(toDoInput.value);
dataArray.push(toDoInput.value);
localStorage.setItem('localData', JSON.stringify(dataArray));
//when submit -> after all the above is done, we will set the input field to empty string
toDoInput.value = '';
});
Demo
I received answers regarding the following contents.
Create Todo list with Javascript
If you enter too many characters, the "state" part will be misaligned. Like in the video, I want to expand the width of the "comment" according to the input value. What should I do?
See also the image.
Have already updated my answer to acomodate this additional bit on the same question :). See this and read the comments on the snippets:
https://stackoverflow.com/a/62356950/4650975
document.addEventListener('DOMContentLoaded', function() {
// 必要なDOM要素を取得。
const addTaskTrigger = document.getElementsByClassName('addTask-trigger')[0];
const addTaskTarget = document.getElementsByClassName('addTask-target')[0];
const addTaskValue = document.getElementsByClassName('addTask-value')[0];
//ID用のインデックスを定義
let nextId = 0;
const addTask = (task,id) => {
// 表のタグを生成する
const tableItem=document.createElement('thead');
const addButton = document.createElement('button');
const removeButton = document.createElement('button');
addButton.style.margin = "5px"; //<------- Added a style here
removeButton.style.margin ="5px"; //<------- Added a style here
// それぞれ作業中、削除という言葉をボタンに入れる
addButton.innerText = '作業中';
removeButton.innerText = '削除';
//ボタンを押したら以下の作業をする
removeButton.addEventListener('click', () => removeTask(removeButton));
// IDを表示するspan要素を作成して tableItem に追加
const idSpan = document.createElement('span');
idSpan.innerText = id;
idSpan.style.marginRight = "20px"; //<------- Added a style here
tableItem.append(idSpan);
const taskSpan = document.createElement('span');
taskSpan.style.width = "60px"; //<------- Added a style here
taskSpan.style.display = "inline-block"; //<------- Added a style here
taskSpan.style.overflow = "hidden"; // <----- This styling for trimming the text if it exceeds certain width
taskSpan.style.textOverflow = "ellipsis"; // <------- This will append a (...) to the exceeding text
taskSpan.innerText = task;
taskSpan.title = task; //If you hover on the text full text will be displayed. In production code, you might like to use fancy tooltips, say, from bootstrap, for this
tableItem.append(taskSpan); //<------- changed this
//入力タスクを表示
addTaskTarget.appendChild(tableItem);
// 作業中ボタンを追加
tableItem.appendChild(addButton);
// 削除ボタンを追加
tableItem.appendChild(removeButton);
};
// 追加ボタンに対して、タスク登録イベントを設定
addTaskTrigger.addEventListener('click', event => {
const task = addTaskValue.value;
addTask(task,nextId ++);
addTaskValue.value = '';
});
});
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel ="stylesheet" href="css/style.css">
<title>Todoリスト</title>
</head>
<body>
<h1>Todoリスト</h1>
<p>
<input type="radio" name="status" value="1" checked="checked">全て
<input type="radio" name="status" value="2">作業中
<input type="radio" name="status" value="3">完了
</p>
<p></p>
<table>
<thead>
<tr>ID コメント 状態</tr>
</thead>
<tbody class ="addTask-target">
<tr>
</tr>
</tbody>
</table>
<h2>新規タスクの追加</h2>
<input class="addTask-value" type="text" />
<button class="addTask-trigger" type="button">追加</button>
<script src="js/main.js"></script>
</body>
</html>
I'm creating a filtered table in JavaScript. Everything is okay. However, the only line that doesn't seem to work is inputValue = ''. Not sure why it doesn't want to clear the field after filtering is done.
If you replace that with document.querySelector('.form__input').value things seem to work, but I don't want to repeat the same code. I already declared it above as inputValue.
const initValues = [
'Walmart',
'State Grid',
'Sinopec Group',
'China National Petrolium',
'Royal Dutch Shell',
'Toyota Motor',
'Volkswagen',
'BP',
'Exxon Mobil',
'Berkshire Hathaway'
];
const tableCreation = array => {
const tableBody = document.querySelector('.table__body');
document.querySelectorAll('tr').forEach(el => el.parentNode.removeChild(el));
array.forEach(el => {
const row = document.createElement('tr');
const cell = document.createElement('td');
const cellText = document.createTextNode(el);
cell.appendChild(cellText);
row.appendChild(cell);
tableBody.appendChild(row);
});
};
tableCreation(initValues);
const filterTable = event => {
event.preventDefault();
let inputValue = document.querySelector('.form__input').value;
const filtered = initValues.filter(el => el.toLowerCase().includes(inputValue.toLowerCase()));
if (filtered) {
inputValue ? tableCreation(filtered) : tableCreation(initValues);
}
inputValue = '';
};
document.querySelector('.form__button').addEventListener('click', filterTable);
<!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="./css/3.css">
<title>Filtered list</title>
</head>
<body>
<form class="form" id="form">
<label for="filter">Filtered: </label>
<input class="form__input" type="text" id="filter" name="input" placeholder="Insert phrase...">
<button class="form__button" form="form" type="submit">Filter</button>
</form>
<table class="table">
<tbody class="table__body"></tbody>
</table>
<script src="./js/3.js"></script>
</body>
</html>
The variable inputValue is holding only the actual value of the field, it's detached from it.
You can save a reference to the field as a variable and clean the value as follows:
const inp = document.querySelector('.form__input');
inp.value = '';
let inputValue = document.querySelector('.form__input').value;
this line return the string value of the input.
When you are trying inputValue = ''; you are only changing the value of the variable 'inputValue' but not of the input field.
to do this juste save you field as a variable instead of it's value and then change it's value :
let inputField = document.querySelector('.form__input');
const filtered = initValues.filter(el => el.toLowerCase().includes(inputValue.toLowerCase()));
if (filtered) {
inputValue ? tableCreation(filtered) : tableCreation(initValues);
}
inputField.value = '';
You already get value only from inputvalue., but u can't change that value so
get dom instance also
kindly change this code to
const filterTable = event => {
event.preventDefault();
let inputElement = document.querySelector('.form__input'),
inputValue = inputElement.value;
const filtered = initValues.filter(el => el.toLowerCase().includes(inputValue.toLowerCase()));
if (filtered) {
inputValue ? tableCreation(filtered) : tableCreation(initValues);
}
inputElement.value = '';
};