Sort Child Div Based On Data Attribute
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.
A function that generates the multisort, it takes two parameters.
- The column priority list order (first by category or by name? You decide).
- 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"