FixedHeaderTable widget

Widget for rendering a table with a specified height, width and with a static header.
Tested in the FF3, IE6-7, Opera browsers.
Table 1.

Template

FixedHeaderTable.html file.
<div><div class="fixedHeaderTable" dojoAttachPoint="Wrapper">
    <div class="fixedHeaderTableHeader" dojoAttachPoint="fixedHeader"></div>
    <div class="fixedHeaderTableBodyWrapper">
        <table class="fixedHeaderTableBody" dojoAttachPoint="Container"></table>
    </div>
</div></div>

CSS

.fixedHeaderTable{ background:DodgerBlue;border:1px solid olive; }
.fixedHeaderTableHeader{
	border-bottom:1px solid red;
	background:DodgerBlue;
	height:21px;line-height:19px; /* no width */
	white-space:nowrap;
	overflow:hidden;
} 
.fixedHeaderTableHeader div {
	padding:1px 5px;
	overflow:hidden;
	float:left; 
	border-right:1px solid orange;
}
html:first-child .fixedHeaderTableBodyWrapper{overflow:auto;} /* older Opera */
.fixedHeaderTableBodyWrapper {
	overflow-y:auto;
	overflow-x:hidden;
	background:yellow;
	clear:left;
} 
.fixedHeaderTableBodyWrapper table{border-collapse:collapse;width:100%;}
.fixedHeaderTableBodyWrapper td{
	padding:1px 5px; /* pixels */
	border-right:1px solid green; 
	border-bottom:1px solid green;
}
.fixedHeaderTableBodyWrapper .row_a{background:lightgreen;}
.fixedHeaderTableBodyWrapper .row_b{background:lightblue;}
.fixedHeaderTableBodyWrapper .centered{text-align:center;color:crimson;}
.fixedHeaderTableBodyWrapper .orange{background:orange;}

Javascript Code

FixedHeaderTable.js file

HTML

A placeholder for the FixedHeaderTable widget
<div id="ph"></div>

Initialization

Due to a specific data for an initializing a FixedHeaderTable widget
the prefered way is a programmatic one.

// dojo.require in the <head>
dojo.require("my.FixedHeaderTable");

<script>
	dojo.addOnLoad(function(){
		var rows = [
			{ className:'', id='', data:['first1','second1']},
			{ className:'', id='', data:['first2','second2']},
			{ className:'', id='', data:['first3','second3']},
			{ className:'', id='', data:['first4','second4']},
			{ className:'', id='', data:['first5','second5']}
		];
		var data = {
			headers:['Anatoliy','Urbanskiy'],
			rows : rows,
			tableHeight: '80px',
			tableWidth: '70%',
			columnWidth: ['300px','auto']
			//noDataMsg: "No Record Found"
		};
		var myTable1 = new my.FixedHeaderTable(data,"ph");
	});
</script>
The real output from this code is a 'Table 1' (see above).

Parameters

*headers    : Array of the header's strings.
tableHeight : String. The height of a visible part of the table. Can be px, %, em.
                     default value is : '200px'.
tableWidth  : String. The width of the table. Can be px, %, em.
                     default value is : '100%'. Prefered value is px. 
                     The header of the table defined with '%' is a breakables.
columnWidth : Array of the strings. Represents a width of each column. Can be px, %, em, auto.
                     default all values are 'auto'.
                     The last column has predefined value 'auto'.
noDataMsg   : String. The message for the table with no data. Default is 'No Record'.
rows        : Array of Objects. Each Objects represents a one table row.
              The size of the data: array must be the same as the size of the headers: array.
              The className and the id arguments are optional and can be used for
              the initializing 'class' and 'id' attributes for a current <TR> tag.
* - mandatory parameter

Public Methods

myTable1.addClassNameColumn({row:2,column:2,className:'orange'});
myTable1.removeClassNameColumn({row:2,column:2,className:'orange'});
	- to add/remove a class for the specified column(s). 
	If the 'row' is ommited, apply for whole specified column(s). 
	The possible values for the row and the column parameters can be:
	integer | 'odd' | 'even'.
	See the result on the Table 1 above.
	
myTable2.addClassNameRow({row:integer|'odd'|'even',className:'some_class'});
myTable2.removeClassNameRow({row:integer|'odd'|'even',className:'some_class'});
	- to add/remove a class for particular row(s).
	If a 'row' is ommited, apply for each row.
	The predefined classes for the table rows are: 
	'row_a' for the odd rows, 
	'row_b' for the even rows.
Table 2.
myTable2.addClassNameColumn({column:2,className:'centered'});
Table 3.
myTable3.addClassNameColumn({column:'even',className:'orange'});
myTable4.updateTableBody(rows);
	- to add a new data into existing table with same number of columns. 
	The rows is an array of objects. 
	If rows is ommited or is empty the 'No Record' message 
	(or predefined with the noDataMsg parameter string) 
	is shown in the empty table body.
Table 4.
Any method of the dojo._Widget object can be used.

Known problems

1. The table should have enough predefined width to represent its data
   and column names.
2. The header cannot contain more than one row (unless you change the height of the header line).
3. The tfoot is not provided for this design.
4. The long string for the header can be problem.
   If there is not enough space for the header string it is truncated (overflow:hidden).
   The string of the last column in this case can be totally invisible.
   Solution: specify a 'columnWidth' property with a desired width for each column.
5. The header line for table with a specified width with '%' can be broken by changing 
   width of the browser view port.
   Solution: the 'px' value is desired.
6. The empty table in the IE6 has cell borders around 'No Record' message. 
   (IE6 doesn't support 'transparent' color for the borders)
   Solution: specify the same color of the borders for an empty table
   as a tbody background color.
7. There is no mechanism for a dynamically sorting by columns.
   Solution: create it, or wait until I'll do it.