ASP.NET postback with JavaScript

258,066

Solution 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

Solution 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>

Solution 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 :)

Solution 4

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) %>;
}

Solution 5

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.

Share:
258,066
ErnieStings
Author by

ErnieStings

Updated on July 08, 2022

Comments

  • ErnieStings
    ErnieStings almost 2 years

    I have several small divs which are 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 page's 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.

  • Alex Rodrigues
    Alex Rodrigues over 14 years
    A question. When a div is dragged the _doPostBack is invoked by you or automatically by ASP.NET?
  • ErnieStings
    ErnieStings over 14 years
    it is invoked by me via javascript
  • ErnieStings
    ErnieStings over 14 years
    what's the first most evil thing that microsoft created for web developers?
  • kim3er
    kim3er over 14 years
    the login control must be pretty high up that list.
  • phairoh
    phairoh over 14 years
    This will work, and I have done something similar in an application, but it is really not a good idea and I hate that I had to do it when I did. If your update panel's name ever changes, it breaks. If you ever put this inside a user control, it breaks. If you add a masterpage, it breaks. Yes it works, but it's quite fragile. At the very least, please use the ClientId property of your update panel instead of the static string.
  • Manitra Andriamitondra
    Manitra Andriamitondra about 12 years
    +1 for completness. Kind of great answers which make me love StackOverflow.
  • Gurucharan Balakuntla Maheshku
    Gurucharan Balakuntla Maheshku over 11 years
    This is one of the best explanations I have ever come across for __doPostBack().. +10 for this !
  • yangli.liy
    yangli.liy over 11 years
    @BrianWebster, Many thanks for your detailed post. Could I suggest anyone who is still with ASP.NET 3.5 and below using C# instead of VB.NET changes the last two lines in the .aspx file to as followings? <asp:Button runat="server" ID="ButtonA" Text="ButtonA" OnClick = "ButtonA_Click"/><br /> <br /> <asp:Button runat="server" ID="ButtonB" Text="ButtonB" OnClick = "ButtonB_Click" />
  • Brian Webster
    Brian Webster almost 11 years
    @yangli.liy You make an excellent point. I'd make the change myself, but I think you covered it well. It's much easier in VB.NET to assign handlers via codebehind. I hope C# allows that in the future.
  • DCastenholz
    DCastenholz almost 10 years
    Very helpful when using master pages.
  • DCastenholz
    DCastenholz almost 10 years
    This is a very helpful solution. If you are using master pages, the id of the buttons gets a bit obfuscated. See user489998's answer below for help getting the correct id for the postback.
  • Dennis T --Reinstate Monica--
    Dennis T --Reinstate Monica-- almost 10 years
    __doPostBack seems to always use the button's name when using master pages.
  • Jan Kukacka
    Jan Kukacka over 9 years
    Can you provide some explanation what makes UpdatePanels so evil thing? If it is so, I would like to read some reasons why and when not to use them. So far I haven't stumbled upon any crucial problems with UpdatePanels.
  • mason
    mason over 8 years
    @JanKukacka They're a poor abstraction of AJAX. The skills you learn in writing update panels don't directly translate to being able to properly utilize AJAX in anything outside of ASP.NET Web Forms. UpdatePanels are difficult to debug. And if you have ViewState on, a large amount of data is transferred to/from the server needlessly, making it bandwidth intensive. Learning proper AJAX (perhaps with some lightweight abstraction layer such as jQuery) is a far better solution when you need to talk to the server without performing a postback.
  • GoldBishop
    GoldBishop over 7 years
    @BrianWebster It is truly rare for someone to be able to provide a complete solution to someone's problem AND supply appropriate alternatives to potential deviations.
  • Eric Eskildsen
    Eric Eskildsen almost 7 years
    Great overview of __doPostBack, but it doesn't address the crux of OP's issue: "when i call this function the whole page is re-loaded but i only want the update panel to be re-loaded"
  • DanielG
    DanielG about 6 years
    This works very well. In my situation, I can declare the Target AJAX controls to be refreshed when btnRefresh is clicked in the HTML markup. By using this, it made it extremely simple to implement this with support for AJAX.