Return to article

TableKit

Introduction

TableKit is a collection of HTML table enhancements using the Prototype framework. TableKit currently implements row striping, column sorting, column resizing and cell editing using Ajax.

Demo: Sortable/Resizable/Editable

Click the table header cells to sort the column, resize the column by dragging the right border of a header cell, click a cell in the table body to edit the value.

UrgencyDateTimeTitleStatusRequested ByCostSize
UrgencyDateTimeTitleStatusRequested ByCostSize
5
24/10/2005 10:47:41 AM10:47:41 AMKeyboard is BrokenIn ProgressTom$200.0030KB
5
24/10/2005 10:49:41 AM10:49:41 AMKeyboard is BrokenIn ProgressTom$200.0030 KB
3
24/10/2005 10:49:41 PM10:49:41 PMWindows is crashingNewBill$300.0030MB
4
17/02/200612:43:16 PMHelp, I'm on fire!NewJohn$250.0030KB
3
06/07/2006xxx03:04:34 PMThe ring came off my pudding canAssignedTom$200.5030GB
2
06/07/200615:06:10Should I open this email?AssignedTom$50.3530TB
1
06/07/200604:12:16 PMI can't printAssignedBill$2005.3030KB
2
31/12/200609:35:47 AMThe internet is brokenAssignedJill$600.0032KB
3
17/07/200604:21:24 PMBlank ScreenAssignedXavier$100.3010GB
4
24/10/2005 01:09:00 AM01:09:00 AMMy cup holder is not workingClosedMark$100.4020 MB
5
24/10/2005 12:47:41 AM12:47:41 AMKeyboard is BrokenIn ProgressTom$200.0030KB
5
24/10/2005 01:49:41 PM01:49:41 PMKeyboard is BrokenClosedTom$200.0030 KB
3
24/10/2005 12:49:41 PM12:49:41 PMWindows is crashingNewBill$300.0030MB
4
17/02/200612:43:16 PMHelp, I'm on fire!NewJohn$250.0030KB
3
06/07/200603:04:34 PMThe ring came off my pudding canAssignedTom$200.5030GB
2
06/07/200615:06:10Should I open this email?ClosedTom$50.3530TB
1
06/07/200604:12:16 PMI can't printAssignedBill$2005.3030KB
2
31/12/200609:35:47 AMThe internet is brokenAssignedJill$600.0032KB
3
17/07/200604:21:24 PMBlank ScreenAssignedXavier$100.3010GB
4
26/07/200603:09:00 PMMy cup holder is not workingIn ProgressMark$100.4020 MB

Documentation

 

TableKit Basics

Installation

Reference the script in your HTML: Prototype and tablekit.js are required of course; Fastinit is optional.

<script type="text/javascript" src="scriptaculous/lib/prototype.js"></script>
<script type="text/javascript" src="fastinit.js"></script>
<script type="text/javascript" src="tablekit.js"></script>

Simple Usage

The easiest way to use TableKit is reference the script in your HTML and give you tables appropriate classes:

<table class="sortable resizable editable">

When a table is initialised, if it doesn't have an id attribute one will be assigned in the form tablekit-table-nn where nn is an incremented number

Options

These are the options used globally for all tables unless otherwise speified.

Options can be modified directly, for example

TableKit.options.rowEvenClass = 'even';

If you supply options using the initialisation methods below, those options will be used for that table only, using the table's id attribute. This way you can specify different options for different tables.

Usage Styles

TableKit supports several usage styles when initialising. You can use table class names as described above or one of the following options.

By Selector

You can change the selector used for automatic initialisation

TableKit.options.sortableSelector = ['table.data-table'];

By Manual Initialisation

You can initialise a specific table using the init() function

TableKit.Sortable.init(table, {options});

By Object Creation

You can create a TableKit option.

var table = new TableKit(table, {options});

A TableKit object has only a few methods that only need to be called if you need to, otherwise all the functionality works automatically

table.sort(column, order) // sort a particular column
table.resizeColumn(column, w) // resize a particular column
table.editCell(row, column) // edit a specific cell

Next Page : 'Sortable' >

TableKit.Sortable

Activation

If the table has a thead then the last row of the thead (the one closest to the body) will be used as the header row to add the sorting 'onclick' event listeners - one to each header cell. If there is no thead the first table row will be used. Only rows in the table body are sorted, all other cells (in the thead or tfoot) are ignored.

Sorting Types

The table will attempt to automatically detect the sorting type for your columns (text, number, date...etc) by analysing the first cell. If you don't want it to do that you can specify the exact sorting by adding a class to your header cell for example class="number". Available ones are:

A special notes about dates: By default the script's automatic sort type detection will favour Australian dates, dd/mm/yyyy. If you want it to favour US dates, mm/dd/yyyy, then either add the class "date-us" to the header cell on the date column or read Advanced Sorting Types below.

CSS Hooks

No Sort columns

If you don't want a column to be sorted then give the header cell a class of "nosort".

Sort First Column

If you want a column to be sorted when the page loads then add a class to the header cell of that column; "sortfirstasc" for ascending and "sortfirstdesc" for descending.

Other CSS Hooks

Header cells will be given the class "sortcol", and when sorted they will be given the class "sortasc" for ascending and "sortdesc" for descending.

API

You can initialise a specific table by using:

TableKit.Sortable.init(table, {options});

where table is a table element reference or ID and options are options matching the TableKit global options, you wish to apply to this table only.

To sort a specific table column (for example if you want to use an external control) you can call the sort function manually.

TableKit.Sortable.sort(table, index, order);

Advanced Sorting Types

a collection of TableKit.Sortable.Type objects handles data type detection and sorting. Each one has a name. The sort function will attempt to match a sort type to a column by first reading the column header cell's id, then all the class names and finally will try automatic detection.

Automatic Detection

The TableKit.Sortable.detectors property is an array of sort type names. Each TableKit.Sortable.Type is queried to see if the first column cell's contents matches the sort type. The default list is:

TableKit.Sortable.detectors = $w('date-iso date date-eu date-au time currency datasize number casesensitivetext text');

You can change it according to your requirements.

Custom Sorting Types

You can create a custom sort type by creating one or more TableKit.Sortable.Type objects and adding them using the TableKit.Sortable.addSortType() function. That function can take any number of objects as arguments. For example:

TableKit.Sortable.addSortType(
new TableKit.Sortable.Type('type1', {options}),
new TableKit.Sortable.Type('type2', {options})

The first argument of a new type object is its name, the second is an array of options that control how the sort type detects and compares. Here's an example:

TableKit.Sortable.addSortType(
	new TableKit.Sortable.Type('number', {
		pattern : /^[-+]?[\d]*\.?[\d]+(?:[eE][-+]?[\d]+)?/,
		normal : function(v) {
			// This will grab the first thing that looks like a number from a string, so you can use it to order a column of various srings containing numbers.
			v = parseFloat(v.replace(/^.*?([-+]?[\d]*\.?[\d]+(?:[eE][-+]?[\d]+)?).*$/,"$1"));
			return isNaN(v) ? 0 : v;
		}
	})
);				

If the default comparison function is not adequate you can specifiy your own by adding compare: function(a,b){} to the options. This function that takes 2 arguments, the 2 values being compared, and returns either 1, 0 or -1. 1 if a is greater than b, -1 if b is greater than a and 0 if they are equal. The default comparison function looks like this:

TableKit.Sortable.Type.prototype.compare = function(a,b){
		return TableKit.Sortable.Type.compare(this.normal(a), this.normal(b));
}
TableKit.Sortable.Type.compare = function(a,b) {
	return a < b ? -1 : a == b ? 0 : 1;
}

Here's an example of custom sort type usage from the demo. I've added a sort type called 'status' to sort the Status column appropriately. I've given the header cell of that column an id of 'status' so that it will use my custom sort type.

TableKit.Sortable.addSortType(
	new TableKit.Sortable.Type('status', {
		pattern : /^[New|Assigned|In Progress|Closed]$/,
		normal : function(v) {
			switch(v) {
				case 'New':
					return 0;
					break;
				case 'Assigned':
					return 1;
					break;
				case 'In Progress':
					return 2;
					break;
				case 'Closed':
					return 3;
					break;
				default:
					return 4;
			}
		}
	}
));

TableKit.Rows

When sorting a table, body rows will also be given the alternating classes "rowodd" and "roweven" on load and after each sort as an added bonus.

API

If you just want to stripe a table you can use:

TableKit.Rows.stripe(table)

where table is a table element reference or ID

Next Page : 'Resizable' >

TableKit.Resizable

Activation

The table header cells are used to trigger column resizing. When the mouse pointer moves close to the right edge of the cell, the cell is given the class 'resize-handle-active' and a 'mousedown' event listener is enabled. If the mousedown event occurs a drag handle is created and the user can drag it left and right. When the mouse button is released the column's width is adjusted accordingly.

Because we are resizing a HTML table the columns may not resize exactly as intended as opposed to a proper data grid. Browsers tend to recalibrate all table columns according to the maximum width of the table, which by default is 100% and the contents of the cells.

CSS Hooks

When appripriate the cell is given the class 'resize-handle-active', which can be used to set the cursor style (as it is in the demo). The resize handle itself is a div element with a class of 'resize-handle'. This can be used to style the resize handle.

API

You can initialise a specific table by using:

TableKit.Resizable.init(table, {options});

where table is a table element reference or ID and options are options matching the TableKit global options, you wish to apply to this table only.

To resize a specific table column (for example if you want to use an external control) you can call the resize function manually.

TableKit.Resizable.resize(table, index, w);

Next Page : 'Editable' >

TableKit.Editable

Activation

Once the table is initialised, a mouse click on a table body cell, will activate a HTML form allowing the user to edit the new value via a Prototype Ajax.Updater.

API

You can initialise a specific table by using:

TableKit.Editable.init(table, {options});

where table is a table element reference or ID and options are options matching the TableKit global options, you wish to apply to this table only.

To edit a specific table cell (for example if you want to use an external control) you can call the edit function manually.

TableKit.Editable.editCell(table, index, cindex);

Cell Editors

A collection of TableKit.Editable.CellEditor objects handles cell editing. Each CellEditor has a name and this name is matched to the id or class name of the column header cell to find the appropriate editor, otherwise a standard text input is used.

Adding cell editors is easy:

TableKit.Editable.textInput(name,attributes); // creates a standard text input (the default)
TableKit.Editable.multiLineInput(name,attributes); // creates a text area
TableKit.Editable.selectInput(name,attributes,selectOptions); // creates a select element

The demo is setup this way:

TableKit.Editable.selectInput('urgency', {}, [
			['1','1'],
			['2','2'],
			['3','3'],
			['4','4'],
			['5','5']																												
		]);
TableKit.Editable.multiLineInput('title');

The demo has a select editor for the Urgency column and a textarea for the Title column.

Updating the Cell

Each cell editor uses a Prototype Ajax Updater. The POST body is generated from the following:

'&row=n&cell=n&id=id&field=field&value=xxxxxx'

This information is POSTed to the URI specified in TableKit.options.editAjaxURI by default. If you initialise a table with options you can specify a different URI for each table. You can also specify a different URI in custom cell editors (see below)

Similarly the Ajax Updater uses the options from TableKit.options.editAjaxOptions

Custom Cell Editors

To make your own cell editor simply make a new TableKit.Editable.CellEditor object and add it to the collection using the TableKit.Editable.addCellEditor function. For example:

TableKit.Editable.addCellEditor(
	new TableKit.Editable.CellEditor('yourname', {
		element : 'select',
		attributes : {name : 'favourite_food', title : 'Please select your favourite food from the list'},
		selectOptions : [['Cheese','Cheese'],['Llama','Llama'],['Staot','Staot'],['Halibut','Halibut']]
	})
);

The available options are:

Custom Cell Editor Objects

Of course you can write your own cell editor objects from scratch. A cell editor object is really just an object with one property name and one method edit

customEditorObject = function(name) {
	this.name = name;
}
customEditorObject.prototype.edit = function(cell){ //do something }

The edit function is called when a body cell is clicked on. The function should handle setting up the form and handling the submit event. It can be added to the collection using the standard TableKit.Editable.addCellEditor function