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