Still stuck on To Do List

Hey guys! So back in January I got some help on how to configure the local storage part of my To do List project. I’m currently stuck on how to set a button for each item in the array. I “kind of” did it, but on a page refresh all of the buttons go to the bottom of the screen. I keep getting stuck, and it’s starting to get frustrating. It’s been about 5 months and I’ve barely made any progress on this project. Thanks!


const itemInput = document.getElementById("item");
const submission = document.getElementById("submit-button");
const clear = document.getElementById("clear");
const tasks = document.getElementById("tasks");
const list = JSON.parse(localStorage.getItem('todoList')) || [];

function createButtons(){
  const editButton = document.createElement('button');
  const deleteButton = document.createElement('button');
  editButton.innerHTML = "editButton";

  tasks.appendChild(editButton);
}


function add(){
  const obj = {
    value: itemInput.value,
  
  };
  list.push(obj)
createTaskElement(obj.value)
updateLocalStorage()
}

function createTaskElement(submittedInput){
const p = document.createElement("p");
p.innerHTML = submittedInput;
tasks.appendChild(p)
}


function updateLocalStorage(){
  localStorage.setItem("todoList", JSON.stringify(list))
}

function displayTask(){
 for(let i = 0; i < list.length; i++){
  createTaskElement(list[i].value)
 }
}

submission.addEventListener("click", e =>{
  add()
  createButtons()
})
displayTask()

clear.addEventListener("click", e =>{
  tasks.innerHTML = "";
 localStorage.clear()
})

for(let i = 0; i < list.length; i++){
  createButtons(list[i].value)
}

could you post the html too ?

my bad

<!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>Grocery List</title>
    <link href="/style.css" rel="stylesheet">   
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" integrity="sha512-YWzhKL2whUzgiheMoBFwW8CKV4qpHQAEuvilg9FAn5VJUDwKZZxkJNuGM4XkWuk94WCrrwslk8yWNGmY1EduTA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
    <h1 id="grocery-list">Grocery List</h1>
    <form>
        <input id="item" name="count" type="text">
        <button type="button" id="submit-button">Submit</button>
    </form>
    <div id="tasks">
    </div>
    <button id="clear">Clear Button</button>
</body>
<script src="/app.js"></script>
</html>

I think I was able to figure it out. Now I’m just trying to figure out how to access a specific value in an array

const itemInput = document.getElementById("item");
const submission = document.getElementById("submit-button");
const clear = document.getElementById("clear");
const tasks = document.getElementById("tasks");
const list = JSON.parse(localStorage.getItem('todoList')) || [];

function createButtons(){
  const editButton = document.createElement('button');
  const deleteButton = document.createElement('button');
  editButton.innerHTML = "editButton";
  deleteButton.innerHTML = "deleteButton";

  tasks.appendChild(editButton);
  tasks.appendChild(deleteButton);

  editButton.addEventListener("click", (e) => {
    for(let i = 0; i < list.length; i++){
      console.log(list[i])
    }
  })
}


function add(){
  const obj = {
    value: itemInput.value,
  
  };
  list.push(obj)
createTaskElement(obj.value)
updateLocalStorage()
}

function createTaskElement(submittedInput){
const p = document.createElement("p");
p.innerHTML = submittedInput;
tasks.appendChild(p)
}


function updateLocalStorage(){
  localStorage.setItem("todoList", JSON.stringify(list))
}

function displayTask(){
 for(let i = 0; i < list.length; i++){
  createTaskElement(list[i].value)
  createButtons(list[i].value)
 }
}

submission.addEventListener("click", e =>{
  add()
})
displayTask()

clear.addEventListener("click", e =>{
  tasks.innerHTML = "";
 localStorage.clear()
})

first of all, in the createButtons function you are defining a deleteButton and doing nothing with it (just an aside).

then you call displayTasks() which add the items in the div with id=‘task’
then you call createButtons() for each tasks which add the button again in the div with id=‘task’

so your output is:

<div id='task'>
  // displayTasks()
  <p> some task </p>
  <p> another task </p>
  // displayButtons()
  <button>
  <button>

you need to create first a task with the relative buttons
and then append it to the task container if you want to keep it together

Like this?

const itemInput = document.getElementById("item");
const submission = document.getElementById("submit-button");
const clear = document.getElementById("clear");
const tasks = document.getElementById("tasks");
const list = JSON.parse(localStorage.getItem('todoList')) || [];


function add(){
  const obj = {
    value: itemInput.value,
  
  };
  list.push(obj)
createTaskElement(obj.value)
updateLocalStorage()
}

function createTaskElement(submittedInput){
const p = document.createElement("p");
p.innerHTML = submittedInput;
tasks.appendChild(p)
}


function updateLocalStorage(){
  localStorage.setItem("todoList", JSON.stringify(list))
}



function createButtons(){
  const editButton = document.createElement('button');
  const deleteButton = document.createElement('button');
  editButton.innerHTML = "editButton";
  deleteButton.innerHTML = "deleteButton";

  tasks.appendChild(editButton);
  tasks.appendChild(deleteButton);
}


function displayTask(){
 for(let i = 0; i < list.length; i++){
  createTaskElement(list[i].value)
  createButtons(list[i].value)
 }
}

submission.addEventListener("click", e =>{
  add()
  createButtons()
})
displayTask()

clear.addEventListener("click", e =>{
  tasks.innerHTML = "";
 localStorage.clear()
})

much better :slight_smile:

sweet! Now I’m trying to figure out how to get specific values from an array using an edit button but I’m stumped on that as well

My advice …
I would wrap all the elements relatives to a task (the paragraph and the buttons) in a


so when you loop throught the array of tasks to create each element is the right moment to save the index of that element in the wrapping div for example.

take a look at this:

Sorry, I’m still a bit confused on what you mean.

oh wait… Do you mean separately wrapping the paragraphs and buttons to a div and then use the indexes of each pair to access the items in the local storage array?

In the displayTasks function you are looping through each element of the array.
the “i” variable is the index of that element in the array.
You are accessing that specific element in with list[i].

Now, in the createButtons function you could easily pass more than one argument, i.e. the array index of the element. You can save this information in the edit and delete buttons. You could save it with a data-index attribute as I suggested in my previous reply, or through closures if you know what they are (I think a data-* attribute is easier in this case).

Once you save this information, it stays there. If you know how to use browser’s devtools to inspect the page you can see that the value is there.

Later in the click listener you can retrieve the index from the button itself and use it to get the correct element in the array.

Now … I know that at first sight looks like a lot of concepts. But the first advice everyone would give you when you start coding is to divide the problem into smallers problems, then again and again till you get the smaller problem you can solve. From them you got a list of small problems to solve instead of just one big problem.

So… start from one thing. Read the documantation about the data-* attribute and try to use it as I explained early to save the array index.

Then step by step you can figure out how to retrieve the data from the click listener.

Believe me, it’s easier than you might think. Just try to concentrate on one small problem at a time.

Okay, gotcha. How do you use the data index thing because I checked the link and I don’t understand it at all

Honestly, I don’t know. Everyone is saying that this is simple, but I just cannot get for the life of me. Like your explanation makes sense, and at the same time it doesn’t. I don’t know if I’m built for this tbh. Thank you for the help though.

I get what I have to do in my head but I can’t translate it to the code.

I guess to give you an example of what I mean is that I think you may need to wrap each pair of paragraphs and buttons in a div, and then use the edit buttons inside of the divs to access the index of it’s own pair. Then, every time you click each edit button, it brings up it’s div index. Then, on click of the edit button, you will loop through the array and use that index number to access the localstorage paragraph values. Then I’ll somehow have to find a way to edit those values and update it to local storage.

That’s what I think needs to be done but somehow I know it’s going to be wrong.

1 Like

This isnt an answer i can accept :sweat_smile:
My fault…

Let me try another approach.

Its exactly what you have to do.
Its not wrong at all.

You have done what I was about to suggest you do.

Before start writing code you need to create an algorithm.
That is simply a list of step to resolve a problem.

And its exactly what you have done.

You already created an algorithm.

You have a list of steps you must do.

Now start from the beginning and do one step at a time.

Start from here.
Delete all the code you have written so far and start again.

Create a function that create a div with a text and two buttons.

When you have this function you have done the first step and you can pass to the next one

function createButtons(){
  const editButton = document.createElement('button');
  const deleteButton = document.createElement('button');
  const div = document.createElement("div");
  editButton.innerHTML = "editButton";
  deleteButton.innerHTML = "deleteButton";

div.append(editButton, deleteButton)
tasks.appendChild(div)
}

okay, here it is.

I don’t think it matters if the text is in it. I just need a pair of either the buttons, text, or anything to get the index

Okay. But its missing the text.

Maybe you could pass the text as an argument to the function.
And you could change the name to createTask for example.

This way you have a function that take a text and create

Div
P text
Button
Button