How to delete parent element using jQuery - javascript

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>Text</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?

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)

what about using unwrap()
<div class="parent">
<p class="child">
</p>
</div>
after using - $(".child").unwrap() - it will be;
<p class="child">
</p>

Use parents() instead of parent():
$("a").click(function(event) {
event.preventDefault();
$(this).parents('.li').remove();
});

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

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>

You could also use this:
$(this)[0].parentNode.remove();

$('#' + catId).parent().remove('.subcatBtns');

Related

How to keep only the first element from a class when cloning with jquery

Each of my divs have a class attributes named remove, the first class has the id: remove_item then the second remove_item_1, the third remove_item_2, etc.
My problem is that i only want to clone first one with the id remove_item and remove all the other one from the clone.
If i do clone.find('.remove'); i am able to gather all the elements with remove class but from there i am kinda lost on how to do that.
Could anyone help ?
Thanks.
You can keep first div by adding :first.
clone.find('.remove:first');
I think I got what you mean
here's an example how to pick the first element of a cloned div:
lets say you have
<ul id="list">
<div id="clone">
<li class="remove remove1">Remove 1 </li>
<li class="remove remove2">Remove 2</li>
<li class="remove remove3">Remove 3</li>
</div>
</ul>
The script to clone the list and remove the first child of the clone goes like this :
<script>
let clone = $('#clone').clone().appendTo('#list');
clone.children().first().remove();
</script>
or you can select the first one by class selection as #Manashree Shah mentioned like this:
clone.find('.remove:first');
The code uses jQuery, you can add this before the script if you haven't already added it :
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

Trouble using .closest function

I'm trying to make a sidebar menu for a dashboard. I want to implement this with .closest as it will fit with my code right. Here is a simple example of what I'm trying to do: https://jsfiddle.net/eu8kjzh4/10/
Why isn't the closest span's (and the only span in this case) text being replaced with a '-'? In my code, I have
$('.' + Key).closest( '.' + Key ).css("color", "#000");
This code works just fine, but the one in the jsfiddle does not.
closest traverses up the DOM and is used for nested elements.
In your markup, your div is not a descendant of your span, not even a sibling.
You have
1. To retrieve the previous sibling (the first li after the body)
2. And find the span inside the li
$(document).ready(function() {
$(".sub").prev().find('span').text('-');
});
Also, in your fiddle, you forgot to include jQuery.
Here is a working code : https://jsfiddle.net/qwc6pepr/1/
Incorrect function: .closest( selector ) Returns: jQuery
Description: For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree
What you want is the prev which finds the first sibling prior to the element
$(document).ready(function() {
$('.sub').prev('li').find('span').text('-');
});
From jQuery documentation
Given a jQuery object that represents a set of DOM elements, the .closest() method searches through these elements and their ancestors in the DOM tree and constructs a new jQuery object from the matching elements
Your span is neither a Parent Element of your div.sub in the DOM, nor matches with the $(".sub") rule.
The only way to make your jQuery code work with your HTML structure :
$("#plusMinus1").text("-");
Or modify your HTML structure to match with the .closest() method requierements
Fiddle
When you go to the parent you'll end up in the body. From there you can find the span.
$(document).ready(function() {
$(".sub").parent().find("span").text("-");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<body>
<li>
<a class="selected" href="#" onclick="return false;">Dashboard 1 <span id="plusMinus1">+</span></a>
</li>
<div class="sub">
<ul>
<li><a id="s1" href="">Test A</a>
</li>
<li><a id="s2" href="">Test B</a>
</li>
<li><a id="s3" href="">Test C</a>
</li>
</ul>
</div>
</body>

How to traverse the DOM to get to specific element

I'm having a brain freeze trying to remember what the best way is to access the data attribute on an anchor tag when clicking a button that's not inside the tags container, could someone assist me on how I would do this, so if I click .js-watchlist-add I want to get the data-id of .js-film-entry:
JS
<div class="ctn">
<a href="/movie/{{id}}" class="film-entry js-film-entry" data-id="{{id}}">
<img src="{{poster}}" class="film-img">
<div class="result-film-details">
<h2 class="film-title">{{title}}</h2>
<p class="film-release-date">Released {{releaseYear}}</p>
<ul class="result-stats-tabs clearfix">
<li>{{vote_average}} <span>Vote Average</span></li>
<li>{{vote_count}} <span>Vote Count</span></li>
</ul>
</div>
</a>
<div class="cta-ctn">
<button class="watchlist-add js-watchlist-add">Add to watchlist</button>
<button class="watchlist-remove js-watchlist-remove">Remove from watchlist</button>
</div>
</div>
You can use closest() to get the parent element and find() to get the descendant within parent.
Live Demo
$(this).closest('.ctn').find('.js-film-entry').data('id');
You can use jQuery's has and find methods.
$('.ctn').has(this).find('.js-film-entry')
Adil's answer is great,
Though it may be more efficient to use children versus find, to avoid traversing descendants.
$(this).closest('.ctn').children('.js-film-entry').data('id');
Just to give another DOM traversal example, you could also use:
$(this).parent().siblings('.js-film-entry').data('id');

Use same div to toggle different parts of the page

Hello I have the following code:
Javascript/jQuery:
$(document).ready(function() {
$(".clickMe").click(function() {
$(".textBox").toggle();
});
});
Html code printed with a for loop:
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled</div>
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled 2</div>
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled 3</div>
I would like to be able:
When the page loads I want the to be hidden and toggle on click.
Using the same ids for <a class="clickMe"> and <div class="textBox"> to be able to toggle or hide the correct/equivalent <div> element.
jsFiddle code:
http://jsfiddle.net/A7Sm4/3/
Thanks
Edit 1: Class instead of Id
Edit 2: Fixed jsfiddle link
id are supposed to be unique
you should use class to do this
[EDIT] updated the jsfiddle to fit Marko Dumic's solution: http://jsfiddle.net/SugvH/
Something like this should do the trick:
$(document).ready(function() {
var divs = [];
$(".textBox").each(function(index) {
divs[index] = this;
});
$(".clickMe").each(function(index) {
$(this).click(function() {
$(divs[index]).toggle();
});
});
});
ID must (as per spec) be unique on the page. You can easily rewrite this to use class attribute:
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled</div>
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled 2</div>
...
Initially, you need to either hide div.textBox when DOM becomes ready, or hide it using CSS.
Then you attach click handlers to a.clickMe:
$(function () {
$('a.clickMe').click(function () {
// find first of following DIV siblings
// with class "textBox" and toggle it
$(this).nextAll('div.textBox:first').toggle();
});
});
However, maybe you don't control the markup but desperately need this done, you can keep your markup as it is and still make it work due to the fact that jQuery uses Sizzle framework to query the DOM which can be forced around the limitation of document.getElementById() (which returns only one element).
E.g. suppose you used id instead of class, if you write $('#clickMe'), you'll get the jQuery collection of only one element (jQuery internally used .getElementById() to find the element), but if you write $('#clickMe'), you get the collection of all elements with the id set to "clickMe". This is because jQuery used document.getElementsByTagName('a') to find all anchors and then filtered-out the elements (by iterating and testing every element) whose attribute value is not "clickMe".
In that case (you used your original markup), this code will work:
$(function () {
$('a#clickMe').click(function () {
$(this).nextAll('div#textBox:first').toggle();
});
});
Again, don't do this unless you absolutely need to!
$(document).ready(function() {
$("a").click(function() {
$(this).parent().find("div").toggle();
});
});
Use something similar to this.
Try appending an index to each pair of a/div's ids (clickme1 and textbox1, etc). Then when an a is clicked, read the id, take the index off the end, and show/hide the textbox with the same index.

How to aceess span directly using jQuery

I want to know how to get access of this [span class="myclass"] in below html structure..
<ul>
<li class="first">
<span class="myclass"></span>
<div class="xx">
<span></span>
........
</div>
<li >
<span class="myclass"></span>
<div class="xx">
<span></span>
........
</div>
</ul>
Here I need to write one function in [span class="myclass"], but i cant do it using $(".myclass") [I have few issues] I just want to directly access the span itself.How to do this..?
EDIT:the sln by phoenix is working fine..but lets say(just for my knowledge) the structure is
<li >
<span class="myclass"></span>
<div class="xx">
<li>
<span></span>
</li>
........
</div>
</ul>
so why the span inside 2 nd li(which is under div) is not getting the ref, is it bcoz they are not in the same level..if I need to access them do I need to do some thing like
enter code here
$("li").next(".xx").find(li span:first-child )..or something else is there?
Thanks.
$("li span.myclass")
EDIT: Okay then maybe with
$("li span:first") //EDIT: Don't do that. See below.
apparently :first stops after the first hit. So :first-child is the way to go.
which will select the first span in every li-element. But this can be tricky in case you have other li-elements with spans inside...
EDIT: If you can't use the class you already have, maybe assigning an additional class helps?
<span class="myclass newClass"></span>
...
var spans = $("li span.newClass");
EDIT:
As phoenix pointed out
$("li span:first-child")
returns a list with all span elements that are the first child of a li-element. I don't know if jQuery treats textnodes as child nodes. So if you have a space between <li> and <span>, this might be counted as the first-child. So check if you have any whitespace between your elements beside line breaks.
If span is the first child then you can use
first-child
selector
$("li span:first-child");

Categories

Resources