1

I'm creating a simple todo app in plain vanilla jS but am having an issue assigning an event listener to the pre-populated data. It's weird because I can assign a button to them but the event listener will not work.

When I create new list items and assign the eventlistener to the button, on click removes the list item no problem.

Spent a good hour and a half on this and can't seem to figure it out. Below block of code is the function which is onload of my html page. I have 4 list items pre-populated and this function successfully adds the button to each List item but fails to add the event listener.

function applyButton(){

 var getListObjects = document.querySelectorAll("li")

for(var i = 0; i< getListObjects.length; i++){

var node2 = document.createElement('BUTTON')
var textnode2 = document.createTextNode('Delete')
node2.appendChild(textnode2)

getListObjects[i].appendChild(node2)
var x = getListObjects[i]

x.querySelector('button').addEventListener('click', function(){
    x.querySelector('button').parentNode.parentNode.removeChild(x)  
})
}
  }

Below code takes the input value and creates a new list item with a delete button that successfully has an event listener to delete the List item. I tried copying this word for word with the other function but to no avail. This below code works perfectly as intended.

var newNoteValue     = document.getElementById('newNote').value
var addItemButton = document.getElementById('addItem')
var onEnter = document.getElementById('newNote')    

addItemButton.addEventListener('click', function(){
var item = document.getElementById('newNote').value
var node = document.createElement("LI")
var textnode = document.createTextNode(item)

node.appendChild(textnode)
document.getElementById('list-body').appendChild(node)

var node2 = document.createElement('BUTTON')
var textnode2 = document.createTextNode('Delete')
node2.appendChild(textnode2)
node.appendChild(node2)

node2.addEventListener('click', function(){
    node2.parentNode.parentNode.removeChild(node)

});

document.getElementById('newNote').value = ''

});

EDIT - Solution based off recommended answer

function applyButton(){

var getListObjects = document.querySelectorAll("li")

for(var i = 0; i< getListObjects.length; i++){

var node2 = document.createElement('BUTTON')
var textnode2 = document.createTextNode('Delete')
node2.appendChild(textnode2)

getListObjects[i].appendChild(node2)
addEventToButton2(getListObjects[i])

}
}

function addEventToButton2(currentListItem){
let y = currentListItem.querySelector('button')
y.addEventListener('click', function(){
    y.parentNode.parentNode.removeChild(currentListItem)    
});
}
noobcoderiam
  • 488
  • 4
  • 19
  • See the linked question's answers. The reason it works as a one-off is that `node2` never changes. The reason it doesn't work in the loop is that `x` **does** change (even though it's declared within the loop body, it actually had function scope). So all those event listeners use the **last** value assigned to `x`. The linked answers say how to fix it. Happy coding! :-) – T.J. Crowder Feb 23 '19 at 15:40
  • Perfect example dude. Understood it easily. I'll edit my answer with the fix. I just created the separate function and adding the event there. – noobcoderiam Feb 23 '19 at 18:39

0 Answers0