On my current assignment, a problem has cropped up three times since the middle of last year. An Active Server Page (ASP) contains a Design Time Control (DTC) list box whose contents are dependent upon another DTC list box’s selection. For example, the shipper is dependent on the source factory. Or here’s an even more intricate example: The shipper is dependent on the source factory, which is dependent on the customer. These dependencies can cause the relationships between list boxes to quickly get complex.

The current solution is to create a server-side JavaScript function onchange() event for each list box whose contents depend on the selection in another list box. While this is a workable solution, it becomes more complicated if you have to write a client-side solution because of a lack of bandwidth. The solution I envisioned would update the DTC list box on the client side and involve the server side only when the form is submitted.

Updating the DTC list box
The solution seemed straightforward, since a DTC list box is really just a fancy way to work with HTML select and option tags. It took me only a few minutes to write a server-side function to create hidden HTML input boxes with the different sets of options for the dependent list box. The client-side JavaScript function to replace the DTC list box’s options based upon the contents of another DTC list box came together just as quickly. The page was coded so that the dependent list box would be empty when the page was initially loaded. It would contain options only when a selection was made in the first list box.

The first try was golden. The solution worked perfectly. Selecting an option from the first list box caused the options in the second to be changed. I played with it for several minutes feeling very pleased with myself. Then, I clicked the Submit button. The server side treated the dependent DTC list box as if it were still empty. Not the functionality that I expected.

Being under the usual tight deadline, I briefly considered a band-aid solution—adding another hidden input box to handle the selection made in the dependent DTC list box. I quickly discarded that solution because it was overly complex to handle. What was needed was a solution with at most one server-side and one client-side element.

A better solution
My search for a better solution began with a look at the generated HTML. It was obvious that something was missed on the client-side, because of the failure of what should have been a simple change.

Examining the HTML generated by IIS revealed something very interesting: Each DTC has a hidden input box associated with it. DTCs are like icebergs—only a fraction is visible above the water line. I made the mistake of assuming that the HTML list box that was visible was all there was and that changing the visible object was sufficient.

The ASP engine employs these hidden input boxes to maintain state so that selections will be retained if the page is reloaded. The list box DTCs mirror the options available in the associated list box. This was the problem with my code: It did only part of the job. It is necessary to update the list box DTC below the water line. Armed with this knowledge, I was ready to take another shot at updating a DTC list box on the client side.

More ways to extend DTC

To find how you can further extend DTCs, check out “Client-side sortable data grids can reduce server traffic.”

Changing a DTC list box option
I will take a step back for a moment to briefly explain how to change a DTC list box’s options. The list box is essentially an HTML select container that holds multiple HTML option container tags. Using JavaScript and the Document Object Model, it is possible to access both the inner and outer HTML for the visible portion of the DTC list box and modify and replace it. Once this is accomplished, the only obstacles are updating the associated hidden input box and preserving the dependent DTC list box’s onchange event.

Updating the value of the hidden input box isn’t a problem once the format of the input box’s name is known. The name of the hidden input box is always an underscore (_), followed by the name the DTC list box, followed by another underscore and the word state, in lowercase. Let’s assume that the DTC list box’s name is plugh. This would make the hidden input box’s name _plugh_state. Knowing this allows us to access the input box’s value and change it.

The value of a hidden input box corresponds to the associated list box, so if the first option is blank, the first part of the value is &t0=. If the second option is red, the value is &t0=&t1=red, and so on, for each option. To reduce bandwidth, I used regular expressions to modify my hidden options into the correct format for the hidden input box value.

This leaves only one task: preserving the dependent DTC list box’s onchange event. That was more difficult than it sounds but was not insurmountable. It was necessary to hang on to the original onchange() event handler and set the event handler for the updated DTC list box to the original event handler.

Using the subroutine and the function
The server-side function, buildDropDown, requires four parameters:

  • The origin DTC list box that has a DTC list box dependent upon it
  • The dependent DTC list box
  • An ADO connection string
  • A SQL command to populate the dependent list box

The format of the SQL is as follows:
SELECT   dependent_value_column,
FROM     table_name
WHERE    origin_value = ‘xxxxxxxx’

The “xxxxxxxx” acts as a placeholder; the origin DTC list box’s option values are substituted to retrieve the information required to build the hidden input boxes. With this in mind, the format to invoke this subroutine is:
Call buildDropDown(origin,dependent,connectionString,sqlCommand)

The client-side function is invoked as part of the onchange event for the origin Design Time Control list box, which is defined using the JavaScript Function constructor in this manner:
document.thisForm.origin.onchange = new Function(‘updateDropDown(document.thisForm.origin, document.thisForm.dependent)’);

The above code snippet can be included either in the page’s onload event handler or in a function invoked by the onload event handler.

Extending the flexibility
Microsoft’s DTCs offer a quick and easy way to build ASPs, but  the process is often at the expense of flexibility. By examining the HTML generated by ASP, it is usually possible to extend the DTCs to give your applications a more polished look and feel.

More DTC?

Do you want more DTC articles? Share your opinions or post your comments below.