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'; };
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 = ''; }
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);