最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Sorting HTML table by two columns - Stack Overflow

programmeradmin3浏览0评论

I have several columns in a table such as column A,B,C,D and E which I need to show in my HTML page. In some pages I need to show sorted results based on only one column of page, such as for Column "C" which is 3rd column of table. I am able to do this using the below code:

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

But I have another requirement wherein I need to show the sorted results based on two columns i.e. based on the sorting of Column C in above case, results of column E should also get sorted. For example:

Before sorting:

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

After sorting Column C only:

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

After sorting Column C then Column 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

Which I am unable to implement. How can I do it?

I have several columns in a table such as column A,B,C,D and E which I need to show in my HTML page. In some pages I need to show sorted results based on only one column of page, such as for Column "C" which is 3rd column of table. I am able to do this using the below code:

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

But I have another requirement wherein I need to show the sorted results based on two columns i.e. based on the sorting of Column C in above case, results of column E should also get sorted. For example:

Before sorting:

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

After sorting Column C only:

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

After sorting Column C then Column 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

Which I am unable to implement. How can I do it?

Share Improve this question edited Apr 28, 2015 at 11:21 Salman Arshad 272k84 gold badges442 silver badges534 bronze badges asked Apr 15, 2015 at 5:34 Nishant KumarNishant Kumar 2352 gold badges4 silver badges13 bronze badges 6
  • 1 Would you mind using code tags to format the HTML so we can see what you want the output to look like? It's a bit hard to tell what you're trying to achieve by looking at your example because it's all scrunched up onto one line. – Eamonn Gormley Commented Apr 15, 2015 at 5:38
  • Its not entirely clear from your post how you want the data sorted. Edit your post to include before and after examples. Make sure they are arranged clearly so they are easier to understand. Try using a bulleted list. – Bob Commented Apr 15, 2015 at 5:43
  • Are you trying to achieve a secondary sort (for column E in the example)? – Udi Cohen Commented Apr 15, 2015 at 5:45
  • You might check out datatables which are capable of this type of sorting with very little coding – Wesley Smith Commented Apr 15, 2015 at 6:31
  • In general, sorting by n columns works as follows: check the results of pare(a.col1, b.col1), pare(a.col2, b.col2), ... until you get a non-zero result or you have checked all the columns, return that result. – Salman Arshad Commented Apr 15, 2015 at 8:31
 |  Show 1 more ment

2 Answers 2

Reset to default 11

To sort by more than one column you write the parison function like this:

(Comparison function is passed two "rows")

  1. Compare row 1 column 1 with row 2 column 1
    • If they are different then return the result (a +ve or -ve number)
  2. Compare row 1 column 2 with row 2 column 2
    • If they are different then return the result (a +ve or -ve number)
  3. Repeat for remaining columns
  4. Return 0

The following example shows how to write the pare function that sorts by two columns. It is possible to use a loop or recursion to sort by n columns.

$(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, pare 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./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>

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

Simple solution in Javascript The above example is in descending order of price if same price column id will be in ascending order

发布评论

评论列表(0)

  1. 暂无评论