How can I make two buttons with the same function work?

Issue

and thank you for your time. Since I’ve added two+ buttons (run the code and press the "add table" button), all it does is add two new rows to the first table, and the subsequent buttons don’t work. I’ve tried calling the classes, using the loop, and putting the code where it should be, but it still refuses. Here is my code:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" type="text/css" href="WELPPproto.css">
</head>
<body>
<h1 style="font-family:verdana">Word List</h1>
<table id="list">
  <tr>
    <th scope="col">Word</th>
    <th scope="col">English</th>
    <th scope="col">Pronunciation</th>
    <th scope="col"><button class="deletethismaybe" id="deletethismaybe" type="button" title="delete this table">X</button></th>
  </tr>
  <tfoot>
    <tr>
      <div class="boxy_gril">
        <td><input type="text" id="w" class="w" required /></td>
        <td><input type="text" id="m" class="m" required /></td>
        <td><input type="text" id="p" class="p" /></td>
      </div>
    </tr>
    <tr>
      <td colspan="3"><div class="button_boi"><button type="button" class="button_boi" id="add">Enter</button>
</div></td>
    </tr>
  </tfoot>
</table>
<div id="ntable" class="ntable" >
  <section>
    
  </section>
</div>
  <br>
  <br>
  <button class="button_gril" id="addtable">Add Table</button>
<script>
document.getElementById("addtable").onclick = function() {
  let puttable = document.getElementById("ntable");
  let section = puttable.querySelector('section');

  let tableHTML = '<br><br>' + '<table id="list">' + '<tr>' +
    '<th scope="col">' + 'Word' + '</td>' +
    '<th scope="col">' + 'English' + '</th>' +
    '<th scope="col">' + 'Pronunciation' + '</th>' + '<th><button class="deletethismaybe" id="deletethismaybe" type="button" title="delete this table">X</button></th>' + 
    '</tr>' +
    '<tfoot><tr><div class="boxy_gril">' + 
    '<td><input type="text" id="w" class="w" required /></td>'+
    '<td><input type="text" id="m" class="m" required />' + 
    '</td><td><input type="text" id="p" class="p" /></td>' + 
    '</div></tr>' + '<tr>' + '<td colspan="3">' + '<div class="button_boi">' + '<button type="button" class="button_boi" id="add">Enter</button>' + '</div>' + '</td>'+ '</tr>' + '</tfoot>' + '</table>';
    
   section.insertAdjacentHTML('beforebegin', tableHTML);
  
}

document.addEventListener('click', (e) => {
  let thatTarget = e.target;
  let thatBtn = thatTarget.closest('.deletethismaybe');
  if (thatBtn) {
    e.preventDefault();
    thatTarget.closest('table').remove();
    thatTarget.closest('button').remove();
  }
})

var asdf = document.getElementsByClassName("button_boi");
for (var i = 0; i < asdf.length; i++) {

asdf[i].onclick = function() {
  let listTable = document.getElementById("list");
  let tfoot = listTable.querySelector('tfoot');

  let wordValue = document.getElementById("w").value;
  let engValue = document.getElementById("m").value;
  let pronunValue = document.getElementById("p").value;

  let trHTML = '<tr>' +
    '<td>' + wordValue + '</td>' +
    '<td>' + engValue + '</td>' +
    '<td>' + pronunValue + '</td>' + '<td><button class="deletethis" type="button" title="delete this row">X</button></td>' +
  '</tr>';
  
  tfoot.closest('tfoot').insertAdjacentHTML('beforebegin', trHTML);
}
}

document.addEventListener('click', (e) => {
  let thisTarget = e.target;
  let thisBtn = thisTarget.closest('.deletethis');
  if (thisBtn) {
    e.preventDefault();
    thisTarget.closest('tr').remove();
  }
})

document.getElementsByClassName('.deletethismaybe').onclick = function() {
let thatTarget = e.target;
let thatBtn = thatTarget.closest('.deletethismaybe')
  if (thatBtn) {
    e.preventDefault();
    thatTarget.closest('table').remove();
  }}
</script>
</body>
</html>

Solution

That’s because the event listeners you created only listens to those that have already been created initially. When new elements get appended in the DOM, you will have to add another event listeners to them as well.

Here’s an example on how to do it:

<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>Document</title>
  </head>
  <body>
    <ul id="lists">
      <li class="list-item">
        <div>List #1</div>
        <button class="btn-delete">Delete</button>
      </li>
    </ul>
    <div>
      <button id="btn-add">Add new item to list</button>
    </div>

    <script>
      const listsEl = document.getElementById('lists');

      // Delete button elements
      let deleteBtnEls = document.querySelectorAll('.btn-delete');
      const deleteBtnOnClick = (e) => {
        const listItemEl = e.target.closest('.list-item');

        listsEl.removeChild(listItemEl);
      };
      const removeEventListeners = () => {
        deleteBtnEls.forEach((deleteBtnEl) => {
          deleteBtnEl.removeEventListener('click', deleteBtnOnClick);
        });
      };
      const updateEventListeners = () => {
        // remove existing event listeners to prevent duplicate event listeners
        removeEventListeners();

        // get the updated list of delete button elements
        deleteBtnEls = document.querySelectorAll('.btn-delete');

        deleteBtnEls.forEach((deleteBtnEl) => {
          deleteBtnEl.addEventListener('click', deleteBtnOnClick);
        });
      };

      // Add new item button element
      const addBtnEl = document.getElementById('btn-add');

      addBtnEl.addEventListener('click', () => {
        const newListItemEl = document.createElement('li');

        newListItemEl.className = 'list-item';
        newListItemEl.innerHTML = `
          <div>List #${listsEl.childElementCount + 1}</div>
          <button class="btn-delete">Delete</button>
        `;

        listsEl.appendChild(newListItemEl);

        updateEventListeners();
      });

      // Initial call
      updateEventListeners();
    </script>
  </body>
</html>

Answered By – unspeakable29

Answer Checked By – Terry (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.