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)