A BAD of Roses – JQuery UI Dialog and ASP.Net AJAX

20 בפברואר 2009

תגיות: , ,
13 תגובות

You see, all I wanted was to integrate JQuery’s dialog into my ASP.Net application. The JQuery guys really did an amazing job there and it’s a shame no to take advantage of it.

So I did.

The outcome: 5 days trying to figure out what’s wrong (that includes the weekend!) and eventually, a fragile solution that made me abandon the whole thing.

In this post I’m going to briefly introduce you with the JQuery UI dialog, explain the problem I had, the cause to the problem and my frail solution suggestion.

The JQuery UI Dialog

The JQuery UI Dialog is a great little component. It gives you everything you need from a dialog – title, body, buttons, resizing, dragging… it’s an all-in-one pack. You can put whole forms inside, change themes, choose opening and closing effects, make it modal, bind to events and more and more.

All you have to do is – create a DIV, put the dialog content inside, and call the dialog method with the needed properties:

<div id="myDialogDiv" title="Dialog's title">
    The content of the dialog
</div>

<script type="text/javascript">
    $("#myDialogDiv").dialog({
        modal: true,
        overlay: {
            backgroundColor: '#000',
            opacity: 0.5
        },
        buttons: { Close: function() { $(this).dialog('close'); } }
    });
</script>

And this is how it looks like (for example):

JQuery UI  Dialog Screenshot 1

JQuery UI  Dialog Screenshot 2

 

The Problem

The problem starts when you want to have a form inside the dialog. And not just that, you put the dialog div (with the form elements) inside an UpdatePanel.

I’ve made a screencast to demonstrate the problem. The upper  part is an update panel that contains a div with a textbox. The div is hidden. The left lower button opens the dialog with the div and the right lower button alerts the textbox value. Look what happens, especially after a callback is generated:

Download the video 

The Cause

In short – The way JQuery’s dialog and ASP.Net’s UpdatePanel work collide.

In details – UpdatePanel is translated into a DIV element. When you generate a callback in it, the div content is being sent to the server. So if you have a textbox there, it will be sent as part of the server request.

The JQuery UI dialog, in order to avoid, I guess, z-index hell and other happy-happy-joy-joy stuff, takes the DIV that you want to present in the dialog and moves it to the end of the body element.

So… one side needs its elements in a certain place, and the other one takes them out of there.

This is the time when all hell breaks loose. You may start running for your life now.

The Solution

The exact line, where JQuery takes the div away is on the dialog’s init function:

(this is from the 1.6rc6 version but the exact thing appears in the 1.5.3 version)

uiDialog = (this.uiDialog = $('<div/>'))
    .appendTo(document.body)
...

This line constructs a new div for the dialog (it will contain the title and buttons as well). This isn’t our div yet. The next line actually takes our div and adds it to this new div:

uiDialogContent = this.element
    ...
    .appendTo(uiDialog),

So the obvious solution is to remove the .appendTo(document.body) line. This doesn’t work. If you try that, you’ll see the dialog fine on the first click, but from the second click and on you won’t see the dialog at all, only the overlay background…

What I eventually did, was commenting out the appendTo(document.body) line and registering to the dialog close event, where I moved my div to its initial parent:

function showDialog()
{
    // Save the dialog div parent
    parentContainer = $("#myDialogDiv").parents().get(0);
    
    // On close, take the div back to where it belongs
    $("#myDialogDiv").bind('dialogclose', function(event, ui)
    {
        var myDiv = $("#myDialogDiv");
        myDiv.css("visibility", "hidden");
        myDiv.css("display", "none");
        myDiv.appendTo(parentContainer);
    });
    
    // Show the dialog
    $("#myDialogDiv").css("visibility", "visible");
    $("#myDialogDiv").css("display", "block");
    $("#myDialogDiv").dialog({
        modal: true,
        overlay: {
            backgroundColor: '#000',
            opacity: 0.5
        },
        buttons: { Close: function() { $(this).dialog('close'); } }
    });
}

This actually works but I’m scared of its consequences. It just doesn’t feel right… This is why I ended up not using it, even though I like it very much.

If you have a solution, please comment!

All the best,

Shay.

Share it: kick it! | shout it! | dzone it!

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

13 תגובות

  1. redsquare22 בפברואר 2009 ב 3:45

    Your issue using cheap updatepanels. There is no need for them. Keep the dialog, use .ajax to post your data and remove those pesky updatepanels

    להגיב
  2. Avi Pinto22 בפברואר 2009 ב 7:57

    personally, i think that using UpdatePanels is a crime against the server,
    but i wanted to use the above scenario for admin pages
    thanks for saving me 5 days!!.

    להגיב
  3. shayf22 בפברואר 2009 ב 9:25

    The more I use it, the more I come to realize what you're saying… UpdatePanels are not something you would want to use in large web applications.

    First action item for the next version! :)

    להגיב
  4. dscott23 בפברואר 2009 ב 23:24

    I've found the exact same thing without a proper solution. I also found the jquery ui dialog to cause all kinds of problems with other query controls that are contained within the form you are displaying. For the record there is nothing wrong with updatepanels, so a solution that works with updatepanels will be welcomed.

    להגיב
  5. xmlninja25 במרץ 2009 ב 17:38

    I found this solution, its simple and works really well… obviously you need to be careful what you do to the divs after you move them, but for basic uses its solid: http://www.trentjones.net/…/jqueryui-dialog-with-aspnet-empty-post-values

    להגיב
  6. abonilla6 באפריל 2009 ב 6:44

    This is the real solution to the problem:

    before submit do something like ".dialog("destroy").appendTo("#myForm");"

    http://groups.google.com/group/jquery-ui-dev/browse_thread/thread/1e960b5b82d2f3a5

    להגיב
  7. Ravi4 ביולי 2009 ב 1:53

    I agree the update panels need to be used with discretion. But in case you need to use them with jquery dialog, here is a how to full sample.
    http://blog.roonga.com.au/2009/07/using-jquery-ui-dialog-with-aspnet-and.html

    להגיב
  8. Indialike20 בינואר 2010 ב 14:34

    Very nice and useful tutorials for web designers,
    Thanks for posting.

    להגיב
  9. Aaron17 במרץ 2010 ב 9:21

    I never normally post

    but serisouly thank you.

    from New Zealand

    להגיב
  10. Aaron17 במרץ 2010 ב 9:21

    I never normally post

    but serisouly thank you.

    from New Zealand

    להגיב
  11. Mojo26 באפריל 2011 ב 22:32

    doesn't .live eliminate that problem?… I'm dumping postbacks and update panels like the bad habit they are.

    להגיב