__doPostBack only works if there is a LinkButton, Calendar or WizardStep control on the page

ぃ、小莉子 提交于 2019-12-07 05:09:44

问题


I have identified a problem with __doPostBack and found a work around. I am seeking an explanation for the cause and/or a better solution than my work around.

Scenario: I have a dropdown populated with the values; "-Select-", "One" & "Two". If the user selects "One" than client side script is executed. If the user selects "Two" than server side script is executed.

Problem: The client script initiates the postback by calling __doPostBack. However, no post back actually occurs unless there is also a LinkButton, Calendar or WizardStep control on the page. I actually went through all of the standard tools in the Visual Studio Toolbox and tested them all. It has to be one of those three.

Work Around: Add a link button surrounded by a span with display set to none.

<span style="display:none;">
    <asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
</span>

Question: Can somebody provide an explanation for this behavior or provide a better fix than my "Work Around"?

Source - Javascript (I placed it between the head tags)

<script language="javascript" type="text/javascript">
    function DropDownList1_change(elementRef) {
        var selectedIndex = elementRef.selectedIndex;
        if (selectedIndex > 0) {
            var selectedValue = elementRef.options[selectedIndex].value;
            if (selectedValue == "One") {
                alert("Because you selected 'One', special javascript code will be executed");
                // Special javascript code goes here
                return;
            }
            else if (selectedValue == "Two") {
                // Special server code gets executed on server DropDownList1_SelectedIndexChanged
                __doPostBack('DropDownList1', '');
            }
        }
    }
</script>

Source - ASPX Controls

    <asp:DropDownList ID="DropDownList1" runat="server"  onchange="DropDownList1_change(this)" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
        <asp:ListItem>-Select-</asp:ListItem>
        <asp:ListItem>One</asp:ListItem>
        <asp:ListItem>Two</asp:ListItem>
    </asp:DropDownList>
    <br />

    <!-- For some unknown reason __doPostBack only works if there is a LinkButton, Calendar or WizardStep control on the page -->      
    <span style="display:none;">
        <asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
    </span>

    Time of last Post Back: <asp:Label ID="Label1" runat="server"></asp:Label><br />
    Time of OnSelectedIndexChanged: <asp:Label ID="Label2" runat="server"></asp:Label>

Source - Code Behind

    protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToLongTimeString();
    }

    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        Label2.Text = DateTime.Now.ToLongTimeString();
    }

Additional Resource - I found the following article after posting this question. Its a very old Microsoft article and the only Microsoft article I found that mentions the specific limitation of DropDowns, return values & postbacks. I haven't digged deep into their solution and not sure time will allow me to. Mainly posting it in case my solution fails down the road or doesn't work for someone else.

Intuitively you might think adding a confirm dialog box for a DropDownList is identical to adding such a dialog box for a Button Web control. That is, simply set the DropDownList's client-side onchange attribute to something like: return confirm(...);. using: DropDownListID.Attributes("onchange") = "return confirm(...);" Unfortunately, this won't work as desired because an AutoPostBack DropDownList's onchange attribute will be set to a bit of JavaScript that causes a postback, namely a call to the client-side __doPostBack function. When setting the onchange attribute programmatically yourself, the end result is that the rendered client-side onchange event handler has both your code and the call to __doPostBack:

The article is long so search for "Confirmation with AutoPostBack DropDownLists"

https://msdn.microsoft.com/en-us/library/aa479302.aspx


回答1:


There are 2 solutions.

Solution 1: A better work around than adding a link button surrounded by hidden span tags is to add the following to the page load event. This ensures that the function __doPostBack is available.

protected void Page_Load(object sender, EventArgs e)
{
    Page.ClientScript.GetPostBackEventReference(this, string.Empty);
}

The function __doPostBack is generated only if a control in the form needs it to perform postbacks. This includes controls like the LinkButton and other controls for which AutoPostBack is set to true. In fact, only the Button and ImageButton controls can perform postbacks without __doPostBack (see this article). For example, we can see in the HTML output that a LinkButton is rendered this way:

<a id="lnk" href="javascript:__doPostBack(&#39;lnk&#39;,&#39;&#39;)">My link</a>


Solution 2: The following approach achieves the same thing without using __doPostBack.

In the present case, you could set AutoPostBack="true" for the DropDownList:

<asp:DropDownList AutoPostBack="true" onchange="if (!confirmPostBack(this)) return false;" ... >

The onchange event handler would return false when you want to prevent the postback. The Javascript function could be something like this:

function confirmPostBack(ddl)
{
    if (condition) {
        ...
        return true;
    } 
    else {
        ...
        return false;
    }
}

Important: The onchange event handler should not return anything to allow the postback to occur. You can use this syntax:

onchange="if (!confirmPostBack(this)) return false;"

For reasons probably explained in the article mentioned in the question, the following syntax does not work. Returning true still prevents the postback.

onchange="return confirmPostBack(this);" // Does not work!


来源:https://stackoverflow.com/questions/38750327/dopostback-only-works-if-there-is-a-linkbutton-calendar-or-wizardstep-control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!