0

I am working on an invoice creator: when a user clicks on a button, it shows down the name and the price (with the total). When I add an event listener that loops through all the buttons with a given class, it works (I selected them by .childNodes property). But when there's new buttons added by .innerHTML, the event listener doesn't work anymore. Is there a method that can loop through new NodeList items and execute the addEventListener method?

Here's how I did it:

const btnContainer = document.getElementById("btn-container") // this is the button container
const serviceBtn = btnContainer.childNodes; // the nodelist buttons (they have a class="service-btn")
for (let i=0; i < serviceBtn.length; i++) { // loops through all the buttons
    serviceBtn[i].addEventListener("click", (event)=> {
        //...the action of the buttons (displaying name, price etc.)
    })
}

This works fine, but when a new button is added...

const addNewBtn = document.getElementById("add-new-btn") // the button that adds new buttons
addNewBtn.addEventListener('click', ()=> {  
    const textInput = document.getElementById("text-input") // IGNORE THIS
    const priceInput = document.getElementById("price-input") // IGNORE THIS
    newButton = `
                 <button class="service-btn">${textInput.value}
                     <span class="btn-price">${priceInput.value}</span> 
                 </button>
    `
    console.log(serviceBtn) 

...I can see that the button is added, the Nodelist has 1 more item (when i log it out into the console), but no button work when I click on any of them (it doesn't show any error or something)

Help please !

Note: i have tried to do it this way in the addNewBtn.addEventListener as well but i still got the same problem (the other buttons work though BUT IT'S ONLY THE NEW ONE THAT DOESN'T):

    let newButton = document.createElement('button')                // <button>
    let span = document.createElement('span')                      // <span>
    let btnText = document.createTextNode(textInput.value + " ")  // <button>textInput.value</button>
    span.append(document.createTextNode(priceInput.value + " ")) // <span>priceInput.value</span
    newButton.setAttribute('class','service-btn')               // <button class="service-btn"...
    span.setAttribute('class','btn-price')                    // <span class="btn-price"...
    newButton.append(btnText, span)                           // <button>...<span>...</span></button>
    btnContainer.appendChild(newButton)                      // append it to the button conatiner
Abd
  • 1
  • Where is your `newButton.addEventListener()` call? – Barmar Apr 07 '22 at 20:06
  • You can use a `MutationObserver` to watch for changes to the DOM. Busy now, but can say more if wanted. – Darryl Noakes Apr 07 '22 at 20:07
  • @Barmar newButton is inside addNewBtn.addEventListener(), it just replaces this : newButton = ` ` – Abd Apr 07 '22 at 20:26
  • it's okay I will check it out, thank youuu @DarrylNoakes ! – Abd Apr 07 '22 at 20:27
  • I know you define `newButton` in there, but you never do `newButton.addEventListener("click", ...)`. So the new button doesn't have an event listener added to it. – Barmar Apr 07 '22 at 20:28
  • @DarrylNoakes There's no need to use MutationObserver for this. Since the new button is only created in one place, that function can do it. MutationObserver is mainly useful if you can't modify the code that adds the new element. – Barmar Apr 07 '22 at 20:29
  • @Barmar Ah, okay. I didn't look at the code much, I'm afraid. – Darryl Noakes Apr 07 '22 at 20:43
  • @Barmar IT WORKED !! I tried to solve through your idea till it worked, thank you so so much !!! – Abd Apr 07 '22 at 23:13

0 Answers0