jquery ui dialog fixed positioning
Asked Answered
L

15

42

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

Legumin answered 17/4, 2010 at 3:13 Comment(1)
If you know another jquery plugin for a dialog that stays fixed and doesn't flicker, i'm interested as wellLegumin
W
46

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.

Workbench answered 28/6, 2011 at 0:20 Comment(3)
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'); });Hanky
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 openingEmeraldemerge
Scotts answer works fine with jQuery-UI 1.11. Just a minor improvement on @Hanky 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" }); });Ahmad
R
33

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();
};
Robledo answered 11/2, 2012 at 18:18 Comment(6)
This appears to me to be the most complete solution, works great - thanks.Hawger
please remove .parent() in update section at line: $(event.target).parent().dialog('option','position',position);Heliotropin
thanks!!!! using an older version of jquery UI (1.8.7). just saved me soooooo much timeEellike
This works fairly well except the box disappears while resizing.Schappe
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.Schappe
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?Etna
C
10

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.

Clanton answered 28/12, 2012 at 12:54 Comment(0)
W
8

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'); 
    }
});
Walford answered 2/3, 2013 at 20:13 Comment(1)
This is the only reliable wayCherubini
P
4

try:

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

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

Purcell answered 18/6, 2010 at 22:52 Comment(4)
This assumes you are using jqueryui.com's dialogPurcell
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).Workbench
Heh. Just googled how to do this and got my own answer! Strange.Purcell
Just posted a solution that is very close to yours but fixes the bug I described in my previous comment.Workbench
Z
3

Force your dialog box's position to be position:fixed using CSS

$('.selector').dialog({ dialogClass: 'myPosition' });

and define the myPosition css class as:

.myPosition {
    position: fixed;
}
Zulemazullo answered 7/7, 2012 at 21:31 Comment(0)
L
2
$("#myDilog").dialog({
    create:function(){
        $(this).parent().css({position:"fixed"});
    }
});
Laveen answered 26/8, 2015 at 9:36 Comment(1)
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.Jeopardous
P
1

I found that these answers didn't work for me but combining some of them did. I used the create function to set the dialog as fixed so it didn't scroll the window down when the dialog was created.

create: function (event) { 
        $(event.target).parent().css('position', 'fixed')
    }

Also I used the open function to make sure the dialog didn't disappear off the screen by changing the top value.

open: function(event, ui) {
        $(event.target).parent().css('top', '30%')
    }

This worked with autoOpen and resizable.

Pithead answered 28/2, 2021 at 21:1 Comment(0)
L
0
 $('#myDialog').dialog({ dialogClass: "flora" });
        $('.flora.ui-dialog').css({ top: "8px" });

this will keep the dialog on top position no matter were we have clicked.

Lingo answered 23/6, 2010 at 6:43 Comment(0)
T
0
$('#'+tweetidstack.pop()).dialog("open").parent().css({position:"fixed"});

Why use $(document).ready ? This might be a recent development, but it works fine now.

Tuppence answered 24/3, 2011 at 13:35 Comment(1)
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.Purcell
B
0
$( ".ui-dialog" ).css("position","fixed");  

$( ".ui-dialog" ).css("top","10px");

put this code on open function of dialog

Balanced answered 4/5, 2013 at 8:52 Comment(0)
F
0

First, create your dialog. Something like this:

$("#dialog_id").dialog({
                autoOpen : false,
                modal : true,
                width: "auto",
                resizable: false,
                show: 'fade',
                hide: { effect:"drop",duration:400,direction:"up" },
                position: top,
                height: 'auto',
                title: "My awesome dialog",
                resizeStart: function(event, ui) {
                    positionDialog();
                },
                resizeStop: function(event, ui) {
                    positionDialog();
                }
            });
            $("#dialog_id").dialog('open');

Then make it auto center with this:

    function positionDialog (){
        setInterval(function(){
            if($("#dialog_id").dialog( "isOpen" )){
                $("#dialog_id").dialog('option','position',$("#dialog_id").dialog( "option", "position" ));
            }
        },500);
    }
//setInterval is for make it change position "smoothly"
//You can take it off and leave just the if clausule and its content inside the function positionDialog.
Furbelow answered 13/6, 2013 at 12:59 Comment(0)
H
0

The solution is actually really simple. I don't know if this applied when the question was asked but it does now anyway.

//First a container/parent-div with fixed position is needed
var dialogContainer=document.body.appendChild(document.createElement("div"));
dialogContainer.style.position="fixed";
dialogContainer.style.top=dialogContainer.style.left="50%";//helps centering the window

 

//Now whenever a dialog is to be created do it something like this:
$(myDialogContent).dialog({
    appendTo: dialogContainer,
    position: { 
        at: 'center center',
        of: dialogContainer
    }
});

About "appendTo": http://api.jqueryui.com/dialog/#option-appendTo
About "position": http://api.jqueryui.com/position/

Hairbreadth answered 5/7, 2014 at 11:19 Comment(0)
C
0

While similar to some of the other answers above, I've found that I had to do more than just position: fix the dialog, but I also had to position: static it's content to keep it attached to the dialog.

$('<div id="myDialog" class="myClass">myContent</div>')
        .dialog(dialogOptions)
        .parent()
        .css({ position: 'fixed' })
        .end()
        .position({ my: 'center', at: 'center', of: window })
        .css({ position: 'static' });

After this, I could call .dialog('open') any time I wanted and it would simply appear where I left it. I actually have this in a function that will return the existing dialog or create a new one as needed and then I just change the values of the dialog before .dialog('open') gets called.

Cydnus answered 15/5, 2017 at 10:28 Comment(0)
K
0

As i wrote in my blog https://xbrowser.altervista.org/informatica-portata/jquery-easyui-bug-fix-window-dialog-position-widget/ I've found a bug in “window” element or “dialog” element. When you instantiate this widget, it go out of the main window browser, in particular in top and left position (when you drag o resize it). To resolve this problem i’ve implemented this solution.

You can read the source code below:

$(dialog).window({
   onMove: function(left, top) {
   if (left < 0 || top < 0) {
     left = (left < 0) ? 0 : left;
     top = (top < 0) ? 0 : top;
     $(this).window('move', {left: left, top: top});
   }
},
onResize: function(width, height) {
  var opt = $(this).window("options");
  var top = opt.top;
  var left = opt.left;
  if (top < 0) {
    top = (top < 0) ? 0 : top;
    $(this).window('move', {left: left, top: top});
  }
}
}).window("open");

The same code is for dialog:

$(dialog).dialog({
  onMove: function(left, top) {
  if (left < 0 || top < 0) {
     left = (left < 0) ? 0 : left;
     top = (top < 0) ? 0 : top;
     $(this).dialog('move', {left: left, top: top});
  }
},
onResize: function(width, height) {
   var opt = $(this).window("options");
   var top = opt.top;
   var left = opt.left;
   if (top < 0) {
     top = (top < 0) ? 0 : top;
     $(this).dialog('move', {left: left, top: top});
   }
}
}).dialog("open");

Futhermore, when you call “$(this).window(“options”);” inside “onResize” method, and start your App, you don’t see the window; so i must insert the “.window(“open”);” at the and of declaration of dialog.

I hope to help you.

Kwabena answered 6/12, 2017 at 12:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.