How to select next matching element? - javascript

This works:
link1
link2
link3
$("a[href*='#/link1'").next('a[href*="#"]').click();
but this does not:
link1<br>
link2<br>
link3<br>
$("a[href*='#/link1'").next('a[href*="#"]').click();
The above tests the "< br >" tag, not the next matching link.
How would I go about making it work in both situations. I want to select the next matching element, not the next element if it matches. Maybe .next() isn't the correct method?

The second example should not select anything at all. Read the documentation of next:
Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector.
You have to use nextAll to get all siblings and filter them accordingly:
$("a[href*='#/link1']").nextAll('a[href*="#"]:first').click();
Reference: nextAll

Use .nextAll() and :first to get the next sibling that matches, rather than the next sibling if it matches, like this:
$("a[href*='#/link1'").nextAll('a[href*="#"]:first').click();

Create your own simple jQuery plugin called nextMatching:
$.fn.nextMatching = function(selector) {
return this.nextAll(selector).first();
};
And use it like this: given the following markup...
<li id="startingElement">one</li>
<li>two</li>
<li>three</li>
<li>four</li>
<li id="targetElement">five</li>
<li>six</li>
...and starting with the element one, you can select element five like this:
$('#startingElement').nextMatching('#targetElement');

Related

match elements by data attribute and id

I am looking for a way to compare elements using jQuery. Basically for every element with a certain data attribute, I want to "appendChild" another element that has a matching ID.
So in the following example, 'a' has a data attribute of data-dropdown="drop-delivery-options". The second element has an ID="drop-delivery-options", so they match. I can select elements with this ID but how do I select elements that match data-attributes/IDs?
So a function that would be like:
If elementA[data-attribute] = elementB[ID] {
(elementA).appendChild(elementB)
}
Add Option
<div id="drop-delivery-options" data-dropdown-content class="f-dropdown content table-options drop-delivery-options">
<ul>
<li>Add Deposit Account</li>
<li>Add Cash Pickup</li>
<li>Send to Card</li>
<li>Add Home Delivery</li>
</ul>
</div>
You can use the data-dropdown attribute to select the select element, then use appendTo() to append it to the a. Note though that given your example you will end up with nested a elements, which is invalid. You should look to change the parent a element to something else.
$('.button').click(function() {
$('#' + $(this).data('dropdown')).appendTo(this);
});
Working example

Get next element with class (while ommitting others)

I have this code:
var toLoad = $('.sidebar').find('.active').next('li.list-element').attr('data-id');
Which should detect the next element after my .active with list-element class. It doesn't. The problem is, I have a list like this:
<li class="list-element active">...</li>
<li class="list-element">...</li>
<li class="ads">...</li>
<li class="list-element">...</li>
<li class="list-element">...</li>
And when I get to ads, my script stops. What can I do?
.next() will only target the next element. You need to use .nextAll() along with :first or :eq(0) to target the next first sibling with the required class:
var toLoad = $('.sidebar').find('.active').nextAll('li.list-element:first').attr('data-id')
The problem is your understanding of the .next() method is wrong, it does not return the element element matching the selector, it will return the next sibling element only if it matches the passed selector
One easy solution is to find all the next elements then use the first one in the set
var toLoad = $('.sidebar').find('.active').nextAll('li.list-element:eq(0)').attr('data-id');
Jquery next()
Get the immediately following sibling of each element in the set of
matched elements. If a selector is provided, it retrieves the next
sibling only if it matches that selector.
So, when you write
$('.sidebar').find('.active')
That will find one element, the li with the class active and .next() can only select from within that group.
You could, however, use just one CSS selector to find the next element from the .active one like so:
$('.sidebar .active ~ li.list-element:first').attr('data-id')
~ is the general sibling selector that matches elements that are after the original element (.active) and share a parent (.sidebar).

Jquery select previous element with class

I have 3 elements:
<div class='first'>First</div>
<div class='second'>Second</div>
<div class='target'>Target</div>
on click on target div I test .prev() function in my js
$(document).on('click','.target',function(){
console.log($(this).prev().html());
console.log($(this).prev('.first').html());
});
Output is like: 'Second undefined', but should be like: 'second first' if I understand right the parameter of .prev() usage.
How can I get first previous element with certain class then?
Here is fiddle for you: http://jsfiddle.net/0fzgzce5/
From jQuery docs,
.prev()
Description: Get the immediately preceding sibling of each element in
the set of matched elements, optionally filtered by a selector.
To select all preceding sibling elements, rather than just the
preceding adjacent sibling, use the .prevAll() method.
http://api.jquery.com/prevAll/
So you should use console.log($(this).prevAll('.first').html());
You can make use of sibling() which will return the element with specific class and at same level as calling elment. But make sure that there is no same div after target
$(document).on('click','.target',function(){
console.log($(this).siblings('.second').html());
console.log($(this).siblings('.first').html());
});
DEMO
OR you can use prevAll()
$(document).on('click','.target',function(){
console.log($(this).prevAll('.second').html());
console.log($(this).prevAll('.first').html());
});
DEMO
Use prevAll() instead of prev()
$(document).on('click', '.target', function() {
alert($(this).prevAll('.second').html());
alert($(this).prevAll('.first').html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='first'>First</div>
<div class='second'>Second</div>
<div class='target'>Target</div>
You can use also $("div:eq(3)") to get the exact element. Best example is $("ul li:eq(3)")
In your second console.log(), yous this is still .target and it does not have .first class so it is saying undefined.
To get the first dive, do:
console.log($(this).prev().prev().html());
Jquery .prev() always get immediate preceding sibling.
if you pass a selector as parameter it will filter the preceding element to match with, if it did not match it will return undefined, in your case this is happening
$('.target').prev().html()
is same as
$('.target').prev('.second').html();
which will return "Second"
If you pass any selector other than '.second' it alway return undefined so, your case
$('.target').prev('.first').html();
is as exprected, returning undefined because '.first' is not matching with preceding element selector.
Update:
if you want to get First the use
$('.target').prev().prev().html();

How to add class to particular li?

I have this HTML:
<ul class="how-long">
<li value="1">Any</li>
<li value="1">1 day</li>
<li value="2">Week end</li>
<li value="7">1 Week</li>
<li value="14">2 Week</li>
<li value="21">3 Week</li>
</ul>
On document ready I want to add new class to the 4th li element.
This is what I tried:
$(".how-long li").slice(3).addClass('change-color');
If I put an alert as:
alert($(".how-long li").slice(3).html());
it gives me 1 week which is right, but when I addclass the class is added to all li after 4th li.
I want to this without adding ID to each li element.
I can hard code class in li element directly but I want to do it dynamicaly using jQuery.
To do it in one selector, use nth-child or eq:
nth-child is considerably faster, see my jsPerf here: http://jsperf.com/nth-child-vs-eq
nth-child:
$(".how-long li:nth-child(4)").addClass('change-color');
eq:
$(".how-long li:eq(3)").addClass('change-color');
The fundamental difference is that nth-child will give you the 4th element of every item with that class (regardless of whether it is a child of the current item), whereas eq will give you the children on the current item.
$(".how-long li").eq(3).addClass('change-color');
slice doesn't return a jQuery object, therefore you can't use the method addClass.
The right way to do what you intend is:
by index:
$(".how-long li").eq(3).addClass('change-color');
by referencing value:
$(".how-long li[value=7]").addClass('change-color');
If you want to use slice method you need to specify end attribute which you are missing
$(".how-long li").slice(3,4).addClass('change-color');
It selects the 4th because Array index's start from 0.
You could always use $('.how-long li:nth-child(4)');
More information here: http://api.jquery.com/nth-child-selector/
You can use the nth-child selector:
$(".how-long li:nth-child(4)").addClass('change-color');
alert($(".how-long li:nth-child(4)").html());
Do it this way
$(".how-long li:nth-child(4)").attr({'class':'test'});
This will add class test to the 4th li
Hope this heps

How to get the container id in javascript or in jquery

I have some HTML blocks look like
<li id="item261">
<div class="itemdesc">
<a class="icon-hide">Hide</a>
</div>
</li>
And i have a jquery like
$(document).ready(function()
{
$('.icon-hide').click(function(){
var elemId = $(this).parent().attr("id");
});
});
I need the ID of the "li" tag on click of ".icon-hide". how can i achive this? any help..
I'd suggest:
$('.icon-hide').click(function(){
var elemId = $(this).closest('li').attr('id');
});
This is because parent() as implied in the name of the method looks at the parent of the element returned by the selector (the parent is the div); whereas closest() continues up the ancestor tree to match the first selector passed to the method.
You could, instead, use parents(), however the important difference between closest() and parents() is that closest() returns zero or one match, whereas parents() will continue all the way to the root element and return every match it finds, so it can return zero, one or many matches.
Another difference is that parents() starts searching from the current element's parent, whereas closest() starts with the current element itself, so it's quite easily possible, using closest() for the method to return the current/$(this) element itself.
References:
closest().
parent().
parents().
$(this).closest('li[id]').attr('id')

Categories