jquery ui dialog fixed positioning

68,758

Solution 1

I tried some of the solutions posted here, but they don't work if the page has been scrolled prior to the dialog being opened. The problem is that it calculates the position without taking into account the scroll position, because the position is absolute during this calculation.

The solution I found was to set the dialog's parent's CSS to fixed PRIOR to opening the dialog.

$('#my-dialog').parent().css({position:"fixed"}).end().dialog('open');

This assumes that you have already initialized the dialog with autoOpen set to false.

Note, this does not work if the dialog is resizable. It must be initialized with resizing disabled in order for the position to remain fixed.

$('#my-dialog').dialog({ autoOpen: false, resizable: false });

Tested this thoroughly and have found no bugs so far.

Solution 2

I combined some suggested solutions to the following code. Scrolling, moving and resizing works fine for me in Chrome, FF and IE9.

$(dlg).dialog({
    create: function(event, ui) {
        $(event.target).parent().css('position', 'fixed');
    },
    resizeStop: function(event, ui) {
        var position = [(Math.floor(ui.position.left) - $(window).scrollLeft()),
                         (Math.floor(ui.position.top) - $(window).scrollTop())];
        $(event.target).parent().css('position', 'fixed');
        $(dlg).dialog('option','position',position);
    }
});

Update:

If you want to make it default for all dialogs:

$.ui.dialog.prototype._oldinit = $.ui.dialog.prototype._init;
$.ui.dialog.prototype._init = function() {
    $(this.element).parent().css('position', 'fixed');
    $(this.element).dialog("option",{
        resizeStop: function(event,ui) {
            var position = [(Math.floor(ui.position.left) - $(window).scrollLeft()),
                            (Math.floor(ui.position.top) - $(window).scrollTop())];
            $(event.target).parent().css('position', 'fixed');
            // $(event.target).parent().dialog('option','position',position);
            // removed parent() according to hai's comment (I didn't test it)
            $(event.target).dialog('option','position',position);
            return true;
        }
    });
    this._oldinit();
};

Solution 3

I could not get Scott's answer to work with jQuery UI 1.9.1. My solution is to reposition the dialog in a callback from the open event. First set the css position to fixed. Then position the dialog where you want it:

$('selector').dialog({
    autoOpen: false,
    open: function(event, ui) {
        $(event.target).dialog('widget')
            .css({ position: 'fixed' })
            .position({ my: 'center', at: 'center', of: window });
    },
    resizable: false
});

Note: As noted in another answer, resizing the dialog will set its position to absolute again, so I've disabled resizable.

Solution 4

Bsed on Langdons's comment above, I tried the following, which works fine with jQuery-UI 1.10.0 and resizable dialogs:

$('#metadata').dialog(
{
    create: function (event) {
    $(event.target).parent().css('position', 'fixed'); 
    },
    resizeStart: function (event) {
    $(event.target).parent().css('position', 'fixed'); 
    },
    resizeStop: function (event) {
    $(event.target).parent().css('position', 'fixed'); 
    }
});

Solution 5

try:

$(document).ready(function() {
  $('#myDialog').dialog({dialogClass: "flora"});
  $('.flora.ui-dialog').css({position:"fixed"});
)};

(from http://dev.jqueryui.com/ticket/2848)

Share:
68,758
scc
Author by

scc

Updated on July 09, 2022

Comments

  • scc
    scc almost 2 years

    I needed the dialog to maintain its position fixed even if the page scrolled, so i used the extension at http://forum.jquery.com/topic/dialog-position-fixed-12-1-2010 but there's 2 problems with it:

    • it flickers in IE and Firefox on page scroll (in Safari/Chrome it's fine)

    • on closing and then reopening, it looses its stickyness and scrolls along with the page.

    Here's the code i'm using for creating the dialog:

    $('<div id="'+divpm_id+'"><div id="inner_'+divpm_id+'"></div><textarea class="msgTxt" id="txt'+divpm_id+'" rows="2"></textarea></div>')
                    .dialog({
                    autoOpen: true,
                    title: user_str,
                    height: 200,
                    stack: true,
                    sticky: true //uses ui dialog extension to keep it fixed
         });
    

    And here's the code i'm using for reopening it:

    jQuery('#'+divpm_id).parent().css('display','block');
    

    Suggestions/solutions?

    Thanks

  • kingjeffrey
    kingjeffrey almost 14 years
    This assumes you are using jqueryui.com's dialog
  • Scott Greenfield
    Scott Greenfield almost 13 years
    This doesn't work if the user opens the dialog after scrolling. The problem with that is that jQuery's dialog calculates the dialog position relative to the window scroll offset, which is not needed for position:fixed. I will post an update when I get that figured out (without forking the source).
  • kingjeffrey
    kingjeffrey almost 13 years
    Heh. Just googled how to do this and got my own answer! Strange.
  • kingjeffrey
    kingjeffrey almost 13 years
    By doing this, you set the css property every time the dialog is opened. If you set it at document ready, it is set once works for all future opens.
  • Scott Greenfield
    Scott Greenfield almost 13 years
    Just posted a solution that is very close to yours but fixes the bug I described in my previous comment.
  • Langdon
    Langdon over 12 years
    I find it better to run this logic in the create event, so that you can call the standard .dialog('open') elsewhere, without having to run this hack each time... $('#metadata').dialog({ create: function (event) { $(event.target).parent().css('position', 'fixed'); });
  • Omu
    Omu over 11 years
    setting dialogClass: to a class with position:fixed was working in 1.8.24, but since 1.9.0 it goes off screen if scrolling down before opening
  • danmux
    danmux about 11 years
    This appears to me to be the most complete solution, works great - thanks.
  • hai
    hai almost 11 years
    please remove .parent() in update section at line: $(event.target).parent().dialog('option','position',position‌​);
  • v3nt
    v3nt over 10 years
    this has saved me so much grief! Thanks!
  • space_balls
    space_balls over 10 years
    thanks!!!! using an older version of jquery UI (1.8.7). just saved me soooooo much time
  • Stefan Haberl
    Stefan Haberl almost 10 years
    Scotts answer works fine with jQuery-UI 1.11. Just a minor improvement on @Langdon comment: Using $("selector").dialog("widget") makes you a little bit more robust to future changes in jQuery's dialog DOM structure. So that becomes: $('#metadata').dialog({ create: function(event) { $(event.target).dialog("widget").css({ "position": "fixed" }); });
  • mpen
    mpen about 9 years
    This works fairly well except the box disappears while resizing.
  • mpen
    mpen about 9 years
    Fixed the disappearing box issue by adding a resize event. Example here: gist.github.com/mnpenner/b214b93ab221cf93ffa0 It uses underscore/lodash's throttle to prevent the resize event from firing too often; not sure if that's necessary.
  • torvin
    torvin about 8 years
    This is the only reliable way
  • zondo
    zondo almost 8 years
    While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.
  • Skeets
    Skeets almost 8 years
    This is great! Just one bug left: dragging the dialog until the screen scrolls messes up the position of the dialog. Probably should disable scrolling while the dialog is being moved?