Toolkit:widgets:magicTable

From Surebert wiki

Contents

Overview

Surebert magicTable can be HTML table in the DOM or tables you create on the fly. MagicTables are sortable, can easily load additional rows via javascript, and have a multitude of events that make working with HTML tables easy.

The code can be found at http://surebert.com/svn/toolkit/trunk/widget/magicTable.js

Requirements

sb.magicTable load in String.prototype.stripHTML. If you don't want an additional ajax request going out to grab it with sb.include than include it in your /surebert/load statement or sb.js compressed file.

HTML Markup

to use sb.widget.magicTable your table HTML markup must have a <thead> which contains a row <tr> of header cells <th>. It also must have a <tbody> element which contains rows <tr> the data cells <td>

Here is example HTML table markup we could use

html4strict code

<table id="myTable">
	<thead>
		<tr><th>Name</th><th>Sex</th><th>Age</th><th>Extension</th></tr>
	</thead>
 
	<tbody>
		<tr><td>Paul</td><td>m</td><td>31</td><td>7445</td></tr>
		<tr><td>Sally</td><td>f</td><td>23</td><td>1234</td></tr>
		<tr><td>Tim</td><td>m</td><td>67</td><td>3456</td></tr>
		<tr><td>Tom</td><td>m</td><td>19</td><td>5665</td></tr>
		<tr><td>Sarah</td><td>f</td><td>13</td><td>1245</td></tr>
		<tr><td>Melinda</td><td>f</td><td>41</td><td>3333</td></tr>
	</tbody>
</table>

javascript code

var myTable = new sb.widget.magicTable({
	table : '#myTable',
	sortable : true
});

You can also build a table using the magicTable constructor directly. The same table built from javascript would use the following

javascript code

var myTable = new sb.widget.magicTable({
	table : {
		headers : ['Name', 'Sex', 'Age', 'Extension'],
		rows : [
			['Paul', 'm', 31, 7445],
			['Sally', 'f', 23, 1234],
			['Tim', 'm', 67, 3456],
			['Tom', 'm', 19, 5665],
			['Sarah', 'f', 13, 1245],
			['Melinda', 'f', 41, 3333]
		]
	},
	sortable : true
});
 
//you must also append it to the DOM somewhere, using the surebert Element.prototype.appendTo
myTable.table.appendTo('body');

Usage tips

  • sb.widget.magicTable instances which are sortable can be sorted by clicking on the <th> of the column you want to sort by. Click once to sort ascending or twice to sort descending.
  • To auto sort by a column without clicking, use the this.sortBy() method. See below.

javascript code

myTable.sortBy('age');

Styles

sb.widget.magicTable instances use CSS.

  • By default, sortable column headers are given the className sb_sortable
  • Any <th> you do not want to be able to sort by should have the class sb_unsortable
  • The <th> that is currently being sorted by is given the className sb_sorted_by
  • Any <th> that you want to force the sort type of should be given the className sb_force_sort'+TheTypeOfSortYouWant e.g. sb_force_sort_alpha'

Directional sort styles

By default, columns being sorting ascendingly get a ↓ and columns being sorted descendingly get a ↑ If instead you want to use different styles to represent ascending and descending, you can add a .up and .down className to the instances .classes property.

The class you want applied to any header being sorted in ascending order

javascript code

myTable.classes.asc = 'asc';

The class you want applied to any header being sorted in descending order (reverse)

javascript code

myTable.classes.desc = 'desc';

Then you would need corresponding CSS. Say you had a 20pxx20px custom up and down arrow graphic. This makes room for the graphic and uses the custom graphic instead of the default HTML entity arrows

css code

#myTable th{
	padding-right:25px;
	background-repeat:no-repeat;
	background-position:top right;
}
 
#myTable th.asc{
	background-image:url('/media/down.png');
}
 
#myTable th.desc{
	background-image:url('/media/up.png');
}

You can define or override the default CSS class names by setting other classes in the constructor argument e.g.

javascript code

var myTable = new sb.widget.magicTable({
	table : '#myTable',
	sortable : true,
	classes : {
		sortable : 'my_sortable_class',
		unsortable : 'my_unsortable_class',
		sorted_by : 'my_unsortable_class',
		force_sort : 'my_force_sort_class',
		desc : 'desc',
		asc : 'asc'
	}
});


Even/odd row styles

If you specify an even and odd class those classes will be applied to the rows after every sort. This handles even and odd row coloring in browsers that can't handle the CSS for it e.g. IE 6, firefox 3

javascript code

var myTable = new sb.widget.magicTable({
	table : '#myTable',
	sortable : true,
	classes : {
		even : 'even',
		odd : 'odd'
	}
});

Simply this CSS would work Safari and is less overhead, but since it is not cross browser compatible, the above example is better unless you are only targeting safari

css code

tr:nth-child(even) {background: #CCC}
tr:nth-child(odd) {background: #FFF}

Properties

table

A $ reference to the instance's table node with all is Element.prototype goodness.

body

A $ reference to the <tbody> of the this.table

head

A $ reference to the <thead> of the this.table

defaultSortedBy

The column name of cell index of the default column to sort by

Event Handlers

onCellClick

Fires when you click on a <td> table cell. It receives the <td> as the first argument. The "this" of the function is the magicTable instance itself.

This example handler turns the <td>'s background color pink. If it detects that the innerHTML of the <td> is the word delete, it removes the <td>'s parent

javascript code

myTable.onCellClick = function(td){
	td.style.backgroundColor = 'pink';
	if(td.innerHTML == 'delete'){
		$(td.parentNode).remove();
	}
};

onCellMouseOver

Fires when you mouseover a <td> table cell. The <td> reference is passed to the function, and the "this" is the magicTable instance itself.

javascript code

myTable.onCellMouseOver = function(td){
	td.style.backgroundColor = 'blue';
};

File:Example.jpg

onCellMouseOut

Fires when you mouseOut of a <td> table cell. The <td> reference is passed to the function, and the "this" is the magicTable instance itself.

javascript code

myTable.onCellMouseOut = function(td){
	td.style.backgroundColor = '';
}

File:Example.jpg

onHeaderClick

Fires when you click on a <th>. The <th> reference is passed to the function, and the "this" is the magicTable instance itself.

javascript code

myTable.onHeaderClick = function(th){
	th.style.backgroundColor = 'blue';
};

onRowClick

Fires when you click on a <tr>. It receives the <tr> clicked as the first argument. The "this" of the function is the magicTable instance itself. onRowClick fires right after onCellClick

This example handler turns the <tr>'s background color blue. If it detects that the innerHTML of the <td> is the word delete, it removes the <td>'s parent

javascript code

myTable.onRowClick = function(tr){
	tr.style.backgroundColor = 'blue';
};

onColClick

Fires when you click on a <td> table cell. It receives the a special object which represents the column clicked as their is no DOM node to represent this as with onCellClick and onRowClick. The "this" of the function is the magicTable instance itself.

column argument properties

  • column.title The title of the column clicked. The innerHTML stripped of its <th>
  • column.values The values of the column cells in an array
  • column.th The DOM reference to the <th> of the column clicked
  • column.tds A sb.nodeList of the <td>s that were in the column
  • column.prevColumn The column object of the previous column clicked.


This example changes the column clickeds backgroundColor to yellow and changes the previous columns background back to if it exists

javascript code

myTable.onColClick = function(column){
 
	column.tds.styles({
		backgroundColor : 'yellow'
	});
 
	if(column.prevColumn){
		column.prevColumn.tds.styles({
			backgroundColor : ''
		});
	}
 
};

onBeforeSort

fires after .sortBy() is called or after actual sort is done by clicking on a header but before actual sort takes place. The "this" is the magicTable instance itself. It receives a reference to the <th> that heads the column that was sorted as its first argument. The "this" of the function is the magicTable instance itself.

This example handler just alerts the column header innerHTML just before it sorts it. Not so useful, sorry.

javascript code

myTable.onBeforeSort = function(th){
 
	alert(th.innerHTML);
 
};

onAfterSort

fires after .sortBy() is called or after actual sort is done by clicking on a header and after sorting takes place. The "this" is the magicTable instance itself. It receives a reference to the <th> that heads the column that was sorted as its first argument. The "this" of the function is the magicTable instance itself.

This example handler assumes the first colum in the table was just the a column representing row number. After the table gets sorted either by .sortBy or when the user clicks on a header, this re-orders those numbers in the first column so they still make sense.

javascript code

myTable.onAfterSort = function(th){
	//renumber the first td in each row after sort
	var rows = this.table.$('tbody tr');
	var x = 1;
	rows.forEach(function(v){
		v.firstChild.innerHTML = x;
		x++;
	});
};

Methods

addRows

Add additional rows to the end of a table.

You can load one row

javascript code

myTable.addRows(['Julie', 'f', 54, 3456]);

or many rows

javascript code

myTable.addRows([['Julie', 'f', 54, 3456],
['Wendy', 'f', 22, 4562],
['Gina', 'f', 78, 5773],
['Timmy', 'm', 12, 5467],
['Jason', 'm', 45, 3452],
['Tony', 'm', 5, 3456]]);

getCellValue

Used to get the value of a table body <td> cell by row and cell index. They are both zero based. You can use it two ways:

returns the value of the td node passed to the function

javascript code

var data = myTable.getCellValue(td);

or pass it a coordinate, returns the value of cell 3 in row 0

javascript code

var data = myTable.getCellValue(0,3);

getHeaderValue

Used to get the value of a table head <th> cell by cell index. It is zero based. You can use it two ways: returns the value of the th node passed to the function

javascript code

var data = myTable.getHeaderValue(th);

or pass it a coordinate, returns the value of cell 3

javascript code

var data = myTable.getHeaderValue(3);

loadRows

Works like addRows but loads the row data from an external URL. The rows are added to the bottom of the table.

javascript code

myTable.loadRows('/table/more/rows');

If you want to do somethign once the data arrives change sthe argument from a string url to an object with url and onLoad properties e.g.

javascript code

myTable.loadRows({
	url : '/table/more/rows',
	onLoad : function(response){
		//do something with table
		return true;
	}
});

The url /table/more/rows should provide a JSON array that represents more rows with the same number of columns. e.g.

javascript code

[['Julie', 'f', 54, 3456],
['Wendy', 'f', 22, 4562],
['Gina', 'f', 78, 5773],
['Timmy', 'm', 12, 5467],
['Jason', 'm', 45, 3452],
['Tony', 'm', 5, 3456]]

removeRows

Removes rows from a magicTable instance, rows start at 0

javascript code

//removes row 1
myTable.removeRows(1);
 
//all rows in the array
myTable.removeRows([0,1,5,7]);
 
//remove all rows in range
myTable.removeRows('0-2');

sortBy

Sorts the table by a specifc row. You pass the header name and optionally if you want it reversed or not. You can also sort by column index, starting at 0 for the first column, or by passing a DOM node reference to the <th> itself that you want to sort by.

e.g.

javascript code

//sort by column with innerHTML 'age'
myTable.sortBy('age');
 
//or reverse
myTable.sortBy('age', true);
 
//sort by column index, they start at zero.
myTable.sortBy(0);
 
//sort by a <th> node DOM reference
myTable.sortBy(th);

setSortTypes

Allow you to predefine the column sort types, must match column header. Compare types defined in sb.widget.magicTable.prototype.compare

e.g.

javascript code

myTable.setSortTypes(['alpha', 'natural', 'usdate', 'usdate', 'alpha']);

Sort Types

All the sort types that magicTable is aware of are defined in sb.widget.magicTable.prototype.compare. You can also add you own sort types. By default the following types exist:

  • alpha
  • reverseAlpha
  • nocase
  • currency
  • numeric
  • natural
  • date
  • usdate

Advanced Usage

Create a table that loads more data to the bottom and removes from the top to keep updating on a timer

This loads data every 5 seconds and removes as many rows as it ads. Say you loaded two new rows, they would be appended to the bottom and then you remove 2 rows from the top.

javascript code

window.setInterval(function(){
	myTable.loadRows({
		url : '/table/data/more',
		onLoaded : function(rows){
			myTable.removeRows('0-'+(rows.length-1));
		}
	});
}, 5000);