Final Version 1.2, updated January 8 2004
This example demonstrates how to create a table scroller with some very nice features:
The scroller uses an Internet Explorer behavior to implement the highlight. You could implement highlighting with javascript and not use a behavior, but the behavior makes reuse easier and gives you the ability to set properties of the scroller - e.g. the color when the highlight is on and the color when it is off, and whether it is a single-select or multi-select scroller - by setting custom attributes in the <TABLE> element. For example, here is the html that specifies values for custom attributes defined in the scroller behavior:
<table class="hiliter" OffColor="D5F1FF" OnColor="#FFFFFF">
See About Behaviors for an introduction to Internet Explorer behaviors.
Try it
| Code | Description 1 | Description 2 | Value |
|---|
| 1112 | Column1 Desc 1 | Column2 Desc 1 | 0.33 |
| 1113 | Column1 Desc 2 | Column2 Desc 2 | 1.63 |
| 1114 | Column1 Desc 3 | Column2 Desc 3 | 1.56 |
| 1115 | Column1 Desc 4 | Column2 Desc 4 | 1.91 |
| 1116 | Column1 Desc 5 | Column2 Desc 5 | 0.27 |
| 1117 | Column1 Desc 6 | Column2 Desc 6 | 0.33 |
| 1118 | Column1 Desc 7 | Column2 Desc 7 | 1.63 |
| 1119 | Column1 Desc 8 | Column2 Desc 8 | 1.56 |
| 1120 | Column1 Desc 9 | Column2 Desc 9 | 1.91 |
| 1121 | Column1 Desc 10 | Column2 Desc 10 | 0.27 |
| 1122 | Column1 Desc 11 | Column2 Desc 11 | 0.33 |
/*--------------------------------------------------------------------
(c) 2001 Gregory Swanson. All Rights Reserved.
File: scroller.htc
You may use this code without royalty or reference.
--------------------------------------------------------------------*/
<PUBLIC:COMPONENT>
<PUBLIC:ATTACH EVENT="onmouseover" ONEVENT="Hilite()" />
<PUBLIC:ATTACH EVENT="onmouseout" ONEVENT="unHilite()" />
<PUBLIC:ATTACH EVENT="onclick" ONEVENT="selectRow()" />
<PUBLIC:ATTACH EVENT="onselectstart" ONEVENT="cancelSelect()" />
<PUBLIC:PROPERTY NAME = MultiSelect VALUE = 0 />
<PUBLIC:PROPERTY NAME = OnColor VALUE = "#FFFFFF" />
<PUBLIC:PROPERTY NAME = OffColor VALUE = "#d5f1ff" />
<PUBLIC:PROPERTY NAME = selectedRow />
<PUBLIC:METHOD NAME="InitializeArray" />
<SCRIPT LANGUAGE="JScript">
var arrSelectedRows = new Array();
function cancelSelect()
{
event.returnValue=false;
}
function Hilite()
{
if (event.srcElement.tagName == "DIV")
{
var objDiv = event.srcElement;
var objTD = objDiv.parentNode;
} else {
var objTD = event.srcElement;
}
var objTR = objTD.parentNode;
if (objTR.tagName == "TR")
{
selectedRow = objTR.rowIndex;
objTR.style.backgroundColor=OnColor;
}
return true;
}
function unHilite()
{
if (event.srcElement.tagName == "SPAN")
{
var objSpan = event.srcElement;
var objTD = objSpan.parentNode;
} else {
var objTD = event.srcElement;
}
var objTR = objTD.parentNode;
if (objTR.tagName == "TR")
objTR.style.backgroundColor=OffColor;
//Re-select selected (i.e. clicked-on) rows
for (var i=0; i<arrSelectedRows.length; i++)
{
arrSelectedRows[i].style.backgroundColor = OnColor;
}
return true;
}
function selectRow()
{
if (event.srcElement.tagName == "SPAN")
{
var objSpan = event.srcElement;
var objTD = objSpan.parentNode;
} else {
var objTD = event.srcElement;
}
var objTR = objTD.parentNode;
if (objTR.tagName == "TR")
{
if (MultiSelect == -1)
{
if (!window.event.ctrlKey)
{
//If user is not pressing Ctrl key, de-select rows.
var theParent = objTR.parentElement;
for (var i=0; i<theParent.rows.length; i++)
{
theParent.rows[i].style.backgroundColor = OffColor;
}
//Reset object styles.
for (var i=0; i<arrSelectedRows.length; i++)
{
arrSelectedRows[i].style.backgroundColor = OffColor;
}
InitializeArray();
}
} else {
//De-select any selected rows
var theParent = objTR.parentElement;
for (var i=0; i<theParent.rows.length; i++)
{
theParent.rows[i].style.backgroundColor = OffColor;
}
//Reset object styles.
for (var i=0; i<arrSelectedRows.length; i++)
{
arrSelectedRows[i].style.backgroundColor = OffColor;
}
InitializeArray();
}
selectedRow = objTR.rowIndex
arrSelectedRows[arrSelectedRows.length] = objTR;
//SET selected row''s color.
objTR.style.backgroundColor = OnColor;
for (var i=0; i<arrSelectedRows.length; i++)
{
arrSelectedRows[i].style.backgroundColor = OnColor;
}
return true;
}
}
function InitializeArray()
{
arrSelectedRows = null;
arrSelectedRows = new Array();
}
</SCRIPT>
</PUBLIC:COMPONENT>
End of scroller code.
Note the declaration for the scoller behavior:
<style type="text/css">
.hiliter {behavior:url(scroller.htc)}
</style>
The above declaration tells Internet Explorer to load the scroller.htc behavior. The example assumes scroller.htc is located in the same directory as the ASP page.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<title>Scroller</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<style type="text/css">
.hiliter {behavior:url(scroller.htc)}
div.scroller_picklist{
background-color:#d5f1ff;
overflow-y:scroll;
border-style:inset;
border-width:thin;
width:650px;
height:100px;
margin-right:0.5in;
margin-left:0.5in;
}
div.scroller_header{
height:20px;
overflow-y:visible;
border-bottom-style:none;
width:653px;
margin-right:0.5in;
margin-left:0.5in;
}
th.reports_header {
font-family:"verdana","arial","helvetica","sans-serif";
font-size:'75%';
font-weight:bold;
color:#FFFFFF;
background-color:#0080C0;
text-align:center;
}
td.picklist{
font-family:"verdana","arial","helvetica","sans-serif";
font-size:8pt;
color:#000000;
text-align:left;
cursor:hand;
}
</style>
<script language="JavaScript" type="text/javascript">
// setReturnValue
// Retrieves the text from the selected row in the scroller.
function setReturnValue()
{
sReturnText = "";
var objTD = event.srcElement;
var objTR = objTD.parentNode;
for (var i=0;i<objTR.cells.length;i++)
sReturnText += objTR.cells(i).innerText + ";";
alert(sReturnText);
// If this code is in a popup window you would set the
// return value and close the window here. The calling
// page would parse the return value on the delimiter; we
// have used semicolons for delimiters in this example.
//if (sReturnText != null)
//{
// window.returnValue = sReturnText;
// window.close();
//}
return true;
}
</script>
</head>
<body bgcolor="#FFFFFF">
<div class="scroller_header">
<table border="0" cellpadding="0" cellspacing="0" style="border-bottom-style:none">
<thead>
<th width='5%' class='reports_header' style='text-align:right;' height='25'>Code </th>
<th width='20%' class='reports_header' style='text-align:left;'> Description 1</th>
<th width='20%' class='reports_header' style='text-align:left;'> Description 2</th>
<th width='10%' class='reports_header' style='text-align:right;'>Value </th>
<th width='1%' class='reports_header' style='text-align:right;'> </th><!--spacer for scroll bar-->
</thead>
</table>
</div>
<div class="scroller_picklist">
<!--
Here we use the hiliter behavior, whose code is in the scroller.htc file.
Behaviors can be written and compiled in C++, but scroller.htc is written
in xml. The hiliter behavior exports four properties, we are interested
in OffColor and OnColor. Note how they are used in the table element below.
-->
<table class="hiliter" OffColor="D5F1FF" OnColor="#FFFFFF" border="0"
cellspacing="0" cellpadding="1" style="table-layout:fixed;">
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1112 </td>
<td class="picklist" width="20%">Column1 Desc 1</td>
<td class="picklist" width="20%">Column2 Desc 1</td>
<td class="picklist" width="10%" style="text-align:right;">0.33 </td>
</tr>
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1113 </td>
<td class="picklist" width="20%">Column1 Desc 2</td>
<td class="picklist" width="20%">Column2 Desc 2</td>
<td class="picklist" width="10%" style="text-align:right;">1.63 </td>
</tr>
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1114 </td>
<td class="picklist" width="20%">Column1 Desc 3</td>
<td class="picklist" width="20%">Column2 Desc 3</td>
<td class="picklist" width="10%" style="text-align:right;">1.56 </td>
</tr>
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1115 </td>
<td class="picklist" width="20%">Column1 Desc 4</td>
<td class="picklist" width="20%">Column2 Desc 4</td>
<td class="picklist" width="10%" style="text-align:right;">1.91 </td>
</tr>
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1116 </td>
<td class="picklist" width="20%">Column1 Desc 5</td>
<td class="picklist" width="20%">Column2 Desc 5</td>
<td class="picklist" width="10%" style="text-align:right;">0.27 </td>
</tr>
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1117 </td>
<td class="picklist" width="20%">Column1 Desc 6</td>
<td class="picklist" width="20%">Column2 Desc 6</td>
<td class="picklist" width="10%" style="text-align:right;">0.33 </td>
</tr>
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1118 </td>
<td class="picklist" width="20%">Column1 Desc 7</td>
<td class="picklist" width="20%">Column2 Desc 7</td>
<td class="picklist" width="10%" style="text-align:right;">1.63 </td>
</tr>
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1119 </td>
<td class="picklist" width="20%">Column1 Desc 8</td>
<td class="picklist" width="20%">Column2 Desc 8</td>
<td class="picklist" width="10%" style="text-align:right;">1.56 </td>
</tr>
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1120 </td>
<td class="picklist" width="20%">Column1 Desc 9</td>
<td class="picklist" width="20%">Column2 Desc 9</td>
<td class="picklist" width="10%" style="text-align:right;">1.91 </td>
</tr>
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1121 </td>
<td class="picklist" width="20%">Column1 Desc 10</td>
<td class="picklist" width="20%">Column2 Desc 10</td>
<td class="picklist" width="10%" style="text-align:right;">0.27 </td>
</tr>
<tr onclick='setReturnValue();' ondblclick='setReturnValue();doOK();'>
<td class="picklist" width="5%" style="text-align:right;">1122 </td>
<td class="picklist" width="20%">Column1 Desc 11</td>
<td class="picklist" width="20%">Column2 Desc 11</td>
<td class="picklist" width="10%" style="text-align:right;">0.33 </td>
</tr>
</table>
</div>
</body>
</html>
This JavaScript code demonstrates how you would open the scroller in a modal dialog box and retrieve the user's selection
function ShowCodes(intLoop)
{
// Show the list and put the user's selection in wndShow.
var sParams = getDialogSetup(880,300);
var wndShow = window.showModalDialog ("lookup.htm","Lookup",sParams);
var undefined;
// If the user made a selection, parse out the information.
if (!(wndShow==undefined)){
// Display string returned - for testing
//alert(wndShow);
// Parse out each field from the returned string.
// Fields are separated by a semicolon.
//****************************************************************
// Field one
var strVal = '';
// Get the position of the first semicolon
var intPosition = wndShow.indexOf(';');
// Parse out the value from beginning of string up to intPosition.
strVal = wndShow.slice(0,intPosition);
fieldOne.value = strVal;
//****************************************************************
// Get the position of the next semicolon and parse out next value
strVal = '';
intPosition += 1;
var intPositionNext = wndShow.indexOf(';',intPosition);
strVal = wndShow.slice(intPosition, intPositionNext);
tableCellTwo.innerText = strVal;
//****************************************************************
// Get the position of the next semicolon and parse out next value
strVal = '';
intPosition = intPositionNext + 1;
var intPositionNext = wndShow.indexOf(';',intPosition);
strVal = wndShow.slice(intPosition, intPositionNext);
fieldTwo.value = strVal;
//****************************************************************
// Get the position of the next semicolon and parse out next value
strVal = '';
intPosition = intPositionNext + 1;
var intPositionNext = wndShow.indexOf(';',intPosition);
strVal = wndShow.slice(intPosition, intPositionNext);
fieldThree.value = strVal;
//****************************************************************
}
}