Sorting table rows according to table header column using javascript or jquery

129,514

Solution 1

You might want to see this page:
http://blog.niklasottosson.com/?p=1914

I guess you can go something like this:

DEMO:http://jsfiddle.net/g9eL6768/2/

HTML:

 <table id="mytable"><thead>
  <tr>
     <th id="sl">S.L.</th>
     <th id="nm">name</th>
  </tr>
   ....

JS:

//  sortTable(f,n)
//  f : 1 ascending order, -1 descending order
//  n : n-th child(<td>) of <tr>
function sortTable(f,n){
    var rows = $('#mytable tbody  tr').get();

    rows.sort(function(a, b) {

        var A = getVal(a);
        var B = getVal(b);

        if(A < B) {
            return -1*f;
        }
        if(A > B) {
            return 1*f;
        }
        return 0;
    });

    function getVal(elm){
        var v = $(elm).children('td').eq(n).text().toUpperCase();
        if($.isNumeric(v)){
            v = parseInt(v,10);
        }
        return v;
    }

    $.each(rows, function(index, row) {
        $('#mytable').children('tbody').append(row);
    });
}
var f_sl = 1; // flag to toggle the sorting order
var f_nm = 1; // flag to toggle the sorting order
$("#sl").click(function(){
    f_sl *= -1; // toggle the sorting order
    var n = $(this).prevAll().length;
    sortTable(f_sl,n);
});
$("#nm").click(function(){
    f_nm *= -1; // toggle the sorting order
    var n = $(this).prevAll().length;
    sortTable(f_nm,n);
});

Hope this helps.

Solution 2

use Javascript sort() function

var $tbody = $('table tbody');
$tbody.find('tr').sort(function(a,b){ 
    var tda = $(a).find('td:eq(1)').text(); // can replace 1 with the column you want to sort on
    var tdb = $(b).find('td:eq(1)').text(); // this will sort on the second column
            // if a < b return 1
    return tda < tdb ? 1 
           // else if a > b return -1
           : tda > tdb ? -1 
           // else they are equal - return 0    
           : 0;           
}).appendTo($tbody);

If you want ascending you just have to reverse the > and <

Change the logic accordingly for you.

FIDDLE

Solution 3

Offering an interactive sort handling multiple columns is nothing trivial.

Unless you want to write a good amount of code handling logic for multiple row clicks, editing and refreshing page content, managing sort algorithms for large tables… then you really are better off adopting a plug-in.

tablesorter, (with updates by Mottie) is my favorite. It’s easy to get going and very customizable. Just add the class tablesorter to the table you want to sort, then invoke the tablesorter plugin in a document load event:

$(function(){
    $("#myTable").tablesorter();
});

You can browse the documentation to learn about advanced features.

Solution 4

I think this might help you:
Here is the JSFiddle demo:

And here is the code:

var stIsIE = /*@cc_on!@*/ false;
sorttable = {
  init: function() {
    if (arguments.callee.done) return;
    arguments.callee.done = true;
    if (_timer) clearInterval(_timer);
    if (!document.createElement || !document.getElementsByTagName) return;
    sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
    forEach(document.getElementsByTagName('table'), function(table) {
      if (table.className.search(/\bsortable\b/) != -1) {
        sorttable.makeSortable(table);
      }
    });
  },
  makeSortable: function(table) {
    if (table.getElementsByTagName('thead').length == 0) {
      the = document.createElement('thead');
      the.appendChild(table.rows[0]);
      table.insertBefore(the, table.firstChild);
    }
    if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
    if (table.tHead.rows.length != 1) return;
    sortbottomrows = [];
    for (var i = 0; i < table.rows.length; i++) {
      if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
        sortbottomrows[sortbottomrows.length] = table.rows[i];
      }
    }
    if (sortbottomrows) {
      if (table.tFoot == null) {
        tfo = document.createElement('tfoot');
        table.appendChild(tfo);
      }
      for (var i = 0; i < sortbottomrows.length; i++) {
        tfo.appendChild(sortbottomrows[i]);
      }
      delete sortbottomrows;
    }
    headrow = table.tHead.rows[0].cells;
    for (var i = 0; i < headrow.length; i++) {
      if (!headrow[i].className.match(/\bsorttable_nosort\b/)) {
        mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
        if (mtch) {
          override = mtch[1];
        }
        if (mtch && typeof sorttable["sort_" + override] == 'function') {
          headrow[i].sorttable_sortfunction = sorttable["sort_" + override];
        } else {
          headrow[i].sorttable_sortfunction = sorttable.guessType(table, i);
        }
        headrow[i].sorttable_columnindex = i;
        headrow[i].sorttable_tbody = table.tBodies[0];
        dean_addEvent(headrow[i], "click", sorttable.innerSortFunction = function(e) {

          if (this.className.search(/\bsorttable_sorted\b/) != -1) {
            sorttable.reverse(this.sorttable_tbody);
            this.className = this.className.replace('sorttable_sorted',
              'sorttable_sorted_reverse');
            this.removeChild(document.getElementById('sorttable_sortfwdind'));
            sortrevind = document.createElement('span');
            sortrevind.id = "sorttable_sortrevind";
            sortrevind.innerHTML = stIsIE ? '&nbsp<font face="webdings">5</font>' : '&nbsp;&#x25B4;';
            this.appendChild(sortrevind);
            return;
          }
          if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
            sorttable.reverse(this.sorttable_tbody);
            this.className = this.className.replace('sorttable_sorted_reverse',
              'sorttable_sorted');
            this.removeChild(document.getElementById('sorttable_sortrevind'));
            sortfwdind = document.createElement('span');
            sortfwdind.id = "sorttable_sortfwdind";
            sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
            this.appendChild(sortfwdind);
            return;
          }
          theadrow = this.parentNode;
          forEach(theadrow.childNodes, function(cell) {
            if (cell.nodeType == 1) {
              cell.className = cell.className.replace('sorttable_sorted_reverse', '');
              cell.className = cell.className.replace('sorttable_sorted', '');
            }
          });
          sortfwdind = document.getElementById('sorttable_sortfwdind');
          if (sortfwdind) {
            sortfwdind.parentNode.removeChild(sortfwdind);
          }
          sortrevind = document.getElementById('sorttable_sortrevind');
          if (sortrevind) {
            sortrevind.parentNode.removeChild(sortrevind);
          }

          this.className += ' sorttable_sorted';
          sortfwdind = document.createElement('span');
          sortfwdind.id = "sorttable_sortfwdind";
          sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
          this.appendChild(sortfwdind);
          row_array = [];
          col = this.sorttable_columnindex;
          rows = this.sorttable_tbody.rows;
          for (var j = 0; j < rows.length; j++) {
            row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
          }
          row_array.sort(this.sorttable_sortfunction);
          tb = this.sorttable_tbody;
          for (var j = 0; j < row_array.length; j++) {
            tb.appendChild(row_array[j][1]);
          }
          delete row_array;
        });
      }
    }
  },

  guessType: function(table, column) {
    sortfn = sorttable.sort_alpha;
    for (var i = 0; i < table.tBodies[0].rows.length; i++) {
      text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
      if (text != '') {
        if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
          return sorttable.sort_numeric;
        }
        possdate = text.match(sorttable.DATE_RE)
        if (possdate) {
          first = parseInt(possdate[1]);
          second = parseInt(possdate[2]);
          if (first > 12) {
            return sorttable.sort_ddmm;
          } else if (second > 12) {
            return sorttable.sort_mmdd;
          } else {
            sortfn = sorttable.sort_ddmm;
          }
        }
      }
    }
    return sortfn;
  },
  getInnerText: function(node) {
    if (!node) return "";
    hasInputs = (typeof node.getElementsByTagName == 'function') &&
      node.getElementsByTagName('input').length;
    if (node.getAttribute("sorttable_customkey") != null) {
      return node.getAttribute("sorttable_customkey");
    } else if (typeof node.textContent != 'undefined' && !hasInputs) {
      return node.textContent.replace(/^\s+|\s+$/g, '');
    } else if (typeof node.innerText != 'undefined' && !hasInputs) {
      return node.innerText.replace(/^\s+|\s+$/g, '');
    } else if (typeof node.text != 'undefined' && !hasInputs) {
      return node.text.replace(/^\s+|\s+$/g, '');
    } else {
      switch (node.nodeType) {
        case 3:
          if (node.nodeName.toLowerCase() == 'input') {
            return node.value.replace(/^\s+|\s+$/g, '');
          }
        case 4:
          return node.nodeValue.replace(/^\s+|\s+$/g, '');
          break;
        case 1:
        case 11:
          var innerText = '';
          for (var i = 0; i < node.childNodes.length; i++) {
            innerText += sorttable.getInnerText(node.childNodes[i]);
          }
          return innerText.replace(/^\s+|\s+$/g, '');
          break;
        default:
          return '';
      }
    }
  },
  reverse: function(tbody) {
    // reverse the rows in a tbody
    newrows = [];
    for (var i = 0; i < tbody.rows.length; i++) {
      newrows[newrows.length] = tbody.rows[i];
    }
    for (var i = newrows.length - 1; i >= 0; i--) {
      tbody.appendChild(newrows[i]);
    }
    delete newrows;
  },
  sort_numeric: function(a, b) {
    aa = parseFloat(a[0].replace(/[^0-9.-]/g, ''));
    if (isNaN(aa)) aa = 0;
    bb = parseFloat(b[0].replace(/[^0-9.-]/g, ''));
    if (isNaN(bb)) bb = 0;
    return aa - bb;
  },
  sort_alpha: function(a, b) {
    if (a[0] == b[0]) return 0;
    if (a[0] < b[0]) return -1;
    return 1;
  },
  sort_ddmm: function(a, b) {
    mtch = a[0].match(sorttable.DATE_RE);
    y = mtch[3];
    m = mtch[2];
    d = mtch[1];
    if (m.length == 1) m = '0' + m;
    if (d.length == 1) d = '0' + d;
    dt1 = y + m + d;
    mtch = b[0].match(sorttable.DATE_RE);
    y = mtch[3];
    m = mtch[2];
    d = mtch[1];
    if (m.length == 1) m = '0' + m;
    if (d.length == 1) d = '0' + d;
    dt2 = y + m + d;
    if (dt1 == dt2) return 0;
    if (dt1 < dt2) return -1;
    return 1;
  },
  sort_mmdd: function(a, b) {
    mtch = a[0].match(sorttable.DATE_RE);
    y = mtch[3];
    d = mtch[2];
    m = mtch[1];
    if (m.length == 1) m = '0' + m;
    if (d.length == 1) d = '0' + d;
    dt1 = y + m + d;
    mtch = b[0].match(sorttable.DATE_RE);
    y = mtch[3];
    d = mtch[2];
    m = mtch[1];
    if (m.length == 1) m = '0' + m;
    if (d.length == 1) d = '0' + d;
    dt2 = y + m + d;
    if (dt1 == dt2) return 0;
    if (dt1 < dt2) return -1;
    return 1;
  },
  shaker_sort: function(list, comp_func) {
    var b = 0;
    var t = list.length - 1;
    var swap = true;
    while (swap) {
      swap = false;
      for (var i = b; i < t; ++i) {
        if (comp_func(list[i], list[i + 1]) > 0) {
          var q = list[i];
          list[i] = list[i + 1];
          list[i + 1] = q;
          swap = true;
        }
      }
      t--;

      if (!swap) break;

      for (var i = t; i > b; --i) {
        if (comp_func(list[i], list[i - 1]) < 0) {
          var q = list[i];
          list[i] = list[i - 1];
          list[i - 1] = q;
          swap = true;
        }
      }
      b++;

    }
  }
}
if (document.addEventListener) {
  document.addEventListener("DOMContentLoaded", sorttable.init, false);
}
/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
    document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
    var script = document.getElementById("__ie_onload");
    script.onreadystatechange = function() {
        if (this.readyState == "complete") {
            sorttable.init(); // call the onload handler
        }
    };
/*@end @*/
/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
  var _timer = setInterval(function() {
    if (/loaded|complete/.test(document.readyState)) {
      sorttable.init(); // call the onload handler
    }
  }, 10);
}
/* for other browsers */
window.onload = sorttable.init;

function dean_addEvent(element, type, handler) {
  if (element.addEventListener) {
    element.addEventListener(type, handler, false);
  } else {
    if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;
    if (!element.events) element.events = {};
    var handlers = element.events[type];
    if (!handlers) {
      handlers = element.events[type] = {};
      if (element["on" + type]) {
        handlers[0] = element["on" + type];
      }
    }
    handlers[handler.$$guid] = handler;
    element["on" + type] = handleEvent;
  }
};
dean_addEvent.guid = 1;

function removeEvent(element, type, handler) {
  if (element.removeEventListener) {
    element.removeEventListener(type, handler, false);
  } else {
    if (element.events && element.events[type]) {
      delete element.events[type][handler.$$guid];
    }
  }
};

function handleEvent(event) {
  var returnValue = true;
  event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
  var handlers = this.events[event.type];
  for (var i in handlers) {
    this.$$handleEvent = handlers[i];
    if (this.$$handleEvent(event) === false) {
      returnValue = false;
    }
  }
  return returnValue;
};

function fixEvent(event) {
  event.preventDefault = fixEvent.preventDefault;
  event.stopPropagation = fixEvent.stopPropagation;
  return event;
};
fixEvent.preventDefault = function() {
  this.returnValue = false;
};
fixEvent.stopPropagation = function() {
  this.cancelBubble = true;
}
if (!Array.forEach) {
  Array.forEach = function(array, block, context) {
    for (var i = 0; i < array.length; i++) {
      block.call(context, array[i], i, array);
    }
  };
}
Function.prototype.forEach = function(object, block, context) {
  for (var key in object) {
    if (typeof this.prototype[key] == "undefined") {
      block.call(context, object[key], key, object);
    }
  }
};
String.forEach = function(string, block, context) {
  Array.forEach(string.split(""), function(chr, index) {
    block.call(context, chr, index, string);
  });
};
var forEach = function(object, block, context) {
  if (object) {
    var resolve = Object;
    if (object instanceof Function) {
      resolve = Function;
    } else if (object.forEach instanceof Function) {
      object.forEach(block, context);
      return;
    } else if (typeof object == "string") {
      resolve = String;
    } else if (typeof object.length == "number") {
      resolve = Array;
    }
    resolve.forEach(object, block, context);
  }
}
table.sortable thead {
  background-color: #eee;
  color: #666666;
  font-weight: bold;
  cursor: default;
}
<table class="sortable">
  <thead>
    <tr>
      <th>S.L.</th>
      <th>name</th>
      <th>Goal</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Ronaldo</td>
      <td>120</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Messi</td>
      <td>66</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Ribery</td>
      <td>10</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Bale</td>
      <td>22</td>
    </tr>
  </tbody>
</table>

JS is used here without any other JQuery Plugin.

Share:
129,514

Related videos on Youtube

user3508453
Author by

user3508453

SUCKAS You all will soon come to know me !

Updated on December 16, 2020

Comments

  • user3508453
    user3508453 over 3 years

    I have something like this

    <table>
        <thead>
            <tr>
                <th>S.L.</th>
                <th>name</th>
            </tr>
        </thead>
    
        <tbody>
            <tr>
                <td>1</td>
                <td>Ronaldo</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Messi</td>
            </tr>
            <tr>
                <td>3</td>
                <td>Ribery</td>
            </tr>
            <tr>
                <td>4</td>
                <td>Bale</td>
            </tr>
        </tbody>
    </table>
    

    What i want is to sort the <tr> of <tbody> when clicked th in ascending and descending order alternatively in according to the following th clicked.

    1. so if some one clicks the S.L th then it shows the table rows in descending and then ascending order alternatively at every click.
    2. When clicked Name th it should show the names in descending order and then ascending order without change in their respective S.L

    here is fiddle

    • Bhavik
      Bhavik almost 10 years
    • Ryan Brewer
      Ryan Brewer almost 10 years
      @Bhavik your "Working Fiddle" does not work.
    • Bhavik
      Bhavik almost 10 years
    • user3508453
      user3508453 almost 10 years
      can u implement it in jquery using my solution coz i am little weak in javascript @Bhavik
    • Bhavik
      Bhavik almost 10 years
      @user3508453 here you go
    • user3508453
      user3508453 almost 10 years
      i got it but my curiosity is how u did it ? canu explain in an answer ? coz i did not understood the functions u used. @Bhavik
    • Bhavik
      Bhavik almost 10 years
      Updated it with few comments.. jsfiddle.net/a2seK/6
    • user3508453
      user3508453 almost 10 years
      but if we dont know the second parameter in your function sort_table i.e the nth child how do we do it ? @Bhavik
    • Dexygen
      Dexygen over 5 years
      Do any of the solutions use memoization, that is, do they store their results so they can be used again? Thinking about it a little harder, this might require a full page refresh if table rows are added/edited/deleted. Another idea is to create the necessary additional data structure(s) and pre-sort the data.
  • user3508453
    user3508453 almost 10 years
    why have u used sortTable(variable,0) & sortTable(variable,1)?
  • naota
    naota almost 10 years
    @user3508453, I appended explanation of parameter of sortTable on my answer above. On the sortTable(f,n) , f : 1 ascending order, -1 descending order , and n : n-th child(<td>) of <tr>
  • user3508453
    user3508453 almost 10 years
    if we are unknown about nth child how do we get the n of td ? @naota
  • naota
    naota almost 10 years
    @user3508453, thanks. Could you explain more about "unknown about nth"? What kind of case do you consider?
  • user3508453
    user3508453 almost 10 years
    i consider adding table headers unknown numbers of time as done in google forms then i dont know how many table headers my user creates.....
  • user3508453
    user3508453 almost 10 years
    U almost solved it. But if i have SL in digits of tens or thousands or even more its causing a problem and mistake while ordering it. Suppose s.l are in range of 1-1000 then it would order it incorrectly.
  • Kraang Prime
    Kraang Prime over 8 years
    Sorry to necro this, but there is a problem when sorting a numeric column as shown in this updated fiddle > jsfiddle.net/a2seK/567 <
  • Kraang Prime
    Kraang Prime over 8 years
    This one also fails to sort numerically properly > jsfiddle.net/8kp2vjm3/59
  • Kraang Prime
    Kraang Prime over 8 years
    This plugin works well unless the table has been modified at runtime. It doesn't take into account changes made to the cell contents. Even running .tablesorter() a second time after modification, it fails to see the new data.
  • naota
    naota about 8 years
    @SanuelJackson: Thank you for pointing me out the issue. I edited my code above. In the new code, each value is checked if it is Numeric or not.
  • Vishal
    Vishal about 7 years
    To make is work numerically just update the code tda < tdb to +tda< +tdb and it will work > See updated fiddle >> jsfiddle.net/vishal_vash/8kp2vjm3/131
  • Severe Torture
    Severe Torture over 6 years
    Thanks for great solution. It´s works well not only on tables, but on "tables makes via divs". +1
  • jouell
    jouell over 5 years
    where would that function() call go? It's not obvious.
  • kamalav
    kamalav about 5 years
    great solution ji
  • Muhammad Hafiz Hussin
    Muhammad Hafiz Hussin over 4 years
    I like this one. Solve my problem for decimal figures. I made it ascending and descending by changing the error. thanks SharmaPattar
  • Pradeep Kumar
    Pradeep Kumar about 4 years
    numbers with decimal gives wrong sorting order. example(for me): 8.67, 8.31, 8.59 – removing if($.isNumeric(v)){ v = parseInt(v,10); } fixed decimal sorting issue
  • Ynjxsjmh
    Ynjxsjmh almost 4 years
    The js code looks silimar with kryogenix.org/code/browser/sorttable/sorttable.js. For how to use it, visit kryogenix.org/code/browser/sorttable.