0

I have a button that append a template containing few divs and buttons. The first button "btnGenerateResult_0" works fine probably because it exists when the page loads, while "btnGenerateResult_1" gets created but doesn't work. How and where can I fix the event listener and attach it to these buttons, I need four buttons?

The bellow code is inside a document.readey function():

$(`#btnGenerateResult_${active}`).click(function () 
{
    var newrow = "";
    for (var i = 1; i < TablesObj[activeTableObj[active]].length; i ++ ) 
    {
            newrow = "";
            newrow= "<tr><td>"  +  TablesObj[activeTableObj[active]][i][0] +  
                    "</td><td>"  + TablesObj[activeTableObj[active]][i][3] + 
                    "</tr>";
            $(`#resultTableMain_${active}`).append(newrow); 
    }

});

1 Answers1

0

One option is to add the event listener to the newly created button after you have created it:

const container = document.getElementById('container');

function handleButtonClicked(e) {
   console.log(`Button ${ e.target.textContent } clicked!`);
}

Array.from(container.children).forEach((button) => {
  button.onclick = handleButtonClicked;
});

setTimeout(() => {
  const newButton = document.createElement('BUTTON');

  newButton.textContent = 'C';

  container.appendChild(newButton);
  
  // Add the event listener to this new button as well:
  newButton.onclick = handleButtonClicked;
}, 2000);
<div id="container">
  <button>A</button>
  <button>B</button>
</div>

Another option, which might scale better, is to use event delegation. It consists of adding a single event listener to the parent or any common ancestor for all those buttons. The click event will then bubble app and you can use e.target to find out which button the event originated from:

const container = document.getElementById('container');

container.onclick = (e) => {  
  if (e.target.tagName !== 'BUTTON') {
    console.log('Something else clicked...');
    
    return;
  }
  
  console.log(`Button ${ e.target.textContent } clicked!`);
};

setTimeout(() => {
  // See how this works with dynamically created buttons as wel, withiout adding the
  // event listener to each of them individually. However, the event might be
  // triggered from undesired elements as well (click in the space between the
  // buttons), so you need to check for that, as you can see above.

  const newButton = document.createElement('BUTTON');

  newButton.textContent = 'C';

  container.appendChild(newButton);
}, 2000);
<div id="container">
  <button>A</button>
  <button>B</button>
</div>
Danziger
  • 13,604
  • 4
  • 30
  • 57