Here is the issue - an ASP.NET application and a database table consisting of unknown number of records, 50 or 50000. Then, the interface control which should allow the user to pick one of the items. The DropDownList does not work here - although there's nothing wrong in putting 50 items into the DropDownList, the list with 50000 elements is rather a bad idea.
My first and almost obvious choice was the AutoCompleteExtender from the ASP.NET Ajax Toolkit. After few tech studies, I've realized how many drawbacks this control has:
- suppose the user picks a correct entry from the list and then modifies the textbox value so it does not correspond to any of available items. Guess what? The suggestion from the article above does not work. The hidden textbox still holds the correct value selected from the list. Cyril Durand notes this issue in his blog entry here.
- unfortunately, even Cyril's trick does not work when the user just types the correct value into the textbox and does not pick anything directly from the list.
Why it is important to have the value of an item available? Well, suppose that the dropdown holds a list of all towns in your country. There are surely many towns with the same name. Instead of putting just a name into the drop down list, you'd rather format items in a custom way so that the user is able to pick the correct item from the list. Now, the page posts back and you get a literal which is surely a name of a town but formatted in a custom way. How are you supposed to retrieve it's database identity? God one knows.
However, the major issue of the AutoCompleteExtender is the need to type something into the textbox while in fact the user could have no idea what he/she should type. In the "list of towns" example - suppose I know the country, I know the region and I know that there are 50 towns in that region but have no idea of their names. If I am to see the complete list, I will surely know what item to pick. However, the AutoCompleteExtender will only show me 10 first items.
Yet another example - a drop down list to pick users. Suppose I know his age, his gender, his address, his company but I completely forgot his name. How am I to pick the user from the list using the AutoCompleteExtender?
This is where my idea comples to play - instead of the AutoCompleteExtender the user will see a plain textbox with small button next to it. Clicking the button will spawn a new browser window with rich user interface to define a custom filter and a paged GridView showing a list of items matching current filter criteria. After user is able to narrow the list so that the correct item can be picked, the new window will return both name and the value (database identity) of the item to the parent window.
So the issue now is - how are we supposed to build a communication link between two browser windows so that when the user picks an item in a child window, the information of the selection will appear in a parent window?
Let's start by putting two textboxes in a parent window.
The first one will receive the item's name, the second one will receive item's value.
Let's also put a html button on the form which will be responsible for spanning a new window:
The button will raise local browser event and a new window will be shown to the user where he/she will be able to pick the item from the list.
The Child.aspx window (which will ultimately return both the name and the value of the item) can be arbitrarily complicated. The only interesting issue here is that I pass two parameters in the QueryString - the controlID parameter holds the name of a parent window control which will receive the name of the item and the targetControlID parameter holds the name of a parent window control which will receive the value of the item.
No matter what you do in the Child.aspx window, ultimately the user presses the OK button which should pass both name and the value of picked item to the parent window.
This snippet does the magic trick. Using window.opener I refer to the parent window from the child window and this script sets both the name textbox and the hidden value textbox to proper values. After this the child window is immediately closed.
And that's it. In the parent window you can ask for the item's value stored in the hidden textbox: