ASP.NET postback with JavaScript

2019-01-01 14:26发布

问题:

I have several small divs which utilizing jQuery draggable. These divs are placed in an UpdatePanel, and on dragstop I use the _doPostBack() JavaScript function. where i extract necessary information from the pages form.

My problem is that when i call this function the whole page is re-loaded but i only want the update panel to be re-loaded.

回答1:

Here is a complete solution

Entire form tag of the asp.net page

<form id=\"form1\" runat=\"server\">
    <asp:LinkButton ID=\"LinkButton1\" runat=\"server\" /> <%-- included to force __doPostBack javascript function to be rendered --%>

    <input type=\"button\" id=\"Button45\" name=\"Button45\" onclick=\"javascript:__doPostBack(\'ButtonA\',\'\')\" value=\"clicking this will run ButtonA.Click Event Handler\" /><br /><br />
    <input type=\"button\" id=\"Button46\" name=\"Button46\" onclick=\"javascript:__doPostBack(\'ButtonB\',\'\')\" value=\"clicking this will run ButtonB.Click Event Handler\" /><br /><br />

    <asp:Button runat=\"server\" ID=\"ButtonA\" ClientIDMode=\"Static\" Text=\"ButtonA\" /><br /><br />
    <asp:Button runat=\"server\" ID=\"ButtonB\" ClientIDMode=\"Static\" Text=\"ButtonB\" />
</form>

Entire Contents of the Page\'s Code-Behind Class

Private Sub ButtonA_Click(sender As Object, e As System.EventArgs) Handles ButtonA.Click
    Response.Write(\"You ran the ButtonA click event\")
End Sub

Private Sub ButtonB_Click(sender As Object, e As System.EventArgs) Handles ButtonB.Click
    Response.Write(\"You ran the ButtonB click event\")
End Sub
  • The LinkButton is included to ensure that the __doPostBack javascript function is rendered to the client. Simply having Button controls will not cause this __doPostBack function to be rendered. This function will be rendered by virtue of having a variety of controls on most ASP.NET pages, so an empty link button is typically not needed

What\'s going on?

Two input controls are rendered to the client:

<input type=\"hidden\" name=\"__EVENTTARGET\" id=\"__EVENTTARGET\" value=\"\" />
<input type=\"hidden\" name=\"__EVENTARGUMENT\" id=\"__EVENTARGUMENT\" value=\"\" />
  • __EVENTTARGET receives argument 1 of __doPostBack
  • __EVENTARGUMENT receives argument 2 of __doPostBack

The __doPostBack function is rendered out like this:

function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
  • As you can see, it assigns the values to the hidden inputs.

When the form submits / postback occurs:

  • If you provided the UniqueID of the Server-Control Button whose button-click-handler you want to run (javascript:__doPostBack(\'ButtonB\',\'\'), then the button click handler for that button will be run.

What if I don\'t want to run a click handler, but want to do something else instead?

You can pass whatever you want as arguments to __doPostBack

You can then analyze the hidden input values and run specific code accordingly:

If Request.Form(\"__EVENTTARGET\") = \"DoSomethingElse\" Then
    Response.Write(\"Do Something else\") 
End If

Other Notes

  • What if I don\'t know the ID of the control whose click handler I want to run?
    • If it is not acceptable to set ClientIDMode=\"Static\", then you can do something like this: __doPostBack(\'<%= myclientid.UniqueID %>\', \'\').
    • Or: __doPostBack(\'<%= MYBUTTON.UniqueID %>\',\'\')
    • This will inject the unique id of the control into the javascript, should you wish it


回答2:

Per Phairoh: Use this in the Page/Component just in case the panel name changes

<script type=\"text/javascript\">
     <!--
     //must be global to be called by ExternalInterface
         function JSFunction() {
             __doPostBack(\'<%= myUpdatePanel.ClientID  %>\', \'\');
         }
     -->
     </script>


回答3:

While Phairoh\'s solution seems theoretically sound, I have also found another solution to this problem. By passing the UpdatePanels id as a paramater (event target) for the doPostBack function the update panel will post back but not the entire page.

__doPostBack(\'myUpdatePanelId\',\'\')

*note: second parameter is for addition event args

hope this helps someone!

EDIT: so it seems this same piece of advice was given above as i was typing :)



回答4:

If anyone\'s having trouble with this (as I was), you can get the postback code for a button by adding the UseSubmitBehavior=\"false\" attribute to it. If you examine the rendered source of the button, you\'ll see the exact javascript you need to execute. In my case it was using the name of the button rather than the id.



回答5:

Have you tried passing the Update panel\'s client id to the __doPostBack function? My team has done this to refresh an update panel and as far as I know it worked.

__doPostBack(UpdatePanelClientID, \'**Some String**\');


回答6:

Using __doPostBack directly is sooooo the 2000s. Anybody coding WebForms in 2018 uses GetPostBackEventReference

(More seriously though, adding this as an answer for completeness. Using the __doPostBack directly is bad practice (single underscore prefix typically indicates a private member and double indicates a more universal private member), though it probably won\'t change or become obsolete at this point. We have a fully supported mechanism in ClientScriptManager.GetPostBackEventReference.)

Assuming your btnRefresh is inside our UpdatePanel and causes a postback, you can use GetPostBackEventReference like this (inspiration):

function RefreshGrid() {
    <%= ClientScript.GetPostBackEventReference(btnRefresh, String.Empty) %>;
}


回答7:

First, don\'t use update panels. They are the second most evil thing that Microsoft has ever created for the web developer.

Second, if you must use update panels, try setting the UpdateMode property to Conditional. Then add a trigger to an Asp:Hidden control that you add to the page. Assign the change event as the trigger. In your dragstop event, change the value of the hidden control.

This is untested, but the theory seems sound... If this does not work, you could try the same thing with an asp:button, just set the display:none style on it and use the click event instead of the change event.



回答8:

You can\'t call _doPostBack() because it forces submition of the form. Why don\'t you disable the PostBack on the UpdatePanel?