42

jQuery Scrollable Table Plugin

jQuery, write less, do more

This jQuery plugin converts a properly formatted table, having thead and tbody elements (tfoot optional), into a scrollable table. Scrollable tables are most useful when having to display lots of tubular data in a fixed space.

Show Me The Money (Demo)

city state code zip latitude longitude county
Holtsville NY 00501 40.8152 -73.0455 Suffolk
Holtsville NY 00544 40.8152 -73.0455 Suffolk
Adjuntas PR 00601 18.1788 -66.7516 Adjuntas
Aguada PR 00602 18.381389 -67.188611 Aguada
Aguadilla PR 00603 18.4554 -67.1308 Aguadilla
Aguadilla PR 00604 18.4812 -67.1467 Aguadilla
Aguadilla PR 00605 18.429444 -67.154444 Aguadilla
Maricao PR 00606 18.182778 -66.980278 Maricao
Anasco PR 00610 18.284722 -67.14 Anasco
Angeles PR 00611 18.286944 -66.799722 Utuado
Arecibo PR 00612 18.4389 -66.6924 Arecibo
Arecibo PR 00613 18.1399 -66.6344 Arecibo
Arecibo PR 00614 18.1399 -66.6344 Arecibo
Bajadero PR 00616 18.428611 -66.683611 Arecibo
Barceloneta PR 00617 18.4525 -66.538889 Barceloneta
10 2 15 - - 9

Table Scroll Plugin Overview

The tablescroll jQuery plugin is a simple markup manipulation plugin, it will manipulate the table, create a couple of new elements and wrap everything in a DIV.

Using the plugin is pretty straight forward, when you download the plugin you can view the demo file to get up to speed and begin working with it immediately.

The HTML TABLE markup is also pretty basic:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<table id="thetable" cellspacing="0">
<thead>
	<tr>
	  <td>city</td>
	  <td>state code</td>
	  <td>zip</td>
	  <td>latitude</td>
	  <td>longitude</td>
	  <td>county</td>
	</tr>
</thead>
<tbody>
	<tr class="first">
	  <td>Holtsville</td>
	  <td>NY</td>
	  <td>00501</td>
	  <td>40.8152</td>
	  <td>-73.0455</td>
	  <td>Suffolk</td>
	</tr>
	<tr>
	  <td>Holtsville</td>
	  <td>NY</td>
	  <td>00544</td>
	  <td>40.8152</td>
	  <td>-73.0455</td>
	  <td>Suffolk</td>
	</tr>
	<tr>
	  <td>Adjuntas</td>
	  <td>PR</td>
	  <td>00601</td>
	  <td>18.1788</td>
	  <td>-66.7516</td>
	  <td>Adjuntas</td>
	</tr>
</tbody>
<tfoot>
	<tr>
	  <td>city</td>
	  <td>state code</td>
	  <td>zip</td>
	  <td>latitude</td>
	  <td>longitude</td>
	  <td>county</td>
	</tr>
</tfoot>
</table>

Styling the table should go pretty smoothly, but be warned, the plugin does some width/height calculations which require the styles to be in place prior to doing the calculations.

Here is the demo CSS which should get you started:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.tablescroll
{ font: 12px normal Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif; background-color:#fff; }
 
.tablescroll td, 
.tablescroll_wrapper,
.tablescroll_head,
.tablescroll_foot
{ border:1px solid #ccc; }
 
.tablescroll td
{ padding:3px 5px; }
 
.tablescroll_wrapper
{ border-left:0; }
 
.tablescroll_head
{ font-size:11px; font-weight:bold; background-color:#eee; border-left:0; border-top:0; margin-bottom:3px; }
 
.tablescroll thead td
{ border-right:0; border-bottom:0; }
 
.tablescroll tbody td
{ border-right:0; border-bottom:0; }
 
.tablescroll tbody tr.first td
{ border-top:0; }
 
.tablescroll_foot
{ font-weight:bold; background-color:#eee; border-left:0; border-top:0; margin-top:3px; }
 
.tablescroll tfoot td
{ border-right:0; border-bottom:0; }

The plugin is basic and only has a few options:

1
2
3
4
5
6
7
$.fn.tableScroll.defaults =
{
	flush: true, // makes the last thead and tbody column flush with the scrollbar
	width: null, // width of the table (head, body and foot), null defaults to the tables natural width
	height: 100, // height of the scrollable area
	containerClass: 'tablescroll' // the plugin wraps the table in a div with this css class
};

Like most jQuery plugins, implementation is a snap:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
jQuery(document).ready(function($)
{
	$('#thetable').tableScroll({height:200});
 
	// other examples
 
	// sets the table to have a scrollable area of 200px
	$('#thetable').tableScroll({height:200}); 
 
	// sets a hard width limit for the table, setting this too small 
	// may not always work
	$('#thetable').tableScroll({width:400}); 
 
	// by default the plugin will wrap everything in a div with this 
	// css class, if it finds that you have manually wrapped the 
	// table with a custom element using this same css class it 
	// will forgo creating a container DIV element
	$('#thetable').tableScroll({containerClass:'myCustomClass'});
});

Like many projects, we developers build out of necessity. I couldn’t quite find what I needed, so i wrote my own! This plugin accomplished all of what I needed, and I thought it useful enough that I would share. If you have any feature requests and/or bug reports please let me know. And the plugin name is pretty generic too (if you have a better one, feel free to drop me a line).

I’ve tested the plugin on Windows with Chrome, FF 3.6, IE 6, IE 8, Safari 4. If anyone is on a Mac, please let me know what your results are?

Download

jQuery TableScroll plugin, this project is on github

Related posts

  1. jQuery Image Preload Plugin
  2. WordPress HiFi Plugin — Head and Foot Injection
  3. WordPress Peekaboo Plugin

{ 42 comments… read them below or add one }

plug April 15, 2010 at 2:06 pm

I needed a scroller for an autogenerated table, and after much fruitless searching for a simple *and* working jQuery table scroller… this one looks like it could be the one :)

I’m on a mac. Just having a quick look on a few browsers now:

FF 3.6.3 – perfect
Opera 10.0 – perfect
Safari 4.0.3 – showing a horizontal scrollbar but otherwise perfect. I’m sure some css will sort knock some sense into that.

I’m cautiously optimistic about checking it on IEx tomorrow :) containerClass is a useful detail too. keep up the good work!

Dimas April 15, 2010 at 4:20 pm

I’m hope that it proves useful to you, please give me any feedback you have so that I can improve the code and make it more robust.

The original project I coded this for needed it primarily for IE6. All my tests worked well on IE6, 7, and 8!

phil May 4, 2010 at 9:43 am

Scrollbars appear, but they don’t constrain the height. The height of the tablescroll_wrapper is set to auto, so no matter what the table’s size is never constrained to the size I set with tableScroll({height:#}); I’m using Safari. I have the table inside another div with a height and max-height set, but the table still expands past this height.

any ideas?

Dimas May 4, 2010 at 10:17 am

phil, for me the demo on this page works as expected in Safari PC, does it also work for you? Send me your source and I’ll take a look at it dimas3 [at] farinspace [dot] com

ian May 5, 2010 at 2:11 am

hi ..
after i play arround with this plugin i find it is cool and very neat ..

but I encounter a problem, when the table height is not long enough for the scroll height, the layout seem like running out ..

do you have any solution on this ?

Dimas May 5, 2010 at 9:16 am

Ian, I’ve applied a fix to the code, download it again and give it a spin…

ian May 5, 2010 at 6:04 pm

thx dimas for you quick fixed. it works !!

really appreciate it…

kingjesse2 May 6, 2010 at 5:04 pm

All I can say is thank God for you and your plugin. I’ve been trying to get IE8 to allow me to scroll the body of a table but it doesn’t seem to like any height restrictions on table body length. This plugin helped me soo much-I wish I wouldn’t have spent the past 6 hours trying to figure out how to do this….

Dimas May 6, 2010 at 5:33 pm

I’m glade you found it useful. I tried to keep the plugin simple, which should allow anyone to further extend it and customize it for their needs.

ian May 7, 2010 at 9:47 pm

omg .. i find the plugin cound’t work in IE7.

Do you have any idea how to make it work ?

Dimas May 7, 2010 at 10:21 pm

Ian, What issues are you experiencing with IE7? I did a quick test an all seems fine…

ian May 7, 2010 at 10:32 pm

ermmm…

now it work back? i wonder whether is my IE issue or not.

I’m using the IETester to test whether it work. it some how the past few hour didn’t work .. now I close all and open it back .. it seem work.

i need to do a few more test .. btw, do you have any recommend tool to test in IE7 ?

Dimas May 7, 2010 at 10:44 pm

I use VirtualBox Images primarily for IE7 and IE6 testing (most troublesome browsers)… I will definitely give IETester a try myself…

ian May 7, 2010 at 10:59 pm

dear dimas,

ok .. i also have a virtualbox (plugable version) recently, haven’t install with the troublesome browsers yet.

now i think i found what is the problem that cause in my application,
i use the following at the end of the code
$(‘#mytable’).tableScroll({ height: 200 });

where I suppose to use
$(document).ready(function() { $(‘#mytable’).tableScroll({ height: 200 }); });

but it work fine for me to use the previous method in IE6 and IE8 without problem.

i also wanna use your plugin together with the tablesorter.com, i think the combination will be the perfect solution :)

anyway .. will do more testing and report you if got any problem .. thanks a lot for your quick response and help ..

hunt May 14, 2010 at 2:00 am

Hi,

This plug-in don’t work when i am trying to add column dynamically, it works only for static tables

Dimas May 14, 2010 at 9:00 am

hunt, thanks for reporting this.

I’ve added a new version (v20100514) which supports an “undo” command which will basically revert the formatting of a table by the plugin. You can then add new columns and essentially redraw the table again.

jQuery('#thetable').tableScroll('undo');

jQuery('#thetable thead tr').append('<td>date</td>');

jQuery('#thetable tbody tr').append('<td>05/14/10</td>');

jQuery('#thetable tfoot tr').append('<td align="center">-</td>');

jQuery('#thetable').tableScroll({width:600,height:150});

Known issue: when a thead column name wraps slight alignment issues may be noticed (I’ll fix this when I have a chance)

Also, to add rows dynamically you do not need to call “undo” you would simply do the following:

jQuery('#thetable tbody').append('<tr><td>Holtsville</td><td>NY</td><td>00501</td><td>40.8152</td><td>-73.0455</td><td>Suffolk</td></tr>');
Akio Hamasaki May 17, 2010 at 1:32 pm

Works like a charm! Thanks a ton

Gee May 19, 2010 at 7:50 am

Hi Dimas

Thanks for you solution which works really well. I would be greatful if you could show me how to modify the plugin so that the header and first row as well as the first column can be frozen?

Many Thanks

Dimas May 19, 2010 at 8:33 am

Gee, when I get a moment I will try to work on those additions.

The plugin basically manipulates the original table data, pulling it apart and then reconstructs new markup.

(view source)

line 109-148 is where the thead and tfoot are pulled from the orginal table. You can modify this to also pull the first row of the table.

A possibly easier solution to locking the first row would be to include it in the thead.

Locking the table column will be a bit more tricky, as I look at it now the plugin will probably have to be revamped to allow locking of columns, I don’t see an easy solution to this in the plugin’s current state.

This plugin works best with vertically scrolling tables vs with horizontally scrolling tables (most likely where locking columns would be most useful).

Gee May 19, 2010 at 9:04 am

Thanks for your quick reply which is much appreciated. Annoyingly its the locking of the first column that we are really keen to get working as we work with large tables. I was thinking along the lines of selecting the first column using JQuery from the original table then passing it to the plugin. Even a quick hack will be much appreciated.

Many thanks again

Ken May 21, 2010 at 3:37 pm

Hi Dimas,

I very much like the plugin. So far it is serving my needs well. I have one question. I have a need to support window re-sizing etc. The plugin is great however when I my browser size increases/decreases the scrollable table does not adjust. I’ve made a few attempts to rectify this but have not arrived a ta solution yet. Do you have any ideas suggestions on what object or objects that I need to adjust the table size dynamically or perhaps a different/better solution?

I’d appreciate any help you can offer.

-Ken

jon June 2, 2010 at 2:22 am

hi,
one problem is when setting the width of a table to 100% when the scrollbar is added to the right, thus enlarging the width of the full table and i have to scroll the window to the right to see the whole scrollbar. i need some solution to keep the table width with the scrollbar the same as the table without scrollbar.
thanks

jon June 2, 2010 at 6:41 am

Another question is how to make this work on IE with jQuery v1.3.1? I’ve tested it on IE7 and the table shows both scrollbars (vertical, horizontal).

Girma June 2, 2010 at 7:12 am

Hi Dimas,

This solution is just what we are after altough we also have a requirement to be able to freeze the first column akin Excel as per Gee’s and now considering other third party datagrids. The only snag I came across from this solution is that the header columns didn’t appear to be inline with the datagrid. Any advice suggestion from anyone would be greatly appreciated.

thanks

Girma

Luca June 6, 2010 at 4:56 pm

Hi,

thanks for the great job. I got a problem with a window’s resize. The table is contained in a div with height 100% and when I resize the window, the window’s column don’t follow the scaling. Any ideas?

Luca Longo June 6, 2010 at 5:00 pm

Sorry: I made a mistake. The problem is the scaling of table’s column contained in a div with Width 100%.

Sam Blowes June 18, 2010 at 4:47 am

This is possible to work around this I have just made a modification to this plugin to accommodate for fluid designs.

Sam Blowes June 18, 2010 at 4:54 am

There seems to be a bug in your code…

In your undo function you have…

container.empty();

- This leave’s an empty div as an artifact in the dom, running your undo function multiple times leaves multiple artifacts.

Try using this…

container.remove();

Seems like a good replacement to me…

I have also written another line to reset the width’s of the table, leaving the table in its original state after the undo function is run.

Here’s my own take on your undo function.
Hope you find a use for this :)

if (options == 'undo') {
    var container = $(this).parent().parent();
    container.find('.tablescroll_head thead').prependTo(this);
    container.find('.tablescroll_foot tfoot').appendTo(this);
    container.find('.tablescroll_body, th, td').width('');
    container.before(this);
    container.remove();
    return;
}
Dimas June 21, 2010 at 9:10 pm

Sam, thanks for the code. My focus has been more on WordPress as of late, but, I will be reviewing this plugin and making adjustments to resolve most of its shortcomings.

Mat June 30, 2010 at 8:43 pm

Your plugin works well but I think it needs some CSS adjustments…

I copied the example from your site and adapted it to my web app. I noticed a slight difference between the spacing of some header columns and their corresponding data columns.

I went through your code and finally discovered that removing this CSS specification :

/*
.tablescroll td
{ padding:3px 5px; }
*/

…makes everything work as expected! Looks like adding some padding to the table cells makes the width calculations go wrong.

I’m not sure of this one but when table header’s width is set by using the $(this).width() of its child cell, maybe the padding is appended to the previously retrieved width . As a result, the total width gets larger than expected.

I’m using FF 3.6.6.

Thanks!

Mat

Björn July 10, 2010 at 2:43 am

Just what I needed -

ben August 4, 2010 at 12:14 am

Nice one!

But I am having a problem with alignment when using “colspan” in any cell inside tbody group.

can anyone help with this?

Example:

	<tbody>
		<tr class="first">
		  <td colspan="6">Holtsville</td>
		</tr>
		<tr>
		  <td>Holtsville</td>
		  <td>NY</td>
		  <td>00501</td>
		  <td>40.8152</td>
		 <td>-73.0455</td>
		  <td>Suffolk</td>
		</tr>
		<tr>
		  <td>Holtsville</td>
		  <td>NY</td>
		  <td>00544</td>
		  <td>40.8152</td>
		  <td>-73.0455</td>
		  <td>Suffolk</td>
		</tr>
	</tbody>
Sam Blowes August 4, 2010 at 8:11 am

I believe this plugin doesn’t cater for colspan in any shape or form.
You may be able to achieve a similar result using another table inside your td rather than using col span

Example:


		  Holtsville

		  Holtsville
		  NY
		  00501
		  40.8152
		 -73.0455
		  Suffolk
Jon Kruger August 5, 2010 at 4:55 am

Doesn’t seem to get the widths of the column headers right if I have hidden columns in my table (I need the hidden columns for the table sorting plugin that I’m using.

Adam Daughterson August 11, 2010 at 3:48 pm

Dumb question: I have *lots* of data going to the table, and prior to its being re-rendered, the “native” ugly table is displayed. Is there a way to hide the table until jquery.tablescroll.js is done with its magic?
Thanks!

Dimas August 12, 2010 at 2:43 pm

@Jon, what sorting plugin are you using?

@Adam, I will see if i can solve this. I tried using some css to hide the table prior to rendering, but this does no good as some of the calculations need the table to be visible. My next test will be to move the table off stage left and then redisplay it after rendering.

bln August 23, 2010 at 5:37 am

Here is a good jquery plugin, working in all browsers !

You have a fixed header table without fixing his width…

Check it : http://www.tablefixedheader.com

Dimas August 23, 2010 at 6:47 am

bln, very nice plugin, great job!

Fuxi August 30, 2010 at 4:40 am

hi dimas,

your plugin is just wonderful – but i encountered a little problem with it:
i’m using ajax for dynamically loading the table’s content.
so the problem is: after loading i need to re-apply the plugin to the table which will end up in a little mess :)

so the plugin should check it was already applied before to the table (classes, wrappers and such) and then only apply things like syncing column widths.

could you please add this? :)

thanks in advance

Dimas August 30, 2010 at 6:59 am

Fuxi, try using:

// first applied
jQuery('#thetable').tableScroll({width:600,height:150});

// undo
jQuery('#thetable').tableScroll('undo');

// reapplied
jQuery('#thetable').tableScroll({width:600,height:150});
Sean LeBlanc August 30, 2010 at 3:39 pm

Hi, I was having the same problem as Fuxi was, and your fix seems to work – except for the header. I’ve noticed that for each new row I add, it scoots the header over to the left a few pixels. Any ideas on how to work around that?

Fuxi August 30, 2010 at 5:30 pm

hi dimas,

sorry – i accidentaly submitted my post too early .. :(

thx for your reply. i’ve tried the undo method but unfortunately it seems to be a bit buggy.

i’ve used the sample supplied from the download and changed the code as u suggested:

jQuery(document).ready(function($)
{
$(‘#thetable’).tableScroll({height:150});
$(‘#thetable’).tableScroll(‘undo’);
$(‘#thetable’).tableScroll({height:150});

$(‘#thetable2′).tableScroll();
});

when checking the source code after that, you’ll notice that inside the <div class=”tablescroll> there’s a second, obsolete div:

<div class=”tablescroll” ></div>

if u undo + re-apply a several times it will be added each time!

when using the plugin on a table which is placed within several other wrappers, things are chaotic – unfortunately i couldn’t reproduce yet – but other div elements outside the table are getting involved as if there’s injected some div which isn’t closed and the html gets messed up.

so i think the easiest way to solve this should be a “init” flag after the plugin is applied for the first time and if it’s already initialized it should only perform the required other functions.

hope i could describe my problem properly :)

thx

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
<pre lang="" line="" escaped="">

Previous post:

Next post: