42

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?

Jason
  • 7,152
  • 11
  • 70
  • 118
  • Here's a related solution, that helped me to get a responsive dialog -- http://stackoverflow.com/a/9236702/1298685 . – Ian Campbell May 30 '14 at 00:25

14 Answers14

67

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
// movemaine@gmail.com

$("#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)
Mike
  • 20,721
  • 13
  • 66
  • 79
Jason
  • 7,152
  • 11
  • 70
  • 118
  • 1
    Thank you very much for this! The width auto, maxwidth bug has been a huge nuisance! – DroidOS Sep 02 '13 at 08:57
  • 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. – DroidOS Sep 02 '13 at 09:07
  • The _else_ bit can be modified quite easily to enforce a minWidth too. `$this.css("min-width",dialog.options.minWidth + 'px')` – DroidOS Nov 22 '13 at 09:40
  • I tried this but it didnt work. Is it because am using javascript gumby? – Sarah James Feb 07 '14 at 15:48
  • 2
    @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'). – luqita Jun 02 '14 at 22:31
  • 1
    @luqita - that's dependent on what version of jQuery UI you are using. They changed the data option for dialog through releases. – Jason Jun 18 '14 at 18:08
  • I edited the answer to take out the "fluid" option since it is no longer an option according to http://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. – Mike Jul 02 '14 at 20:04
  • @Mike - `fluid` was never part of the api. `fluid` was an option I was adding. – Jason Jul 03 '14 at 21:45
  • @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. – Jason May 10 '16 at 11:55
  • This should have the "click outside" set to not close by default to maintain the prior behavior without forcing an option to be set. – Mark Schultheiss Feb 07 '17 at 13:35
  • 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 me – aayushi Mar 30 '17 at 11:41
  • nice. rather than have a function that just calls another function, you can: // resize on window resize $(window).on("resize", resize); – Garr Godfrey Feb 02 '18 at 04:29
  • This is buggy especially when resizing the dialog and then the window. I posted an alternative solution. – Adam Jimenez Feb 07 '18 at 20:16
  • @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. – Jason Feb 27 '18 at 19:10
  • @Jason 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. – Adam Jimenez Feb 28 '18 at 10:20
39

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");
  }
});
tsi
  • 1,146
  • 10
  • 9
10

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/

iautomation
  • 840
  • 10
  • 16
  • I tried this approach. It succeeded in making the dialog responsive, but prevents both draggable and resizable. – Jeffrey Simon Feb 26 '16 at 19:56
  • @JeffreySimon thankyou for pointing that out. Please see the EDIT – iautomation Feb 26 '16 at 21:57
  • 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). – Jeffrey Simon Feb 27 '16 at 00:13
  • 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. – DaveS Mar 03 '16 at 08:11
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>
gracia16
  • 113
  • 1
  • 6
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".

Adrian P.
  • 4,484
  • 1
  • 40
  • 43
  • very similar to my Ui Dialog extended approach. https://github.com/jasonday/jQuery-UI-Dialog-extended – Jason Oct 31 '14 at 14:31
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.

Jeffrey Simon
  • 702
  • 2
  • 9
  • 19
3
$("#content").dialog({
    width: 'auto',
    create: function (event, ui) {
        // Set max-width
        $(this).parent().css("maxWidth", "600px");
    }
});

This Worked for me

Himalaya Garg
  • 1,262
  • 15
  • 22
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
});
kiranutt
  • 21
  • 5
  • 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. – Jeffrey Simon Feb 26 '16 at 19:59
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);
    }
});
everis
  • 195
  • 2
  • 10
1

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;
}
wogsland
  • 7,351
  • 16
  • 46
  • 79
Fang Fang
  • 53
  • 5
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 =)

Chandler Zwolle
  • 1,399
  • 1
  • 9
  • 7
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();
});
Felipe Volpatto
  • 145
  • 1
  • 11
amchugh89
  • 1,068
  • 13
  • 27
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

Adam Jimenez
  • 2,714
  • 3
  • 29
  • 30
0

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!

Jason
  • 73
  • 1
  • 4