views:

58

answers:

2

The file I'm loading into the modal dialog can vary in height. When the first link is opened, the top of the dialog is centered horizontally (meaning the dialog is positioned too low). After I close this and reopen again, with either the same edit button or a different one, the positioning is better.

It seems like it's always one step behind: the first load it can't tell what the width/height is of the file being loaded, then on a subsequent load of the same file, it's positioned perfectly.

I'm using the following code as a modal edit for a data table:

$(".editMe").button({
    icons: {
        primary: 'ui-icon-document'
    },
    text: false
}).click(function () {
    var eventLink = $(this).attr("name");
    var dialogOpts = {
        title: "Make Modifications or Delete This Event",
        modal: true,
        autoOpen: false,
        height: "auto",
        width: "auto",
        open: function () {
            //The height of the file below can vary, and in the
            //JS Bin environment the dialog loads just fine blank
            $("#modify").load("themes_edit.asp?id=" + eventLink);
        },
        close: function () {
            oTable.fnDraw();
        }
    };
    $("#modify").dialog(dialogOpts).dialog("open");
    return false;
});

And here's some sample HTML (though the file loaded into #modify isn't live). I've also set this up at JS Bin.

<html>
  <head>
<link class="jsbin" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"&gt;&lt;/script&gt;
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.0/jquery-ui.min.js"&gt;&lt;/script&gt;
<link class="jsbin" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
  </head>
    <body>
      <button class="editMe" name="2810">edit</button>
      <button class="editMe" name="2811">edit</button>
      <button class="editMe" name="2812">edit</button>
      <button class="editMe" name="2813">edit</button>
      <div id="modify"></div>
  </body>
</html>
​

A: 

You can trigger a re-center once the content is loaded (so you know the size), like this:

var dialogOpts = {
    title: "Make Modifications or Delete This Event",
    modal: true,
    autoOpen: false,
    height: "auto",
    width: "auto",
    open: function () {
        $("#modify").load("themes_edit.asp?id=" + eventLink, function() {
          $(this).dialog('option', 'position', 'center');
        });
    },
    close: function () {
        oTable.fnDraw();
    }
};

This just uses the callback for .load() and sets the position option, which triggers a re-center at the appropriate time...which is as soon as you know what the correct size is.


As a side note, since you're creating and then opening the dialog, you can remove both the autoOpen: false, property and .dialog("open"), the default behavior is to open immediately :)

Nick Craver
Thanks! I'd actually tried that method earlier but didn't like the flicker of the resize. Can the dialog be hidden until after the open resize function?
Paul
@Paul - You could wrap the whole `.dialog()` call in the `.load()` callback, instead of the `.load()` being inside the open function...but the dialog would seem to lag to users, a loading image in there would be a better/more informative approach I think.
Nick Craver
A: 

The 'one step behind' will be because in your dialog open event you try to load the data. So when the dialog shows it will show the old content and then suddenly the new content will appear.

One way to approach this is to open the dialog but first clear the existing content and show a loading gif whilst you wait for the ajax call to respond with the data, which you then load into the dialog.

N.B If you are worried about the screen jerk when the dialog resizes then you could put the ajax response into a div that is positioned off screen then get the dimensions, then nicely animate the resize of the dialog whilst fading in the new content.

var dialogOpts = {
        title: "Make Modifications or Delete This Event",
        modal: true,
        autoOpen: false,
        height: "auto",
        width: "auto",
        close: function () {
            oTable.fnDraw();
        }
};

var $editDialog = $('#modify').dialog(dialogOpts);

$(".editMe").button({
    icons: {
        primary: 'ui-icon-document'
    },
    text: false
}).click(function () {

    var eventLink = $(this).attr("name");

    //clear existing dialog content and show an ajax loader
    $editDialog.html('<div class="loading" />');

    //show the dialog
    $editDialog.dialog("open");

    //get dynamic content and load it into the dialog and resize
    $.get("themes_edit.asp?id=" + eventLink, function(response){

        //fade out ajax loader
        $editDialog.find('div.loading').fadeOut(500, function(){

              $editDialog.html( response )
                         .dialog('option', 'position', 'center');

        });

    });

    return false;

});
redsquare
This would add an unnecessary half-second delay to each dialog though, I wouldn't recommend this for most applications, always display the data ASAP, make the experience as fast as possible.
Nick Craver
@NickCraver The user would not notice as it acts much smoother than quick face slap content appearance, especially since the ui dialog opening does not nicely support open/close animation x-browser + the op mentioned his disgust at things flickering;)
redsquare
The dialog itself would be that, remember your solution will still jerk to a new size then fade in (a delay *after* it's loaded, that's the unnecessary part, this should be a much shorter duration if used), to me this combination is more jarring than just showing the content at the correct size/position originally. - For your edit: I find the effects work great cross browser, for example I prefer drop for hiding the dialog. Are you having other issues?
Nick Craver
see my N.B - to smoothly animate the dialog to its new required dimensions
redsquare
Nick - it was more the opening of the dialogs, there is no nice animation that works x-browser (especially fade) - without hacking the life out of the plugin.
redsquare
@redsquare - There's no need for that, you can just `.load()` the content then make the dialog appear, with whatever open effect you specified, much simpler, less code, less hacky, that's the solution I proposed to the OP in comments, though I'd recommend against a non-indicative approach, there should be some notice that *something* is happening.
Nick Craver
@redsquare - Do you have some evidence of this? Fading in works fine in IE7, 8, Chrome, Firefox and Safari for me: http://jsfiddle.net/W4B3E/
Nick Craver
Thanks to both of you! I'm going to pursue this avenue, though I think eventually I'll force the dialog to a fixed size (which would eventually work with my app).
Paul