I have a list of items,
<ul class="testList">
<li class="a">Should be grouped in a UL with id name = a</li>
<li class="b">2</li>
<li class="c">Should be grouped in a UL with id name = c</li>
<li class="c">Should be grouped in a UL with id name = c</li>
<li class="d">2</li>
<li class="e">3</li>
<li class="a">Should be grouped in a UL with id name = a</li>
</ul>
I am trying to locate duplicate LI classes and then group them into ULs.
Here is my jQuery code
$('ul.testList li').each(function(index, el) {
var li = $(this);
var cls = li.attr('class');
var match = $('li[class="' + cls + '"]');
if (match.length > 0) {
var ul = $('<ul id="'+ cls +'"></ul>');
match.appendTo(ul);
$(this).add(match).addClass('matched');
}
});
See the jsFiddle: https://jsfiddle.net/b4vFn/41/
How to get all LI elements in UL using JavaScript. In JavaScript, you can use the .getElementsByTagName () method to get all the <li> elements in <ul>. In-addition, you can use the .querySelectorAll () method also to get all the <li>. I have shared few simple examples here explaining how you can use the method to extract all the LI elements.
You can limit the result to a single or particular <ul> element only, by providing the class name of the <ul> as selector to querySelectorAll () method. In this example, let us assume I have a <ul> with class name navi.
Your li elements need to have unique IDs. Once they do, you can select all li children of the ul with the ">" operator: var ul_elem = $("#id_of_ul"); $("> li", ul_elem).click(...); OR $("#id_of_ul > li").click(...);
3 ID's have to be unique in a document, so having multiple <li>elements with the id "category"is invalid. Change that to a class or a data attribute or something else. Or just assign a class to the parent <ul>so you can easily retrieve all li's inside it.
This appends a new UL for each and removes the original. Also assumes that there will only ever be one class on these li. Also assumes there can be no other similar ID's in page
$('ul.testList li').each(function(index, el) {
var li = $(this),
cls = li.attr('class'),
$parent=$('#'+cls);
// if new parent doesn't exist create it
if(!$parent.length){
$parent = $('<ul id="'+cls+'">').appendTo('body');
}
$parent.append(li.addClass('matched'))
});
// remove original
$('ul.testList').remove()
DEMO
At first glance, I'd suggest:
// finding all direct children of the <ul> with the class 'testList'
// which are both <li> elements and have a 'class' attribute,
// iterating over them using the each() method:
$('ul.testList > li[class]').each(function () {
// if a <ul> already exists with the class-name of the
// current <li> element over which we're iterating
// (which would lead to a truthy non-zero length):
if ($('ul.' + this.className).length) {
// we append this <li> element to the found <ul>:
$(this).appendTo($('ul.' + this.className));
} else {
// otherwise we create a <ul> element:
$('<ul>', {
// give it the class-name of the current <li> element:
'class': this.className
// wrap it (the created <ul>) with an <li> element:
}).wrap('<li></li>')
// append the <ul> (wrap returns the original node) to
// the current parent-node of the <li>:
.appendTo(this.parentNode)
// and append the original <li> node (appendTo also returns
// the original node) to the <ul>:
.append(this);
}
// adding the 'matched' class-name to the current <li>
// element:
this.classList.add('matched');
});
$('ul.testList > li[class]').each(function() {
if ($('ul.' + this.className).length) {
$(this).appendTo($('ul.' + this.className));
} else {
$('<ul>', {
'class': this.className
}).wrap('<li></li>').appendTo(this.parentNode).append(this);
}
this.classList.add('matched');
});
.matched {
color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="testList">
<li class="a">should be red and grouped in a UL with id name = a</li>
<li class="b">2</li>
<li class="c">should be red and grouped in a UL with id name = c</li>
<li class="c">should be red and grouped in a UL with id name = c</li>
<li class="d">2</li>
<li class="a">should be red and grouped in a UL with id name = a</li>
</ul>
JS Fiddle demo.
References:
append().appendTo().each().Try using .appendTo() , .append() , .is() . Note , if li className is not repeated within .testList , li is not given matched class , not appended to new ul element
$("ul.testList li").each(function(i, el) {
if (!$(el).parent().find("#" + this.className).is("*")
// if `.testList` has another `li` element having `this.className`
&& $(el).parent().find("." + this.className).not(this).is("*")) {
$(el).parent()
.append(
$("<li />", {
html: $("<ul />", {
id: el.className
}).append($(el).addClass("matched"))[0].outerHTML
})
);
} else {
$(el).appendTo("#" + this.className).addClass("matched")
}
})
.matched {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="testList">
<li class="a">should be grouped in a UL with id name = a</li>
<li class="b">2</li>
<li class="c">should be grouped in a UL with id name = c</li>
<li class="c">should be grouped in a UL with id name = c</li>
<li class="d">2</li>
<li class="e">3</li>
<li class="a">should be grouped in a UL with id name = a</li>
</ul>
You can do something like this
var cls = [];
// getting unique class names
$('.testList li').attr('class', function(i, v) {
if (cls.indexOf(v) == -1) cls.push(v);
});
// iterating over class name and creating ul and appending
for (var i = 0; i < cls.length; i++) {
// creating ul with id as class name
var ul = $('<ul/>', {
id: cls[i]
});
// selecting all elements with classname and appending it to ul
$('.' + cls[i]).appendTo(ul);
// creating new li to add to main ul, setting html as created ul.
$('<li/>', {
html: ul
}).appendTo('.testList');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="testList">
<li class="a">should be red and grouped in a UL with id name = a</li>
<li class="b">2</li>
<li class="c">should be red and grouped in a UL with id name = c</li>
<li class="c">should be red and grouped in a UL with id name = c</li>
<li class="d">2</li>
<li class="a">should be red and grouped in a UL with id name = a</li>
</ul>
Or combined version
var cls = [];
$('.testList li').attr('class', function(i, v) {
if (cls.indexOf(v) == -1) cls.push(v);
});
for (var i = 0; i < cls.length; i++) {
$('<li/>', { // mail ul list item
html: $('<ul/>', { // it's content as new ul
id: cls[i], // setting ul id as class name
html: $('.' + cls[i]) // appending parent ul to new ul
})
}).appendTo('.testList'); // appending li to parent ul
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="testList">
<li class="a">should be red and grouped in a UL with id name = a</li>
<li class="b">2</li>
<li class="c">should be red and grouped in a UL with id name = c</li>
<li class="c">should be red and grouped in a UL with id name = c</li>
<li class="d">2</li>
<li class="a">should be red and grouped in a UL with id name = a</li>
</ul>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With