The Joy of Tables On Cows
Wow! This takes me back! Please check the date this post was authored, as it may no longer be relevant in a modern context.
On June 12th MooTools 1.2 was released, to great rejoicing. It’s a release that really sets MooTools apart with better Fx, more browser compatibility effort, and a jaw dropping element storage feature. That means it’s time to update the table sort script I’ve blogged here before (The Joy of a Minimal, Complete Javascript Table Sort and The Joy of an Optimized, Complete Javascript Table Sort). This release does more than just port, and also adds a few features:
- Sorts more out of the box:
- strings
- numbers
- decimal currency (12.34, 4.50)
- dates (YYYY-MM-DD, YYYY-M-D)
- relative dates (1 day ago, 38 years ago)
- disk memory (1.75 MB, 34 KB, 8 TB)
- Passes the matcher into the conversion_function for re-use.
- Classes set for forward and reverse sorting th tags.
- A “don’t sort” class.
- It’s on github!
- Integration with the brand new pagination library.
Oh yeah, and that. There’s now a pagination library supporting all the same things like expanding rows. It’ll do multiple pagination link areas and drop offset and cut-off numbers into the DOM. Let’s take a look.
The Old: Reviewing SortingTable
SortingTable doesn’t need any wonky DOM rewrite, that’s one of it’s best perks. Just use a thead and tbody, and make proper use of th.
<table cellpadding="0" cellspacing="0" id="sort_this">
<thead>
<tr>
<th>a header</th>
</tr>
</thead>
<tbody>
<tr>
<td>a value
</tr>
<tr>
<td>another value</td>
</tr>
</tbody>
</table>
To sort this table you could use the most simplistic of initializations:
new SortingTable( 'sort_this' );
These are the default settings that are assumed:
new SortingTable( 'sort_table', {
zebra: true, // Stripe the table, also on initialize
paginator: false, // Pass a paginator object
dont_sort_class: 'nosort', // Class name on th's that don't sort
forward_sort_class: 'forward_sort', // Class applied to forward sort th's
reverse_sort_class: 'reverse_sort' // Class applied to reverse sort th's
});
So if you wanted to not sort a given column, just add class=“nosort” and it’ll be ignored. You could also change that to any other class. The same goes for the classes forward_sort and reverse_sort.
The passing of conversion_matcher into the conversion_function makes it more DRY to use regex on a td for sort. Take a look at the date sorter:
// YYYY-MM-DD, YYYY-m-d
{ matcher: /(\d{4})-(\d{1,2})-(\d{1,2})/,
conversion_function: function( row ) {
var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
cell = this.conversion_matcher.exec( cell );
return new Date(parseInt(cell[1]), parseInt(cell[2], 10) - 1, parseInt(cell[3], 10));
}
},
We get to re-use that regex right in the conversion_function.
That’s it for incremental changes to SortingTable. PaginatingTable is the thing to introduce.
The New: Introducing PaginatingTable
To paginate a table you’ll need to add one DOM element:
<ul id="sort_table_pagination"></ul>
And then paginating the simple table provided above would look like:
new PaginatingTable( 'sort_table', 'sort_table_pagination' );
That’s the simplest way to go. A more complex pagination might involve two paginators as well as displaying offsets and cutoffs.
<ul id="sort_table_pagination"></ul>
Now showing items <span id="offset"></span> - <span id="cutoff"></span>
<table cellpadding="0" cellspacing="0" id="sort_this">
<thead>
<tr>
<th>a header</th>
</tr>
</thead>
<tbody>
<tr>
<td>a value
</tr>
<tr>
<td>another value</td>
</tr>
</tbody>
</table>
<ul id="sort_table_bottom_pagination"></ul>
To start this up:
new PaginatingTable( 'sort_table', ['sort_table_pagination', 'sort_table_bottom_pagination'], {
per_page: 3, // Only 3 items per page, please
current_page: 2, // Start on page 2
offset_el: 'offset', // Use this id for offset numbers
cutoff_el: 'cutoff' // And this id for cutoffs
});
Swank. This will paginate, but you don’t get any sorting or zebra striping. That’s still tied to SortingTable, and you’ll need to use them together.
PaginatingTable also provides update_pages on a given instance- so if you add rows to a table you can have the pagination update itself.
Will It Blend? SortingTable and PaginatingTable Together
SortingTable will accept a PaginatingTable object and use it to reset to the first page when you sort. Just pass it in:
new SortingTable( 'sort_table', {
paginator: new PaginatingTable( 'sort_table', 'sort_table_pagination' )
});
If you have expanding rows, you’ll need to tell both SortingTable and PaginatingTable about it:
new SortingTable( 'sort_table', {
details: true
paginator: new PaginatingTable( 'sort_table', 'sort_table_pagination', { details: true } )
});
You can check out the example to see this in action, and get the javascript from github. A big thanks to all the people that wrote conversion functions and made tweaks to this script, and kept it crawling from an example into a more capable library. Enjoy!