Exclude a column from being sorted using jQuery tablesorter
Asked Answered
F

9

20

I am looking for a way to exclude a single column from being sorted using jQuery's tablesorter plugin. Specifically, I have a fairly large table and would like to keep a "row number" column fixed so that it is easy to see what position in the table a particular row is, after sorting.

For example:

#    name
-----------
1    papaya
2    apple
3    strawberry
4    banana

When sorted on the name column, should result in:

#    name
-----------
1    apple
2    banana
3    papaya
4    strawberry

Thanks.

Floorwalker answered 12/1, 2009 at 22:37 Comment(0)
N
20

Here is a widget you can use that will accomplish what you are looking for:

$(function() {
    // add new widget called indexFirstColumn
    $.tablesorter.addWidget({
        // give the widget a id
        id: "indexFirstColumn",
        // format is called when the on init and when a sorting has finished
        format: function(table) {               
            // loop all tr elements and set the value for the first column  
            for(var i=0; i < table.tBodies[0].rows.length; i++) {
                $("tbody tr:eq(" + i + ") td:first",table).html(i+1);
            }                                   
        }
    });

    $("table").tablesorter({
        widgets: ['zebra','indexFirstColumn']
    });

});
Nadabas answered 12/1, 2009 at 23:12 Comment(2)
Very nice! I think that in the for loop there should be '<=' rather than '<'.Immunogenic
Great stuff, one small thing though, it shouldn't start looping from var i=0; but var i=1; otherwise it will get 0 index at the bottom of the table.Immunogenic
R
36

For those who find this while looking for a way to exclude a column from being sortable (i.e. clickable header on the column), the below example excludes column 4 (zero-indexed) from being sorted):

$("table").tablesorter({
    headers: {4: {sorter: false}}
});
Redfaced answered 16/10, 2012 at 23:41 Comment(0)
N
20

Here is a widget you can use that will accomplish what you are looking for:

$(function() {
    // add new widget called indexFirstColumn
    $.tablesorter.addWidget({
        // give the widget a id
        id: "indexFirstColumn",
        // format is called when the on init and when a sorting has finished
        format: function(table) {               
            // loop all tr elements and set the value for the first column  
            for(var i=0; i < table.tBodies[0].rows.length; i++) {
                $("tbody tr:eq(" + i + ") td:first",table).html(i+1);
            }                                   
        }
    });

    $("table").tablesorter({
        widgets: ['zebra','indexFirstColumn']
    });

});
Nadabas answered 12/1, 2009 at 23:12 Comment(2)
Very nice! I think that in the for loop there should be '<=' rather than '<'.Immunogenic
Great stuff, one small thing though, it shouldn't start looping from var i=0; but var i=1; otherwise it will get 0 index at the bottom of the table.Immunogenic
E
6
$("table").tablesorter({
    headers: {4: {sorter: false},8: {sorter: false}}
});
Eryneryngo answered 15/11, 2016 at 12:16 Comment(1)
Upvoted. Nothing ingenious about your answer, but still a very useful one because info is not easy to find on Github documentation about tablesorter.Entomologize
T
5

Edit: I've made a sample of this technique at http://jsbin.com/igupu4/3. Click any column heading to sort...

While I don't have an answer to your question about jquery, here's an alternate way to get the specific behaviour you described here, fixed row numbers after sorting. (Using CSS, specifically the content property, and counter related properties/functions.)

<html>
<head>
  <title>test</title>
  <style type="text/css">
    tbody tr 
    {
      counter-increment : rownum ; 
    }
    tbody 
    { 
      counter-reset: rownum; 
    }
    table#sample1 td:first-child:before 
    { 
      content: counter(rownum) " " ; 
    }
    table#sample2 td.rownums:before 
    { 
      content: counter(rownum) ; 
    }
  </style>
  <script src="jquery-1.2.6.min.js" ></script>
  <script src="jquery.tablesorter.min.js" ></script>
  <script>
    $(document).ready(function() 
      { 
        $("table").tablesorter(); 
      } 
    ); 
  </script>
</head>

<body>
  <table id="sample1">
    <thead>
      <tr>
        <th>Col 1</th>
        <th>Col 2</th>
    </thead>
    <tbody>
      <tr>
        <td>
          <p>foo</p>
        </td>
        <td>
          <p>quuz</p>
        </td>
      </tr>

      <tr>
        <td>bar</td>
        <td>quux</td>
      </tr>

      <tr>
        <td>baz</td>
        <td>baz</td>
      </tr>
    </tbody>
  </table>

  <table id="sample2">
    <thead>
      <tr>
        <th>Rownums</th>
        <th>Col 1</th>
        <th>Col 2</th>
        <th>More Rownums</th>
    </thead>
    <tbody>
      <tr>
        <td class="rownums"></td>
        <td>
          <p>foo</p>
        </td>
        <td>
          <p>bar</p>
        </td>
        <td class="rownums"></td>
      </tr>

      <tr>
        <td class="rownums"></td>
        <td>quuz</td>
        <td>baz</td>
        <td class="rownums"></td>
      </tr>

      <tr>
        <td class="rownums"></td>
        <td>fred</td>
        <td>quux</td>
        <td class="rownums"></td>
      </tr>
    </tbody>
  </table>
</body>
</html>

If your browser is sufficiently CSS2.1 compatible, you can use tr:before instead of td:first-child:before in sample 1. (Mozilla only supports this in trunk for now...)

In sample 2, you can see how to position your row-number columns anywhere, not just in the first column.

Tedric answered 13/1, 2009 at 0:18 Comment(0)
U
3

This would skip sorting for the first column, and allow it for the second one. Just set true/false for all columns starting with first column as zero.

<script>
$(document).ready(function() { 
    $("table").tablesorter({
        headers: {
            0: {sorter: false},
            1: {sorter: true},
            3: {sorter: false}
        }//headers
    }); 
});            
</script>
Unsightly answered 6/3, 2014 at 16:14 Comment(0)
M
2

The answer of Brian Fisher is correct, but it is too slow in large tables (+1600 rows in my example). I improved the way of iterating through every rows. Everything else is the same.

$(function() {
    // add new widget called indexFirstColumn
    $.tablesorter.addWidget({
        // give the widget a id
        id: "indexFirstColumn",
        // format is called when the on init and when a sorting has finished
        format: function(table) {               
            // loop all tr elements and set the value for the first column  
            $(table).find("tr td:first-child").each(function(index){
                $(this).text(index+1);
            })                                  
        }
    });

    $("table").tablesorter({
        widgets: ['zebra','indexFirstColumn']
    });
});
Maulmain answered 25/10, 2016 at 9:48 Comment(0)
K
0

Hrm. From tablesorter's method of reorganizing the table, I'm pretty sure that this isn't entirely possible. Tablesorter pulles each tr out of the DOM one by one and sorts them based on an indexed field, reinserting the entire tr without changing the tr's contents in any way. Your requested solution would then need to iterate back through the table after each sort and re-enumerate the first column. Tablesorter does have a plugin method, which is used by the zebrastripe and other extensions. Perhaps this could be used to hook the sort methods?

Knockknee answered 12/1, 2009 at 22:50 Comment(0)
G
0

The answer of Stobor is perfect. The only problem is that needs to wait until the table is rendered completly to put the numbers.

Some observations:

  • You need to give an empty column for this method put the numbers.
  • If you have headers in the table you have to use the tags THEAD and TBODY to let tablesorter to sort only the data in the TBODY section.
  • If you have a footer in your tables, you have to let this out of the TBODY section to avoid tablesorter to sort his content, also you have to use tags TH instead TD to avoid numerating the footer.

Note: The method shown by Abdul only restricts to the user to sort by the indicated columns, but his content is always ordered with the rest of the row when an order by other unrestricted column is selected.

Granddaddy answered 17/11, 2016 at 19:49 Comment(0)
L
0

Just an update on this question. While the top voted answer is a wonderful solution, the jstablesorter team added this feature so in your html cell add the following attribute:

data-sorter="false"

And that is a seamless way to disable any header from sorting.

Lutanist answered 24/7, 2021 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.