<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title>OS3 Grid Example 3 - Selectable Cells Grid</title> <!-- examples.css --> <style type="text/css" rel="stylesheet"> html, body { height: 100%; width: 100%; font-family: Arial, Verdana, sans-serif; color: #cccc99; font-size: 1em; /* overflow: auto; */ margin-left: 0px; margin-top: 0px; margin-bottom: 0px; margin-right: 0px; }
#block_top { margin: 5px; background-color: #d0d0d0; border: 1px solid #000; }
#block_left { margin-left: 5px; left: 0px;
background-color: #76808b; border: 1px solid #000; float: left;
width: 15%; }
#block_middle { margin-left: 18%; margin-right: 5%; padding: 5px;
background-color: #959595; border: 1px solid #000; }
.block { margin: 5px; border: 1px solid #000; }
a { text-decoration: none; margin-left: 5px; }
a:hover { text-decoration: underline overline ; }
h1,h2,h3,h4,h5,h6.center { text-align: center; }
body { color: #000000; background: #666666; }
/* Menu */ .menu_title { margin: 4px; padding: 5px; border: 1px solid #000; background-color: #454545; color: white; font-weight: bold; }
/* Description Menu */ .descr_menu { border: 1px solid black; background-color: #353535; } .descr_menu th { width:150px; background:#8080ff; } .descr_menu th a { text-decoration:none; color:#000000; } .descr_menu td { font-weight: bold; background: #add8e6; padding: 5px; }
/* Form 1 */ .form1 { border: 1px solid black; padding: 5px; margin: 5px; background-color: #a5a5cc; display: none; }
.field_descr { text-align: right; font-weight: bold; margin-right: 5px; }
.code { padding: 5px; margin: 5px; font-family: courier; background: #ccccff; white-space: pre; }
.result { padding: 3px; margin: 2px; background: #eee; }
.note { padding: 5px; margin: 2px; background: #ffaaaa; border: solid; border-width: 1px; } </style> <!-- os3grid.css --> <style type="text/css" rel="stylesheet"> .g_table { margin: 0; padding: 0; border: 0; border-collapse: separate; border-spacing: 0px; }
.g_header { border: 2px solid; border-color: #fff #333 #333 #fff; background-color: #eeeeee; padding-right: 9px; padding-left: 9px; padding-bottom: 2px; cursor: pointer; text-align: center; color: black; font-size: 12px; }
.g_resize { cursor: e-resize; }
.g_header_down { border: solid; border-color: #333 #555 #555 #333; border-width: 2px; background-color: #eeeeee; padding-top: 2px; padding-left: 10px; padding-right: 8px; text-align: center; color: black; cursor: pointer; font-size: 12px; }
.g_cell { border: solid; border-width: 1px 1px 1px 1px; border-color: #ccc; padding: 4px; font-size: 10px; }
.g_cell_hl { border: dashed; border-width: 1px; border-color: #f00; background-color: #ddd; }
.g_edit_box { border: solid; border-width: 1px; border-color: #999; padding: 3px; background: white; } </style> <!-- os3grid.js --> <script type="text/javascript"> /* OS3Grid v0.5
by Fabio Rotondo - fsoft ( at ) sourceforge.net
0.5: - ATTR: start_counter - resize_cols - set_col_render ()
*/
// =================================================================== // GLOBAL STUFF - Init global data class // =================================================================== function os3_grid_global_data () { this.grid_arr = new Array (); this.sort_field = 0; this.sort_inverted = 0; }
var _os3_grid_global_data = new os3_grid_global_data (); var _os3g_resize_cell; var _os3g_resize_start_x = -1;
// Flag T/F to know if the current browser is the almighty bugged Internet Exploder. var _os3g_is_ie = ( document.all != null );
// =================================================================== // Grid Resize Functions // =================================================================== function grid_resize_cell_down ( id ) { _os3g_resize_cell = document.getElementById ( id );
document.onmousemove = grid_resize_callback; if ( ! _os3g_is_ie ) { document.captureEvents(Event.MOUSEMOVE); } else { while ( ! _os3g_resize_cell ) { _os3g_resize_cell = document.getElementById ( id ); if ( confirm ( "The buggy Internet Explorer cannot get the ID: " + id + ". Try again?nBTW: You should really consider to switch to Mozilla Firefox (www.getfirefox.com)" ) == false ) break; } } }
function grid_resize_cell_up () { if ( ! _os3g_resize_cell ) return;
document.onmousemove = null;
// later if ( ! _os3g_is_ie ) { document.releaseEvents(Event.MOUSEMOVE); }
if ( _os3g_resize_cell.old_className ) _os3g_resize_cell.className = _os3g_resize_cell.old_className; _os3g_resize_start_x = -1;
// Save the new column width inside _column_width array; var res = _os3g_resize_cell.id.split ( "_th" ); var name = res [ 0 ]; var num = res [ 1 ];
var grid = _os3_grid_global_data.grid_arr [ name ];
grid._column_width [ num ] = _os3g_resize_cell.width;
_os3g_resize_cell = null; }
function grid_resize_callback ( e ) { var cur_x, cur_y;
if ( ( ! _os3g_is_ie ) && ( e.pageX ) ) cur_x = e.pageX; else cur_x = event.x;
if ( _os3g_resize_start_x == -1 ) { _os3g_resize_start_x = 1; _os3g_resize_start_x = cur_x - _os3g_resize_cell.offsetWidth; }
if ( cur_x <= _os3g_resize_start_x ) cur_x = _os3g_resize_start_x +1;
_os3g_resize_cell.width = ( cur_x - _os3g_resize_start_x ); }
// =================================================================== // Grid Edit Functions // =================================================================== function grid_edit_abort_or_blur ( input, cell_id, evt ) { evt = (evt) ? evt : event;
var ccode = ( evt.charCode ) ? evt.charCode : ( ( evt.which ) ? evt.which : evt.keyCode ); var ch = String.fromCharCode ( ccode );
// User confirmed input by pressing "enter key" if ( ccode == 13 ) return input.blur ();
// User aborted input if ( ccode == 27 ) { var v = cell_id.split ( ":" ); var grid = _os3_grid_global_data.grid_arr [ v [ 0 ] ]; input.value = grid.rows [ v [ 2 ] ] [ "data" ] [ v [ 1 ] ]; input.blur (); }
return true; }
function grid_edit_end ( input, cell_id ) { var v = cell_id.split ( ":" ); var grid = _os3_grid_global_data.grid_arr [ v [ 0 ] ]; var oldv = grid.rows [ v [ 2 ] ] [ "data" ] [ v [ 1 ] ];
if ( oldv != input.value ) { if ( grid._column_validator [ v [ 1 ] ] ) if ( grid._column_validator [ v [ 1 ] ] ( input.value ) == false ) { alert ( "Invalid input: " + input.value ); return input.focus (); }
grid.rows [ v [ 2 ] ] [ "data" ] [ v [ 1 ] ] = input.value; if ( grid.onchange ) grid.onchange ( grid, v [ 1 ], v [ 2 ], input.value ); if ( grid.sort_on_edit ) grid.sort (); }
return grid.render (); }
function grid_cell_txt_edit ( cell ) { var v = cell.id.split ( ":" ); var grid = _os3_grid_global_data.grid_arr [ v [ 0 ] ]; var val; var s, el, size; var type = grid._column_type [ v [ 2 ] ];
if ( ! type ) type = 'str';
val = String ( grid.rows [ v [ 2 ] ] [ "data" ] [ v [ 1 ] ] );
s = '<input type="text" id="grid_edit_cell" value="' + val + '" '; s += ' onblur="grid_edit_end ( this, '' + cell.id + '' )" '; s += ' onfocus="this.select()" ';
if ( grid._column_chars [ v [ 1 ] ] ) s += 'onkeypress="return grid_edit_filter_chars ( event, '' + grid._column_chars [ v [ 1 ] ] + '' )" ';
s += ' onkeydown="grid_edit_abort_or_blur(this, '' + cell.id + '', event)" '; s += ' size="'+ val.length + '" '; s += ' class="g_edit_box" '; if ( type == 'int' ) s += ' style="text-align: right;" '; s += '/>';
cell.innerHTML = s;
el = document.getElementById ( "grid_edit_cell" ); el.focus (); }
function grid_edit_filter_chars ( evt, valids ) { evt = (evt) ? evt : event;
if ( evt.charCode < 32 ) return true; var ccode = ( evt.charcode ) ? evt.charcode : ( ( evt.which ) ? evt.which : evt.keycode ); var ch = String.fromCharCode ( ccode ).toLowerCase ();
valids = valids.toLowerCase ();
if ( valids.indexOf ( ch ) == -1 ) return false;
return true; }
function grid_header_mdown ( header ) { if ( header.className == 'g_header_down' ) return;
header.old_className = header.className; header.className = 'g_header_down'; }
function grid_header_mup ( header ) { if ( header.old_className ) header.className = header.old_className; }
function grid_header_click ( header ) { var name, num, res, grid; res = header.id.split ( "_gh" ); name = res [ 0 ]; num = res [ 1 ];
grid = _os3_grid_global_data.grid_arr [ name ];
grid.set_sort_field ( num );
grid.sort () }
function grid_row_over ( row ) { var old_col = row.style.backgroundColor; var hover_col = _os3_grid_global_data.grid_arr [ row.firstChild.id.split ( ":" ) [ 0 ] ].cols [ "hover" ];
if ( _os3g_resize_cell ) grid_resize_cell_up ();
if ( ( row.selected ) || ( old_col == hover_col ) ) return;
row.old_color = old_col; row.style.backgroundColor = hover_col; }
function grid_row_out ( row ) { if ( ! row.selected ) row.style.backgroundColor = row.old_color; }
function grid_cell_click ( cell ) { var v = cell.id.split ( ":" ); var grid = _os3_grid_global_data.grid_arr [ v [ 0 ] ]; var val;
val = grid.rows [ v [ 2 ] ] [ "data" ] [ v [ 1 ] ];
sel = grid._cell_click ( grid, cell, v [ 2 ], v [ 1 ], val ); if ( sel ) { cell.old_border = cell.style.borderColor; cell.style.borderColor = grid.cols [ "rowsel" + ( v [ 2 ] % 2 ) ]; } else cell.style.borderColor = cell.old_border;
cell.selected = sel; }
// =================================================================== // Row selection function // =================================================================== function grid_row_click ( cell, grid_id, row_num ) { var grid = _os3_grid_global_data.grid_arr [ grid_id ]; var row = cell.parentNode;
if ( row.selected ) { row.selected = false; grid_row_out ( row ); } else { row.selected = true; row.style.backgroundColor = grid.cols [ "rowsel" + ( row_num % 2 ) ]; }
grid.rows_selected [ row_num ] = row.selected;
if ( grid.onrowselect ) grid.onrowselect ( grid, row_num, row.selected ); }
// =================================================================== // Internal Functions // =================================================================== function os3_grid_int_sort ( a, b ) { var res = 0; var v1, v2;
v1 = parseInt ( a [ "data" ][ _os3_grid_global_data.sort_field ] ); v2 = parseInt ( b [ "data" ][ _os3_grid_global_data.sort_field ] );
if ( v1 < v2 ) res = -1; else if ( v1 > v2 ) res = 1;
if ( _os3_grid_global_data.sort_inverted ) res *= -1;
return res; }
function os3_grid_str_sort ( a, b ) { var res = 0; var v1, v2;
v1 = a [ "data" ][ _os3_grid_global_data.sort_field ]; v2 = b [ "data" ][ _os3_grid_global_data.sort_field ];
if ( v1 < v2 ) res = -1; else if ( v1 > v2 ) res = 1;
if ( _os3_grid_global_data.sort_inverted ) res *= -1;
return res; }
function _os3g_set_headers () { this.headers = arguments; }
function _os3g_set_sort_field ( num ) { if ( num == this.sort_field ) this.sort_inverted = ! this.sort_inverted; else { this.sort_field = num; this.sort_inverted = false; } }
function _os3g_set_cell_click ( fname ) { this._cell_click = fname;
if ( this.id && this.autorender ) this.render (); }
function _os3g_set_size ( w, h ) { this._width = w; this._height = h; if ( this.id && this.autorender ) this.render (); }
function _os3g_set_scrollbars ( sbars ) { this._scrollbars = sbars; if ( this.id && this.autorender ) this.render (); }
function _os3g_set_border ( bsize, style, color ) { this._border = bsize; if ( style ) this._border_style = style; if ( color ) this._border_color = color;
if ( this.id && this.autorender ) this.render (); }
function _os3g_set_sortable ( sortable ) { this._sortable = sortable ;
if ( this.id && this.autorender ) this.render (); }
function _os3g_set_highlight ( hl ) { this._row_hl = hl ;
if ( this.id && this.autorender ) this.render (); }
function _os3g_sort () { if ( this.sort_field == -1 ) return;
var ctype = this._column_type [ this.sort_field ]; var sfunc;
if ( ! ctype ) ctype = "str"; sfunc = { "str" : os3_grid_str_sort, "int" : os3_grid_int_sort, "date": os3_grid_str_sort } [ ctype ];
_os3_grid_global_data.sort_field = this.sort_field; _os3_grid_global_data.sort_inverted = this.sort_inverted; this.rows.sort ( sfunc ); this.render ( this.id ); }
function _os3g_add_row () { var arr;
arr = { "data" : arguments, "style" : this.current_style };
this.rows.push ( arr ); }
function _os3g_get_str () { var t, len; var s = '<table class="g_table">'; var id, td_id;
// Row selections are discarted on rendering this.rows_selected = new Array ();
if ( this.headers ) { s += '<tr>'; if ( this._show_row_num ) s+= '<td><div class="g_header"> </div></td>';
len = this.headers.length;
for ( t = 0; t < len; t ++ ) { td_id = this.id + "_th" + t; id = this.id + "_gh" + t;
s += '<td id="' + td_id + '" '; if ( this._column_width [ t ] ) s += 'style="width: ' + this._column_width [ t ] + 'px;" '; s +='><div id="' + id + '" class="g_header"'; if ( this._click_cb [ t ] ) { if ( this._click_cb [ t ] != -1 ) { s += ' onclick="' + this._click_cb [ t ] + '"'; s += ' onmousedown="grid_header_mdown(this)"'; s += ' onmouseup="grid_header_mup(this)"'; // s += ' onmouseout="grid_header_mup(this)" '; } } else if ( this._sortable ) { s += ' onclick="grid_header_click(this)"'; s += ' onmousedown="grid_header_mdown(this)"'; s += ' onmouseup="grid_header_mup(this)"'; //s += ' onmouseout="grid_header_mup(this)" '; }
s += '>'+ this.headers [ t ] + "</div></td>";
if ( this.resize_cols ) s += '<td class="g_resize" onmousedown="grid_resize_cell_down('' + td_id + '')" onmouseup="grid_resize_cell_up()"></td>'; } s += '</tr>'; }
var r, i, rlen, bgc, align, hl, style, rowcol, fullrow, v;
len = this.rows.length; rlen = this.rows[0]['data'].length; // All rows must be equal size for ( t = 0; t < len; t ++ ) { fullrow = this.rows [ t ]; r = fullrow [ 'data' ]; style = fullrow [ 'style' ]; rowcol = fullrow [ 'color' ];
if ( rowcol ) bgc = ' bgcolor="' + rowcol + '"'; else bgc = ' bgcolor="' + this.cols [ style + ( t % 2 ) ] + '"';
if ( this._row_hl ) hl = ' onmouseover="grid_row_over(this)" onmouseout="grid_row_out(this)" '; else hl = ''; s += '<tr ' + hl + bgc + '>'; if ( this._show_row_num ) { s+= '<td class="g_header"'; if ( this._row_sel ) { s += ' onmousedown="grid_header_mdown(this)"'; s += ' onmouseup="grid_header_mup(this)"'; s += ' onclick="grid_row_click(this,'' + this.id + '',' + t + ')"'; }
s += ' id="' + this.id + ':' + t + '"';
s+= '>' + ( this.start_counter + t ) + '</td>'; }
for ( i = 0; i < rlen; i ++ ) { if ( this._column_align [ i ] ) align = 'align="' + this._column_align [ i ] + '"'; else if ( ( this._column_type [ i ] ) && ( this._column_type [ i ] != 'str' ) ) align = 'align="right"'; else align = ""; s += '<td class="g_cell" valign="top" ' + align; if ( this.resize_cols ) s += ' colspan="2"'; if ( this._column_edit [ i ] ) s += ' ondblclick="grid_cell_' + this._column_edit [ i ] + '_edit(this)" '; if ( this._cell_click ) s += ' onclick="grid_cell_click(this)" '; s += ' id="' + this.id + ':' + i + ':' + t + '"'; s += '>'; if ( this._column_render [ i ] ) v = this._column_render [ i ] ( r [ i ] ); else v = r [ i ]; s += v; s += '</td>'; } s += '</tr>'; }
s += "</table>"; return s; }
function _os3g_render ( objId ) { if ( objId == undefined ) objId = this.id;
this.id = objId; var obj = document.getElementById ( objId );
obj.innerHTML = this.get_str ();
if ( this._scrollbars ) obj.style.overflow = "auto"; else obj.style.overflow = "visible"; // was "none"
if ( this._width ) obj.style.width = this._width; if ( this._height ) obj.style.height = this._height; if ( this._border ) { if ( this._border_style ) obj.style.border = this._border_style; if ( this._border_color ) obj.style.borderColor = this._border_color; obj.style.borderWidth = this._border + "px"; } // Bind element to the os3_grid_array _os3_grid_global_data.grid_arr [ objId ] = this;
if ( this.onrender ) this.onrender ( this ); }
function _os3g_set_row_color ( col, row_num ) { if ( ( row_num == undefined ) || ( row_num == -1 ) ) row_num = this.rows.length -1;
this.rows [ row_num ] [ 'color' ] = col; }
function _os3g_set_row_style ( style, row_num ) { if ( ( row_num == undefined ) || ( row_num == -1 ) ) row_num = this.rows.length -1; this.rows [ row_num ] [ 'style' ] = style; }
function _os3g_set_col_align ( col, align ) { this._column_align [ col ] = align; }
function _os3g_set_col_editable ( col, edit ) { this._column_edit [ col ] = edit; }
function _os3g_get_value ( x, y ) { return this.rows [ y ] [ x ]; }
function _os3g_set_col_valid_chars ( col, chars ) { this._column_chars [ col ] = chars; }
function _os3g_set_col_validation ( col, func ) { this._column_validator [ col ] = func; }
function _os3g_set_row_select ( rsel ) { this._row_sel = rsel; if ( this._row_sel ) this._show_row_num = true;
if ( this.id && this.autorender ) this.render (); }
function _os3g_show_row_num ( show ) { this._show_row_num = true; if ( this.id && this.autorender ) this.render (); }
function _os3g_set_col_type ( col, type ) { this._column_type [ col ] = type; }
function _os3g_set_col_render ( col, render ) { this._column_render [ col ] = render; }
function _os3g_get_row ( row ) { return this.rows [ row ] [ "data" ]; }
function _os3g_set_click_cb ( col, callback ) { this._click_cb [ col ] = callback;
if ( this.id && this.autorender ) this.render (); }
function _os3g_set_style ( style ) { this.current_style = style;
if ( this.id && this.autorender ) this.render (); }
function OS3Grid ( auto_render ) { // =========================================== // Public attribs // ===========================================
this.id = 0;
this.start_counter = 0;
// =========================================== // PUBLIC FLAGS // ===========================================
// Flag T/F. If True, any modification (done with set_* funcs) will immediately renderd on grid this.autorender = auto_render;
// Flag T/F. If True, grid will be re-sorted on value changes this.sort_on_edit = false;
// =========================================== // PUBLIC CALLBACKS // =========================================== // Function to be called when data in grid changes this.onchange = false;
// Function to be called after the grid redraws this.onrender = false;
// Callback to be called when the user selects / deselects a row this.onrowselect = false;
// Flag T/F. If True, user can resize column at runtime this.resize_cols = false; // =========================================== // PUBLIC ATTRIBUTES // ===========================================
// Array rows_selected this.rows_selected = false; // This array keeps track of selected rows
// Colors this.cols = { "hover" : "#8ec4cf", "rowsel0" : "#ffa07f", "rowsel1" : "#df8c6f", "normal0" : "#ffffff", "normal1" : "#dfdfdf", "error0" : "#ff0033", "error1" : "#cc0033", "warn0" : "#ffff99", "warn1" : "#ffff66", "note0" : "#9aff9a", "note1" : "#4eee94" };
// Default style this.current_style = "normal";
// ============================================================================================= // Private Stuff - Do not directly modify these values! // ============================================================================================= this.headers = 0; this.rows = new Array (); this.sort_field = -1; this.sort_inverted = false; this._row_style = new Array (); this._column_align = new Array (); this._column_edit = new Array (); this._column_chars = new Array (); this._column_validator = new Array (); this._column_width = new Array (); this._column_render = new Array ();
// This array stores the custom click callbacks this._click_cb = new Array (); // This array contains the column type. By default it is "str" // Valid values are: "str", "int", "date" this._column_type = new Array ();
// Flag T/F. If True, the grid is sortable (by clicking on the headers) this._sortable = false;
// Flag T/F. If True, scrollbars are used. this._scrollbars = false;
// Force grid container width this._width = 0;
// Force grid container height this._height = 0;
// Grid container border size (in pixels) this._border = 0;
// Grid container border style (solid, dashed, dotted...) this._border_style = 0;
// Grid container block color this._border_color = 0;
// Function callback for every cell click this._cell_click = 0;
// Function callback for every row click this._row_click = 0;
// Flag T/F. If True rows will be highlighted when the mouse scrolls over them. this._row_hl = false;
// Flag T/F. If True rows number are shown and rows are selectable by clicking on them. this._show_row_num = false;
// Flag T/F. If True rows number are shown and rows are selectable by clicking on them. this._row_sel = false;
// Public methods this.add_row = _os3g_add_row; this.get_row = _os3g_get_row; this.get_str = _os3g_get_str; this.getv = _os3g_get_value; this.render = _os3g_render; this.set_border = _os3g_set_border; this.set_cell_click = _os3g_set_cell_click; this.set_click_cb = _os3g_set_click_cb; this.set_col_align = _os3g_set_col_align; this.set_col_editable = _os3g_set_col_editable; this.set_col_render = _os3g_set_col_render; this.set_col_type = _os3g_set_col_type; this.set_col_valid_chars = _os3g_set_col_valid_chars; this.set_col_validation = _os3g_set_col_validation; this.set_headers = _os3g_set_headers; this.set_highlight = _os3g_set_highlight; this.set_row_color = _os3g_set_row_color; this.set_row_select = _os3g_set_row_select; this.set_row_style = _os3g_set_row_style; this.set_scrollbars = _os3g_set_scrollbars; this.set_size = _os3g_set_size; this.set_sort_field = _os3g_set_sort_field; this.set_sortable = _os3g_set_sortable; this.set_style = _os3g_set_style; this.show_row_num = _os3g_show_row_num; this.sort = _os3g_sort; } </script>
</head> <body> <div id="block_top"> <h2 class="center">OS3Grid Example 3 - Selectable Cells Grid</h2> <h4 class="center">By Fabio Rotondo - fsoft (@) sourceforge ( dot ) net</h4> </div>
<div id="block_middle"> <div> <div class="result">
<div id="grid"></div> <script type="text/javascript"> function cell_clicked ( grid, cell, row_num, col_num, val ) { alert ( "Grid: " + grid.id + " cell: " + cell + " - rown: " + row_num + " - col: " + col_num + " - val: " + val );
return ( true ); }
// Create an OS3Grid instance var g = new OS3Grid ();
// Grid Headers are the grid column names g.set_headers ( 'nick', 'Name', 'Surname', 'E-Mail Address' );
// If contents is bigger than container, Grid will automatically show scrollbars g.set_scrollbars ( true );
// The grid will have a solid border (these are CSS attributes) g.set_border ( 1, "solid", "#cccccc" );
// Now, we add some rows to the grid g.add_row ( 'fsoft', 'Fabio', 'Rotondo', 'fsoft (@) sourceforge (dot) net' ); g.add_row ( 'john', 'John', 'Bustone', 'jbust (@) somewhere (dot) net' ); g.add_row ( 'mkey', 'Mark', 'Key', 'mkey (@) okay (dot) net' ); g.add_row ( 'jdoe', 'John', 'Doe', 'redbull (@) batman (dot) net' );
// Enable sortable rows g.set_sortable ( true );
// Enable highlight of rows with the mouse g.set_highlight ( true );
g.set_cell_click ( cell_clicked );
// Show the grid replacing the original HTML object with the "grid" ID. g.render ( 'grid' ); </script>
</div> </div> </div> </body> </html>
|