jQuery:按多列值对表进行排序

詹姆斯·G

我已经为此苦苦挣扎了一段时间,每次我测试一些东西时,我最终都会得到不同的结果。

JSFIDDLE

我有一个用于测试目的的基本表,其中包含 3 个条目,其中包含 3 个不同的标题,可按以下方式排序:姓名、年龄、加入日期。

这是表:

<table class="table">
<thead>
  <tr>
    <th scope="col">#</th>
    <th scope="col" id="firstName">name</th>
    <th scope="col" id="age">age</th>
    <th scope="col" id="date">date joined</th>
  </tr>
</thead>
<tbody>
  <tr>
    <th scope="row">1</th>
    <td class="firstName">Mark</td>
    <td>12</td>
    <td>12/02/2006</td>
  </tr>
  <tr>
    <th scope="row">2</th>
    <td class="firstName">Jacob</td>
    <td>30</td>
    <td>03/04/2018</td>
  </tr>
  <tr>
    <th scope="row">3</th>
    <td class="firstName">Larry</td>
    <td>22</td>
    <td>07/01/2009</td>
  </tr>
</tbody>

这是我的JS:

function sortTable(column) {
        var $tbody = $('.table tbody');
        $tbody.find('td.' + column).sort(function(a,b){ 
            var tda = $(a).find('td:eq(1)').text();
            var tdb = $(b).find('td:eq(1)').text();
                    // 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);
}

$('#firstName').click(function() {
    sortTable("firstName");
});
$('#age').click(function() {
    sortTable("age");
});
$('#date').click(function() {
    sortTable("date");
});

我正在努力实现的目标

我希望能够单击每个标题以按其各自的内容对表格进行排序。例如,当我单击名称时,它将按名称排序。当我单击年龄时,它将按年龄排序,当我单击加入的日期时,它将按日期排序。

我也很想学习,所以我会给 100 分的答案,其中有很好的评论,可以为我解释发生了什么。

谢谢你。

function sortTable(column) {
  var $tbody = $('.table tbody');
  $tbody.find('td.' + column).sort(function(a, b) {
    var tda = $(a).find('td:eq(1)').text();
    var tdb = $(b).find('td:eq(1)').text();
    // 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);
}

$('#firstName').click(function() {
  sortTable("firstName");
});
$('#age').click(function() {
  sortTable("age");
});
$('#date').click(function() {
  sortTable("date");
});
@import 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css';
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col" id="firstName">name</th>
      <th scope="col" id="age">age</th>
      <th scope="col" id="date">date joined</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td class="firstName">Mark</td>
      <td>12</td>
      <td>12/02/2006</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td class="firstName">Jacob</td>
      <td>30</td>
      <td>03/04/2018</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td class="firstName">Larry</td>
      <td>22</td>
      <td>07/01/2009</td>
    </tr>
  </tbody>
</table>

埃迪

目前,您正在对 进行排序<td>,这实际上是一个单元格而不是行(<tr>)。

.sort的回调函数有 2 个参数。您需要比较 2 个参数和:

  1. 如果第一个参数应该在前,则返回一个负值。
  2. 如果第二个参数应该在前,则返回一个正值。
  3. 如果位置没有变化,则返回 0。

您必须根据其类型(数字、文本、日期)比较数据。还使用了列的索引而不是文本,因为我认为它更容易。

function sortTable(column, type) {

  //Get and set order
  //Use -data to store wheater it will be sorted ascending or descending
  var order = $('.table thead tr>th:eq(' + column + ')').data('order');
  order = order === 'ASC' ? 'DESC' : 'ASC';
  $('.table thead tr>th:eq(' + column + ')').data('order', order);

  //Sort the table
  $('.table tbody tr').sort(function(a, b) {
  //                                 ^  ^
  //                                 |  | 
  //        The 2 parameters needed to be compared. 
  //        Since you are sorting rows, a and b are <tr>                                 

    //Find the <td> using the column number and get the text value.
    //Now, the a and b are the text of the <td>
    a = $(a).find('td:eq(' + column + ')').text();
    b = $(b).find('td:eq(' + column + ')').text();

    switch (type) {
      case 'text':
        //Proper way to compare text in js is using localeCompare
        //If order is ascending you can - a.localeCompare(b)
        //If order is descending you can - b.localeCompare(a);
        return order === 'ASC' ? a.localeCompare(b) : b.localeCompare(a);
        break;
      case 'number':
        //You can use deduct to compare if number.
        //If order is ascending you can -> a - b. 
        //Which means if a is bigger. It will return a positive number. b will be positioned first
        //If b is bigger, it will return a negative number. a will be positioned first
        return order === 'ASC' ? a - b : b - a;
        break;
      case 'date':
        var dateFormat = function(dt) {
          [m, d, y] = dt.split('/');
          return [y, m - 1, d];
        }

        //convert the date string to an object using `new Date`
        a = new Date(...dateFormat(a));
        b = new Date(...dateFormat(b));

        //You can use getTime() to convert the date object into numbers. 
        //getTime() method returns the number of milliseconds between midnight of January 1, 1970
        //So since a and b are numbers now, you can use the same process if the type is number. Just deduct the values.
        return order === 'ASC' ? a.getTime() - b.getTime() : b.getTime() - a.getTime();
        break;
    }

  }).appendTo('.table tbody');
}

$('#firstName').click(function() {
  sortTable(1, 'text');
});
$('#age').click(function() {
  sortTable(2, 'number');
});
$('#date').click(function() {
  sortTable(3, 'date');
});
table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #dddddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col" id="firstName">name</th>
      <th scope="col" id="age">age</th>
      <th scope="col" id="date">date joined</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row">1</td>
      <td class="firstName">Mark</td>
      <td>12</td>
      <td>12/02/2006</td>
    </tr>
    <tr>
      <td scope="row">2</td>
      <td class="firstName">Jacob</td>
      <td>30</td>
      <td>03/04/2018</td>
    </tr>
    <tr>
      <td scope="row">3</td>
      <td class="firstName">Larry</td>
      <td>22</td>
      <td>07/01/2009</td>
    </tr>
  </tbody>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章