Get index of an element among other elements with the same class - javascript

Assume I have a set of divs:
<div class="index-me"></div>
<div class="ignore-me"></div>
<div class="ignore-me"></div>
<div class="index-me"></div>
How do I use jQuery .index() so that when I run it against the last element in this list, it returns 1, not 3? So, I want to any elements but with some certain class to be excluded from indexing.
Thanks!

$('div.index-me:eq(1)').index('div.index-me')
As the .index() docs show, you can pass a selector or element to make the index relative to:
If no argument is passed to the .index() method, the return value is
an integer indicating the position of the first element within the
jQuery object relative to its sibling elements.
If .index() is called on a collection of elements and a DOM element or
jQuery object is passed in, .index() returns an integer indicating the
position of the passed element relative to the original collection.
If a selector string is passed as an argument, .index() returns an
integer indicating the position of the first element within the jQuery
object relative to the elements matched by the selector. If the
element is not found, .index() will return -1.

var index = $('.index-me:last-child').index('.index-me');
Here is fiddle:
http://jsfiddle.net/Pg9XQ/

Related

Get data attribute value of the Nth element using jQuery

I am trying to get the data attribute value of the first element from the elements matched by this jQuery selector but it is giving me an error:
$("p.expiryItem").get(0).attr("data-id")
Uncaught TypeError: $(...).get(...).attr is not a function(…)
Yet it works with this:
$("p.expiryItem").attr("data-id")
What if I want to use the Nth element? Thanks
The problem is because although get(N) returns the Nth element in the matched set, it returns the underlying DOMElement which does not have an attr() method and hence the error.
To fix this you could use eq() which does the same job, but returns the element in a jQuery object:
$("p.expiryItem").eq(0).data('id') // zero-based
Or you could use the :nth-child selector:
$("p.expiryItem:nth-child(1)").data('id') // one-based
Note the preferred use of data() here to retrieve the data-* attribute.
$("p.expiryItem:nth-child(1)").attr("data-id")
Use selector :nth-child()
note that it starts with 1
Description: Selects all elements that are the nth-child of their parent.
Use eq(n).
difference between get(n) and eq(n) is that get returns JavaScript reference to the element, but eq returns jQuery object, which has the function attr().
$("p.expiryItem").eq(n).attr("data-id");
PS:
You can use data() function for data-attributes.
$("p.expiryItem").eq(n).data("id");
You can use .eq() jQuery method.
Eg.
HTML :
<p class="expiryItem" id="1">1</p>
<p class="expiryItem" id="2">2</p>
<p class="expiryItem" id="3">3</p>
<p class="expiryItem" id="4">4</p>
<p class="expiryItem" id="5">5</p>
JavaScript :
//For 2nd `p`
console.log("Attribute value of 2nd : "+$("p.expiryItem").eq(1).attr("id"));
//For 5th `p`
console.log("Attribute value of 2nd : "+$("p.expiryItem").eq(4).attr("id"));
JSFiddle

Get class of forth cell adjacent to current cell

I am trying to get class of fourth cell using eq() selector. Its working without eq selector like this :
alert($cell.closest( "td" ).next().next().next().attr("class"));
I tried using multiple variation of eq() but it's not working please help.
None of the below are working.
$cell = $(this);
alert($cell.find( "td" ).eq(3).attr("class"));
alert($cell.closest( "td" ).eq(3).attr("class"));
alert($cell.( "td:eq(3)" ).attr("class"));
That's not how the eq method work.
Given a jQuery object that represents a set of DOM elements, the .eq() method constructs a new jQuery object from one element within that set. The supplied index identifies the position of this element in the set.
As the closest method returns one element, eq(3) returns an empty set in here. You can use the nextAll method for creating a set of next siblings. Then eq(3) will return the fourth element in that set:
$cell.closest("td").nextAll().eq(3).attr("class");
Please note that if this here refers to a td element then closest('td') does nothing.

How will i able to get the DOM position of the character

HTML
<div id="board">
<div>ab X</div>
<div>a <span class='target'>V</span> b</div>
<div>Xab</div>
<div>
I wanted to access the DOM place of V in my HTML and alert V, I must not use $('#board').eq(1).text().charAt(2). I need its DOM position so that I can easily trace the span that is wrapping the V.
THIS is not working, What's the right way?
alert($('#board').eq(1).eq(2).text());
This is the original problem, i can get someone who can help me so im trying to revised it How will i get the span class id under which the text belongs?
ALGORTIHM:
1. Found V from row looping and y looping
2. Find the span where it belongs to
Assuming span elements that have V text content should be selected, you can use .filter() method:
var $span = $('#board span').filter(function() {
return (this.textContent || this.innerText) === 'V';
});
Getting index of selected element:
$span.index();
Index of the V character within the text content of span's parent element:
var vIndex = $span.parent().text().indexOf('V');
Note that jQuery returns a jQuery-wrapped array of the selected elements, as you are using ID selector, the returned collection has only one wrapper/top-level selected element:
Object[div#board]
.eq(1)(just like getting an element by index from a simple array) returns the second top-level selected element that doesn't exist in the collection. Apart from that chaining .eq() methods in that way doesn't make any sense as it returns only one element.

jQuery .index() strangeness

I'm by no means a jQuery (or JavaScript) expert so forgive me if I'm misunderstanding or overlooking something. I have the following HTML:
<html>
<body>
<div class="ted">Ted</div>
<div class="ted">Ted</div>
<div class="tim">Tim</div>
<div class="ted">Ted</div>
<div class="tim">Tim</div>
</body>
</html>
And the following JS:
$('.ted').click(function() {
alert($(this).index());
});
When I click a div with the class '.ted' the alert should show the index of that div.
Clicking the first div alerts '0' (expected), the second div alerts '1' (expected). However, clicking the last '.ted' div (the fourth in the list) alerts '3' - why is this not giving an index of 2? (as JS arrays are 0 based) and this is the third '.ted' div?
It's as if $('.ted') is actually bringing back all the divs in the list?
Example here: http://jsfiddle.net/nha2f/6/
The .index() method docs make this behaviour clear. Here's the relevant part (emphasis added):
If no argument is passed to the .index() method, the return value is an integer indicating the position of the first element within the jQuery object relative to its sibling elements.
Since the third element that matches your selector is actually the fourth child of its parent, it has an index of 3.
Continue reading through the documentation to find the solution to your problem:
If a selector string is passed as an argument, .index() returns an integer indicating the position of the original element relative to the elements matched by the selector.
So, you can pass the same selector to .index() and it will return the index of the element relative to the matched set:
alert($(this).index(".ted"));
.index() returns the index of the clicked element in it's parent, relative to it's siblings. Not compared to other divs with the same event listeners / class / id. Your third '.ted' div is the fourth child of your body.
To get the behavior you want, add a selector to your index call: Fiddle
$('.ted').click(function() {
alert($(this).index(".ted"));
});
When you pass a selector into index, it tells jQuery to look for the element in that set. If you don't, it looks to see where it is relative to all of its sibling elements.
Or alternately, remember the list of ted elements and then invert things: Fiddle
var teds = $(".ted");
teds.click(function() {
alert(teds.index(this));
});
When you pass an element into index, that tells jQuery to look for that element in the set.
the index is the child within the parent. If you want to enumerate the .ted elements try this:
$('.ted').each( function( i, a ){
$(a).click( function(){
alert( i ); // <- should be 0, 1 or 2.
} );
} );

Is there a method in jQuery that will traverse up the dom tree from an element and check selectors before its parent element

For example:
<div class="mainWrapper">
<div class="FirstLayer">
<input class="foo" value="foo" />
</div>
<div class="SecondLayer">
<div class="thirdLayer">
<input class="fee" />
</div>
</div>
</div>
Lets say I have the input.fee as a jQuery object and I also need to get the value of input.foo.
Now I know I can use a multitude of approaches such as $(this).parents(':eq(2)').find('.foo') but I want to use this one method on layouts which will have varying levels and numbers of nodes.
So I am wondering if there is a method which will simply start from .fee and just keep going up until it finds the first matching element, .prevAll() does not appear to do this. There are many .foo and .fee elements and I need specifically the first one above the .fee in context.
How about this:
$('input.fee').closest(':has("input.foo")')
.find('input.foo').val();
Here's JS Fiddle to play with. )
UPDATE: Kudos to #VisioN - of course, parents:first is well replaced by closest.
This will select the previous input.foo
// self might have siblings that are input.foo so include in selection
$( $("input.fee").parentsUntil(":has(input.foo)").andSelf()
// if input.off is sibling of input.fee then nothing will
// be returned from parentsUntil. This is the only time input.fee
// will be selected by last(). Reverse makes sure self is at index 0
.get().reverse() )
// last => closest element
.last()
//fetch siblings that contain or are input.foo elements
.prevAll(":has(input.foo), input.foo")
// first is closest
.first()
// return jQuery object with all descendants
.find("*")
// include Self in case it is an input.foo element
.andSelf()
.filter("input.foo")
// return value of first matching element
.val()
jQuery.closest() takes selector and does exactly what you need - finds the first matching element that is parent of something. There's also jQuery.parents() that does take a selector to filter element ancestors. Use those combined with find method and you're set.
$('input.fee').closest('.mainWrapper").find('.foo') does the trick, doesn't it?

Categories