How to add class to particular li? - javascript

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

Related

jQuery: How to check if an element exists and change css property

First of all, sorry if this is a simple question. I am new to jQuery and I want to know how can I check if an element exists and if it does, change the css property.
Here is what I mean: I have the following list:
<ul class="element-rendered">
<li class="element-choice">Item A</li>
<li class="select-inline">Item B</li>
</ul>
I want to know how can I check if the class select-inline exists inside element-rendered and if it does, how can I change the css background of element-choice to blue?
I created a fiddle to reproduce this example.
Again sorry if this is a simple question but I am new to jQuery.
You can use .length to check if the element exists in DOM.
$('.element-rendered .select-inline') will select all the elements having class select-inline inside the element with class element-rendered. .length on selector will return the number of matched elements. So, number greater that one, means the element exists. Then you can use .css to set inline styles.
Demo
if ($('.element-rendered .select-inline').length) {
$('.element-choice').css('background', 'blue');
}
.element-choice {
width: 100%;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<ul class="element-rendered">
<li class="element-choice">Item A</li>
<li class="select-inline">Item B</li>
</ul>
I'll also recommend you to use class in CSS and add it to the element by using addClass.
Demo
var eR = $(".element-rendered");
if (eR.find(".select-inline").length > 0){
eR.find(".element-choice").css("color", "blue");
}
This would work for your specific example.
Find the select-line element which is a child of element-rendered.
The find all of the sibling elements with class element-choice and apply the css.
$('.element-rendered>.select-inline').siblings('.element-choice').css('background','blue')
http://jsfiddle.net/SeanWessell/hjpng78s/3/
To check if element exists could use .is() , or as suggested by #Tushar .length
var container = $(".element-rendered");
// alternatively `!!$(".select-inline", container).length`
$(".select-inline", container).is("*")
&& $(".element-choice", container).css("background", "blue");
jsfiddle http://jsfiddle.net/hjpng78s/6/
Demo
if($(".element-rendered .select-inline")[0])
$(".element-rendered .select-inline").css("background-color","red");
How can I check if the class select-inline exists inside element-rendered and if it does, how can I change the css background of element-choice to blue?
if ( $(".element-rendered > .select-inline").length ) {
$(".element-rendered > .element-choice").css({
'background-color': 'blue'
});
}
Docs:
Find the number of elements in the jQuery object.
Set one or more CSS properties for the matched element

How to get parent element?

I have this part of HTML:
<div id="menu">
<ul>
<li>Startseite</li>
<li class="active">Brillengläser</li>
<li>Komplettbrille</li>
<li>Sportbrillen</li>
<li>Marketing</li>
<li>Statistik</li>
</ul>
</div>
I want to remove class="active" parameter and set it in li tag where I have href="/pacmodule/completeglass" atribute.
First part I successfully done with jquery:
$("#menu").find("ul:first").find(".active").removeClass("active");
But I have problems with second part. This select just a tag:
$('a[href="/pacmodule/completeglass"]').parent().html();
And this all ul tag:
$('a[href="/pacmodule/completeglass"]').parent().parent().html();
How can I set class="active" attribute in li tag where href="/pacmodule/completeglass"
Thank you for help.
You do not need the html() calls. They just return the innerHTML as a string. You probably expected that would return the outerHTML (for the outerHTML use something like ...parent()[0].outerHTML)
Try this:
$('a[href="/pacmodule/completeglass"]').closest('li').addClass('active');
It will find the anchor based on the href = "/pacmodule/completeglass", then find the closest ancestor that is an LI, then add the class active to it.
closest is the most useful way to find an ancestor of a specific type. It is better than using parent() as closest copes with the HTML structure changing.
Note: If you explain the overall aim, there may be better ways to do this than searching for the link href :)
Update
You do not want to remove the previous selection with this as it is too specific:
$("#menu").find("ul:first").find(".active").removeClass("active");
try this instead:
$("#menu li.active").removeClass("active");
.closest()
$("li").removeClass("active").find($('a[href="/pacmodule/completeglass"]')).closest('li').addClass('active');
DEMO
Easily do this (into your js document):
$("#menu li").removeClass("active");
$('a[href="/pacmodule/completeglass"]').parent().addClass("active");
$("#menu").find("ul:first").find(".active").removeClass("active");
This can be made more effective writing it as:
$("#menu").find("li.active").removeClass("active");
Then the DOM dont need to search for any ul, instead it goes directly to the class .active
why don't you try this :
$("#menu").find("ul:first").find(".active").removeClass("active");
$('a[href="/pacmodule/completeglass"]').parent().addClass("active");
you might wanna check this fiddle

Select LI children from a not none-displayed UL

The title sounds strange but what I want to achieve is simple.
In a tree of uls I want to get all li children from any ul that have not the - inline - style display: none. So I found this post and I mixed with the negation function :not(). The result was:
'ul:not([style*="display: none"]) .k-item'
Where .k-item is a common class for all my li elements. That selector worked in this simple fiddle. The problem is that it doesn't works in my application. I have a screenshot of some console commands that will illustrate my scenario:
As you can see on second command, it returns some li elements that lies under an ul which haves display: none among other attributes in its inline style. Example of those unexpected li with attribute data-uid with values starting with 099d, bbca and 14d2.
I don't know what I'm doing wrong or if exists a better selector for that purpose.
I would suggest using jQuery's :visible rather than looking for something in the style string and string matching in the style string could be problematic.
$("ul:visible .k-item")
First of all get all the li and check whether its parent (ul) is visible.
jsfiddle
$('li', '#layers').each(function(){
if($(this).parent().is(":visible")){
alert($(this).text())
}
});
OR
a neat version
jsfiddle
$(".k-item:visible").each(function(){
alert($(this).text())
});
Try using
$('ul:not([style*="display: none"]) li.k-item').each(function() { alert($(this).html()) });
HTML
<ul style="display: none">
<li class="k-item">1</li>
<li class="k-item">2</li>
<li class="k-item">3</li>
</ul>
<ul>
<li class="k-item">4</li>
<li class="k-item">5</li>
<li class="k-item">6</li>
</ul>
Fiddle: http://jsfiddle.net/3M2ZM/

Using javascript, how to select an li relative to a specific other li

Given the following html list:
<ul>
...
<li>
<li> // <-- item to be selected
<li>
<li class='current'>
<li>
<li>
<li>
...
</ul>
How do I select the li two instances ahead of the li with class current?
Any pure javascript or jquery solution would be great!
Making it more generic, i.e if you want to select a li possibly(2nd or 3rd or what ever instance that appears prior to your selector), then try
$('li.current').prevAll(':eq(' + n-1 + ')');
Here n would be the instance # that you are talking about (Since it is 0 based index). In your case this would be:
$('li.current').prevAll(':eq(1)');
Do remember that prevAll returns the elements in the order starting from the selector, so you can just provide the index of the element from that position in prevAll with eq selector.
Fiddle
Very easily:
$('.current').prev().prev()
You can try
$('.current').prev().prev()
This may help...
var li=document.getElementsByTagName('li');
var i, n;
for(i=0;i<li.length;i++)
{
if(li[i].className=='current')
{
n=(i+2)%(li.length);
}
}
var x=li[n];
I have accepted an answer. My own solution first identified the index of the element to be selected:
var index = $('.current').index()-n+1;
n equals the number of items you want to be ahead of the current object. The +1 is because indexing starts at zero, yet nth-child at 1.
I then used the nth-child selector to get the right element:
$('ul li:nth-child('+index+')')

How to select next matching element?

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');

Categories