简体   繁体   English

使用javascript或jquery根据表头列对表行进行排序

[英]Sorting table rows according to table header column using javascript or jquery

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.我想是排序的<tr><tbody>当点击th升序和根据以下可选地降序th点击。

  1. so if some one clicks the SL th then it shows the table rows in descending and then ascending order alternatively at every click.因此,如果有人点击了SL th就说明在下降,然后在每一次点击或者按升序排列表格行。
  2. When clicked Name th it should show the names in descending order and then ascending order without change in their respective SL单击Name th它应按降序显示名称,然后按升序显示名称,而不会更改其各自的SL

here is fiddle这是小提琴

You might want to see this page:您可能希望看到此页面:
http://blog.niklasottosson.com/?p=1914 http://blog.niklasottosson.com/?p=1914

I guess you can go something like this:我想你可以这样做:

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

HTML: HTML:

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

JS: 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.希望这可以帮助。

use Javascript sort() function使用 Javascript sort()函数

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小提琴

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. tablesorter ,(由 Mottie 更新)是我的最爱。 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:只需将tablesorter类添加到要排序的表中,然后在文档加载事件中调用 tablesorter 插件:

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

You can browse the documentation to learn about advanced features.您可以浏览文档以了解高级功能。

I think this might help you:我认为这可能对您有所帮助:
Here is the JSFiddle demo :这是JSFiddle 演示

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>SL</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.这里使用 JS,没有任何其他 JQuery 插件。

You can use jQuery DataTables plugin for applying column sorting in desired way.您可以使用 jQuery DataTables 插件以所需的方式应用列排序。

Column Sorting using DataTable 使用 DataTable 进行列排序

I've been working on a function to work within a library for a client, and have been having a lot of trouble keeping the UI responsive during the sorts (even with only a few hundred results).我一直在为客户端开发一个在库中工作的函数,并且在排序过程中保持 UI 响应时遇到了很多麻烦(即使只有几百个结果)。

The function has to resort the entire table each AJAX pagination, as new data may require injection further up.该函数必须在每次 AJAX 分页时对整个表进行重新排序,因为新数据可能需要进一步向上注入。 This is what I had so far:这是我到目前为止所拥有的:

  • jQuery library required.需要 jQuery 库。
  • table is the ID of the table being sorted. table是被排序的表的 ID。
  • The table attributes sort-attribute , sort-direction and the column attribute column are all pre-set.表属性sort-attributesort-direction和列属性column都是预先设置好的。

Using some of the details above I managed to improve performance a bit.使用上面的一些细节,我设法稍微提高了性能。

function sorttable(table) {
    var context = $('#' + table), tbody = $('#' + table + ' tbody'), sortfield = $(context).data('sort-attribute'), c, dir = $(context).data('sort-direction'), index = $(context).find('thead th[data-column="' + sortfield + '"]').index();
    if (!sortfield) {
        sortfield = $(context).data('id-attribute');
    };
    switch (dir) {
        case "asc":
            tbody.find('tr').sort(function (a, b) {
                var sortvala = parseFloat($(a).find('td:eq(' + index + ')').text());
                var sortvalb = parseFloat($(b).find('td:eq(' + index + ')').text());
                // if a < b return 1
                return sortvala < sortvalb ? 1
                       // else if a > b return -1
                       : sortvala > sortvalb ? -1
                       // else they are equal - return 0    
                       : 0;
            }).appendTo(tbody);
            break;
        case "desc":
        default:
            tbody.find('tr').sort(function (a, b) {
                var sortvala = parseFloat($(a).find('td:eq(' + index + ')').text());
                var sortvalb = parseFloat($(b).find('td:eq(' + index + ')').text());
                // if a < b return 1
                return sortvala > sortvalb ? 1
                       // else if a > b return -1
                       : sortvala < sortvalb ? -1
                       // else they are equal - return 0    
                       : 0;
            }).appendTo(tbody);
        break;
  }

In principle the code works perfectly, but it's painfully slow... are there any ways to improve performance?原则上代码可以完美运行,但是速度很慢……有什么方法可以提高性能?

 var TableIDvalue = "myTable"; var TableLastSortedColumn = -1; function SortTable() { var sortColumn = parseInt(arguments[0]); var type = arguments.length > 1 ? arguments[1] : 'T'; var dateformat = arguments.length > 2 ? arguments[2] : ''; var table = document.getElementById(TableIDvalue); var tbody = table.getElementsByTagName("tbody")[0]; var rows = tbody.getElementsByTagName("tr"); var arrayOfRows = new Array(); type = type.toUpperCase(); dateformat = dateformat.toLowerCase(); for (var i = 0, len = rows.length; i < len; i++) { arrayOfRows[i] = new Object; arrayOfRows[i].oldIndex = i; var celltext = rows[i].getElementsByTagName("td")[sortColumn].innerHTML.replace(/<[^>]*>/g, ""); if (type == 'D') { arrayOfRows[i].value = GetDateSortingKey(dateformat, celltext); } else { var re = type == "N" ? /[^\\.\\-\\+\\d]/g : /[^a-zA-Z0-9]/g; arrayOfRows[i].value = celltext.replace(re, "").substr(0, 25).toLowerCase(); } } if (sortColumn == TableLastSortedColumn) { arrayOfRows.reverse(); } else { TableLastSortedColumn = sortColumn; switch (type) { case "N": arrayOfRows.sort(CompareRowOfNumbers); break; case "D": arrayOfRows.sort(CompareRowOfNumbers); break; default: arrayOfRows.sort(CompareRowOfText); } } var newTableBody = document.createElement("tbody"); for (var i = 0, len = arrayOfRows.length; i < len; i++) { newTableBody.appendChild(rows[arrayOfRows[i].oldIndex].cloneNode(true)); } table.replaceChild(newTableBody, tbody); } function CompareRowOfText(a, b) { var aval = a.value; var bval = b.value; return (aval == bval ? 0 : (aval > bval ? 1 : -1)); } function deleteRow(i) { document.getElementById('myTable').deleteRow(i) }
 <table id="myTable" border="1"> <thead> <tr> <th> <input type="button" onclick="javascript: SortTable(0, 'T');" value="SORT" /></th> </tr> </thead> <tbody> <tr> <td>Shaa</td> <td>ABC</td> <td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td> </tr> <tr> <td>cnubha</td> <td>XYZ</td> <td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td> </tr> <tr> <td>Fine</td> <td>MNO</td> <td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td> </tr> <tr> <td>Amit</td> <td>PQR</td> <td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td> </tr> <tr> <td>Sultan</td> <td>FGH</td> <td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td> </tr> <tr> <td>Hello</td> <td>UST</td> <td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td> </tr> </tbody> </table>

I found @naota's solution useful, and extended it to use dates as well我发现@naota 的解决方案很有用,并将其扩展为也使用日期

//taken from StackOverflow:
//https://stackoverflow.com/questions/3880615/how-can-i-determine-whether-a-given-string-represents-a-date
function isDate(val) {
    var d = new Date(val);
    return !isNaN(d.valueOf());
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM