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="_ctl4DL1" onchange="__doPostBack('_ctl4$DDL1','')"
language="javascript" id="_ctl4_DDL1">
....
<select name="_ctl4DL2" 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>
<aspropDownList id="DDL1" runat="server" onchange="doPostBack(this.name)">
<aspropDownList 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.
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="_ctl4DL1" onchange="__doPostBack('_ctl4$DDL1','')"
language="javascript" id="_ctl4_DDL1">
....
<select name="_ctl4DL2" 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>
<aspropDownList id="DDL1" runat="server" onchange="doPostBack(this.name)">
<aspropDownList 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.