Book Excerpt - Table Manipulation
Packt Publishing has just posted an excerpt of our new book Learning jQuery: Better Interaction Design and Web Development with Simple JavaScript Techniques on their site. The excerpt covers table sorting, pagination, row highlighting/striping, and basic tooltips. It also gives a hat tip to Roger Johansson of 456 Berea Street and Christian Bach of jQuery Table Sorter fame (by the way, Christian has just released version 2.0 of the plugin, and it’s awesome!). Here is the summary:
In this article by Karl Swedberg and Jonathan Chaffer, we will use an online bookstore as our model website, but the techniques we cook up can be applied to a wide variety of other sites as well, from weblogs to portfolios, from market-facing business sites to corporate intranets.
In this article, we will use jQuery to apply techniques for increasing the readability, usability, and visual appeal of tables, though we are not dealing with tables used for layout and design. In fact, as the web standards movement has become more pervasive in the last few years, table-based layout has increasingly been abandoned in favor of CSS‑based designs. Although tables were often employed as a somewhat necessary stopgap measure in the 1990s to create multi-column and other complex layouts, they were never intended to be used in that way, whereas CSS is a technology expressly created for presentation.
But this is not the place for an extended discussion on the proper role of tables. Suffice it to say that in this article we will explore ways to display and interact with tables used as semantically marked up containers of tabular data. For a closer look at applying semantic, accessible HTML to tables, a good place to start is Roger Johansson’s blog entry, Bring on the Tables at www.456bereastreet.com/archive/200410/bring_on_the_tables/.
Some of the techniques we apply to tables in this article can be found in plug‑ins such as Christian Bach’s Table Sorter. For more information, visit the jQuery Plug‑in Repository at jQuery.com/plugins.
You can read the full article/excerpt or check out the table-manipulation demos here and here.



October 3rd, 2007 at 5:29 pm
Any chance this doesn’t run “out of the box” against jQuery 1.2.1? I’m getting error “$table.find(”tbody tr”).show().lt is not a function” on line 85 of table.js, but not if I run against your copy of jquery.js. Perhaps I haven’t included enough code…
October 3rd, 2007 at 6:57 pm
Hi Scott,
It’s possible that you haven’t included enough code. Whenever we store a jQuery object as a variable, we precede the variable with “$”. It could be that you don’t have the
$tablevariable defined anywhere. Without looking back at the code, I think we had something likevar $table = $(this);.The only reason it might fail in 1.2.1 as opposed to an earlier version is if we used an XPath selector there, but that doesn’t seem to be the case.
Hope that helps.
October 9th, 2007 at 6:18 pm
Interesting - so far I’m doing well with the book, but got my first real stumper on the next line of the same script:
if ($(this).is.('.sortAlpha')) {
where I get a “XML filtering predicate operator called on incompatible Function” error in Firebug.
is .is xpath?
October 11th, 2007 at 6:23 pm
Hi Joe,
The
.is()method is not xpath. Is the period after “is” in your code above a typo? It shouldn’t be there. We have a working demo that you might want to look at for comparison.November 7th, 2007 at 4:13 pm
Hi Guys,
Thanks for a great book to help me learn jQuery! I’ve been out of the js loop for a few years, doing more administrative type stuff at my job… but lately I’ve been asked to get back into helping with actual coding. So I have a lot of catching up to do, and this is a great help.
I’m working through the book, and happen to be on this chapter. I’d like to submit a jQuery 1.2.1 problem and its fix as well as a Safari problem I just can’t seem to get around.
First, the jQuery 1.2.1 problem/fix:
In the pagination code in tables.js, I was getting an error that
$table.find('tbody tr').show().lt()is not a function. After a bunch of searching, I found that jQuery 1.2 doesn’t support.lt()or.gt()anymore. We now must use.slice(0, n)in place of.lt()and.slice(n+1)in place of.gt(), thus:$(document).ready(function(){
$('table.paginated').each(function()
{
var currentPage = 0;
var numPerPage = 10;
var $table = $(this);
$table.bind('repaginate',
function()
{
$table
.find('tbody tr')
.show()
//lt was removed from jquery, use slice instead
//.lt(currentPage * numPerPage)
//new syntax:
.slice(0, currentPage * numPerPage)
.hide()
.end()
//gt was removed from jquery, use slice instead
//.gt((currentPage + 1) * numPerPage - 1)
//new syntax:
.slice((currentPage + 1) * numPerPage - 1)
.hide()
.end();
});
//...code continues
Hopefully, that’ll help anyone else new and struggling as I am.
Now for my Safari vs. collapsing table rows problem.
I’m using Safari 2.0.4. It appears that “opacity” is not a property of <tr> (or thead, tbody, tfoot, for that matter). So the collapse code just makes the rows disappear, but not fade out prettily. Then, when I un-collapse, the spacing is all messed up: too much space between table rows, table row height shrinking, etc. Using hide/show instead of fadeOut/fadeIn works as expected (w/o the fade effect, obviously, but also with no funkiness w/regard to spacing).
The most recent thing I tried was to fade out the table cells instead of the rows. The first fade out appears to work fine. Fade in, however, does not: it seems to actually add table cells to each row (and they don’t fade, in, they just appear). Then, subsequent fade outs are flaky: the rows are not completely absent. This also breaks firefox on the fade out, in that it leaves a space between the <th> row above and below the collapsed rows. Example here: http://hurleyhouse.com/learning_jquery/chapter_7/news/
I’ve searched and searched, and haven’t been able to find anyone else having the problem… Am I alone? Does anyone know of a workaround? Or is it possible I’ve just done something completely wrong here?
$(document).ready(function(){
var toggleMinus = '../icons/bullet_toggle_minus.png';
var togglePlus = '../icons/bullet_toggle_plus.png';
var $subHead = $('tbody th:first-child');
$subHead.prepend('<img src="'+toggleMinus+'" alt="collapse this section" />');
$('img', $subHead)
.addClass('clickable')
.click(function()
{
var toggleSrc = $(this).attr('src');
if (toggleSrc == toggleMinus)
{
$(this)
.attr('src', togglePlus)
.parents('tr')
.siblings()
.addClass('collapsed')
// .hide(); //works fine in safari
.children() //need this for next to work in safari, because safari doesn't allow tr opacity
/*
problem is, it leaves a big space in firefox (mac, anyway) also fadein is broken
see fadein note below
*/
.fadeOut('slow');
}
else
{
$(this)
.attr('src', toggleMinus)
.parents('tr')
.siblings()
.not('.filtered')
.removeClass('collapsed')
// .show(); //works fine in safari, when hide is used above
/*
the following totally breaks in safari... each time it's called, it adds more table cells
first, it's one td for each existing td, then subsequent, it's one less than the original
number of tds... so you have four at first, then eight, then eleven, then fourteen, etc.
*/
.children()
.fadeIn('slow');
}
});
});
thanks so much!
tree
December 3rd, 2007 at 1:02 pm
Hi,
justed want to say “Thanks!” for such an invaluable book. I’m one of the many developers to whom Jquery (and your book) opened the doors of rich client scripting.
That said, I have a little question about table filtering. I was able to set up filtering for my table using some <select>, using the following code:
The above code will generate a <select> for each column marked as filterable. But, as soon as another select gets clicked, the previous filtering will be “forgotten” by the script. In other words, only the last clicked select is considered.
Now, I wish to push filtering a step further, i.e. combining multiple filters. The user should be able to filter rows using one select and then refine his/her search using other ones.
Any advice will be appreciated.
Thanks,
Corrado Fiore
December 3rd, 2007 at 3:01 pm
Hi Corrado,
I’m so glad you like the book! To keep filtering, try replacing these lines …
with these …