3

I'm having a problem with my javascript. I want to create some kind of to-do list but I can't figure out how to delete an item.

When creating an item, it adds to the list with a delete button, but I don't know what to do for the item to delete itself when clicking on the button.

I have this on the addItem function

var item = document.createElement("li");
item.innerHTML = itemText + "<button class='delete'>Delete item</button>";
list.appendChild(item);

And this would be the function to delete the item, but I don't know what to put inside ...

function deleteItem() {

}
3
  • just pass a event parameter inside deleteItem(e) , now further see e.target element and perform removal of this element. I hope this will solve your issue. Try this. ie. Add item.innerHTML = itemText + "<button class='delete' onClick='deleteItem(e)'>Delete item</button>"; Commented May 10, 2015 at 10:36
  • I added what you told me to add on the innerHTML, but what should I write exactly on the deleteItem(e) function? I'm not very good with javascript .. Commented May 10, 2015 at 10:39
  • can you please share some part of working code in fiddle or something. ? Commented May 10, 2015 at 10:41

4 Answers 4

9

You have a couple of options:

  1. You could attach it as a handler directly to the button, then use this.parentNode to access the parent element. To actually remove it, you'd probably want to go one step higher up the hierarchy (DOM4 defines a remove method on elements, but it may not be supported by older browsers). That would look like this:

    var item = document.createElement("li");
    var btn = document.createElement("button");
    btn.className = "delete";
    btn.innerHTML = "Delete item";
    btn.addEventListener("click", deleteItem, false);
    item.appendChild(btn);
    list.appendChild(item);
    
    // ...
    
    function deleteItem() {
        this.parentNode.parentNode.removeChild(this.parentNode);
    }
    
  2. Instead of that, though, I'd use event delegation: Hook click on the list, and if the click passed through one of these delete buttons, handle it then: Your code for adding the list item and button would be unchanged. In one place, you'd have this:

    list.addEventListener("click", deleteItem, false);
    

    and deleteItem would look like this:

    function deleteItem(e) {
        var btn = e.target;
    
        // Since `button` elements can have elements inside them,
        // we start with the element that was the target of the
        // event and look to see if any the event passed through
        // a `button class="delete"` on its way to the list.
        while (btn && (btn.tagName != "BUTTON" || !/\bdelete\b/.test(btn.className))) {
            btn = btn.parentNode;
            if (btn === this) {
                btn = null;
             }
        }
        if (btn) {
            // Yes, it did -- remove the button's parent from the list
            // (`this` is the list, because that's what we hooked the
            // event on)
            this.removeChild(btn.parentNode);
        }
    }
    

Here's a live example of #2:

var list, item, n;

// Get the list, add a handler to it
list = document.getElementById("the-list");
list.addEventListener("click", deleteItem, false);

// Add items to it; you can do this at any time
for (n = 1; n <= 10; ++n) {
  item = document.createElement("li");
  item.innerHTML = "Item #" + n + "<button class='delete'>Delete item</button>";
  list.appendChild(item);
}

// Handle clicks that might come through the delete button
function deleteItem(e) {
  var btn = e.target;
  while (btn && (btn.tagName != "BUTTON" || !/\bdelete\b/.test(btn.className))) {
    btn = btn.parentNode;
    if (btn === this) {
      btn = null;
    }
  }
  if (btn) {
    this.removeChild(btn.parentNode);
  }
}
<ul id="the-list"></ul>

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for creating a comprehensive and well-written answer, and going the extra mile for others, especially for one who is using SO for the first time.
2
function registerClickHandler () {
    var x = document.querySelectorAll(".image");
    for(var i = 0; i < x.length; i++) {
       x[i].querySelector(".remove").onclick = function(){
           this.parentNode.parentNode.removeChild(this.parentNode);
    };
}

Comments

1

You have to remove the parent element from that one's parent element using removeChild.
Assuming button refers to your button element:

button.parentNode.parentNode.removeChild(button.parentNode);

So to make your button clickable. you might wanna do something like

button.addEventListener('click', function(event)
{
    var button = event.target;
    button.parentNode.parentNode.removeChild(button.parentNode);
});

Edit:

Since Samuel Liew wanted me to add it so badly, here's how you obtain the button element from the context of item (after setting innerHTML):

var buttons = item.getElementsByTagName('button');
var button = buttons[buttons.length - 1]; // Just in case there is more than one button

Putting this all together:

var item = document.createElement("li");
item.innerHTML = itemText + "<button class='delete'>Delete item</button>";
var buttons = item.getElementsByTagName('button');
var button = buttons[buttons.length - 1];
button.addEventListener('click', function(event)
{
    var button = event.target;
    button.parentNode.parentNode.removeChild(button.parentNode);
});
list.appendChild(item);

3 Comments

I provided a snippet and I explicitly said that I assume the variable button to refer to the button in question.
Yes, but the 'button' is just a string. How would OP know? Isn't he trying to learn?
I don't know, by Googling maybe? I'm not going to write an entire JavaScript tutorial here. But fine, I'll add how to get the button element.
0

You can also relate to this much simpler solution: For example with an image gallery;
//.................................................

<div class="image">
  <img src="" alt="First">
  <button class="remove">X</button>
</div>
<div class="image">
  <img src="" alt="Second">
  <button class="remove">X</button>
</div>
<div class="image">
  <img src="" alt="Third">
  <button class="remove">X</button>
</div>
<div class="image">
  <img src="" alt="Forth">
  <button class="remove">X</button>
</div>

var x = document.querySelectorAll(".image");

for(var i = 0; i < x.length; i++) {
  x[i].querySelector(".remove").onclick = registerClickHandler;
}

function registerClickHandler () {
   this.parentNode.parentNode.removeChild(this.parentNode);

}

Hope it helps :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.