The hidden workings of __doPostBack - Full or Partial Postback?

In experimenting with how I could manually create a partial postback, I ran into some odd behavior.  I was using the old '__doPostBack('target', 'argument')' javascript call to perform the post back and that was all well and good, but I noticed that my page was doing a full post back instead of a partial each time.

After digging around for a bit (where would software development be w/o Google search?), I found this tidbit here (I'm always grateful when others have spent a few hours finding little programming nuggets to share - less time searching for me):
  1. __doPostBack starts by trying to retrieve an element in the client DOM with the corresponding ClientID to the UniqueID you pass as the first argument to __doPostBack. (it translates the UniqueID to a ClientID by replacing the "$"s in the UniqueID with "_"s)
  2. If it finds a corresponding client element, it searches up the DOM for a parent that has the same id as an updatepanel (it keeps a list of the updatepanel ids).
  3. If it finds an updatepanel in the parent DOM hierarchy, it performs an async postback passing the UniqueID of the original control in __EVENTTARGET and using the updatepanel it found as a parameter to the OnSucceeded delegate.
  4. The server processes the async postback, uses the uniqueid in __EVENTTARGET to hook up the server events for the control firing the event, and the control event is fired. This is normal postback processing in action.
  5. The resulting html is passed in the response back to the client and the OnSucceeded delegate in the client side framework does some DOM manipulation to update the updatepanel discovered in step 2.
Now, let's say that step 1 fails to find a corresponding element in the DOM for the UniqueID. The framework does the following...
  1. The framework parses the UniqueID on the "$"s, and uses the parts to search the client DOM for a matching element. Again, converting the parsed UniqueIDs to ClientIDs
  2. When it finds one, it again searches up the DOM from that element for a containing UpdatePanel just like in step 3 above. If it finds one, it proceeds as above.
  3. If it does not find an UpdatePanel in the parent hierarchy, it sets _EVENTTARGET to the original control again, but this time, it does a full postback.

After reading this succinct and very helpful summary, it became obvious what was wrong, b/c here's my code:
__doPostBack('MultiplePrintReportButton', '');

I did not have a client-side id of 'MultiplePrintReportButton', so it had no UpdatePanel parent; I was just using it as a command keyword in the code behind to engage in a special mode in my control.

I changed it to this:
__doPostBack('<%=bPrintReports.ClientID%>;', 'MultiplePrintReportButton');

...and the partial post happened as it should b/c this control was within my user-control which I knew would always reside within an update panel.

The key of course to getting your partial postback like you want is giving the function a real element ID so that it can resolve the view state; otherwise, it will think it needs to refresh everything b/c something's out of whack.

Comments

  1. I know this is an old post, but I just wanted to say thank you so much for sharing your findings. I was having so many problems with my update panel doing a full postback and I haven't been able to find a real solution for almost a week now. I finally stumbled upon this, and just have to say THANK YOU. Usually, I use the ClientID, I don't know why I didn't for this application. Oh well, thanks again for the solution to my woes! :)

    ReplyDelete

Post a Comment

Popular posts from this blog

35x Improved T-SQL LevenShtein Distance Algorithm...at a cost

Facing Death...dum de dum dum