Подтвердить что ты не робот

Сортировка строк таблицы по столбцу заголовка таблицы с помощью javascript или jquery

У меня есть что-то вроде этого

  <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>

Я хочу сортировать <tr> из <tbody> при нажатии th в порядке возрастания и убывания в зависимости от того, в соответствии со следующим нажатием th.

  • поэтому, если кто-то нажимает S.L th, тогда он показывает строки таблицы в нисходящий, а затем восходящий порядок поочередно при каждом нажатии.
  • При нажатии Name th он должен показывать имена в нисходящем порядок, а затем восходящий порядок без изменений в их соответствующих S.L

здесь скрипка

4b9b3361

Ответ 1

Возможно, вам захочется увидеть эту страницу:
http://blog.niklasottosson.com/?p=1914

Я думаю, вы можете пойти примерно так:

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);
});

Надеюсь, что это поможет.

Ответ 2

Предлагая интерактивную сортировку, обрабатывающую несколько столбцов, нет ничего тривиального.

Если вы не хотите писать хорошую логику обработки кода для нескольких щелчков по ряду, редактируя и обновляя содержимое страницы, управляя алгоритмами сортировки для больших таблиц... тогда вам действительно лучше использовать подключаемый модуль.

tablesorter, (с обновлениями от Mottie) - мой любимый. Его легко получить и очень настраиваемый. Просто добавьте класс tablesorter в таблицу, которую вы хотите отсортировать, а затем вызовите плагин tablesorter в событии загрузки документа:

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

Вы можете просмотреть документацию, чтобы узнать о дополнительных функциях.

Ответ 3

использовать функцию 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);

Если вы хотите по возрастанию, вам просто нужно отменить функции > и <

Измените логику для вас.

FIDDLE

Ответ 4

Я думаю, это может помочь вам:
Вот демо: http://jsfiddle.net/aung48vm/

И вот код:
HTML:

<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:

var stIsIE = /*@[email protected]*/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);
    }
};

JS используется здесь без какого-либо другого плагина JQuery.

Ответ 6

 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)
        }
    </script>

</head>
<body>
    <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>
</body>
</html>

Ответ 7

Я работаю над функцией для работы в библиотеке для клиента и испытываю большие проблемы с сохранением пользовательского интерфейса во время сортировки (даже при наличии нескольких сотен результатов).

Функция должна использовать всю таблицу для разбивки на страницы AJAX, так как новые данные могут потребовать дополнительной инъекции. Это то, что у меня было до сих пор:

  • Требуется библиотека jQuery.
  • table - идентификатор сортируемой таблицы.
  • Атрибуты таблицы sort-attribute, sort-direction и атрибут столбца column заданы заранее.

Используя некоторые из приведенных выше подробностей, мне удалось немного улучшить производительность.

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;
  }

В принципе, код работает отлично, но он очень медленный... есть ли способы повысить производительность?