Since we will be improving the ListBox control, it is wise
first of all to implement ListBox class. The goal we are after is to upgrade
the ListBox to function properly with the client side changes on its collection
of items.
The code below shows how to implement the ListBox class.
Listing 1
public class xListBox : ListBox
{
All the public properties and methods of the ListBox will
continue to use them as before.
One method of interest, which is the OnPreRender, will be
overridden to add the two mentioned Hidden Fields in a previous section.
The OnPreRender is as follows:
Listing 2
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
// Force the LoadPostData to fire always
if (Page != null)
Page.RegisterRequiresPostBack(this);
// Register the hidden field to hold the added items
Page.RegisterHiddenField(this.HFItemsAdded, "");
// Register the hidden field to hold the indicies of removed items
Page.RegisterHiddenField(this.HFItemsRemoved, "");
// Register the JavaScript file that includes utility methods
if (!Page.IsClientScriptBlockRegistered("UtilMethods"))
Page.RegisterClientScriptBlock("UtilMethods", jsScript);
}
What we have done is call the base OnPreRender almost every
time when developing custom controls and this is usually done to preserve any
code that has been added by the base class.
Any client side code, like JavaScript or any control
registering on the parent Page of the control, should be done in this stage of
the control life cycle, the PreRender stage.
Notice that we have registered a JavaScript block with the
key UtilityMethods. This code provides two main client side functions, mainly
the AddItemToList and RemoveItemFromList. Those functions are used to Add and
Remove items from the two Hidden Field mentioned above. They have been
implemented in such a way to keep those two Hidden Fields synchronized so to
not have items present in both Hidden Fields.
The JavaScript code is shown below.
Listing 3
// Add a new ListItem to the ListBosID_ADDED HiddenField
function AddListItem(listName, text, value)
{
var hiddenField = GetHiddenField(listName.id + '_ADDED');
if (hiddenField != null)
{
// Add a separator
var tmp = hiddenField.value;
if (tmp != '')
hiddenField.value += ',';
// Add the item to the hidden field
hiddenField.value += text + '|' + value;
// if present in the REMOVED hidden field, remove it
var removeHiddenField = GetHiddenField(listName.id + '_REMOVED');
if (removeHiddenField != null)
{
var removedItems = removeHiddenField.value.split(',');
removeHiddenField.value = '';
for (var i = 0; i < removedItems.length; i++)
{
if (value != removedItems[i])
{
// Add a separator
var tmp1 = removeHiddenField.value;
if (tmp1 != '')
removeHiddenField.value += ',';
removeHiddenField.value += removedItems[i];
}
}
}
}
}
// Removes an item from the ListBoxID_REMOVED HiddenField
function RemoveListItem(listName, value)
{
var hiddenField = GetHiddenField(listName.id + '_REMOVED');
if (hiddenField != null)
{
// Add a separator
var tmp = hiddenField.value;
if (tmp != '')
hiddenField.value += ',';
hiddenField.value += value;
// if present in the ADDED hidden field, remove it
var addHiddenField = GetHiddenField(listName.id + '_ADDED');
if (addHiddenField != null)
{
var addedItems = addHiddenField.value.split(',');
addHiddenField.value = '';
for (var i = 0; i < addedItems.length; i++)
{
if (addedItems[i].match(value) == null)
{
// Add a separator
var tmp1 = addHiddenField.value;
if (tmp1 != '')
addHiddenField.value += ',';
addHiddenField.value += addedItems[i];
}
}
}
}
}
// Finds a hidden field on the page
function GetHiddenField(fieldName)
{
var hiddenField;
hiddenField = document.getElementById(fieldName);
if (hiddenField != null)
return hiddenField;
return null;
}
The above code is being injected in the OnPreRender method. Later
on when we discuss the "How to use the new ListBox" we will show you
how to call those methods properly.
There are three main methods:
AddListItem
RemoveListItem
GetHiddenField
The AddListItem starts by getting the Hidden Field titled _ADDED,
where this Hidden Field contains all the items, in the form of (Text|Value)
that will be added to the ListBox. The new item to be added is constructed in
the following format (Text|Value) and then appended to any item already present
in the Hidden Field. If any of those items are present in the Hidden Field
titled _REMOVED they will be removed from that Hidden Field. This ensures that
items to be removed are removed and items to be added are added correctly.
The RemoveListItem starts by getting the Hidden Field titled
_REMOVED, where this Hidden Field contains all the values of the items to be
removed from the ListBox. The new item’s value to be removed from the ListBox
is added to any existing value in the Hidden Field and separated by a “,” sign.
Again, the item’s value to be removed is checked against the values present in
the _ADDED Hidden Field to maintain consistency between items removed and
added.
Finally, the GetHiddenField is a utility method that is used
to find any Hidden Field on the page.