79

I have some list item tags in my jsp. Each list item has some elements inside, including a link ("a" tag) called delete. All that I want is to delete the entire list item when I click the link.

Here is the structure of my code:

$("a").click(function(event) {
  event.preventDefault();
  $(this).parent('.li').remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li id="191" class="li">
  <div class="text">Some text</div>
  <h4><a href="URL">Text</a></h4>
  <div class="details">
    <img src="URL_image.jpg">
    <span class="author">Some info</span>
    <div class="info"> Text
      <div class="msg-modification" display="inline" align="right">
        <a name="delete" id="191" href="#">Delete</a>
      </div>
    </div>
  </div>
</li>

But this doesn't work. I'm new at jQuery, so I tried some things, like for example:

$(this).remove();

This works, it deletes the link when clicked.

$("#221").remove();

This works, it deletes the indicated list item, but it's not "dynamic".

Can someone give me a tip?

Noob
  • 1,077
  • 2
  • 14
  • 16

7 Answers7

136

Simply use the .closest() method: $(this).closest('.li').remove();
It starts with the current element and then climbs up the chain looking for a matching element and stops as soon as it found one.

.parent() only accesses the direct parent of the element, i.e. div.msg-modification which does not match .li. So it never reaches the element you are looking for.

Another solution besides .closest() (which checks the current element and then climbs up the chain) would be using .parents() - however, this would have the caveat that it does not stop as soon as it finds a matching element (and it doesn't check the current element but only parent elements). In your case it doesn't really matter but for what you are trying to do .closest() is the most appropriate method.


Another important thing:

NEVER use the same ID for more than one element. It's not allowed and causes very hard-to-debug problems. Remove the id="191" from the link and, if you need to access the ID in the click handler, use $(this).closest('.li').attr('id'). Actually it would be even cleaner if you used data-id="123" and then .data('id') instead of .attr('id') to access it (so your element ID does not need to resemble whatever ID the (database?) row has)

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 1
    @Thifmaster: .parents("li:first") should stop at the first matching element – Reporter Jul 11 '11 at 08:58
  • @reporter: True. But that's not a feature of `.parents()` but simply due to the selector. In his case even `.parents('.li')` might work if there's no other `.li` present in the parents.. – ThiefMaster Jul 11 '11 at 09:04
  • 2
    Very good solution and very useful comment! Thank you very much :D (I'll remove the id in the link, I don't need it. Thanks!) – Noob Jul 11 '11 at 09:21
  • @ThifMaster: Unfortunatly, somesometimes you have to abuse some things ;-) – Reporter Jul 11 '11 at 09:29
  • @thief how can we remove dynamically added content using closest()? – Karthik May 03 '16 at 10:26
30

what about using unwrap()

<div class="parent">
<p class="child">
</p>
</div>

after using - $(".child").unwrap() - it will be;

<p class="child">
</p>
dav
  • 8,931
  • 15
  • 76
  • 140
18

Use parents() instead of parent():

$("a").click(function(event) {
  event.preventDefault();
  $(this).parents('.li').remove();
});
josemota
  • 974
  • 1
  • 8
  • 27
11

Delete parent:

$(document).on("click", ".remove", function() {
       $(this).parent().remove(); 
});

Delete all parents:

$(document).on("click", ".remove", function() { 
       $(this).parents().remove();
});
Prais
  • 907
  • 9
  • 14
2

I have stumbled upon this problem for one hour. After an hour, I tried debugging and this helped:

$('.list').on('click', 'span', (e) => {
  $(e.target).parent().remove();
});

HTML:

<ul class="list">
  <li class="task">some text<span>X</span></li>
  <li class="task">some text<span>X</span></li>
  <li class="task">some text<span>X</span></li>
  <li class="task">some text<span>X</span></li>
  <li class="task">some text<span>X</span></li>
</ul>
Shivam Jha
  • 3,160
  • 3
  • 22
  • 36
1

You could also use this:

$(this)[0].parentNode.remove();
Zoe
  • 27,060
  • 21
  • 118
  • 148
Andres Paul
  • 1,020
  • 16
  • 18
0
$('#' + catId).parent().remove('.subcatBtns');
Kyll
  • 7,036
  • 7
  • 41
  • 64
  • 4
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Kyll Nov 29 '16 at 10:03