jquery ordering and group li elements - javascript

Let's say I have a list of items under a div or UL. I want to take all the list items with the same title attribute and wrap a UL around it. The next part though is that I want that UL to be under the LI with the same attribute. So, I'm trying to group basically.
So.... I start with.....
<li>Insurance</li>
<li>Education</li>
<li>Sports</li>
<li>Construction</li>
<li title ="Insurance">Malpractice</li>
<li title ="Construction">Carpentry</li>
<li title ="Education">College</li>
<li title ="Insurance">Automobile</li>
<li title ="Education">High School</li>
<li title ="Construction">Iron Worker</li>
and I want to get to......
<li>Insurance
<ul>
<li title ="Insurance">Malpractice</li>
<li title ="Insurance">Automobile</li>
</ul>
</li>
<li>Education
<ul>
<li title ="Education">College</li>
<li title ="Education">High School</li>
</ul>
</li>
<li>Sports</li>
<li>Construction
<ul>
<li title ="Construction">Carpentry</li>
<li title ="Construction">Iron Worker</li>
</ul>
</li>
Any help would be appreciated. Obviously new to the jquery and javascript world so I'm trying to wrap my brain around this.

Input:
<div id="stuffs">
<li>Insurance</li>
<li>Education</li>
<li>Sports</li>
<li>Construction</li>
<li title ="Insurance">Malpractice</li>
<li title ="Construction">Carpentry</li>
<li title ="Education">College</li>
<li title ="Insurance">Automobile</li>
<li title ="Education">High School</li>
<li title ="Construction">Iron Worker</li>
</div>
jQuery:
​$("#stuffs li").each(function(){
$("#stuffs li[title='"+$(this).text()+"']").appendTo($(this)).wrapAll("<ul />");
});​​​​​​​​​​
Output:
<div id="stuffs">
<ul>
<li>Insurance
<ul>
<li title="Insurance">Malpractice</li>
<li title="Insurance">Automobile</li>
</ul>
</li>
<li>Education
<ul>
<li title="Education">College</li>
<li title="Education">High School</li>
</ul>
</li>
<li>Sports</li>
<li>Construction
<ul>
<li title="Construction">Carpentry</li>
<li title="Construction">Iron Worker</li>
</ul>
</li>
</ul>
</div>
Smile :-)
Demo here

// first we fetch all items without title attribute
var topLevel = $('li:not([title])');
// for each of those...
topLevel.each(function() {
var li = $(this),
// ... we get its text ...
title = li.text(),
// ... and other li elements with the corresponding title
children = $('li[title="' + title + '"]');
// if there are any...
if (children.length > 0) {
// ... create an empty list ...
var ul = $('<ul></ul>');
// ... fill it and ...
children.appendTo(ul);
// ... append it to the original li element
ul.appendTo(li);
}
});
jQuery documentation: :not(), [title], each(), appendTo()

This should work
$('#id li:not([title])').append('<ul />');
$('#id li[title]').each(function() {
$(this).appendTo('#id li:contains(' + $(this).attr('title') + ') ul');
})
A demo

Related

Move li element with javascript

I would like to move a li element after a list of li with the same class, is that possible?
$("li#anonymous_element_2").insertAfter("li.amscheckout-row:last");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="amscheckout-row"> </li>
<li class="amscheckout-row"> </li>
<li class="amscheckout-row"> </li>
<li class="fields" id="anonymous_element_2"> </li>
<li class="amscheckout-row"> </li>
<li class="amscheckout-row"> </li>
<li class="amscheckout-row"> </li>
<li class="amscheckout-row"> </li>
jQuery has a built in last() function:
var elementToMove = $('#anonymous_element_2');
var targetPosition = $('.amscheckout-row').last();
elementToMove.insertAfter(targetPosition);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="amscheckout-row">1</li>
<li class="amscheckout-row">2</li>
<li class="amscheckout-row">3</li>
<li class="fields" id="anonymous_element_2">4</li>
<li class="amscheckout-row">5</li>
<li class="amscheckout-row">6</li>
<li class="amscheckout-row">7</li>
<li class="amscheckout-row">8</li>
Yes you can!
The method that should fit your requirements is: after.
If I understand you want to "move" and, to do that, you have to "remove/add" the element into the list of values.
I suggest you to try this code:
var $liToAppend = $('li#anonymous_element_2');
var $lastLi = $('ul li:last'); // I suppose you are using the root tag UL!
// The final solution:
$liToAppend.remove();
$lastLi.after($liToAppend);
With jQuery you can to this in lot of ways:
$('li#anonymous_element_2').remove().appendTo('ul');
Should work too!
Try This
<script>
$("<li>Hello world!</li>").insertAfter(".amscheckout-row:last")
</script>

How to sort list items based on id attribute using jquery?

Hello so I have this problem, I use magento and my I can't find a place how to switch my tabs in position so I thought JQuery could come in hand. So this is what i have as an example
<li id="tab-4">
<li id="tab-3">
<li id="tab-2">
<li id="tab-1">
And i need to make it
<li id="tab-1">
<li id="tab-2">
<li id="tab-3">
<li id="tab-4">
Is there a fast way to do it? Or I have to do it one by one?
I guess you have an <ul> around you <li>
ul = $('ul'); // your parent ul element
ul.children().each(function(_,li){ul.prepend(li)})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id="tab-4">4</li>
<li id="tab-3">3</li>
<li id="tab-2">2</li>
<li id="tab-1">1</li>
</ul>
Pure JS solution.
var a = document.getElementsByTagName('li');
var b = document.getElementById('list');
var arr = [];
Array.from(a).forEach(v => arr.push(v));
arr.reverse().forEach(v => b.append(v));
<ul id='list'>
<li id="tab-4">4</li>
<li id="tab-3">3</li>
<li id="tab-2">2</li>
<li id="tab-1">1</li>
</ul>
Also, for a sollution working (actually sorting) regardless of the initial order you can use sort() and append like this:
$("ul li").sort(function(a,b){
if(a.id.substring(4, 5) < b.id.substring(4, 5)) {
return -1;
} else {
return 1;
}
}).each(function() { $('ul').append(this);});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id="tab-4">4</li>
<li id="tab-1">1</li>
<li id="tab-3">3</li>
<li id="tab-2">2</li>
</ul>
$(".list > li").detach().sort(function(a, b) {
return +a.id.replace("tab-","") - b.id.replace("tab-","") ;
}).appendTo("ul.list");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list">
<li id="tab-3">3
<li id="tab-4">4
<li id="tab-2">2
<li id="tab-1">1
</ul>
If your HTML code like this you can write your code using detach and a single appendTo like this.
More about detach(): https://www.w3schools.com/jquery/html_detach.asp

Show first level children of a nested ul li using jquery

I have an HTML file like this:
JS:
function functionName(event) {
event.stopPropagation();
var item = event.data.param;
document.getElementById("list").innerHTML = item;
}
$(document).ready(function() {
$("li").each(function() {
$(this).on('click', {param: this.id}, functionName);
});
});
HTML:
<div id="main">
<div id="tree">
<ul class="xyz">
<li class="hide">AVC</li>
<li class="hide">Anna</li>
<li class="hide">Peter</li>
<li id="foo1">Gary
<ul class="xyz">
<li class="hide">John</li>
<li class="hide">Anna</li>
<li id="foo2">Briton
<ul class="xyz">
<li class="hide">gg</li>
<li class="hide">hh</li>
<li id="foo3">Layla
<ul class="xyz">
<li class="hide">gg</li>
<li class="hide">hh</li>
<li id="foo4">Undertaker
<ul class="xyz">
<li class="hide">gg</li>
<li class="hide">hh</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div id="list"></div>
</div>
I have two div tags whose id is receptively tree and list. Tree div contains the nested ul li tags and each li have unique id.
I want to show the first level children of a ul li tag. For example, when I am clicking on Gary, it should show the first level children ( John, Anna, Britton) in right div i.e. list.
Right now I am able to get the id of ul li element in list div when clicking any item.
How can I traverse the first level children of clicking element using jquery/javascript and display them in list div?
Thanks
Try using find() ,> ul selects the direct descendant
$('li[id^="foo"]').click(function(e){
e.stopPropagation();
var x = $(this).last().find(' > ul').clone().find('ul').remove().end();
console.log(x[0])
$('#list').html(x);
$('#list .hide').show();
});
simple demo : https://jsfiddle.net/sk30mwud/4/
'$('#tree').on('click', 'li', function(){
$(this).find('> ul > li').toggleClass('hide');
return false;
})'
Can you please take a look at this approach:
It uses .contents().get(0).nodeValue to fetch the text present in child li nodes and not from its childerns if any.
function functionName(event) {
event.stopPropagation();
var item = event.data.param;
var names = [];
$("#" + item).children("ul").children("li").each(function() {
names.push($(this).contents().get(0).nodeValue);
});
$("#list").text(names.join(","));;
}
$(document).ready(function() {
$("li").each(function() {
$(this).on('click', {
param: this.id
}, functionName);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="main">
<div id="tree">
<ul class="xyz">
<li class="hide">AVC</li>
<li class="hide">Anna</li>
<li class="hide">Peter</li>
<li id="foo1">Gary
<ul class="xyz">
<li class="hide">John</li>
<li class="hide">Anna</li>
<li id="foo2">Briton
<ul class="xyz">
<li class="hide">gg</li>
<li class="hide">hh</li>
<li id="foo3">Layla
<ul class="xyz">
<li class="hide">gg</li>
<li class="hide">hh</li>
<li id="foo4">Undertaker
<ul class="xyz">
<li class="hide">gg</li>
<li class="hide">hh</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div id="list"></div>
</div>

How to iterate through each parent list items in jquery?

I just started working with jQuery and I'm running into a bit of a snag with iterating through each parent UL's list items.
I have a simple accordion menu where I'm adding transition-delay inline style to each individual list item. The issue I have is that I'm not sure how to iterate through each set of parent's list items.
Below is an example of what is occurring on every list item.
<ul class="sub-menu">
<li style="transition-delay: 0ms;></li>
<li style="transition-delay: 25ms;>
<ul class="sub-menu">
<li style="transition-delay: 50ms;>
<li style="transition-delay: 75ms;>
<li style="transition-delay: 100ms;>
</ul>
</li>
<li style="transition-delay: 125ms;></li>
<li style="transition-delay: 150ms;></li>
<li style="transition-delay: 175ms;></li>
</ul>
This is what I'm looking to achieve:
<ul class="sub-menu">
<li style="transition-delay: 0ms;></li>
<li style="transition-delay: 25ms;>
<ul class="sub-menu">
<li style="transition-delay: 0ms;>
<li style="transition-delay: 25ms;>
<li style="transition-delay: 50ms;>
</ul>
</li>
<li style="transition-delay: 50ms;></li>
<li style="transition-delay: 75ms;></li>
<li style="transition-delay: 100ms;></li>
</ul>
This is what my jQuery looks like:
$('ul.mobile-menu li.menu-item-has-children ul.sub-menu li').each(function(i){
$(this).css({ 'transition-delay': (i*25)+"ms" });
});
Any help would greatly be appreciated as I am just getting started with jQuery. I created a codepen so you can see the menu in action and visually see the issue.
http://codepen.io/creativenauts/pen/wGLqPg
Here is my approach:
$('.sub-menu').each(function() {
// $(this) = single ul element
$(this).children('li').each(function(idx, el){
// idx = index of current list [0 ... number]
// $(el) = single li element
$(el).css('transition-delay', (idx * 25) + 'ms');
});
});
But in this use case (w.r.t. the size of the list) you can and should use CSS, something like this.
You could use .index(), which gives an element's position among its siblings:
$('ul.mobile-menu li.menu-item-has-children ul.sub-menu li').each(function(){
$(this).css({ 'transition-delay': ($(this).index()*25)+"ms" });
});
Like this:
$('ul.mobile-menu li.menu-item-has-children ul.sub-menu').each(function(j, subMenu){
$(subMenu).children('li').each(function(i, li){
$(li).css('transition-delay', (i*25)+'ms')
})
});

Display nested list over hovering at parent list

I have a menu structure in which sub menus are present as nested lists like this
<nav>
<ul>
<li class="itm">A
<ul>
<li>One</li>
<li>Two
<ul>
<li>Menu Item</li>
<li> Menu Item </li>
<li> Menu Item </li>
</ul>
</li>
<li> Three </li>
<li> Four </li>
</ul>
</li>
<li class="icon"><span class="img"></span></li>
<li class="itm">B</li>
<li class="itm">C</li>
</ul>
</nav>
Nowi want to show the sub menu (sub list) when the cursor hovers over the parent li and for that I am doing this:
$('nav ul li').hover(function () {
console.log(this);
$(this > ul).fadeIn();
}, function () {
$(this > ul).fadeOut();
});
But on hover it showing this error in JS Console: Uncaught ReferenceError: ul is not defined
Your selector is combining this, which is a literal, and what should be a string in a selector (> ul). ul is being treated as a variable, and the ul variable doesn't exist.
Try this:
http://jsfiddle.net/cyzsw/
$(this).children('ul').fadeIn();

Categories