Introduction
In a lot of websites I've built and seen, the flow of the program needed lookup information. Some used AJAX to retrieve records out of those 100000+ records. This solution, however, uses a classic but workable popup-form to search and select that single record.
I also wanted to have this control be used with different business objects. These business-objects have to be created dynamically. This is done in a factory using a little Reflection.
This demo application consists of a webform, a user control and a popup form. The webform contains the user control. Actually, this demo contains three of these user controls which are filled with different types of data. The user control is a bag for handling the popup form. It contains a readonly textbox in which the selection will be placed, and a Search button which is supposed to open the popup form and give it focus. The user then enters a search-string and clicks on the Search button. The results are presented in a DataGrid
. Selecting a record closes the popup form, and the selected record will be found back in the original webform. The user control has been built using a specifically defined set of properties, so it can be used with all kinds of meta-data. So, for example, organizations can be 'looked-up' with the same control as, for instance, social-security numbers.
Background
This solution was part of an ASP website migration to .NET. Users where used to getting a new webform on screen and selecting certain records within that form. This interface had to be rebuilt in .NET
Using the code
The control uses JavaScript to show a new window. In this window, a textbox with a button will be shown. Entering a text and pressing the button will fill the GridView
. Clicking a record in the GridView
will close the window (JavaScript) and will fill in the original field with the selected record.
Because the control is made for use with different business objects, as long as it uses the predefined dataset, it has to create different business objects, and therefore, it uses a simple factory. The dataset holds a table with text, value, and description. Usually, this is enough. The value can be disabled in the popup form by using a property. So, for example, for software, you only see the text and the description, but for organizations, there is also a value added. The factory uses Reflection, and finds, in the namespace business
, the classes which have the same name given in the ASPX-page. So, if a person-popup-lookup-form is needed, the type is person
, and the factory finds, in the namespace business
, the string person
and creates it. Below is the factory code:
public static IBusiness Create(string businessName)
{
Assembly a = Assembly.GetExecutingAssembly();
Type[] types = a.GetTypes();
foreach (Type t in types)
{
if (t.Namespace == "Business")
{
if (t.FullName.EndsWith(businessName))
{
return Activator.CreateInstance(t) as IBusiness;
}
}
}
throw new ApplicationException(string.Format("Business object" +
" [{0}] not known", businessName));
}
The interface IBusiness
has all the methods the business objects need for the popup form.
Points of interest
Setting the readonly property of a textbox disables the viewstate functionality. I use this to remember the value during postback. To workaround the absence of viewstate, I had to place the value of the textbox in another special hidden value control, unfortunately. That control is called, hiddenText
, in case you are looking for it in the code.
Another point of interest is in the JavaScript. Firefox demands first to close the popup form and then insert the values by calling the window.opener.InsertValue
. Peculiar... IE does not demand this.
function LocalSelect(str_Text, str_Value)
{
var objForm = window.document.forms[0];
var objHiddenText = objForm["hiddenTextId"];
var objShownText = objForm["shownTextId"];
var objHiddenValue = objForm["hiddenValueId"];
if (!window.opener) {
alert('No more valid reference in calling form');
window.close();
return;
}
if (!window.opener.InsertValue) {
alert('The calling form does not contain ' +
'an implementation of InsertValue(params)');
window.close();
return;
}
CloseWindow();
window.opener.InsertValue(objHiddenText.value, objShownText.value,
str_Text, objHiddenValue.value, str_Value);
}
I found the following line to disable auto-complete by the web browser. It is useful for disabling auto-complete for specific controls.
this.txtSearch.Attributes.Add("autocomplete", "off");
That's about it. I hope you liked it, and will use the control. Please give me some reactions and teach me tricks I don't know. Bye.
History
- Version 1.0, January 2008.