Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort list-items with subcategories

I have the following code to sort a List like this by the order attribute:

<div id="a-categories">
    <a href="blabla" order="2" class="leftCats">Cat 2</a>
    <a href="blabla" order="1" class="leftCats">Cat 1</a>
    <a href="blabla" order="4" class="leftCats">Cat 4</a>
</div>

Code:

var list = document.id('a-categories');
var listGroupObjects = document.getElementsByClassName('leftCats');

var listGroupArray = [];
for (var i = 0; i < listGroupObjects.length; ++i) {
    listGroupArray.push(listGroupObjects[i]);
}

listGroupArray.sort(function (a, b) {
    return (a.getAttribute('order') - b.getAttribute('order'));
});

for (var i = 0; i < listGroupArray.length; i++) {
    list.removeChild(listGroupArray[i]);
}

for (var i = 0; i < listGroupArray.length; i++) {
    list.appendChild(listGroupArray[i]);
}

This works very finde. But now I have this:

<div id="a-categories">
    <a href="blabla" order="2" class="leftCats">Cat 2</a>
    <a href="blabla" order="1" class="leftCats">Cat 1</a>
    <a href="blabla" order="1" parOrder="2" class="leftCats">Cat 2.1</a>
    <a href="blabla" order="2" parOrder="2" class="leftCats">Cat 2.2</a>
    <a href="blabla" order="4" class="leftCats">Cat 4</a>
</div>

It's like subitems. So every item having the "parOrder" attribute is a child. And parOrder gives the order of the parent-item and order of itself.

How can I order it, so that the Childs are ordered itself under the parent item. In this example it would be:Edit:

<div id="a-categories">
    <a href="blabla" order="1" class="leftCats">Cat 1</a>
    <a href="blabla" order="2" class="leftCats">Cat 2</a>
    <a href="blabla" order="1" parOrder="2" class="leftCats">Cat 2.1</a>
    <a href="blabla" order="2" parOrder="2" class="leftCats">Cat 2.2</a>
    <a href="blabla" order="4" class="leftCats">Cat 4</a>
</div>
like image 838
progNewbie Avatar asked Feb 01 '26 07:02

progNewbie


1 Answers

You can sort by order only those items which have no parOrder (1-level nodes). Then, while appending items without parOrder, you can find items which are "child" items for the current, sort them by order and append. Just a simple nested loop.

By the way, you don't need to removeChild if you want to sort items. Executing appendChild on existing DOM element will remove it from the original location before inserting in a new location.

Something like this:

var list = document.getElementById('a-categories');
var listGroupObjects = [].slice.call(document.querySelectorAll('.leftCats:not([parOrder])'));

listGroupObjects.sort(function (a, b) {
    return (a.getAttribute('order') - b.getAttribute('order'));
});

for (var i = 0; i < listGroupObjects.length; i++)
{
    list.appendChild(listGroupObjects[i]);

    var sublistGroupObjects = [].slice.call(list.querySelectorAll(".leftCats[parOrder='" + listGroupObjects[i].getAttribute('order') + "']"));

    sublistGroupObjects.sort(function (a, b) {
        return (a.getAttribute('order') - b.getAttribute('order'));
    });

    for (var j = 0; j < sublistGroupObjects.length; j++) 
    {
        list.appendChild(sublistGroupObjects[j]);    
    }
}

In other words, it sorts 1-level nodes and gets 1, 2, 4. Then, it appends 1 - no child items; appends 2 - two child nodes are being sorted and inserted after the current one; appends 4.

Of course, this code can be easily optimized by removing a duplicating code which sorts items. It's up to your fantasy. Here is just a working JSFiddle Demo.

like image 132
Yeldar Kurmangaliyev Avatar answered Feb 02 '26 21:02

Yeldar Kurmangaliyev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!