A BAD of Roses - JQuery UI Dialog and ASP.Net AJAX
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):
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!