I've had a recent need to use jQuery for the first time, and at first blush, it's really a rather well done library.  In fact, I'd wager that the problems I'd recently run into had very little, if nothing to do with the core jQuery code.  I think the fault may lie with simpleModal, but the ever popular juxtaposition of coding with something completely new and being under a tight deadline this week is causing me to forgo troubleshooting the code I was told I had to use for now.

Problem: After loading up a hidden DIV with content, showing it as a dialog via $.ajax(...) and modal(...) calls, and closing the dialog using the built-in simpleModal functionality, subsequent attempts to cause an ASP.Net postback on the page failed miserably with a JavaScript error: "theForm.__EVENTTARGET is null or not an object". Popping other dialog boxen worked just fine.

Just the facts:

  1. The content rendered into the dialog box is the result of a same-page GET, which results in a single User Control being rendered to the Response.OutputStream.
  2. RenderControl on the user control was failing unless the content of the control was rooted in a server-side form element.
  3. When the dialog was rendered, the control's form element was rendered as well, with the same id and name as the page's form element.
  4. When the dialog was closed, the default simpleModal functionality left behind the control's form element, albeit empty.
  5. Despite all this, postbacks worked just fine in Firefox (naturally)

The solution (as of my last checkin before lunch):

  1. Override the dialog's onClose event, and do the following:
    1. Call the dialog's default Close function
    2. Set the dialog div's innerHTML to a single  
    3. Hijack __doPostBack, pointing it to a new function, newDoPostBack

From some comments I’ve seen on the web, point 1 needs some clarification.  Unfortunately, I’m no longer with the same employer, and don’t have access to the code I used, but I’ll do what I can.  First off, you need to override the dialog’s onClose function by defining a new function, and pointing your dialog to it, like this:

$('#myJQselector).modal({onClose: mynewClose});
  • Call the dialog's default Close function.  In the function you define, you should first call the default functionality (a best practice for just about anything you override usually):
  • Set the dialog div's innerHTML to a single   – This is not a required step, so skip it if you don’t understand this.
  • Hijack __doPostBack, pointing it to a new function, newDoPostBack
function myNewClose (dialog)
{
    dialog.close();
    __doPostBack = newDoPostBack;
}
  1. Write the newDoPostBack function:
function newDoPostBack(eventTarget, eventArgument)
{
    var theForm = document.forms[0];
    if (!theForm)
    {
        theForm = document.aspnetForm;
    }
 
    if (!theForm.onsubmit || (theForm.onsubmit() != false))
    {
        document.getElementById("__EVENTTARGET").value = eventTarget;
        document.getElementById("__EVENTARGUMENT").value = eventArgument;
        theForm.submit();
    }
}
	

The newDoPostBack function differs from the original __doPostBack in three small but significant ways.  First, it finds the theForm variable every time it's called; something in the dialog's lifecycle was causing the original page-level JavaScript variable to get nulled-out.  Second, it finds that variable using an integer indexer, and not via the string indexer, by name.  For some reason, getting it by name returned a JS variable of type DispHTMLElementCollection, and not DispHTMLFormElement.  You can't call submit() on the former, so we use the integer indexer to get the latter.  Third, getting the __EVENT* fields using the DOM (i.e. document.__EVENTTARGET) was not working - something about the dialog lifecycle broke this as well.  However, using document.getElementById still gets us what we want, so we use that.

Once we do all that, we get our post-dialog postbacks back.  Thank God for the new-and-improved IE Developer Toolbar with built-in DOM inspector; it was a piece of memorry-hogging CRAP back in 2006, but seems to be behaving itself now.

- G