jquery select first child with class of a parent with class - javascript

How can i select only the first child of a particular class of a parent with a particular class for the purposes of clone()?
<div class="sector_order">
<div class="line_item_wrapper">
SELECT THIS DIV
</div>
<div class="line_item_wrapper">
NOT THIS DIV
</div>
</div>
I am trying like this:
var form1 = $(this)
.parents('.sector_order')
.children('.line_item_wrapper')
.children().clone(true)
and get both inner divs with the class line_item_wrapper, but I get an empty object when I try with this addition:
children('.line_item_wrapper :first')
Thanks!

Your problems is that your selector is wrong, in a few ways:
parents() returns one, two or many elements that match the selector passed to the method; to limit yourself to the first-matched element use closest() (which returns one, or no, elements that match the passed-in selector).
Your first use of the children() method returns both elements, since they both match the supplied selector and have the class of line_item_wrapper; you need to explicitly state which of the two you want, you can either use the :first selector (or the first() method), or the :first-child selector.
The second call to the children() method finds the children of the first element matched by the selector, which you don't seem to want.
Anyway, if you must use the parent (starting from the same $(this) element):
var form1 = $(this).closest('.sector_order').find('.line_item_wrapper:first').clone(true);
Or:
var form1 = $(this).closest('.sector_order').find('.line_item_wrapper').first().clone(true);
Or:
var form1 = $(this).closest('.sector_order').find('.line_item_wrapper:first-child').clone(true);
Or, frankly, a simpler approach (but this does dispense with the parent class-name check):
var form1 = $(this).prevAll('.line_item_wrapper:last');
Or:
var form1 = $(this).siblings('.line_item_wrapper').eq(0);
References:
closest().
eq().
find().
:first.
:first-child.
first().
:last.
parents().
prevAll().
siblings().

You're passing an invalid selector to children().
Instead of
.children('.line_item_wrapper :first')
try
.children('.line_item_wrapper').first()

Use :first-child
var form1 = $(this).closest('.sector_order').find(':first-child');
OR .first()
var form1 = $(this).closest('.sector_order').find('.line_item_wrapper').first();

Try this:
var $firstDiv = $(".sector_order > .line_item_wrapper:eq(0)");
This will get you the first direct descendant of sector_order with the class line_item_wrapper.
Example fiddle

Related

How to put into querySelector some IDs?

querySelector("#ID1, #ID2, ID#3")
Is there a possibility to put into one querySelector some IDs?
querySelectorAll can be used to target multiple selectors.
document.querySelectorAll("#div1, .div2, h3");
Simple ! Use following code.
document.querySelectorAll('#id1, #id2 , #id3');
This will return nodelist which you can iterate and can perform actions that you want.
The querySelector() method returns the first element that matches a specified CSS selector(s) in the document.
Keep in mind that to return all the matches, use the querySelectorAll() method instead.
example
<div class="bar">.first </div>
<div class="bar">.second</div>
//get the first element with class bar
let firstElement = document.querySelector('.bar');
//log the first match
console.log(firstElement)
//get all elements with class bar
let allElements = document.querySelectorAll('.bar')
//You can use any common looping statement to access the matches
allElements.forEach(function(elements){
console.log(elements);
});
/*
querySelector("#ID1, #ID2, ID#3")
*select element matches #ID1
*select element matches #ID2
*select element matches #ID3
**/
//select elements matches specified selectors #id1 , #id2 , #id3 and use any common looping statement to access them
let allMatchesId = document.querySelectorAll('#id1 , #id2 , #id3');
allMatchesId .forEach(function(elements){
console.log(elements);
});
read the docs here at MDN https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
const divs = document.querySelectorAll('#id1, #id2');
console.log(divs[0], divs[1]);
<div id="id1"><div id="id2"></div></div>
Source
Just some more explanation:
This will work (if you correct the error ID#3 instead of #ID3), however querySelector only returns the first element in the document that it matches (NOT the first ID in the list).
If you want all of the elements, then use querySelectorAll, but again the order of the elements will NOT be the order of the IDs, but the order of elements in the document. For example, given the following HTML:
<div id="id2"></div>
<div id="id1"></div>
then following JS:
const divs = document.querySelectorAll("#id1, #id2");
alert(divs[0].id); // This will show "id2"!

jquery selector efficiently

<div id="parent">
<div id="child"></div>
</div>
<!-- script -->
<script type="text/javascript">
var $parent = $("#parent");
//$parent().dosomething()
// ... use $parent do something
//!!! now i want use child !!!
var $child = $parent.find("#child"); //method one
var $child = $("#child"); //method two
//$child().dosomething()
</script>
Question: method one or method two is better ??(hope explanation in detail ,thanks!)
waiting for your help
here is a breakdown of what would be fastest. It shows that the $parent.find method is about 50% slower than the direct selector method. That means that if you've got to do with ids at all, it's quite significantly faster to just use the selector on its own.
As elclanrs said, as each ID must be unique, it's more efficient to call directly the ID selector (method two) than calling the find() function. Moreover, the find() function will get all the descendants of each element in the current set of matched elements, filtered by a selector (in this case it wouldn't be a good idea cause you are requesting just one element, filtered by its ID, which once again, must be unique). Method one will be useful just if you need to get more than one element inside the parent div, like <li> selectors, elements of the same class, etc.

How to select element by id within existing selection?

Given HTML:
<div id="div-a"></div>
<div id="div-b"></div>
<div id="div-c"></div>
And a previously-created jQuery selection:
var $divs = $("div");
How can I select a particular div in that selection by its id?
Note: the $divs selection has not yet been appended to the DOM, so I can't just select directly (e.g. $("#div-b")).
find() selects descendants of a selection, so this does not work:
$divs.find("#div-b");
has() / :has() selects elements that contain an element with the specified selector, so this does not work:
$divs.has("#div-b");
You want to use filter() to reduce the set/.
var elem = $divs.filter("#div-b");
I think you are looking for filter():
var $subset = $divs.filter("#div-b");
If you want to only examine elements within a particular jQuery object that you've already created, you can use the .filter() method:
var $divs = $("div");
var item = $divs.filter("#div-a");
This will examine only the elements within the $divs jQuery object so see if any of them match the selector "#div-a" and will return to you a new jQuery object that contains only the matches (either zero or one object in this case).

Select Element From List by Index with jQuery

<form id="foo">
<input></input>
<input></input>
<input></input>
</form>
I want to do:
document.getElementById("foo").getElementsByTag("input")[1];
But in jQuery. I want to select a certain object under #foo by an index.
This is my first guess as to how to do this:
$('#foo input[1]').val("BlahBlah");
I think it would be the same in CSS too.
You could do it this way:
$('#foo input').eq(1).val("BlahBlah");
That will give you the second input. If you want the first, change the 1 to a 0. The .eq() function is 0 based.
In jQuery there are a couple of methods defined to select and use elements from a (DOM objects) list.
By using:
var list = $("#foo");
You would capture the entire #foo. If your in for simplicity you could get the children (i.e the input fields) by using var children = list.children(); But if you want something that seems a bit more like findElementsByTag, you could use var children = list.find('input'); (Which ofcourse could be a one liner, but usually you want to re-use the entire list too)
To get the first and last item of a certain list of children there are some predefined functions:
var first = children.first();
var last = children.last();
To find an -nth element you can use http://api.jquery.com/eq/ or http://api.jquery.com/nth-child-selector/
So you would get (note it works just like an array with 0-based index)
var second = children.eq(1);
If you like CSS selector style more you can also try (note the 1-based index)
var second_b = $("#foo input:nth-child(2)");
$('#foo :input').eq(1).val('BlahBlah')
You can use the eq() selector:
$('#foo input:eq(1)').val("BlahBlah");
You can use the eq selector. It receives a zero-based index:
$('#foo input:eq(1)').val('a value');
Use nth-child(n) pseudo class like this ...
$("#foo input:nth-child(0)").val("BlahBlah");
$("#foo input:nth-child(1)").val("BlahBlah");
.
.
.
$("#foo input:nth-child(n)").val("BlahBlah");
I'll say :
$($('#foo input')[1]).val("BlahBlah");

How do I get the n-th level parent of an element in jQuery?

When I want to get, for example, the 3rd level parent of the element I must write $('#element').parent().parent().parent() Is there a more optimal method for this?
Since parents() returns the ancestor elements ordered from the closest to the outer ones, you can chain it into eq():
$('#element').parents().eq(0); // "Father".
$('#element').parents().eq(2); // "Great-grandfather".
Depends on your needs, if you know what parent your looking for you can use the .parents() selector.
E.G:
http://jsfiddle.net/HenryGarle/Kyp5g/2/
<div id="One">
<div id="Two">
<div id="Three">
<div id="Four">
</div>
</div>
</div>
</div>
var top = $("#Four").parents("#One");
alert($(top).html());
Example using index:
//First parent - 2 levels up from #Four
// I.e Selects div#One
var topTwo = $("#Four").parents().eq(2);
alert($(topTwo ).html());
You could give the target parent an id or class (e.g. myParent) and reference is with $('#element').parents(".myParent")
Didn't find any answer using closest()
and I think it's the most simple answer when you don't know how many levels up the required element is, so posting an answer:
You can use the closest() function combined with selectors to get the first element that matches when traversing upwards from the element:
('#element').closest('div') // returns the innermost 'div' in its parents
('#element').closest('.container') // returns innermost element with 'container' class among parents
('#element').closest('#foo') // returns the closest parent with id 'foo'
A faster way is to use javascript directly, eg.
var parent = $(innerdiv.get(0).parentNode.parentNode.parentNode);
This runs significantly faster on my browser than chaining jQuery .parent() calls.
See: http://jsperf.com/jquery-get-3rd-level-parent
It's simple. Just use
$(selector).parents().eq(0);
where 0 is the parent level (0 is parent, 1 is parent's parent etc)
Just add :eq() selector like this:
$("#element").parents(":eq(2)")
You just specify index which parent: 0 for immediate parent, 1 for grand-parent, ...
If you plan on reusing this functionality, the optimal solution is to make a jQuery plugin:
(function($){
$.fn.nthParent = function(n){
var $p = $(this);
while ( n-- >= 0 )
{
$p = $p.parent();
}
return $p;
};
}(jQuery));
Of course, you may want to extend it to allow for an optional selector and other such things.
One note: this uses a 0 based index for parents, so nthParent(0) is the same as calling parent(). If you'd rather have 1 based indexing, use n-- > 0
If you have a common parent div you can use parentsUntil() link
eg: $('#element').parentsUntil('.commonClass')
Advantage is that you need not to remember how many generation are there between this element and the common parent(defined by commonclass).
you can also use :
$(this).ancestors().eq(n)
ex: $(this).ancestors().eq(2) -> the parent of the parent of this.
using eq appears to grab the dynamic DOM whereas using .parent().parent() appears to grab the DOM that was initially loaded (if that is even possible).
I use them both on an element that has classes applied it to on onmouseover. eq shows the classes while .parent().parent() doesnt.
As parents() returns a list, this also works
$('#element').parents()[3];
You could use something like this:
(function($) {
$.fn.parentNth = function(n) {
var el = $(this);
for(var i = 0; i < n; i++)
el = el.parent();
return el;
};
})(jQuery);
alert($("#foo").parentNth(2).attr("id"));
http://jsfiddle.net/Xeon06/AsNUu/

Categories

Resources