Sorting elements by date in jQuery and JavaScript

Sorting elements by date in jQuery and JavaScript

How to sort elements by date in jQuery and JavaScript.

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.