0

I'm trying to build a simple to do list application. I've linked my input field to an array which gets rendered out as an ordered list, and there are two buttons added to each item, one to state "completed" and one for "remove".

I've having difficulty with two parts: 1) adding event handlers to the buttons rendered out in the OL (I've managed to in the code below but I'm not sure if it's the right way. Part 2) identifying the index of the item so that I can modify it with the completed and remove buttons.

I've tried to use event delegation to tackle part 1 but I'm not sure if this is correct, and I don't know how to relate it to part 2.

document.getElementById("parent-list").addEventListener("click", function(e) {
    if(e.target && e.target.nodeName == "BUTTON") {
        console.log(e.target);
    }
});
Jake Kumra
  • 21
  • 1
  • If the items are dynamically created, you can try adding the listener to the document and not to the parent-list ul/div. See this link: https://stackoverflow.com/questions/34896106/attach-event-to-dynamic-elements-in-javascript Beyond that, probably the easiest and clearest way to determine which button is clicked is by adding a data attribute to the button. Maybe data-content="ITEM ID GOES HERE" – BeLEEver Feb 10 '22 at 23:55
  • If you want help, add more code and HTML. read : https://stackoverflow.com/help/minimal-reproducible-example from https://stackoverflow.com/help/how-to-ask – Mister Jojo Feb 10 '22 at 23:55

2 Answers2

0

One way would be to add the index as an attribute of the LI element within your ordered list. Then you could access it like so:

document.getElementById("parent-list").addEventListener("click", function(e) {
  if (e.target && e.target.nodeName == "BUTTON") {
    const list = e.target.closest('li[data-idx]');
    const idx = list.dataset.idx;
    console.log(e.target, list, idx);
  }
});
<ol id='parent-list'>
  <li data-idx='1'><button class='action'>click me</button></li>
  <li data-idx='2'><button class='action'>click me</button></li>
</ol>

Of course this is just a proof of concept, you'd need to add error handling and such.

David784
  • 7,031
  • 2
  • 22
  • 29
0

First off, you should keep track of the items

const items = document.querySelectorAll('.my-classname');

This will create an items array where you can do all sorts of stuff, like .forEach(). This is great, because you need the index of the item as well.

That would solve part 2.


Now, for part 1..

You should add classnames to each buttons, like

<button class="completed-btn"></button>
<button class="remove-btn"></button>

The reason you need this is to be able to differentiate them and their handlers.

Next step is same as with items. You want to keep track of each button.

const completedButtons = document.querySelectorAll('.completed-btn');
const removeButtons = document.querySelectorAll('.remove-btn');

You can now add your handlers

completedButtons.forEach((button, i) => {
  button.addEventListener("click", function (e) { 
    const item = items[i];
    const target = e.target;

    // do stuff
  });
});

removeButtons.forEach((button, i) => {
  button.addEventListener("click", function (e) { 
    const item = items[i];
    const target = e.target;

    // do stuff
  });
});

The variable i will match the index of the clicked item's button, therefore will match the index of the item.

kmp
  • 692
  • 6
  • 17