Saturday, May 9, 2009

Using ThickBox with Server-side Buttons

For a while now I've been looking for a jQuery equivalent to the Modal Popup Extender. Two key requirements were:
  1. It had to be able to be called from server-side code.
  2. The dialog box itself had to have ASP.Net buttons.
The first requirement proved easy, using code like this:

string script = "$(document).ready(function() {tb_show('Sample Title', '#TB_inline?height=120&width=300&inlineId=sampleContent', null);});";
ScriptManager.RegisterStartupScript(Page, typeof(Page), "", script, true);

But the second requirement proved much more difficult. It seemed that no matter which open source dialog box I tried, it would just not allow server-side events to be fired.

Eventually though, through the help of ASP.Net user PNasser, I found a solution! The key was to add a simple Javascript function call to each ASP.Net button in the dialog box:

OnClientClick="doPostBack(this);"

Which then calls this:

function doPostBack(element) {
tb_remove();
setTimeout('__doPostBack(\'' + element.name + '\',\'\')', 500);
}

That's it! What's happening is that first the call is made to the ThickBox to remove itself. This is precisely the same function that's called when you click on "close" in its title bar or press "Esc".


Then a postback is explicitly called via the __doPostBack function. But it isn't called immediately. Instead, it's executed after a 500ms delay. I don't precisely know the reason why the delay is necessary but am guessing that it provides the ThickBox enough time to fade out and dispose of itself. I experimented with the delay time and found on my computer that as low as 300ms worked. Less than that though and a full postback occurred, which is not the effect one wants on an AJAX-enabled page!

I've created a little demonstration project which you can download here.

15 comments:

  1. Tanx a Lot ...
    Looking Exactly for Something Like This!

    ReplyDelete
  2. i couldn't download demonstration project! it seems the link is dead.

    ReplyDelete
  3. My apologies! I've recently changed DNS registrars and am working with the fellow who hosts the site in question to correct the DNS records. Will do so within 24 hrs! Thanks for letting me know!

    ReplyDelete
  4. Hi,

    The solutions you provide works perfectly. but using jQuery for a while i bumped to a weird error. i put a asp.net textbox inside the thickbox, when i do post back (from the thickbox) the text that was entered into textbox was lost. have u ever encounter that also?

    ReplyDelete
  5. I just checked and I have yet to use a textbox within a thickbox. So I haven't experienced what you have.

    I would strongly recommend you create a simple web page showing this example, publish it somewhere on the Internet, and then pose your question on the ASP.Net forums. If someone can see a tangible example then help will usually come quickly.

    ReplyDelete
  6. I have a question: when I run your solution I do not get a postback reload. However, when I try to take what you did into my own page, pressing the button causes a postback before the thickbox is shown. What can I do to fix this??? Thanks

    ReplyDelete
  7. I cannot explain why it's not working properly on your page. Might you have AutoPostBack="true" somewhere?

    Perhaps another solution is to add "return false;" in your client call. Here's an example:

    <input type="submit" value="OK" onclick="$('div.subtleMsg').hide(); return false;" />

    ReplyDelete
  8. Thanks for the speedy response! It turns out it was due to me not having an update pannel around my content. I am going to read up on update pannels, as I don't fully understand their use. Thanks again!

    ReplyDelete
  9. hi,
    is there a way to use this but open a separate page, not a panel within the same page?

    Thanks,
    Ron

    ReplyDelete
  10. Ron/Amir,

    It sounds like what you're looking for is the "window.open" Javascript command. Here's one tutorial on that: http://www.javascript-coder.com/window-popup/javascript-window-open.phtml

    ReplyDelete
  11. Hi Robert

    I deeply appreciated your time and skill for writing such a wonderful piece of code, which helped me a lot.

    Thanks
    Asutosh

    ReplyDelete
  12. Brilliant - this just saved me 4 hours of figuring this think out! Thanks very much.

    ReplyDelete
  13. For People using Textbox in Thickbox:
    Make sure you call "tb_remove();" before the __doPostBack() in order to preserve the textbox value. Otherwise the textbox will always show empty string.

    ReplyDelete
  14. I spend a lot of time to find this, thank you.
    I use it to call a iframe, work fine for me

    Dim script As String = "$(document).ready(function() {tb_show('', '../contact_form.aspx?keepThis=true&TB_iframe=true&height=530&width=450', null);});"
    ScriptManager.RegisterStartupScript(Page, GetType(Page), "", script, True)

    ReplyDelete
  15. This is exactly what I'm looking for.. THANKS!!

    ReplyDelete