按两个字段排序HTML表格

4

我有一个表格中的几个列,比如A、B、C、D和E,我需要在我的HTML页面中显示它们。在一些页面中,我需要仅基于一页的一个列(例如表格的第3列"C")显示排序结果。我可以使用以下代码实现:

function Ascending(a, b) {
  if (a < b) return -1;
  if (a > b) return 1;
  return 0;
}
var rows = $('#table tr').not(':first').get();
$('#table tr').slice(1).remove();
rows.sort(function(rowA, rowB) {
  var keyA = $(rowA).children('td').eq(2).text().toUpperCase();
  var keyB = $(rowB).children('td').eq(2).text().toUpperCase();
  return Ascending(keyA, keyB);
});

但是我还有另一个要求,需要根据两列排序结果来显示结果,即基于上述情况中列C的排序,列E的结果也应该被排序。例如:

排序前:

Column C  Column E
2         Fish
1         Box
7         Cat
2         Dog
1         Apple
2         Box
2         Axe
7         Box
2         Answer
7         Apple
6         Year
2         Goat

仅对C列进行排序后:

Column C  Column E
1         Box
1         Apple
2         Dog
2         Fish
2         Box
2         Axe
2         Goat
2         Answer
6         Year
7         Box
7         Apple
7         Cat

在对C列和E列进行排序后:

Column C  Column E
1         Apple
1         Box
2         Answer
2         Axe
2         Box
2         Dog
2         Fish
2         Goat
6         Year
7         Apple
7         Box
7         Cat

示例表格,其中M应在第二列下方的L之后

我无法实现它。该怎么做呢?


1
您介意使用代码标签来格式化HTML吗?这样我们就可以看到您想要的输出效果是什么样子的。通过查看您的示例,很难确定您试图实现什么,因为它们都挤在一行上。 - Eamonn Gormley
从您的帖子中并不完全清楚您希望如何对数据进行排序。编辑您的帖子,加入示例说明排序前后的情况。确保它们排列清晰,以便更容易理解。尝试使用项目符号列表。 - Bob
你是否正在尝试实现二次排序(例如对于E列)? - Udi Cohen
你可以查看 https://www.datatables.net/,它们能够以非常少的编码实现这种类型的排序。 - Wesley Smith
通常情况下,按n列排序的工作原理如下:检查compare(a.col1, b.col1),compare(a.col2, b.col2)等结果,直到获得非零结果或检查完所有列,返回该结果。 - Salman A
感谢@Salman A的评论。我清楚逻辑,但实现它对我来说是个问题。如果您能以我上面给出的相同方式帮助我编写代码,那将是太好了。 - Nishant Kumar
2个回答

11
为了按多列排序,你需要像这样编写比较函数:
(比较函数传递两个“行”)
  1. 比较第一列第1行与第二列第1行
    • 如果它们不同,则返回结果(一个正数或负数)
  2. 比较第一列第2行与第二列第2行
    • 如果它们不同,则返回结果(一个正数或负数)
  3. 重复剩余的列
  4. 返回0
下面的示例显示如何编写按两列排序的比较函数。 可以使用循环或递归来按n列进行排序。
$(function() {
  function sortByColumn3(row1, row2) {
    var v1, v2;
    v1 = $(row1).find("td:eq(2)").text();
    v2 = $(row2).find("td:eq(2)").text();
    // for numbers you can simply return a-b instead of checking greater/smaller/equal
    return v1 - v2;
  }

  function sortByColumn3And5(row1, row2) {
    var v1, v2, r;
    v1 = $(row1).find("td:eq(2)").text();
    v2 = $(row2).find("td:eq(2)").text();
    r = v1 - v2;
    if (r === 0) {
      // we have a tie in column 1 values, compare column 2 instead
      v1 = $(row1).find("td:eq(4)").text();
      v2 = $(row2).find("td:eq(4)").text();
      if (v1 < v2) {
        r = -1;
      } else if (v1 > v2) {
        r = 1;
      } else {
        r = 0;
      }
    }
    return r;
  }
  $("#button1, #button2").on("click", function() {
    var rows = $("#table1 tbody tr").detach().get();
    switch (this.id) {
      case "button1":
        rows.sort(sortByColumn3);
        break;
      case "button2":
        rows.sort(sortByColumn3And5);
        break;
    }
    $("#table1 tbody").append(rows);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<input type="button" id="button1" value="sortByColumn3">
<input type="button" id="button2" value="sortByColumn3And5">

<table id="table1" border="1" width="100%">
  <thead>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>x</td>
      <td>y</td>
      <td>2</td>
      <td>z</td>
      <td>Fish</td>
    </tr>
    <tr>
      <td>y</td>
      <td>z</td>
      <td>1</td>
      <td>x</td>
      <td>Box</td>
    </tr>
    <tr>
      <td>z</td>
      <td>x</td>
      <td>7</td>
      <td>y</td>
      <td>Cat</td>
    </tr>
    <tr>
      <td>x</td>
      <td>y</td>
      <td>2</td>
      <td>z</td>
      <td>Dog</td>
    </tr>
    <tr>
      <td>y</td>
      <td>z</td>
      <td>1</td>
      <td>x</td>
      <td>Apple</td>
    </tr>
    <tr>
      <td>z</td>
      <td>x</td>
      <td>2</td>
      <td>y</td>
      <td>Box</td>
    </tr>
    <tr>
      <td>x</td>
      <td>y</td>
      <td>2</td>
      <td>z</td>
      <td>Axe</td>
    </tr>
    <tr>
      <td>y</td>
      <td>z</td>
      <td>7</td>
      <td>x</td>
      <td>Box</td>
    </tr>
    <tr>
      <td>z</td>
      <td>x</td>
      <td>2</td>
      <td>y</td>
      <td>Answer</td>
    </tr>
    <tr>
      <td>x</td>
      <td>y</td>
      <td>7</td>
      <td>z</td>
      <td>Apple</td>
    </tr>
    <tr>
      <td>y</td>
      <td>z</td>
      <td>6</td>
      <td>x</td>
      <td>Year</td>
    </tr>
    <tr>
      <td>z</td>
      <td>x</td>
      <td>2</td>
      <td>y</td>
      <td>Goat</td>
    </tr>
  </tbody>
</table>


非常感谢@Salman A提供的帮助和详细的代码。它运行得很好。 如果第5列包含DDMMYYYY格式的日期,您有任何想法如何实现相同的功能吗? - Nishant Kumar
你需要创建一个JavaScript日期对象。然后使用减法逻辑进行比较。DDMMYY不能直接与日期一起使用,你需要使用子字符串函数提取DD、MM和YYYY,并使用长日期构造函数(new Date(year, month, date))。 - Salman A
好的,非常感谢您的回复。我会尝试在我的代码中实现相同的功能。 - Nishant Kumar

0

function sortTable() {
    var table, rows, switching, i, x, y, a, b, shouldSwitch;
    table = document.getElementById("mytable");
    switching = true;
    while (switching) {
        switching = false;
        rows = table.getElementsByTagName("TR");
        for (i = 0; i < (rows.length - 1); i++) {
            shouldSwitch = false;
            /*Get the two elements you want to compare,
            one from current row and one from the next:*/
            x = rows[i].getElementsByTagName("TD")[3];
            y = rows[i + 1].getElementsByTagName("TD")[3];
            //check if the two rows should switch place:
            if (Number(x.innerHTML) < Number(y.innerHTML)) {
                //if so, mark as a switch and break the loop:
                shouldSwitch = true;
                break;
            }


        }
        if (shouldSwitch) {
            /*If a switch has been marked, make the switchcand mark that a switch has been done:*/
            rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
            switching = true;
        }
    }
  
    for (i = 0; i < (rows.length - 1); i++) {
        /*Get the two elements you want to compare,one from current row and one from the next:*/
        for (j = i + 1; j < (rows.length); j++) {
            x = rows[i].getElementsByTagName("TD")[3];
            y = rows[j].getElementsByTagName("TD")[3];
            a = rows[i].getElementsByTagName("TD")[0];
            b = rows[j].getElementsByTagName("TD")[0];
            //check if the two rows should switch place:
            if (Number(x.innerHTML) == Number(y.innerHTML)) {
                //if so, swap
                if (Number(a.innerHTML) > Number(b.innerHTML)) {
                    rows[i].parentNode.insertBefore(rows[j], rows[i]);

                }
            }
        }
    }
}
<body>
<div class="container">
  <form class="form-horizontal" role="form">
    <div class="form-group">
      <button id="sort" onclick="sortTable()" type="button" class="btn btn-default">sort</button>
    </div>
  </form>

  <div class="contents">
    <table class="table">
      <thead>
        <tr>
          <th>Id</th>
          <th>Image</th>
          <th>Name</th>
          <th>Price</th>
        </tr>
      </thead>
     <tbody id="mytable"><tr><td>5</td><td><img src="image/5.gif"></td><td>cony #5</td><td>170</td></tr><tr><td>1</td><td><img src="image/1.gif"></td><td>cony #1</td><td>170</td></tr><tr><td>2</td><td><img src="image/2.gif"></td><td>cony #2</td><td>270</td></tr><tr><td>8</td><td><img src="image/8.gif"></td><td>cony #8</td><td>70</td></tr><tr><td>10</td><td><img src="image/10.gif"></td><td>cony #10</td><td>170</td></tr><tr><td>4</td><td><img src="image/4.gif"></td><td>cony #4</td><td>150</td></tr><tr><td>3</td><td><img src="image/3.gif"></td><td>cony #3</td><td>130</td></tr><tr><td>6</td><td><img src="image/6.gif"></td><td>cony #6</td><td>160</td></tr><tr><td>9</td><td><img src="image/9.gif"></td><td>cony #9</td><td>170</td></tr><tr><td>7</td><td><img src="image/7.gif"></td><td>cony #7</td><td>170</td></tr></tbody>
   
    </table>
  </div>
</div>
</body>

Javascript中的简单解决方案 如果价格相同,则以上示例按价格降序排列,如果列ID相同,则按升序排列。


仅提供代码答案并不鼓励,因为它们对于未来的读者提供的信息不多,请在您编写的内容中提供一些解释。 - WhatsThePoint
@WhatsThePoint 上述代码按价格列的降序对表进行排序,如果价格相同,则按ID列的升序排序。 - Ramesh arr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接