Simple Table sorting - jQuery - sortElements.js

HTML

<script src="https://rawgithub.com/padolsey/jQuery-Plugins/master/sortElements/jquery.sortElements.js"></script>
<table>
    <tr>
        <!--<th id="facility_header">Facility name</th>
        <th id="phone" >Phone #</th>
        <th id="city_header">City</th>
        <th id="spec">Speciality</th>-->
        <th class="sortable">Facility name</th>
        <th class="sortable" >Phone #</th>
        <th class="sortable">City</th>
        <th class="sortable">Speciality</th>
    </tr>
    <tr>
        <td>CCC</td>
        <td>00001111</td>
        <td>Amsterdam</td>
        <td>GGG</td>
    </tr>
    <tr>
        <td>JJJ</td>
        <td>55544444</td>
        <td>London</td>
        <td>MMM</td>
    </tr>
    <tr>
        <td>AAA</td>
        <td>33332222</td>
        <td>Paris</td>
        <td>RRR</td>
    </tr>
    <tr>
        <td>KKK</td>
        <td>77772222</td>
        <td>Bucharest</td>
        <td>PPP</td>
    </tr>
</table>

CSS

td, th { border: 1px solid #111; padding: 6px; }
th { 
    font-weight: 700;
    
}


/* sortElements.js source */
/**
 * jQuery.fn.sortElements
 * --------------
 * @author James Padolsey (http://james.padolsey.com)
 * @version 0.11
 * @updated 18-MAR-2010
 * --------------
 * @param Function comparator:
 *   Exactly the same behaviour as [1,2,3].sort(comparator)
 *   
 * @param Function getSortable
 *   A function that should return the element that is
 *   to be sorted. The comparator will run on the
 *   current collection, but you may want the actual
 *   resulting sort to occur on a parent or another
 *   associated element.
 *   
 *   E.g. $('td').sortElements(comparator, function(){
 *      return this.parentNode; 
 *   })
 *   
 *   The <td>'s parent (<tr>) will be sorted instead
 *   of the <td> itself.
 */
/*jQuery.fn.sortElements = (function(){
    
    var sort = [].sort;
    
    return function(comparator, getSortable) {
        
        getSortable = getSortable || function(){return this;};
        
        var placements = this.map(function(){
            
            var sortElement = getSortable.call(this),
                parentNode = sortElement.parentNode,
                
                // Since the element itself will change position, we have
                // to have some way of storing it's original position in
                // the DOM. The easiest way is to have a 'flag' node:
                nextSibling = parentNode.insertBefore(
                    document.createTextNode(''),
                    sortElement.nextSibling
                );
            
            return function() {
                
                if (parentNode === this) {
                    throw new Error(
                        "You can't sort elements if any one is a descendant of another."
                    );
                }
                
                // Insert before flag:
                parentNode.insertBefore(this, nextSibling);
           ...

JavaScript

var table = $('table');
    
 //   $('#facility_header, #city_header, #phone, #spec')
$('.sortable')
        .wrapInner('<span title="sort this column"/>')
        .each(function(){
            
            var th = $(this),
                thIndex = th.index(),
                inverse = false;
            
            th.click(function(){
                
                table.find('td').filter(function(){
                    
                    return $(this).index() === thIndex;
                    
                }).sortElements(function(a, b){
                    
                    return $.text([a]) > $.text([b]) ?
                        inverse ? -1 : 1
                        : inverse ? 1 : -1;
                    
                }, function(){
                    
                    // parentNode is the element we want to move
                    return this.parentNode; 
                    
                });
                inverse = !inverse;    
            });    
        });