How to find a parent with a known class in jQuery? - javascript

I have a <div> that has many other <div>s within it, each at a different nesting level. Rather than give every child <div> an identifier, I rather just give the root <div> the identifier. Here’s an example:
<div class="a" id="a5">
<div class="b">
<div class="c">
<a class="d">
</a>
</div>
</div>
</div>
If I write a function in jQuery to respond to class d and I want to find the ID for its parent, class a, how would I do this?
I cannot simply do $('.a').attr('id');, because there are multiple class as. I could find its parent’s parent’s parent’s ID but that seems of poor design, slow, and not very polymorphic (I would have to write different code for finding the ID for class c).

Assuming that this is .d, you can write
$(this).closest('.a');
The closest method returns the innermost parent of your element that matches the selector.

Pass a selector to the jQuery parents function:
d.parents('.a').attr('id')
EDIT Hmm, actually Slaks's answer is superior if you only want the closest ancestor that matches your selector.

You can use parents() to get all parents with the given selector.
Description: Get the ancestors of each
element in the current set of matched
elements, optionally filtered by a
selector.
But parent() will get just the first parent of the element.
Description: Get the parent of each
element in the current set of matched
elements, optionally filtered by a
selector.
jQuery parent() vs. parents()
And there is .parentsUntil() which I think will be the best.
Description: Get the ancestors of each
element in the current set of matched
elements, up to but not including the
element matched by the selector.

Extracted from #Resord's comments above. This one worked for me and more closely inclined with the question.
$(this).parent().closest('.a');
Thanks

<div id="412412412" class="input-group date">
<div class="input-group-prepend">
<button class="btn btn-danger" type="button">Button Click</button>
<input type="text" class="form-control" value="">
</div>
</div>
In my situation, i use this code:
$(this).parent().closest('.date').attr('id')
Hope this help someone.

Use .parentsUntil()
$(".d").parentsUntil(".a");

Related

Jquery Find first direct child of a type

I am looking for a way to find the first direct child of an element, of a precise type.
Let's imagine this markup:
<div id="mainDiv">
<div id="otherDiv">
<p> Stuff </p>
</div>
<p> Stuff 2 </p>
<p> Stuff 3 </p>
</div>
So here, what I want to get is "Stuff 2" the first paragraph to be a direct child.
If using jquery I do something like $('#mainDiv').find('p:first'); I will get the paragraph inside the first div.
What I need is to ignore nested childs and take only the first direct one. How should I do that?
Use the direct descendant selector >
$('#mainDiv > p:first')
or even children()
$('#mainDiv').children('p').first()

Parent of an id using Jquery

<div class="cdlButton" style="width:40px; float: left;"> // want this div element
<div style="">
<a id="changestatus" class="" onclick="changeWorkflowStatus()" href="#">
<img id="" width="32px" height="32px" title="disable" alt="disable" src="images/disable.png">
</a>
</div>
</div>
I want div with help of jquery
Right now i am doing this way
$("#changestatus ").parent().parent().addClass('disablecdlButton');
Is there any other way to get top div element
$('#changestatus').closest('div.cdlButton').addClass('disablecdlButton');
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.
Official Document
You can do various things here
$(".cdlButton").addClass('disablecdlButton');
$('#changestatus').closest('div.cdlButton').addClass('disablecdlButton');
$($('#changestatus').parents().get(-1)).addClass('disablecdlButton');
use closest()
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.
$("#changestatus").closest("div.cdlButton").addClass('disablecdlButton');
You can try
$("#changestatus ").parents(".cdlButton").addClass('disablecdlButton');
$("#changestatus ").parents('div.cdlButton').addClass('disablecdlButton');
DEMO
Try this, .parents('div').last() will select the top most parent div element of the selected element , here it is changestatus
$("#changestatus ").parents('div').last().addClass('disablecdlButton');
Hope this helps,Thank you

How to find first parent element in jquery

Conside below html -
<div class="container1">
<div class="container2">
<div class="container3">
<div class="container4">
<div class="element">
...
</div>
</div>
</div>
</div>
if I want to get <div class="element"> element and I have reference to the container1. In jquery what I do is,
$(".container1").find(".element")
instead of -
$(".container1").children().children().children().find(".element")
This is process to find any child element when I have reference to any of the parent element. But instead when I have reference to a child element and want to get parent element then every time I have to go one level up -
$(".element").parent().parent().parent().parent()
and I can't do like this -
$(".element").findParent()
I have not come across any method like findParent() in jquery. Is there which I am not aware of? Or is it not there for some reason?
$(".element").parents();
will give all parents of .element(including html and body)
DEMO
To find any specific parent, suppose container1 then
$('.element').parents('.container1')
DEMO
jQuery .parents() generally find all parents, but if you passed a selector then it will search for that.
just use
$(".element").closest('#container1');
if no ancestor with that id is found then
$(".element").closest('#container1').length will be 0
To get the first parent personally I use the following construction:
var count_parents = $(".element").parents().length;
$(".element").parents().eq(count_parents - 1);
Hope, it will be helpful for someone.

from parent to child without traversing the full path

My divs are nested like this.
<div id="top">
<div class="child1">
<div class="child-child">
<div class="child-child-child">
</div>
</div>
</div>
<div class="child2">
<div class="child-child">
<div class="child-child-child">
</div>
</div>
</div>
</div>
Right now I'm going from #top to .child-child-child by doing this.
$('#top').children('.child1')
.children('.child-child')
.children('.child-child-child');
Do I have to specify the full path like this? I want to omit the middle divs if there's a syntax that would let me do that. But I probably still need to specify whether I want to go through .child1 or .child2.
You do need to specify which path to take, but you could make it a little shorter:
$('#top > .child1').find('.child-child-child');
This will give you the '.child-child-child' that is a descendant of .child1.
Or you could write it like this, using only selectors:
$('#top > .child1 .child-child-child');
Or this, using only traversal methods:
$('#top').children('child1').find('.child-child-child');
You can just use a descendant selector (a space) to find the child anywhere beneath (as .find() does), like this:
$('#top .child-child-child');
Or, a bit more specific:
$('#top > .child1 .child-child-child');
To simplify this, you can use the selector:
$('#top .child1 .child-child-child');
This selector says "an element with a class of .child-child-child that is inside an element with a class of .child1 that's inside an element with an id of top".

Referring to a div inside a div with the same ID as another inside another

How can I refer to a nested div by id when it has the same id as a div nested in a similarly named div
eg
<div id="obj1">
<div id="Meta">
<meta></meta>
</div>
</div>
<div id="obj2">
<div id="Meta">
<meta></meta>
</div>
</div>
I want to get the innerHTML of meta
document.getElementById('obj1').getElementById('Meta').getElementsByTagName('meta')
doesn't work
IDs should only be used when there is one of that item on the page, be it a SPAN, DIV or whatever. CLASS is what you should use for when you may have a repeating element.
Code there doesn't work because you're referring to an element by unique ID, but have more than one on the page.
Id is supposed to be unique.
Hate to point out the obvious, but in your example, obj1_Meta and obj2_Meta are unique id's, so if it's the case in your working code:
document.getElementById('obj1_Meta').getElementsByTagName('meta')[0].innerHTML;
would work as described. As a double check, did you over think this?
If not, bummer...
As "bad" or "wrong" as your code is, an option that will work is to use a JavaScript framework like jQuery. Once you've included it, you can get elements by passing it a CSS selector (even a semantically incorrect one) like so:
$('#obj1 #obj1_Meta meta').html()
$() is jQuery's way of saying document.getElementById() ...on steroids.
.html() is its equivalent of .innerHTML
Other frameworks, like PrototypeJS and MooTools also provide similar functionality.
Prototype for example:
$$('#obj1 #obj1_Meta meta').innerHTML;//note the double $'s
Frameworks save lots of time and trouble with regard to browser compatibility, "missing" JavaScript methods (like getElementsByClassName) and coding AJAX quickly. These things make them a good idea to use to anyway.
IDs are meant to be unique, use classes intelligently.
<div id="obj1" class="obj">
<div id="obj1_Meta" class="obj_Meta">
<meta></meta>
</div>
</div>
<div id="obj2" class="obj">
<div id="obj2_Meta" class="obj_Meta">
<meta></meta>
</div>
</div>
.obj = targets both elements
#obj1.obj = targets only the first
#obj1.obj_Meta = targets obj1 inner DIV
#obj2.obj = targets only the second
#obj2.obj_Meta = targets obj2 inner DIV
You may also run into problems with this markup because the "meta" tag is only legal inside the head tag, not the body tag. As far as I can tell from looking at Firebug, Firefox will even go so far as to pull those meta tags out of the body and toss them into the head (and, in this case, put any text content inside the parent div), so you won't see them in the DOM at all.
For the HTML you've given, this should work:
document.getElementById('obj1').getElementsByTagName('div')[0].getElementsByTagName('meta');
Just ignore the bogus id on the inner div and get it by tag name. You should also be able to ignore the inner div completely, since getElementsByTagName searches the entire subtree:
document.getElementById('obj1').getElementsByTagName('meta');
As the id attribute is a unique document-wide identifier, you should probably namespace your ids.
<div id="obj1">
<div id="obj1_Meta">
<meta></meta>
</div>
</div>
<div id="obj2">
<div id="obj2_Meta">
<meta></meta>
</div>
</div>
document.getElementById('obj1_Meta').getElementsByTagName('meta')

Categories