During the last month I've been writing a lot of JavaScript code for three interesting projects. One of these projects required the implementation of a client-side filter to sort WordPress posts
by date without refreshing the page. The solution I've found is pretty simple: rewrite the HTML structure by using Unix timestamps as parameters for sorting elements. Another solution is obviously
AJAX: you simply pass the keywords ASC
or DESC
to PHP and the server-side script will return an HTML string as the output of an SQL query.
jQuery implementation
(function( $ ) {
$.sortByDate = function( elements, order ) {
var arr = [];
/* Create an array of objects containing the HTML
* of each element and its current timestamp.
*/
elements.each(function() {
var obj = {},
$el = $( this ),
// change <time> to whichever element contains the element's date
time = $el.find( "time" ).text(),
date = new Date( $.trim( time ) ),
timestamp = date.getTime(); // Unix timestamp
obj.html = $el[0].outerHTML; // The whole HTML string of an element
obj.time = timestamp;
arr.push( obj );
});
// Sort the array using the timestamp
var sorted = arr.sort(function( a, b ) {
if( order == "ASC" ) {
return a.time > b.time;
} else {
return b.time > a.time;
}
});
return sorted;
};
})( jQuery );
JavaScript implementation
(function() {
var trim = function( str ) {
var trimmed = "";
if( typeof String.prototype.trim !== "function" ) {
trimmed = str.replace( /^\s+|\s+$/gm, "" );
} else {
trimmed = str.trim();
}
return trimmed;
};
var sortByDate = function( elements, order ) {
var arr = [];
/* Create an array of objects containing the HTML
* of each element and its current timestamp.
*/
for( var i = 0; i < elements.length; ++i ) {
var obj = {},
el = elements[i],
// change <time> to whichever element contains the element's date
time = el.querySelector( "time" ).firstChild.nodeValue,
date = new Date( trim( time ) ),
timestamp = date.getTime(); // Unix timestamp
obj.html = el.outerHTML; // The whole HTML string of an element
obj.time = timestamp;
arr.push( obj );
}
// Sort the array using the timestamp
var sorted = arr.sort(function( a, b ) {
if( order == "ASC" ) {
return a.time > b.time;
} else {
return b.time > a.time;
}
});
return sorted;
};
})();
Demo
See the Pen jQuery: sort elements by date by Gabriele Romanato (@gabrieleromanato) on CodePen.
Caveats
The main problem with this solution is that you're actually rewriting an entire document fragment from scratch. This means that the element's order in the DOM and all the events attached to the nodes must to be recreated after sorting elements.
In jQuery, plugins must be invoked again after the new HTML and DOM structure has been created. If you forget to do so, nothing will happen because plugins are no longer bound to elements.