Skip to content Skip to sidebar Skip to footer

Sort Child Div Based On Data Attribute

Trying to sort children div based on data attributes The html code below is being generated by a CM and the data can be retrieved in any random order. the html code is

Solution 1:

EDIT: I missed the jQuery tag... leaving the answer still.

var productCt = document.getElementById('ProductContainer'),
    reInsertProductCt = tempRemove(productCt);


[].slice.call(productCt.children)
  .sort(function (a, b) {
    var aName = a.dataset.name,
        bName = b.dataset.name;
  
    return aName < bName? -1 : +(aName > bName);
  })
  .forEach(productCt.appendChild.bind(productCt));

reInsertProductCt();





functiontempRemove(el) {
    var parent = el.parentNode,
        nextSibling = el.nextSibling;
  
    parent.removeChild(el);
  
    returnfunction () {
        if (nextSibling) parent.insertBefore(el, nextSibling);
        else parent.appendChild(el);
    };
}
<divid="ProductContainer"class="row"><divid="1232132"data-name="B"data-category="Category_A"class="explore-cell"><h>TEST NAME B</h><p>TEST</p></div><divid="123"data-name="A"data-category="Category_A"class="explore-cell"><h>TEST NAME A</h><p>TEST</p></div><divid="1232152351"data-name="C"data-category="Category_A"class="explore-cell"><h>TEST NAME C</h><p>TEST</p></div><divid="12342341"data-name="E"data-category="Category_B"class="explore-cell"><h>TEST NAME E</h><p>TEST</p></div><divid="1325321"data-name="D"data-category="Category_B"class="explore-cell"><h>TEST NAME D</h><p>TEST</p></div></div>

Solution 2:

You can use .sort method like this

var$wrapper = $('#ProductContainer');

$wrapper.find('.explore-cell').sort(function (a, b) {
    return a.getAttribute('data-name') > b.getAttribute('data-name');
})
.appendTo( $wrapper );

But I don't sure about the cross browsing support

Solution 3:

Calling only sort on them won't actually visually change the DOM, it just returns a sorted collection. So basically you just need to get the collection, sort it, then return it. Something like this should work:

$('#ProductContainer > div').detach().sort(function (a, b) {
  var contentA = $(a).data('name');
  var contentB = $(b).data('name');
  return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0;
}).appendTo('#ProductContainer');

You'll want to make sure that you use the detach() method and not remove(), as detach() will retain all of the data and events associated with the collection items.

Solution 4:

Why choose to sort by category or by name when you can sort by both?

I tried to write a generic multisort function generator, which should also work with the native array sort function.

JSFIDDLE HERE

A function that generates the multisort, it takes two parameters.

  1. The column priority list order (first by category or by name? You decide).
  2. I also wanted a way to provide values for columns (since you might not retrieve them the same way for each of them), it is an object that describes for each column a function to retrieve data.

Here it is

functiongetMultisortFn(columns, provideColumnData) {
    returnfunction (a, b) {
        for (var i = 0, l = columns.length; i < l; i++) {
            var column = columns[i];
            var aColumnData = provideColumnData[column.name](a, column.name);
            var bColumnData = provideColumnData[column.name](b, column.name);
            if (aColumnData !== bColumnData) {
                if (column.asc) {
                    returnString.prototype.localeCompare.call(aColumnData, bColumnData);
                }

                returnString.prototype.localeCompare.call(bColumnData, aColumnData);    
            }
        }
    };
}

Now this is the part where you actually use the multisort generated

functionretrieveDataAttribute(item, attribute) {
    return $(item).data(attribute);
}

var$container = $('#ProductContainer'); 
var$products = $container.find('div');

var multisort = getMultisortFn([{
        name: 'category',
        asc: false
    }, {
        name: 'name',
        asc: true
    }], {
        name: retrieveDataAttribute,
        category: retrieveDataAttribute
    });



$products.sort(multisort);

And finally the DOM manipulation to apply the new order

$products.detach().appendTo($container);

EDITthanks toplalx:

$container.detach().append($products).appendTo('section.box.explore');

Post a Comment for "Sort Child Div Based On Data Attribute"