comment appending on the first post only in Vanilla JavaScript - javascript

I am creating a status posting and commenting system.
It is implemented in Vanilla JavaScript. Anyone can add a post and can comment on the post.
Everything is working fine but the comment section is working on first post only.
deletion of comment and post is working fine.
I don't know what's the problem is, if anyone could help me..
Here is the HTML code
<div class="container-post" id="container-post">
<div class="create-post">
<form>
<div class="form-group">
<div class="username">
<p class="name" style="top:15px;">User Name</p>
</div>
<p class="qoutes">
<textarea style=" font-size: 15pt;" class="form-control" id="enter-post" rows="7" id="mypara" placeholder="Share Your Thoughts..."></textarea>
</p>
<div class="postbar">
<button type="button" class="btn btn-primary post-me" id="post-button"> <span id="postText">Post</span></button>
</div>
</div>
</form>
</div>
<hr class="line-bar">
<div class="allpost">
<div class="mainpost" id="post-div"></div>
</div>
Here is the JavaSCript code
showTask();
showComment();
let addPost = document.getElementById("enter-post");
let addPostBtton = document.getElementById("post-button");
addPostBtton.addEventListener("click", function () {
var addPostVal = addPost.value;
if (addPostVal.trim() != 0) {
let webtask = localStorage.getItem("localtask");
if (webtask == null) {
var taskObj = [];
}
else {
taskObj = JSON.parse(webtask);
}
taskObj.push(addPostVal);
localStorage.setItem("localtask", JSON.stringify(taskObj));
}
showTask();
});
function showTask() {
let webtask = localStorage.getItem("localtask");
if (webtask == null) {
var taskObj = [];
}
else {
taskObj = JSON.parse(webtask);
}
let htmlVal = '';
let createPost = document.getElementById("post-div");
taskObj.forEach((item, index) => {
htmlVal += `
<div class="post-class"><div class="username u-name">
<p class="name i-name">${"User Name " + index}</p>
<i class="fas fa-trash-alt" onclick="removePost(${index});"></i></button>
</div>
<hr>
<p class="quotes">
${item}
</p>
<div class="comment-section" id="comment-section">
<p class="comment-qoute">
<textarea style=" font-size: 15pt;" class="form-control commentBox" rows="3" id="mypara" placeholder="Leave a comment"></textarea>
</p>
<button class="btn btn-primary comment-btn" id="commentBtn">comment</button>
<ul class="comments" id="comments-portion">
<p></p>
</ul>
</div>
</div>
<br><br>`
});
createPost.innerHTML = htmlVal;
}
function removePost(index) {
let webtask = localStorage.getItem("localtask");
let taskObj = JSON.parse(webtask);
taskObj.splice(index, 1);
localStorage.setItem("localtask", JSON.stringify(taskObj));
showTask();
}
var commentPost = document.getElementById('mypara');
var commentBtn = document.getElementById('commentBtn');
commentBtn.addEventListener('click', function () {
var commentValue = commentPost.value;
if (commentValue.trim() != 0) {
let commentTask = localStorage.getItem("comments");
if (commentTask == null) {
var commentObj = [];
}
else {
commentObj = JSON.parse(commentTask);
}
commentObj.push(commentValue);
localStorage.setItem("comments", JSON.stringify(commentObj));
}
showComment();
});
function showComment() {
let commentsTask = localStorage.getItem("comments");
if (commentsTask == null) {
var commentObj = [];
}
else {
commentObj = JSON.parse(commentsTask);
}
let commentHTMLValue = '';
var createComment = document.getElementById("comments-portion");
commentObj.forEach((item, index) => {
commentHTMLValue += `<div class="comment-box-btn">
<p>${index + ". "}<span>${item}</span></p>
<i class="far fa-times-circle fa-2x" onclick="removeComment(${index});"></i>
</div>
`;
});
createComment.innerHTML = commentHTMLValue;
}
var deleteBtn = document.querySelector('.comment-del');
deleteBtn.addEventListener('click', () => {
});
// remove comment
function removeComment(index) {
let commentTask = localStorage.getItem("comments");
let commentObj = JSON.parse(commentTask);
commentObj.splice(index, 1);
localStorage.setItem("comments", JSON.stringify(commentObj));
showComment();
}

When you use code like:
createComment.innerHTML = commentHTMLValue;
you are completely replacing the contents of the element. Try using:
createComment.innerHTML += commentHTMLValue;
which appends new content to the end of the existing contents.

I can't do a snippet here as the use of localStorage is not allowed. Copy this block into a blank file and save it as an html file and then open that in a browser.
This is how I think you are describing your requirements and is also based on the data format in my comments. It's not pretty and needs plenty of sprucing up, but it runs.
<!DOCTYPE html>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<html>
<head>
<title>Task listing</title>
<script type="text/javascript">
let taskList = [];
function checkTasks() {
let tasksList = getTasksList();
if (tasksList.length == 0) {
let newTask = prompt("Please enter a task description");
if (newTask) {
let thisIndex = getNewIndex();
let a = {"id": thisIndex, "task": newTask, "comments": []}
taskList.push(a);
saveTasksList(taskList);
}
}
displayTasks();
}
function displayTasks() {
let container = document.getElementById("tasks");
container.innerHTML = "";
let taskList = getTasksList();
taskList.forEach(function(task){
let d = document.createElement("div");
d.id = "task_" + task.id;
d.className = "commentdiv";
d.innerHTML = "<h3>" + task.task + "</h3>";
let l = document.createElement("ul");
l.id = "comments_" + task.id;
let comments = task.comments;
if (comments.length > 0) {
let commentindex = 0;
comments.forEach(function(comment) {
let c = document.createElement("li");
c.innerHTML = comment;
let cb = document.createElement("button");
cb.id = "deletecomment_" + task.id + "_" + commentindex;
cb.innerHTML = "Delete comment";
cb.onclick = function() {deleteComment(task.id, commentindex);};
c.appendChild(cb);
l.appendChild(c);
})
}
let b = document.createElement("button");
b.id = "addcomment_" + task.id;
b.onclick = function() {addComment(task.id);};
b.innerHTML = "Add comment";
d.appendChild(b);
d.appendChild(l);
container.appendChild(d);
})
}
function addComment(taskid) {
let newcomment = prompt("Enter comment");
if (newcomment) {
let tasklist = getTasksList();
let filtered = tasklist.filter(task => task.id == taskid);
if (filtered[0]) {
let thisTask = filtered[0];
thisTask.comments.push(newcomment);
let thisIndex = taskList.findIndex((task) => task.id == taskid);
taskList[thisIndex] = thisTask;
}
saveTasksList(taskList);
displayTasks();
}
}
function addNewTask() {
let newTask = prompt("Enter task description");
let taskList = getTasksList();
let lastindex = localStorage.getItem("tasksindex");
let index = getNewIndex();
let a = {"id": index, "task": newTask, "comments": []}
taskList.push(a);
saveTasksList(taskList);
displayTasks();
}
function deleteComment(taskid, commentindex) {
let tasklist = getTasksList();
let filtered = tasklist.filter(task => task.id == taskid);
// as long as there is at least one task with the taskid value, find and delete the comment
// based on the index position of the comment in the comments array
if (filtered[0]) {
let thisTask = filtered[0];
thisTask.comments.splice(commentindex, 1);
let thisIndex = taskList.findIndex((task) => task.id == taskid);
taskList[thisIndex] = thisTask;
}
saveTasksList(taskList);
displayTasks();
}
function getTasksList() {
let tasks = localStorage.getItem("tasks");
taskList = JSON.parse(tasks);
if (!taskList) {
taskList = [];
}
return taskList;
}
function saveTasksList(taskList) {
localStorage.setItem("tasks", JSON.stringify(taskList));
}
function getNewIndex() {
let lastindex = localStorage.getItem("tasksindex");
let idx = 0;
if (!lastindex) {
idx = 1;
} else {
idx = Number(lastindex) + 1;
}
localStorage.setItem("tasksindex", idx);
return idx;
}
function removeAll() {
localStorage.removeItem("tasks");
localStorage.removeItem("tasksindex");
displayTasks();
}
window.onload = checkTasks;
</script>
<style type="text/css">
.commentdiv {
border:1px solid black;
width:1000px;
padding:5px;
border-radius:5px;
}
button {
margin-left:10px;
}
h3 {
width:100%;
border-bottom: 1px dotted black;
}
ul {
list-style-type:decimal;
}
</style>
</head>
<body>
<h2>My task list <button id="addNewTaskButton" onclick="addNewTask();">Add new task</button></h2>
<hr>
<div id="tasks">
</div>
<button id="removeAll" onclick="removeAll();">Remove all tasks</button>
</body>
</html>

Related

Draw in two tables vanilla JS

I am working with program that will randomly choose who is making a Christmas gift to whom.
I've created an empty array. When you add a "player" it's pushing the name into two different arrays. Players[] and Players2[].
When you start a draw. The program writes the names of the Players[] on the left hand side and on the right side it writes the drawn names from Players2[].
Every Player from Players2[], after being drawn, is being deleted from the array so in the end we have an empty Players2[] array and full Players[] array.
The problem is: I can't make a working if statement that is checking if the person will not draw himself...
let Players = [];
let Players2 = [];
const addBTN = document.getElementById('addBTN');
const onlyLetters = /^[a-zżźćóęśńłA-ZŻŹĆÓŁĘŚŃŁ ]+$/;
const refreshBTN = document.getElementById('refreshBTN');
const warningBTNyes = document.getElementById('warning-button-yes');
const warningBTNno = document.getElementById('warning-button-no');
const playersList = document.getElementById('playersList');
const playersList2 = document.getElementById('playersList2');
const startBTN = document.getElementById('startBTN');
const drawLotsBTN = document.getElementById('drawLotsBTN');
addBTN.addEventListener('click', function() {
const input = document.getElementById('addPLAYER');
const person = document.getElementById('addPLAYER').value;
if (input.value == "") {
console.log('error_empty_input');
document.getElementById('errorMSG').style.color = "red";
document.getElementById('errorMSG').innerHTML = "Wpisz imię osoby!";
} else if (input.value.match(onlyLetters)) {
console.log('good');
Players.push(person);
Players2.push(person);
playersList.innerHTML = playersList.innerHTML + "<br>" + person;
document.getElementById('addPLAYER').value = "";
document.getElementById('errorMSG').style.color = "green";
document.getElementById('errorMSG').innerHTML = "Powodzenie! Dodaj kolejną osobę.";
} else {
console.log('error_input');
document.getElementById('errorMSG').style.color = "red";
document.getElementById('errorMSG').innerHTML = "Coś jest nie tak z imieniem. Pamiętaj aby wprowadzać same litery!";
}
});
refreshBTN.addEventListener('click', function() {
document.getElementById('warning').style.display = "block";
});
warningBTNyes.addEventListener('click', function() {
location.reload(true);
document.getElementById('addPLAYER').value = "";
});
warningBTNno.addEventListener('click', function() {
document.getElementById('warning').style.display = "none";
});
startBTN.addEventListener('click', function() {
drawLotsBTN.disabled = false;
const input = document.getElementById('addPLAYER');
const person = document.getElementById('addPLAYER').value;
if (input.value == "") {
} else if (input.value.match(onlyLetters)) {
console.log('good');
Players.push(person);
Players2.push(person);
playersList.innerHTML = playersList.innerHTML + "<br>" + person;
document.getElementById('addPLAYER').value = "";
document.getElementById('errorMSG').style.color = "green";
document.getElementById('errorMSG').innerHTML = "Powodzenie! Zaczynasz losowanie!";
} else {
console.log('error_input');
document.getElementById('errorMSG').style.color = "red";
document.getElementById('errorMSG').innerHTML = "Coś jest nie tak z imieniem. Pamiętaj aby wprowadzać same litery!";
}
document.getElementById('addPLAYER').disabled = true;
});
drawLotsBTN.addEventListener('click', function() {
for (let i = 0; i = Players2.length; i++) {
if (Players2.length > 0) {
randomPerson = Math.floor(Math.random() * Players2.length);
if (randomPerson != Players.indexOf(i)) {
console.log(Players2[randomPerson]);
playersList2.innerHTML = playersList2.innerHTML + "<br>" + Players2[randomPerson];
Players2.splice(randomPerson, 1);
}
} else {
console.log('error_empty_array');
}
}
});
<div id="warning" class="warning">
<div class="warning-flex">
<h1>Wszelkie wpisane imiona zostaną usunięte</h1>
<div class="warning-buttons">
<button id="warning-button-yes" class="warning-button-yes">Tak</button>
<button id="warning-button-no" class="warning-button no">Nie</button>
</div>
</div>
</div>
<div class="lotteryContainer">
<div class="left">
<p>dodaj osobę</p>
<div class="addPerson">
<input required id="addPLAYER" type="text">
<button id="addBTN">+</button>
<p id="errorMSG"></p>
<div class="refresh">
<button id="refreshBTN">Od nowa</button>
<button id="startBTN">Start</button>
</div>
</div>
</div>
<div class="right">
<p>Uczestnicy</p>
<div class="tables">
<div class="tableLeft">
<p id=playersList></p>
</div>
<div class="tableRight">
<p id="playersList2"></p>
</div>
</div>
<button id="drawLotsBTN">Losuj</button>
</div>
</div>
<script src="app.js"></script>
Now if I understand what your program aims to do, there is a simple algorithm for it.
How I understand your goal:
You have a list of persons who are going to give presents to each other. (like in secret Santa). It is random who will give to who, but each person gives and receives one gift.
How to implement it (i'd normaly use maps, but I am guessing you are more comfortable with arrays):
players = ["Adam", "Bret", "Clay", "Donald"];
players.sort(function(a, b){return 0.5 - Math.random()}); // shuffles array
gives_to = [...players]; // copy values of array
gives_to.push(gives_to.shift()); // let the first element be the last
Here the first player (players[0]) will give to gives_to[0] and the second to gives_to[1] etc.
I've created this JS script trying to use Trygve Ruud algorithm but it doesn't work like desired.
drawLotsBTN.addEventListener('click', function(){
if(Players.length > 0) {
console.log(Players)
Players.sort(function(a, b){
return 0.5 - Math.random();
});
for(let i = 0; i < Players.length; i++){
playersList2.innerHTML = playersList2.innerHTML + "<br>" + Players[i];
}
}
else{
console.log('error_empty_array');
}
});

Getting an Uncaught TypeError: Cannot set property 'onclick' of null with <script> at the end

I've looked at previous questions like this and cannot find the answer to my problem. I am working in javascript creating a checkout screen and I have two onclicks for two different html files but when I go to the html file for both it says that the other onclick is null. I have tried window.load and moving the script to the bottom of the
var cart = [];
var search = document.getElementById("addItem");
let placement = 0;
var cartElement = document.getElementById("showCart");
var cartTotal = document.getElementById("totalCart");
search.onclick = function(e) {
var userInput = document.getElementById("query").value;
var cartHTML = "";
e.preventDefault();
placement = 0;
for (i = 0; i < menu.length; i++) {
if (menu[i][0].includes(userInput)) {
cart.push(menu[i]);
placement++;
}
}
if (placement == 0) {
alert("Menu option not included. Please try again.");
}
cart.forEach((item, Order) => {
var cartItem = document.createElement("span");
cartItem.textContent = item[0] + " (" + item[1] + ")";
cartHTML += cartItem.outerHTML;
});
cartElement.innerHTML = cartHTML;
}
window.onload = function() {
var checkout = document.getElementById("addCartButton");
checkout.onclick = function(event) {
cart.forEach()
var cartTotalHTML = "";
event.preventDefault();
cart.forEach(Item, Order => {
var totalInCart = 0;
var writeCart = document.createElement("span");
totalInCart += Order[1];
});
writeCart.textContent = cartTotal += item[1];
cartTotalHTML = writeCart.outerHTML;
cartTotal.innerHTML = cartTotalHTML;
console.log(cartTotal);
}
}
<h3>Search for items in the menu below to add to cart</h3>
<form id="searchMenu">
<input type="search" id="query" name="q" placeholder="Search Menu..."></inpuut>
<input type = "Submit" name= "search" id="addItem" ></input>
</form>
<h4>Your cart: </h4>
<div class="Cart">
<div id="showCart"></div>
</div>
<script src="Script.js"></script>
<h4>Cart</h4>
<button id='addCartButton' class="Cart">Add Cart</button>
<div class="ShowCart">
<div id="totalCart"></div>
</div>
<script src="Script.js"></script>

To-Do-List Delete All Function

How can I fix the function to delete all todoItems? My guess is that the for loops is not working right :\ I appreciate any help with my problem! I have only 1-month of experience with javascript.
How can I fix the function to delete all todoItems? My guess is that the for loops is not working right :\ I appreciate any help with my problem! I have only 1-month of experience with javascript.
function selectColorStatus(event){
let target = event.target;
target.classList.toggle('todoTextSelected');
}
function createToDoItem(userInputValue){
// To-Do Item Container
let todoItem = document.createElement("div");
todoItem.classList.add("row", "flx");
todoItem.onclick = selectColorStatus;
// Clear List
let btnDeleteItem = document.getElementById('btnDeleteItem');
btnDeleteItem.onclick = function (){
for(let i = 0; i < todoItem; i++){
todoItem.remove();
}
}
// Inner Text
let todoText = document.createElement('div');
todoText.classList.add('grow');
todoText.innerText = userInputValue;
// Date
let CreateDate = document.createElement('div');
CreateDate.classList.add('date');
let date = new Date();
year = date.getFullYear();
month = date.getMonth();
day = date.getDay();
CreateDate.innerText = 'Created at ' + year + '-' + month + '-'+ day;
// Delete Button
let deleteBtn = document.createElement('div');
deleteBtn.classList.add('btnDelete');
deleteBtn.innerText = 'X';
deleteBtn.onclick = function(){
todoItem.remove();
}
todoItem.appendChild(todoText);
todoItem.appendChild(CreateDate)
todoItem.appendChild(deleteBtn);
let todoItemsContainer = document.getElementById('todoItemsContainer');
todoItemsContainer.appendChild(todoItem);
}
// Item Entry and Validation
function ToDoItemHandler(){
let userInput = document.getElementById('toDoEntry');
let userInputValue = userInput.value;
if(userInputValue == ''){
alert('Entry can not be empty!')
}else{
createToDoItem(userInputValue);
userInput.value = '';
}
}
// Add Item Button
let btnAddItem = document.getElementById('btnAddItem');
btnAddItem.onclick = ToDoItemHandler;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href = './style/style.css' rel='stylesheet'>
<title>To-Do-List</title>
</head>
<body>
<div id = 'container'>
<div id="toDoHeader">
<h1>To-Do List</h1>
<div id = 'toDoContent'>
<input type = 'text' id = 'toDoEntry' name = 'toDoEntry' placeholder = 'Add item here'>
<button type = 'button' id = 'btnAddItem' name = 'addToDoList'>Add</button>
<button type = 'button' id = 'btnDeleteItem' name = 'deleteList'>Delete All</button>
</div>
</div>
<div id="todoItemsContainer">
</div>
</div>
<script src = './js/app.js'></script>
</body>
</html>
Change your delete function to
let btnDeleteItem = document.getElementById('btnDeleteItem');
btnDeleteItem.onclick = function (){
const items = document.querySelectorAll('.row') // select all todos
items.forEach(el => {
el.remove() // remove each one
})
}
function selectColorStatus(event) {
let target = event.target;
target.classList.toggle('todoTextSelected');
}
function createToDoItem(userInputValue) {
// To-Do Item Container
let todoItem = document.createElement("div");
todoItem.classList.add("row", "flx");
todoItem.onclick = selectColorStatus;
// Clear List
let btnDeleteItem = document.getElementById('btnDeleteItem');
btnDeleteItem.onclick = function () {
const items = document.querySelectorAll('.row')
items.forEach(el => {
el.remove()
})
}
// Inner Text
let todoText = document.createElement('div');
todoText.classList.add('grow');
todoText.innerText = userInputValue;
// Date
let CreateDate = document.createElement('div');
CreateDate.classList.add('date');
let date = new Date();
year = date.getFullYear();
month = date.getMonth();
day = date.getDay();
CreateDate.innerText = 'Created at ' + year + '-' + month + '-' + day;
// Delete Button
let deleteBtn = document.createElement('div');
deleteBtn.classList.add('btnDelete');
deleteBtn.innerText = 'X';
deleteBtn.onclick = function () {
todoItem.remove();
}
todoItem.appendChild(todoText);
todoItem.appendChild(CreateDate)
todoItem.appendChild(deleteBtn);
let todoItemsContainer = document.getElementById('todoItemsContainer');
todoItemsContainer.appendChild(todoItem);
}
// Item Entry and Validation
function ToDoItemHandler() {
let userInput = document.getElementById('toDoEntry');
let userInputValue = userInput.value;
if (userInputValue == '') {
alert('Entry can not be empty!')
} else {
createToDoItem(userInputValue);
userInput.value = '';
}
}
// Add Item Button
let btnAddItem = document.getElementById('btnAddItem');
btnAddItem.onclick = ToDoItemHandler;
<div id = 'container'>
<div id="toDoHeader">
<h1>To-Do List</h1>
<div id = 'toDoContent'>
<input type ='text' id='toDoEntry' name ='toDoEntry' placeholder = 'Add item here'>
<button type ='button' id='btnAddItem' name ='addToDoList'>Add</button>
<button type ='button' id='btnDeleteItem' name ='deleteList'>Delete All</button>
</div>
</div>
<div id="todoItemsContainer">
</div>
</div>
simply do:
// Clear List
let btnDeleteItem = document.getElementById('btnDeleteItem');
btnDeleteItem.onclick = function () {
document.getElementById('todoItemsContainer').innerHTML = ''
}

Element text not changing when passing selected textContent and new value to an update function

I'm creating a CRUD page where the user can add, delete and edit text, but I have an issue in updating the text after I select it for edit.
In editText function when I click the edit button the text that was added will pop up inside the input field. When I click on the update button (triggering the updateText function), I can see the text in console log but the corresponding html is not updated.
HTML
<div class="main">
<form>
<input type="text" placeholder="search">
</form>
<ul></ul>
<div>
<input class="add-text" type="text" placeholder="Add Text">
<button id="add">Add</button>
<button id="update">update</button>
</div>
</div>
Javascript
const inputsearch = document.querySelector('form input');
const addInputBtn = document.querySelector('#add');
const update = document.querySelector('#update');
addInputBtn.addEventListener('click', addtext);
function addtext(){
let li = document.createElement('li');
let inputadd = document.querySelector('.add-text');
let addedtext = inputadd.value;
let h1Tag = '<h1 id="text">'+addedtext+'</h1>';
let tags = h1Tag + '<button id="delete">Delete</button><button id="edit">Edit</button>';
if(addedtext == ''){
alert('please add some text');
return;
}else{
li.innerHTML = tags;
document.querySelector('ul').appendChild(li);
}
li.querySelectorAll('#delete')[0].addEventListener('click', deleteText);
li.querySelectorAll('#edit')[0].addEventListener('click', editText);
getlist(li, h1Tag);
inputadd.value = '';
}
function deleteText(e) {
e.target.parentNode.remove();
document.querySelector('.add-text').value = '';
}
function editText(e) {
let currentText = e.target.parentNode.firstChild.textContent;
let currentValue = document.querySelector('.add-text');
currentValue.value = currentText;
getupdate(currentText, currentValue);
}
function getupdate(currentText, currentValue) {
update.addEventListener('click', updateText);
function updateText() {
currentText = currentValue.value
console.log(currentText = currentValue.value);
}
}
function getlist(li, h1Tag) {
inputsearch.addEventListener('keyup', serchText);
function serchText(e) {
let typetext = e.target.value.toLowerCase();
if(h1Tag.toLowerCase().indexOf(typetext) != -1){
li.style.display = 'block';
}else{
li.style.display = 'none';
}
}
}
To solve the issue without changing your overall approach, your edit button click needs to get the corresponding element (not just its textContent) and pass it to your getupdate() function to be updated when your update button is clicked. Relatively minor changes to your current functions:
function editText(e) {
const currentText = e.target.parentNode.firstChild;
const currentValue = document.querySelector('.add-text');
currentValue.value = currentText.textContent;
getupdate(currentText, currentValue);
}
function getupdate(currentText, currentValue) {
update.addEventListener('click', updateText);
function updateText() {
currentText.textContent = currentValue.value;
}
}
There are some other issues with your code, particularly the creation of multiple elements with the same id (which is malformed and will likely become problematic as you add additional features). Following is a snippet that addresses that issue as well as simplifying some of your functions and fixing the search.
const search = document.querySelector('form input');
const input = document.querySelector('.add-text');
const container = document.querySelector('ul');
let items = null;
let currentItem = null;
const searchItems = (event) => {
if (items) {
const s = event.currentTarget.value.toLowerCase();
for (const item of items) {
if (item.firstChild.textContent.toLowerCase().indexOf(s) !== -1) {
item.style.display = 'block';
} else {
item.style.display = 'none';
}
}
}
};
const deleteItem = (event) => {
currentItem = null;
event.currentTarget.parentNode.remove();
};
const editItem = (event) => {
currentItem = event.currentTarget.parentNode.firstChild;
input.value = currentItem.textContent;
};
const updateItem = () => {
if (currentItem) {
currentItem.textContent = input.value;
}
};
const addItem = () => {
let val = input.value
if (val) {
const li = document.createElement('li');
let inner = '<h1 class="text">' + val + '</h1>';
inner += '<button class="delete">Delete</button>';
inner += '<button class="edit">Edit</button>';
li.innerHTML = inner;
container.appendChild(li);
val = '';
currentItem = li.firstChild;
items = document.querySelectorAll('li');
for (let del of document.querySelectorAll('.delete')) {
del.addEventListener('click', deleteItem);
}
for (let edit of document.querySelectorAll('.edit')) {
edit.addEventListener('click', editItem);
}
} else {
alert('please add some text');
return;
}
};
search.addEventListener('keyup', searchItems);
document.querySelector('#add').addEventListener('click', addItem);
document.querySelector('#update').addEventListener('click', updateItem);
<div class="main">
<form>
<input type="text" placeholder="Search">
</form>
<ul></ul>
<div>
<input class="add-text" type="text" placeholder="Add Text">
<button id="add">Add</button>
<button id="update">Update</button>
</div>
</div>

How to remove array objects from localStorage using dynamic buttons? [JS only]

New to JS here, been struggling with this one for a few hours now.
So I created a to do list with a button that stores objects in an array inside localStorage and also creates dynamic list items with content and delete buttons. Whenever I click the delete button it removes the dynamic list item but doesn't remove it from localStorage. I can't figure out how to assign each button to the specific array index in localStorage.
https://codepen.io/jupiterisland/pen/ooPXWV
var taskList = []; //build array
if(localStorage.taskList){ //call func to recreate li's on refresh
taskList = JSON.parse(localStorage.taskList) || [];
createTasks(taskList)
}
function submitFunc() {
var task = { //build objects
desc: document.getElementsByTagName("textarea")[0].value,
date: document.getElementsByTagName("input")[0].value,
time: document.getElementsByTagName("input")[1].value,
important: document.getElementsByTagName("input")[1].checked
};
if(task.desc && task.date !== ""){
taskList[taskList.length] = task; //put objects inside array
localStorage.taskList = JSON.stringify(taskList); //store array with stringify
newTaskList = JSON.parse(localStorage.taskList); //retrieve array with parse
createTasks(newTaskList)
document.getElementById("error").style.display = "none";
return false; //prevent submit
} else {
document.getElementById("error").style.display = "block";
document.getElementById("error").innerHTML = "Please enter a task description and a date.";
return false;
}
}
function createTasks (newTaskList){
for (i = 0; i < newTaskList.length; i++) { // display objects in list items
var currentTask = newTaskList[i];
var taskIndex = newTaskList.indexOf(currentTask);
newElement();
function newElement() {
var liNode = document.createElement("li");
var titleNode = document.createElement("h3");
var dNode = document.createElement("p");
var tNode = document.createElement("p");
var delNode = document.createElement("button")
liNode.className = "liNode";
titleNode.className = "titleNode";
dNode.className = "dNode";
tNode.className = "tNode";
delNode.className = "delete";
delNode.innerText = "Delete";
var titleText = newTaskList[i].desc;
var dateText = newTaskList[i].date;
var timeText = newTaskList[i].time;
var descNode = document.createTextNode(titleText);
var dateNode = document.createTextNode(dateText);
var timeNode = document.createTextNode(timeText);
titleNode.appendChild(descNode);
dNode.appendChild(dateNode);
tNode.appendChild(timeNode);
liNode.appendChild(titleNode);
liNode.appendChild(dNode);
liNode.appendChild(tNode);
liNode.appendChild(delNode);
document.getElementById("taskBoard").appendChild(liNode);
if (taskBoard.childElementCount > newTaskList.length) { //remove excess divs
for (n = 0; taskBoard.childElementCount - 2; n++) {
taskBoard.removeChild(taskBoard.firstChild);
}
}
function deleteTasks(){
var listItem = this.parentNode;
var ul = listItem.parentNode;
ul.removeChild(listItem);
}
delNode.addEventListener("click", deleteTasks);
}
}
}
<!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">
<title>Document</title>
</head>
<body>
<h1>My Task Board</h1>
<div class="container">
<form onsubmit="return submitFunc()">
<div>
<label for="">Task:</label>
<textarea name="name" rows="8" cols="80"placeholder="Please enter your task description"></textarea>
</div>
<div>
<label for="">Deadline:</label>
<input type="date" placeholder="Choose a date">
<input type="time" placeholder="Set time">
</div>
<div>
<label for="">Important:</label>
<input type="checkbox" name="" value="">
</div>
<button type="submit" name="button">Add Task</button>
<div id="error"></div>
</form>
</div>
<div>
<ul id="taskBoard"></ul>
</div>
</body>
</html>
var taskList = []; //build array
if(localStorage.taskList){ //call func to recreate li's on refresh
taskList = JSON.parse(localStorage.taskList) || [];
createTasks(taskList)
}
function fakeGuid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
function submitFunc() {
var task = { //build objects
desc: document.getElementsByTagName("textarea")[0].value,
date: document.getElementsByTagName("input")[0].value,
time: document.getElementsByTagName("input")[1].value,
important: document.getElementsByTagName("input")[1].checked,
id :fakeGuid()
};
if(task.desc && task.date !== ""){
taskList[taskList.length] = task; //put objects inside array
localStorage.taskList = JSON.stringify(taskList); //store array with stringify
newTaskList = JSON.parse(localStorage.taskList); //retrieve array with parse
createTasks(newTaskList)
document.getElementById("error").style.display = "none";
return false; //prevent submit
} else {
document.getElementById("error").style.display = "block";
document.getElementById("error").innerHTML = "Please enter a task description and a date.";
return false;
}
}
function createTasks (newTaskList){
for (i = 0; i < newTaskList.length; i++) { // display objects in list items
newElement(i);
function newElement(currentIndex) {
var liNode = document.createElement("li");
var titleNode = document.createElement("h3");
var dNode = document.createElement("p");
var tNode = document.createElement("p");
var delNode = document.createElement("button")
liNode.className = "liNode";
titleNode.className = "titleNode";
dNode.className = "dNode";
tNode.className = "tNode";
delNode.className = "delete";
delNode.innerText = "Delete";
var titleText = newTaskList[i].desc;
var dateText = newTaskList[i].date;
var timeText = newTaskList[i].time;
var descNode = document.createTextNode(titleText);
var dateNode = document.createTextNode(dateText);
var timeNode = document.createTextNode(timeText);
titleNode.appendChild(descNode);
dNode.appendChild(dateNode);
tNode.appendChild(timeNode);
liNode.appendChild(titleNode);
liNode.appendChild(dNode);
liNode.appendChild(tNode);
liNode.appendChild(delNode);
document.getElementById("taskBoard").appendChild(liNode);
if (taskBoard.childElementCount > newTaskList.length) { //remove excess divs
for (n = 0; taskBoard.childElementCount - 2; n++) {
taskBoard.removeChild(taskBoard.firstChild);
}
}
function deleteTasks(node, currentTask) {
var listItem = node.parentNode;
var ul = listItem.parentNode;
ul.removeChild(listItem);
taskList = taskList.filter(function(t) {
return t.id !== currentTask.id;
});
localStorage.taskList = JSON.stringify(taskList); //store array with stringify
}
var currentTask = newTaskList[currentIndex];
delNode.addEventListener("click", () => deleteTasks(delNode, currentTask));
}
}
}
Don't try to use index to manipulate DOM element. Instead use some kind of unique ID. In this case I created a fake GUID.
Read more on closure. The reason you are not able to pass index down to the function is because the index is bound to another context.
Any reason to stringify JSON for local storage? You can simply store an array.

Categories