Responsive jQuery UI Dialog ( and a fix for maxWidth bug )
Asked Answered
M

15

46

With many sites leveraging jQuery UI, there are some major shortcomings that have to be overcome because jQuery UI does not support responsive design and there's a longstanding bug when maxWidth is used in conjunction with width:'auto'.

So the question remains, how to make jQuery UI Dialog responsive?

Morion answered 9/5, 2013 at 22:3 Comment(1)
Here's a related solution, that helped me to get a responsive dialog -- https://mcmap.net/q/169314/-enlarging-an-image-to-full-screen-maintain-aspect-ratio-and-then-center .Alizaalizarin
M
68

Below is how I achieved a responsive jQuery UI Dialog.

To do this, I added a new option to the config - fluid: true, which says to make the dialog responsive.

I then catch the resize and dialog open events, to change the max-width of the dialog on the fly, and reposition the dialog.

You can see it in action here: http://codepen.io/jasonday/pen/amlqz

Please review and post any edits or improvements.

// Demo: http://codepen.io/jasonday/pen/amlqz
// [email protected]

$("#content").dialog({
    width: 'auto', // overcomes width:'auto' and maxWidth bug
    maxWidth: 600,
    height: 'auto',
    modal: true,
    fluid: true, //new option
    resizable: false
});


// on window resize run function
$(window).resize(function () {
    fluidDialog();
});

// catch dialog if opened within a viewport smaller than the dialog width
$(document).on("dialogopen", ".ui-dialog", function (event, ui) {
    fluidDialog();
});

function fluidDialog() {
    var $visible = $(".ui-dialog:visible");
    // each open dialog
    $visible.each(function () {
        var $this = $(this);
        var dialog = $this.find(".ui-dialog-content").data("ui-dialog");
        // if fluid option == true
        if (dialog.options.fluid) {
            var wWidth = $(window).width();
            // check window width against dialog width
            if (wWidth < (parseInt(dialog.options.maxWidth) + 50))  {
                // keep dialog from filling entire screen
                $this.css("max-width", "90%");
            } else {
                // fix maxWidth bug
                $this.css("max-width", dialog.options.maxWidth + "px");
            }
            //reposition dialog
            dialog.option("position", dialog.options.position);
        }
    });

}

EDIT

Updated approach: https://github.com/jasonday/jQuery-UI-Dialog-extended

The repository above also includes options for:

  • Click outside of dialog to close
  • Hide title bar
  • hide close button
  • responsive (to address above)
  • scale width & height for responsive (ex: 80% of window width)
Morion answered 9/5, 2013 at 22:3 Comment(15)
Thank you very much for this! The width auto, maxwidth bug has been a huge nuisance!Justness
It is perhaps worth pointing out that fluidDialog could also be called from dialog open: to ensure that width:'auto' + maxWidth:www are both respected immediately after opening the dialog - without any window resizing.Justness
The else bit can be modified quite easily to enforce a minWidth too. $this.css("min-width",dialog.options.minWidth + 'px')Justness
I tried this but it didnt work. Is it because am using javascript gumby?Murchison
@SarahJames: It probably didn't work because you have to change this line: var dialog = $this.find(".ui-dialog-content").data("ui-dialog"), to var dialog = $this.find(".ui-dialog-content").data("dialog") //.data('dialog') instead of .data('ui-dialog').Hydrokinetic
@Hydrokinetic - that's dependent on what version of jQuery UI you are using. They changed the data option for dialog through releases.Morion
I edited the answer to take out the "fluid" option since it is no longer an option according to api.jqueryui.com/dialog, however I see that another big chunk of the answer needs to be edited accordingly as well since it relies on this property. For now I just reverted it.Councilman
@Councilman - fluid was never part of the api. fluid was an option I was adding.Morion
@Mark follow the github link in my answer. I've created a plug in to extend jQuery UI Dialog with more options, including click outside handling, etc.Morion
This should have the "click outside" set to not close by default to maintain the prior behavior without forcing an option to be set.Irruption
awesome it is , can you please tell me how to make a text area in mvc responsive ? I had tries all the solutions but none of those worked for meLabellum
nice. rather than have a function that just calls another function, you can: // resize on window resize $(window).on("resize", resize);Tippet
This is buggy especially when resizing the dialog and then the window. I posted an alternative solution.Ruckman
@AdamJimenez - I'm not surprised, as I haven't updated it in some time and I'm sure there are conflicts with newer versions of jQuery. As always, people are welcome to open pull requests with updates and hopefully I'l have some time to look at it myself.Morion
@Morion I would have created a PR if it wasn't so flawed! Don't mean to be harsh but I spent some time trying to fix it before going with a rewrite which ended up being a simpler, more elegant, more stable and cleaner solution.Ruckman
J
44

Setting maxWidth on create works fine:

$( ".selector" ).dialog({
  width: "auto",
  // maxWidth: 660, // This won't work
  create: function( event, ui ) {
    // Set maxWidth
    $(this).css("maxWidth", "660px");
  }
});
Javelin answered 26/11, 2013 at 13:42 Comment(3)
Works perfectly. Thanks.Melt
I had to do $(this).parent().css('maxWidth', '660px');, but other than that, perfect, thank you.Antiperspirant
In my case, to make sure my dialog does not exceed the width of narrow displays, and is actually inset a little, i used $(this).parent().css('maxWidth', 'calc(100% - 20px)');.Evergreen
M
11

No need for jQuery or Javascript. CSS solves everything for this.

This is my project solution for a responsive jquery dialog box. Default width and height, then max width and height for as small as the browser shrinks. Then we have flexbox to cause the contents to span the available height.

Fiddle: http://jsfiddle.net/iausallc/y7ja52dq/1/

EDIT

Updated centering technique to support resizing and dragging

.ui-dialog {
    z-index:1000000000;
    top: 0; left: 0;
    margin: auto;
    position: fixed;
    max-width: 100%;
    max-height: 100%;
    display: flex;
    flex-direction: column;
    align-items: stretch;
}
.ui-dialog .ui-dialog-content {
    flex: 1;
}

Fiddle: http://jsfiddle.net/iausallc/y7ja52dq/6/

Meunier answered 23/10, 2015 at 2:35 Comment(4)
I tried this approach. It succeeded in making the dialog responsive, but prevents both draggable and resizable.Pyroelectric
@JeffreySimon thankyou for pointing that out. Please see the EDITMeunier
I tried the revised version. The previous version (with issues) dynamically resized as you changed the size of the browser window. But only was responsive with respect to changing the window and then reloading. One could make a good case that this is sufficient, because users don't change the size of their device; only developers test by dynamically changing the browser width. However, if that is the goal, my solution below is even simpler, by using width: Math.min(400, $(window).width() * .8). At this point, I am tending to go for the dynamic solution given as the answer above (fluidDialog).Pyroelectric
I liked this solution very much because it just required a chunk of CSS. It worked perfectly for me, and although I also liked the next solution, this was the first I tried and once it worked, I'm sold.Collude
T
8

I gathered these codes from several sources and I put them together. This is how I came up with a responsive jQuery UI Dialog. Hope this helps..

<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">

<title>jQuery UI Dialog - Modal message</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>

<script>
  $(document).ready(function() {
  $("#dialog-message").dialog({
    modal: true,
    height: 'auto',
    width: $(window).width() > 600 ? 600 : 'auto', //sets the initial size of the dialog box 
    fluid: true,
    resizable: false,
    autoOpen: true,
    buttons: {
       Ok: function() {
         $(this).dialog("close");
       }
    }
  });
    $(".ui-dialog-titlebar-close").hide();
  });
  $(window).resize(function() {
  $("#dialog-message").dialog("option", "position", "center"); //places the dialog box at the center
  $("#dialog-message").dialog({
    width: $(window).width() > 600 ? 600 : 'auto', //resizes the dialog box as the window is resized
 });
});
</script>

</head>
<body>

<div id="dialog-message" title="Responsive jQuery UI Dialog">
  <p style="font-size:12px"><b>Lorem Ipsum</b></p>
  <p style="font-size:12px">Lorem ipsum dolor sit amet, consectetur 
   adipiscing elit. Quisque sagittis eu turpis at luctus. Quisque   
   consectetur ac ex nec volutpat. Vivamus est lacus, mollis vitae urna 
   vitae, semper aliquam ante. In augue arcu, facilisis ac ultricies ut, 
   sollicitudin vitae  tortor. 
  </p>
</div>

</body>
</html>
Tillage answered 9/7, 2015 at 15:53 Comment(0)
I
3

I have managed to to a responsive dialog with old

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

like this

            var dWidth = $(window).width() * 0.9;
            var dHeight = $(window).height() * 0.9; 

            $('#dialogMap').dialog({
                autoOpen: false,
                resizable: false,
                draggable: false,
                closeOnEscape: true,
                stack: true,
                zIndex: 10000,
                width: dWidth,
                height: dHeight,    
                modal: true,
                open:function () {          

                }
            });
            $('#dialogMap').dialog('open'); 

Resize the window on JSFiddle result and click "Run".

Indemnity answered 5/10, 2014 at 22:38 Comment(1)
very similar to my Ui Dialog extended approach. github.com/jasonday/jQuery-UI-Dialog-extendedMorion
P
3

I am not sure that my simple solution solves the problem of this question, but it works for what I am trying to do:

$('#dialog').dialog(
{
    autoOpen: true,
    width: Math.min(400, $(window).width() * .8),
    modal: true,
    draggable: true,
    resizable: false,
});

That is, the dialog opens with a 400px width, unless the width of the window requires a smaller width.

Not responsive in the sense that if the width is narrowed the dialog shrinks, but responsive in the sense that on a specific device, the dialog will not be too wide.

Pyroelectric answered 1/11, 2015 at 21:3 Comment(1)
Perfect. Short 'n sweet, not dynamic, but I didn't need that. Thank you!Bearing
P
3
$("#content").dialog({
    width: 'auto',
    create: function (event, ui) {
        // Set max-width
        $(this).parent().css("maxWidth", "600px");
    }
});

This Worked for me

Pixie answered 24/8, 2016 at 16:29 Comment(1)
This is the simplest and most responsive solution while being native. ThanksLabrum
A
2

If your site is restricted to a max size, then below approach will work. Attach a css style to your dialog.

.alert{
    margin: 0 auto;
    max-width: 840px;
    min-width: 250px;
    width: 80% !important;
    left: 0 !important;
    right: 0 !important;
}

$('#divDialog').dialog({
    autoOpen: false,
    draggable: true,
    resizable: true,
    dialogClass: "alert",
    modal: true
});
Alithia answered 14/4, 2014 at 19:56 Comment(1)
I tried this approach. I works smoother than iautomation for responsive. However, draggable and resizable only work vertically. Dragging horizontally does not work, and resizing horizontally leaves the dialog at the same dimension, but resizes the content only.Pyroelectric
A
2

I just found a solution for this issue.

I pasted my css style, hope this can help someone

.ui-dialog{
  position: fixed;

  left: 0 !important;
  right: 0 !important;

  padding: rem-calc(15);
  border: 1px solid #d3dbe2;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);

  max-width: rem-calc(620);
  top: rem-calc(100) !important;

  margin: 0 auto;
  width: calc(100% - 20px) !important;
}
Aguascalientes answered 8/6, 2016 at 17:43 Comment(0)
M
1

I have managed to do responsive dialog like this. Because use percent on maxWidth looked weird.

var wWidth = $(window).width();
var dWidth = wWidth * 0.8;

$('.selector').dialog({
    height: 'auto',
    width: 'auto',
    create: function(){
        $(this).css('maxWidth', dWidth);
    }
});
Moynihan answered 16/1, 2014 at 15:5 Comment(0)
H
0

Thanks for the posts! This saved me a great deal of time.

I would also like to add, though, that I was getting some funky positioning when the dialog first opened on certain screen sizes. If you encounter such an error, try doing something like this:

if (wWidth < dialog.options.maxWidth + 50) {
    // keep dialog from filling entire screen
    $this.css("max-width", "90%");

    // ADDED
    $this.css("left", "5%");
} else {
    // fix maxWidth bug
    $this.css("max-width", dialog.options.maxWidth);

    // ADDED
    var mLeft = (wWidth - dialog.options.maxWidth) / 2;
    $this.css("left", mLeft + "px");
}

Hopefully this saves someone a headache =)

Henig answered 21/1, 2014 at 20:16 Comment(0)
H
0

Thank you, this makes responsive, but I still had an issue with the dialog being offcenter b/c my content (django form template) was loading after the dialog opened. So Instead of $( "#my-modal" ).load(myurl).dialog("open" );, I call $( "#my-modal" ).dialog("open" ); Then in the dialog, I add the option 'open' and call a load, then your fluidDialog() function:

in the dialog options (modal, fluid, height..etc):

open: function () {
    // call LOAD after open
    $("#edit-profile-modal").load(urlvar, function() {
    // call fluid dialog AFTER load
    fluidDialog();
});
Hemmer answered 10/11, 2015 at 17:54 Comment(0)
R
0

The accepted solution is rather buggy and overengineered imo. I came up with dialogResize which is cleaner and more straightforward for my purposes.

Implement like so:

$("#dialog").dialogResize({
  width: 600,
  height: 400,
  autoOpen: true,
  modal: true
});

Demo

Ruckman answered 7/2, 2018 at 20:15 Comment(0)
Y
0

Creating a maximum window in advance is not very good. I liked css: <style> .ui-dialog{ max-width: calc(100% - 20px) !important; } </style> a good solution. And if we complicate the task? After the window is displayed, there is a request to the database and filling an empty BODY in the table. After inserting the data, the dialog size changes. There is not enough automatic centering. It is possible to do this for .ui-dialog using css?

Yetah answered 30/10, 2023 at 10:31 Comment(2)
what is this? an answer? a question?Magavern
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Ricoriki
M
-1

For me, I liked gracia's answer the most. The gist of gracia's answer was using simple JS ternary operator to set the width:

    $("#dialogDiscount").dialog({
        autoOpen: false,
        modal: true,
        width: $(window).width() > 500 ? 450 : 300,  //this is what fixed it for me
        show: {
            effect: "fade",
            duration: 500
        }
    });

Just so you have more information about my context, I was having the too-big-dialog issue only in the portrait view on iPhone. CSS solutions above had the impact of sometimes showing the transformations (starts out big, then morphs to smaller size, etc.) So I think creating the dialog at the right size is important. And gracia's solution uses number in pixels, instead of percentage, because a number in px is what jQuery-ui dialog expects, without having to modify things. Hope this helps someone!

Morion answered 31/7, 2020 at 17:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.