Jeffrey Bernardo
Jeffrey Bernardo

Reputation: 47

Adding and Removing Child Element

I am currently working on our homework, to add and remove a Name on a list using only JavaScript. I have successfully coded how to remove and add names but im having a bug... once a name has been added it cannot be deleted.

<!DOCTYPE html>
<html>
<head>
    <title>JS DOM</title>
</head>
<body>
    <div>
        <h1 id="heading">JS DOM</h1>
        <ul>
            <li>
                <span>John</span>   
                <button class="del">Delete</button>
            </li>
            <li>    
                <span>Paul</span>   
                <button class="del">Delete</button> 
            <li>
                <span>George</span> 
                <button class="del">Delete</button>
            </li>   
            <li>
                <span>Ringo</span>  
                <button class="del">Delete</button>
            </li>
        </ul>
        <input id="input"  placeholder="Add Name">
        <button class="add">Add</button>
    </div>

    <script type="text/javascript" src="script.js"></script>
</body>
</html>
let x = document.querySelector("ul");
let btn = document.querySelectorAll(".del")
let btn1 = document.querySelector(".add");

 x.addEventListener("click", function(e){
    if (e.target.className == "del"){
        const li = e.target.parentElement;
        x.removeChild(li)
    } 
 })

btn1.addEventListener("click", function(){
    let z = (input.value);
    let span = document.createElement("span");
    let node = document.createElement("li");
    let text = document.createTextNode(z);
    let x = document.querySelector("ul");

    let addBtn = document.createElement("button");
    addBtn.innerHTML = "Delete"

    span.appendChild(text);
    x.appendChild(node);
    node.appendChild(span);
    node.appendChild(addBtn);
});

seems that the newly added names are not inheriting the my delete function. I saw answers here but they are already using JQuery, is there a way to fix this using JS only? I'm coding JS for about 2 weeks now, it would really help me if someone explain the answer here.

Thanks a lot!

Upvotes: 2

Views: 102

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370689

You're almost there - your event delegation handler checks

if (e.target.className == "del"){
    const li = e.target.parentElement;
    x.removeChild(li)
} 

So, every delete button needs a del class for the handler to recognize it and use removeChild. These classes are present in your original HTML:

<button class="del">Delete</button>

But not in your appended elements:

let addBtn = document.createElement("button");
addBtn.innerHTML = "Delete"
// ...
node.appendChild(addBtn);

Set addBtn's className to del, and everything works:

addBtn.className = 'del';

let x = document.querySelector("ul");
let btn = document.querySelectorAll(".del")
let btn1 = document.querySelector(".add");

x.addEventListener("click", function(e) {
  if (e.target.className == "del") {
    const li = e.target.parentElement;
    x.removeChild(li)
  }
})

btn1.addEventListener("click", function() {
  let z = (input.value);
  let span = document.createElement("span");
  let node = document.createElement("li");
  let text = document.createTextNode(z);
  let x = document.querySelector("ul");

  let addBtn = document.createElement("button");
  addBtn.className = 'del';
  addBtn.innerHTML = "Delete"

  span.appendChild(text);
  x.appendChild(node);
  node.appendChild(span);
  node.appendChild(addBtn);
});
<div>
  <h1 id="heading">JS DOM</h1>
  <ul>
    <li>
      <span>John</span>
      <button class="del">Delete</button>
    </li>
    <li>
      <span>Paul</span>
      <button class="del">Delete</button>
      <li>
        <span>George</span>
        <button class="del">Delete</button>
      </li>
      <li>
        <span>Ringo</span>
        <button class="del">Delete</button>
      </li>
  </ul>
  <input id="input" placeholder="Add Name">
  <button class="add">Add</button>
</div>

You also might consider naming it deleteBtn instead, since it deletes the current row. You may also assign to the textContent of an element rather than appending a createTextNode, to make your code less verbose. In addition, let node doesn't particularly describe what the variable node contains - perhaps call it li instead, because it always references an <li>:

const x = document.querySelector("ul");
const btn = document.querySelectorAll(".del")
const btn1 = document.querySelector(".add");

x.addEventListener("click", function(e) {
  if (e.target.className == "del") {
    e.target.parentElement.remove();
  }
})

btn1.addEventListener("click", function() {
  const span = document.createElement("span");
  const li = document.createElement("li");

  const deleteBtn = document.createElement("button");
  deleteBtn.className = 'del';
  deleteBtn.innerHTML = "Delete"

  span.textContent = input.value;
  x.appendChild(li);
  li.appendChild(span);
  li.appendChild(deleteBtn);
});
<div>
  <h1 id="heading">JS DOM</h1>
  <ul>
    <li>
      <span>John</span>
      <button class="del">Delete</button>
    </li>
    <li>
      <span>Paul</span>
      <button class="del">Delete</button>
      <li>
        <span>George</span>
        <button class="del">Delete</button>
      </li>
      <li>
        <span>Ringo</span>
        <button class="del">Delete</button>
      </li>
  </ul>
  <input id="input" placeholder="Add Name">
  <button class="add">Add</button>
</div>

Upvotes: 2

Related Questions