jQuery add class numericly up to x and start over - javascript

With jQuery I can add consecutive numeric classes to list items like so:
$(".item-list li").each(function (i) {
$(this).addClass("item-list-" + i);
});
So with an HTML structure as such:
<ul class="item-list">
<li>an item</li>
<li>another item</li>
<li>another item</li>
<li>another item</li>
<li>another item</li>
</ul>
... this will output nice list item classes in numeric order:
class="item-list-0"
class="item-list-1"
... etc...
What I'm trying to do is number of to 4 items and then start the numbering over at zero again. I figured I'd have to use nth child within my numeric + i code but I just have not been able to find any documentation on this. Everything that I've found relates to finding an nth element but not starting a count over after a specified amount.

you can do this using modulus operator itself:
$(".item-list li").each(function (i) {
$(this).addClass("item-list-" + (i%4));
});
Output markup
<ul class="item-list">
<li class="item-list-0">an item</li>
<li class="item-list-1">another item</li>
<li class="item-list-2">another item</li>
<li class="item-list-3">another item</li>
<li class="item-list-0">another item</li>
<li class="item-list-1">another item</li>
<li class="item-list-2">another item</li>
<li class="item-list-3">another item</li>
<li class="item-list-0">another item</li>
</ul>
Demo

Related

How to randomly order two synchronized lists using javascript?

Aparently shuffling an array is not so complicated:
How to randomize (shuffle) a JavaScript array?
But what if I have to (Html DOM) lists that are synchronized and I need to shuffle the order of the elements, but they should have the same final order?
For example, initial state:
<!-- List A) -->
<ul>
<li>First title</li>
<li>Second Title</li>
<li>Thrid title</li>
</ul>
<!-- List B) -->
<ul>
<li>First text</li>
<li>Second text</li>
<li>Thhird text</li>
</ul>
After shuffle:
<!-- List A) -->
<ul>
<li>Second title</li>
<li>First Title</li>
<li>Thrid text</li>
</ul>
<!-- List B) -->
<ul>
<li>Second text</li>
<li>First text</li>
<li>Third text</li>
</ul>
How can this be achieved?
Get length of items and loop through it and in loop generate random number and using generated number select an li and append it end of parent.
var ul = document.querySelectorAll("ul");
var length = ul[0].querySelectorAll("li").length;
for (var i=0; i<length; i++){
var rand = Math.floor(Math.random()*(length));
ul.forEach(function(ele){
ele.appendChild(ele.querySelectorAll("li")[rand]);
});
}
<ul>
<li>First title</li>
<li>Second Title</li>
<li>Thrid title</li>
</ul>
<ul>
<li>First text</li>
<li>Second text</li>
<li>Thhird text</li>
</ul>
Also you can use jQuery to write less code
var $ul = $("ul:first li");
$ul.each(function(){
var rand = Math.floor(Math.random()*$ul.length);
$("ul").each(function(i, ele){
$("li", ele).eq(rand).appendTo(ele);
});
});
$("button").click(function(){
var $ul = $("ul:first li");
$ul.each(function(){
var rand = Math.floor(Math.random()*$ul.length);
$("ul").each(function(i, ele){
$("li", ele).eq(rand).appendTo(ele);
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click</button>
<ul>
<li>First title</li>
<li>Second Title</li>
<li>Thrid title</li>
</ul>
<ul>
<li>First text</li>
<li>Second text</li>
<li>Thhird text</li>
</ul>
You can easily shuffle an DOM html in various number of ways. One way that is easy to understand is to convert the DOM elements into an array, then randomly splice each element out of its parent array and append them back to the parent DOM element.
In my snippet below, I used jQuery to make the code easier to read, but it can be done with native javascript just as well.
$('#shuffle').click(function(){
var items = []; // start with an empty array
$('#list_a li').each(function(i,d){
items.push(d); // add all li items into the array in their current order
});
$('#list_a').html(''); // clear the ul list
// execute this loop as many times as items.length
for(var i=items.length-1; i>=0; i--) {
var r = Math.floor(Math.random()*items.length); // pick a random array position
var item = items.splice(r,1); // take that item out of the array
$('#list_a').append(item); // append it back to the ul
}
});
ul
{
background-color: #def;
display: inline-block;
border: 1px solid grey;
padding: 30px;
border-radius: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<b>List A</b>
<ul id="list_a">
<li>First Item</li>
<li>Second Item</li>
<li>Third Item</li>
<li>Fourth Item</li>
<li>Fifth Item</li>
</ul>
<button id="shuffle">Shuffle</button>

Adding a sort function to order by class name

I am trying to get a sort function to work with the following code.
The code below filters through a list of items and groups by class name.
However, I wand to sort the order by the class of the parent ul
like so:-
<ul class="parent-section-a">
<li class="section-a">item One</li>
<li class="section-a">item Two</li>
<li class="section-a">item Three</li>
<li class="section-a">item Four</li>
</ul>
<ul class="parent-section-b">
<li class="section-b">item One</li>
<li class="section-b">item Two</li>
<li class="section-b">item Three</li>
<li class="section-b">item Four</li>
</ul>
<ul class="parent-section-c">
<li class="section-c">item One</li>
<li class="section-c">item Two</li>
<li class="section-c">item Three</li>
<li class="section-c">item Four</li>
</ul>
The code i have so far is:-
// Get all the classes
var classes = $('[class^=section]').map(function() {
return $(this).attr('class');
});
// Filter only unique ones
var uniqueClasses = $.unique(classes);
// Now group them
$(uniqueClasses).each(function(i, v)
{
$('.'+v).wrapAll('<ul class ="parent-'+v+'"></ul>');
});
Your help would be greatly appreciated
Mark
If you want to sort the order by the class of ul, this should be helping:
jQuery sort list items on class name

jQuery insert after li element with attribute [duplicate]

This question already has answers here:
How to add a list item to an existing unordered list
(14 answers)
Closed 5 years ago.
I have list:
<ul class="customList">
<li data-featured="1">First item</li>
<li data-featured="0">Another item</li>
<li data-featured="0">Last item..</li>
</ul>
How can I insert my custom <li> after featured="1"? If all featured 0, then insert as first li.. Thanks in advance.
var self = this;
self.scope.find('.customList').prepend(myCustomItem); //this code inserts in begin, not after featured items..
$(myCustomItem).insertAfter('[data-featured="1"]'); //I've tried to build something.. but this fails
Sorry for my bad English
EDIT
myCustomItem.insertAfter('[data-featured="1"]'); looks like is working, but when there is any data-featured=1, then nothing happens. Any suggestions?
Use the jQuery attribute selector [attribute=value]:
$(" <li data-featured='222'>NEW ITEM</li>").insertAfter('.customList li[data-featured="1"]');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="customList">
<li data-featured="1">First item</li>
<li data-featured="0">Another item</li>
<li data-featured="0">Last item..</li>
</ul>
Or if you want to insert it after the first li tag the, use this:
$(" <li data-featured='222'>NEW ITEM</li>").insertAfter('.customList li:first');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="customList">
<li data-featured="1">First item</li>
<li data-featured="0">Another item</li>
<li data-featured="0">Last item..</li>
</ul>
You can first use the jQuery attribute selector [attribute=value]: to check if li with data-featured="1" is exist or not. If exist then use the jQuery method .insertAfter() to insert the new li after it and if not then insert new li at the first position using .insertBefore().
if($('.customList li[data-featured="1"]').length>0)
{
$("<li data-featured='99'>NEW ITEM</li>").insertAfter('.customList li[data-featured="1"]');
}
else
{
$("<li data-featured='99'>NEW ITEM</li>").insertBefore('.customList li:first');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="customList">
<li data-featured="0">First item</li>
<li data-featured="0">Another item</li>
<li data-featured="0">Last item..</li>
</ul>
First of all i would say don't use append() when the question is about insert after an li. Check below snippet, first check the condition for data-featured=1 available or not and then prepend() or insertAfter() based on that.
var flag = false;
$('.customList li').each(function() {
if ($(this).data('featured') == '1') {
flag = true;
}
});
if (flag) {
$("<li data-featured='222'>NEW ITEM</li>").insertAfter('.customList li[data-featured="1"]');
} else {
$('.customList').prepend(" <li data-featured='222'>NEW ITEM</li>");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="customList">
<li data-featured="1">First item</li>
<li data-featured="0">Another item</li>
<li data-featured="0">Last item..</li>
</ul>
newStatus.insertAfter('[data-featured="1"]');
Works fine but just have to check for the case when the item added is the first item or not. That can be easily done by if condition.
something like this:
if($('li[data-featured="1"]') != null)
here is the example: Link

Get the size of the parent LI inside an UL?

How can I modify the below code so that I get only the parent li within the first ul and then with another variable get the sub li of the given sub ul?
$(function () {
var vULSize = $("ul li").size();
console.log(vULSize);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul>
<li>First</li>
<li>Second
<ul>
<li>Second Sub 1</li>
<li>Second Sub 2</li>
</ul>
</li>
<li>Third</li>
<li>Third
<ul>
<li>Third Sub 1</li>
<li>Third Sub 2</li>
</ul>
</li>
</ul>
Fiddle: http://jsfiddle.net/0sp9pohr/
You can ignore all li's that are descendants of an li like
$(function() {
var vULSize = $("ul li:not(li li)").size();
snippet.log(vULSize);
});
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>First</li>
<li>Second
<ul>
<li>Second Sub 1</li>
<li>Second Sub 2</li>
</ul>
</li>
<li>Third</li>
<li>Third
<ul>
<li>Third Sub 1</li>
<li>Third Sub 2</li>
</ul>
</li>
</ul>
First you need to wrap it all in something, say for instance a div with the id container. Then you can do something like this:
var vULSize = $("#container > ul > li").length;
The > selector gives you only the direct descendants.
If you want to count the number of list elements one level down, this will give you an array with the result:
var counts = $("#container > ul > li").map(function() {
return $(this).find("li").length
}).get();
As pointed out in comments, you should use .length instead of .size().

jQuery selecting the top li of a menu

Sorry for the noobish question.
I've got a menu similar to this:
<div id="navigation">
<ul>
<li>menu item</li>
<li>menu item
<ul>
<li>sub menu item</li>
<li>sub menu item
<ul>
<li>sub sub menu item</li>
<li>sub sub menu item</li>
<li>sub sub menu item</li>
</ul>
</li>
<li>sub menu item</li>
<li>sub menu item</li>
</ul>
</li>
<li>menu item</li>
<li>menu item</li>
</ul>
</div>
I'm trying to change the class for the selected page. I'm part way there with this:
$(function(){
var path = location.pathname.substring(1);
if ( path ){
$('#navigation a[href$="' + path + '"]').parent().attr('class', 'selected');
}
});
Which changes the class on the parent li. Cool. But what I really want to do is change the class on top level li. In other words if a "sub sub menu item" is selected goes all the way up the tree and changes the very first li that contains that link.
Would appreciate any help at all.
Thanks,
Andy.
You can use .parents() and :last (since they're returned in the order found...top parent is last) when looking for the <li>, like this:
$('#navigation a[href$="' + path + '"]').parents('li:last').addClass('selected');
Also .addClass() is probably what you're after here :)
$('#navigation>ul>li:has(a[href$="' + path + '"])')
use >
$('#navigation > ul > li > a[href$="' + path + '"]')

Categories

Resources