DropDownLists, AutoPostBack and the back button

S

Stephen Balkum

We have a page with multiple DropDownLists, each with AutoPostBack = true,
each with an onSelectedIndexChanged event handler. When the user makes a
selection in one of the dropdowns (DDL1), the event handler fires and the
client is redirected to a new page.

Next, the user decides to hit the back button from the new page and is
brought back to the page with dropdowns. The dropdown selection the user
had made (DDL1) is still selected. The user then makes another selection
from a different dropdown (DDL2) that is located after the first dropdown.
At this point, the event handler for DDL1 fires and the client is
redirected. If the redirection code is commented out, we discovered that
the DDL2 event handler also fires, but it comes in second.

Dissecting the problem, we concentrated on the additions created by setting
AutoPostBack to true:

<input type="hidden" name="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" value="" />
<script language="javascript">
<!--
function __doPostBack(eventTarget, eventArgument) {
var theform;
if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1)
{
theform = document.forms["_ctl0"];
}
else {
theform = document._ctl0;
}
theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}
// -->
</script>
<select name="_ctl4:DDL1" onchange="__doPostBack('_ctl4$DDL1','')"
language="javascript" id="_ctl4_DDL1">
....
<select name="_ctl4:DDL2" onchange="__doPostBack('_ctl4$DDL2','')"
language="javascript" id="_ctl4_DDL2">

It would appear that the two __EVENT... controls are set properly, but that
the postback processing on the server ignores the __EVENTTARGET control
which would indicate which single event handler to fire. Rather, it must be
comparing the controls with the __VIEWSTATE and firing event handlers for
every control that has changed.

For a workaround, we have set AutoPostBack to false for each dropdown and
inserted our own javascript:

<script language="javascript">
<!--
function doPostBack(ddl) {
var theform;
var i;
for(i=0;i<document.Form1.length;i++) // set selectedIndex of all
dropdowns to 0 except ddl !!!!
{
if(document.Form1.elements.type == "select-one") {
if(document.Form1.elements.name != ddl)
document.Form1.elements.selectedIndex = 0;
}
}
if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1)
{
theform = document.forms["Form1"];
}
else {
theform = document.Form1;
}
theform.submit();
}
// -->
</script>
<asp:DropDownList id="DDL1" runat="server" onchange="doPostBack(this.name)">
<asp:DropDownList id="DDL2" runat="server" onchange="doPostBack(this.name)">

We then handled the event in Page_Load:

if(DDL1.SelectedIndex != 0) // index 0 is "Please select" item
// Do something here;
if(DDL2.SelectedIndex != 0)
// Do something here;

Is there a better alternative, especially one that works within the
framework?

I can post a small example of the before and after if needed.
 
J

Jacob Yang [MSFT]

Hi Stephen,

Based on my research and experience, the following Knowledge Base article
is useful to you.

HOW TO: Manually Post Back for Specific Events in an .aspx Page Using
Visual Basic .NET
http://support.microsoft.com/default.aspx?scid=kb;en-us;328923

It states that

When AutoPostBack is True for a control, the control may post back to the
server in response to events that you did not want to cause a postback.

For example, setting AutoPostBack to True on the TreeView control causes a
postback in response to these events: onExpand; onCollapse; onCheck; and
onSelectedIndexChange.

Does it answer your question? If I have misunderstood your concern, please
feel free to let me know.

Best regards,

Jacob Yang
Microsoft Online Partner Support
<MCSD>
Get Secure! ¨C www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
S

Stephen Balkum

Interesting. After my initial post we came up with yet another "cleaner"
solution and the KB article is not that far from it.

What concerns me is that the solution in the KB article depends on the
__doPostBack javascript function existing. If no control on the page has
AutoPostBack = true, then the postback function will not get created. The
only controls on our page are six dropdowns.

The second solution we have employed leaves the AutoPostBack = true for all
dropdowns, thus, the __doPostBack function is created. Then, I added a
javascript block to the page that resets the selected index for all
dropdowns other than one specified (0 is our "Please select one" entry):

<script language="javascript">
<!--
function ResetOthers(t) {
var theform;
var i;
for(i=0;i<document.HomeForm.length;i++) {
if(document.HomeForm.elements.type == "select-one") {
if(document.HomeForm.elements.name != t)
document.HomeForm.elements.selectedIndex = 0;
}
}
}
// -->
</script>

For each control, I specified an onChange handler:

<asp:DropDownList id="WUDRH" Runat="server"
onChange="ResetOthers(this.name); ">

And finally, in OnInit, I set the event handler:

WUDRH.SelectedIndexChanged = new System.EventHandler(
DDL_SelectedIndexChanged ) ;

The browser receives this:

<select name="_ctl3:WUDRH" onchange="ResetOthers(this.name);
__doPostBack('_ctl3$WUDRH','')" language="javascript" id="_ctl3_WUDRH">

Good news, the onChange handler is inserted just before the
SelectedIndexChanged-__doPostBack handler. Intellisense does not recognize
the "onChange" in the control, but the runtime smartly prepends it to the
code it generates for onChange.

This works well in our opinion because it uses more of the functionality
designed in the framework, i.e. less hacking around what we perceive as a
flaw: an event handler for a control is actually called for all controls
with changed data rather than for just the control that was changed.

-Stephen
 
J

Jacob Yang [MSFT]

Hi Stephen,

Thank you for sharing your solution. It is helpful to everybody here.

Best regards,

Jacob Yang
Microsoft Online Partner Support
<MCSD>
Get Secure! ¨C www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,738
Latest member
JinaMacvit

Latest Threads

Top