Introduction
When I was involved in one of my projects, where we used many aspx pages with DropDownLists
and ListBoxs
for selecting persons, departments and etc., my customer asked me if he could type the characters on his keyboard and select the suitable item. And I tried to make work easier for him. At first it was only javascript code and now it is ASP.Net server controls.
So, I'd like to describe two ASP.Net server controls: xNetDropDownList
and xNetListBox
with possibility to move focus to the first most suitable item on the list when a user types in characters on the keyboard.
Background
The principle of work for both components is similar, therefore I will describe xNetDropDownList
.
On a client side element xNetDropDownList
is represented as an HTML <select> box. When an element receives focus a Tooltip appears above it. Entered characters are represented in Tooltip and focus moves to the first suitable item on the list. Pressing Escape deletes all entered characters and focus moved to the first item. Backspace key deletes the last entered character. Focus is moved to the item on the list, corresponding the text in the Tooltip after deleting the character. When an element losses focus Tooltip disappears.
For correct work the list of items must be sorted in an ascending order!
Implementation
The component xNetDropDownList
is inherited from the System.Web.UI.WebControls.DropDownList
. Several new properties were added to it. They are mainly used for setting visual parameters of the ToolTip.
These properties are described in the table:
Public property | Type | Description |
ToolTipHide | bool | Gets or sets visibility of ToolTip. False - to show ToolTip, true not to show |
ToolTipBackColor | Color | Gets or sets the background color |
ToolTipBorderColor | Color | Gets or sets the border color |
ToolTipBorderStyle | BorderStyle | Gets or sets the border style |
ToolTipBorderWidth | Unit | Gets or sets the border width |
ToolTipFontFamily | string | Gets or sets an ordered array of font names |
ToolTipFontSize | FontUnit | Gets or sets the font size |
ToolTipFontBold | bool | Gets or sets a value that indicates whether the font is bold |
ToolTipForeColor | Color | Gets or sets the color of the text |
ToolTipOffsetLeft | int | Gets or sets horizontal moving the left top point of ToolTip as for the co-ordinate of DropDownList or ListBox. Measuring unit is a pixel. In the properties designer just figures (integers) are typed in. |
ToolTipOffsetTop | int | Gets or sets vertical moving the left top point of ToolTip as for the co-ordinate of DropDownList or ListBox. Measuring unit is a pixel. In the properties designer just figures (integers) are typed in. |
ToolTipPadding | Unit | Gets or sets the amount of space to insert between the text and border |
ToolTipInitialWidth | Unit | Gets or sets initial width |
ToolTipZIndex | int | Gets or sets z-index |
ToolTipSaveText | bool | Gets or sets saving the typed in text in ToolTip. If true typed in text is saved, when the element loses and again acquires focus. If false the typed in text is lost |
The picture gives explanation for ToolTipOffsetLeft
and ToolTipOffsetTop
properties:
The functionality of searching suitable item on the list is realized on JavaScript.
Function xOnFocus()
is used for creating and setting properties for ToolTip.
When element <select> receives focus first time new HTML element <div> is created, otherwise function controls behavior of ToolTip as for settings in ToolTipSaveText
and ToolTipHide
properties.
function xOnFocus(elm)
{
var el = document.getElementById('div_' + elm.id);
if (!el)
{
var xdiv = document.createElement('DIV');
xdiv.id = 'div_' + elm.id;
xdiv.noWrap = true;
xdiv.style.position = 'absolute';
xdiv.ToolTipText = '';
xdiv.style.color = elm.ToolTipForeColor;
xdiv.style.width = elm.ToolTipInitialWidth;
xdiv.style.padding = elm.ToolTipPadding;
xdiv.style.display = (elm.ToolTipHide == 'false') ? 'inline' : 'none';
xdiv.style.backgroundColor = elm.ToolTipBackColor;
xdiv.style.borderColor = elm.ToolTipBorderColor;
xdiv.style.borderStyle = elm.ToolTipBorderStyle;
xdiv.style.borderWidth = elm.ToolTipBorderWidth;
xdiv.style.fontFamily = elm.ToolTipFontFamily;
xdiv.style.fontSize = elm.ToolTipFontSize;
xdiv.style.fontWeight = elm.ToolTipFontBold;
xdiv.style.zIndex = elm.ToolTipZIndex;
xdiv.style.top = document.body.scrollTop + elm.getBoundingClientRect().top - parseInt(elm.ToolTipOffsetTop);
xdiv.style.left = document.body.scrollLeft + elm.getBoundingClientRect().left + parseInt(elm.ToolTipOffsetLeft);
document.body.insertBefore(xdiv);
}
else
{
if (elm.ToolTipSaveText == 'false')
{
el.innerText = '';
el.ToolTipText = '';
}
el.style.display = (elm.ToolTipHide == 'false') ? 'inline': 'none';
}
}
Function xOnBlur()
hides ToolTip.
function xOnBlur(elm)
{
var el = document.getElementById('div_' + elm.id);
if (el) el.style.display = 'none';
}
Function xOnKeyUp()
handles pressing the following keys: Esc, BackSpace, Enter.
Notice, if property AutoPostBack
is true, in addition to standard behavior of DropDownList
and ListBox
controls, an automatic postback to the server will occur when the user presses Enter key.
function xOnKeyUp(key_event)
{
var lb = key_event.srcElement;
var el = document.getElementById('div_' + lb.id);
if (el)
{
if (key_event.keyCode == 8)
{
key_event.returnValue = false;
if (el.ToolTipText.length > 0) el.ToolTipText = el.ToolTipText.substr(0, el.ToolTipText.length - 1);
el.innerText = el.ToolTipText + ' ';
xFindItem(el.ToolTipText, lb);
}
if (key_event.keyCode == 27)
{
key_event.returnValue = false;
el.ToolTipText = '';
el.innerText = '';
xFindItem(el.ToolTipText, lb);
}
if (key_event.keyCode == 13)
{
key_event.returnValue = false;
if(lb.AutoPostBack == 'true') lb.onchange();
}
}
}
Function xOnKeyPress()
processes alphanumeric characters.
function xOnKeyPress(key_event)
{
var lb = key_event.srcElement;
var el = document.getElementById('div_' + lb.id);
if (el)
{
el.ToolTipText = el.ToolTipText + String.fromCharCode(key_event.keyCode);
el.innerText = el.ToolTipText +' ';
xFindItem(el.ToolTipText, lb);
key_event.returnValue = false;
}
}
Function xFindItem()
is main function and it is responsible for searching an item on the list.
function xFindItem(s, lb)
{
s = s.toUpperCase();
var slen = s.length;
var lblen = lb.length;
var lbo = lb.options;
if (slen == 0 && lblen > 0)
{
lb.selectedIndex = 0;
return;
}
for (i = 0; i < lblen; i++)
{
if (lbo[i].text.toUpperCase().substr(0, slen) == s)
{
lb.selectedIndex = i;
break;
}
}
}
Components were tested in Internet Explorer version 6.0.