Automatically resize jQuery UI dialog to the width of the content loaded by ajax
Asked Answered
N

14

137

I'm having a lot of trouble finding specific information and examples on this. I've got a number of jQuery UI dialogs in my application attached to divs that are loaded with .ajax() calls. They all use the same setup call:

 $(".mydialog").dialog({
        autoOpen: false,
        resizable: false,
        modal: true
 });

I just want to have the dialog resize to the width of the content that gets loaded. Right now, the width just stays at 300px (the default) and I get a horizontal scrollbar.

As far as I can tell, "autoResize" is no longer an option for dialogs, and nothing happens when I specify it.

I'm trying to not write a separate function for each dialog, so .dialog("option", "width", "500") is not really an option, as each dialog is going to have a different width.

Specifying width: 'auto' for the dialog options just makes the dialogs take up 100% of the width of the browser window.

What are my options? I'm using jQuery 1.4.1 with jQuery UI 1.8rc1. It seems like this should be something that is really easy.

EDIT: I've implemented a kludgy workaround for this, but I'm still looking for a better solution.

Nannette answered 9/2, 2010 at 18:26 Comment(0)
T
258

I've just wrote a tiny sample app using JQuery 1.4.1 and UI 1.8rc1. All I did was specify the constructor as:

var theDialog = $(".mydialog").dialog({
        autoOpen: false,
        resizable: false,
        modal: true,
        width:'auto'
});

I know you said that this makes it take up 100% width of the browser window but it works sweet here, tested in FF3.6, Chrome and IE8.

I'm not making AJAX calls, just manually changing the HTML of the dialog but don't think that will cause any probs. Could some other css setting be knocking this out?

The only problem with this is that it makes the width off-centre but I found this support ticket where they supply a workaround of placing the dialog('open') statement in a setTimeout to fix the problem.

Here is the contents of my head tag:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript" src="jquery-ui.min.js"></script>
<link href="jquery-ui.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
    $(function(){
        var theDialog = $(".mydialog").dialog({
            autoOpen: false,
            resizable: false,
            modal: true,
            width: 'auto'
        });

        $('#one').click(function(){
            theDialog.html('some random text').dialog('open');
        });

        $('#two').click(function(){
            theDialog.html('<ul><li>Apple</li><li>Orange</li><li>Banana</li><li>Strawberry</li><li>long text string to see if width changes</li></ul>').dialog('open');
        });

        $('#three').click(function(){
            //this is only call where off-centre is noticeable so use setTimeout
            theDialog.html('<img src="./random.gif" width="500px" height="500px" />');
            setTimeout(function(){ theDialog.dialog('open') }, 100);;
        });
     });
</script>

I downloaded the js and css for Jquery UI from http://jquery-ui.googlecode.com/files/jquery-ui-1.8rc1.zip. and the body:

<div class='mydialog'></div>
<a href='#' id='one'>test1</a>
<a href='#' id='two'>test2</a>
<a href='#' id='three'>test3</a>
Topography answered 14/2, 2010 at 19:13 Comment(9)
Fermin - thanks for your example and post. It turns out it really was a problem with the CSS, although it's still not clear what the exact problem was (it certainly wasn't obvious from Firebug anyway). By moving all my dialog divs to the top level and using the default 1.8.1 CSS (instead of our themed version) it works great. I'll gradually move our themed version back in when 1.8.1 release drops, and find the root of the issue. Thanks!Nannette
No problem, glad I could help. I've been there before, it's a case of moving 1 css statement over at a time.... enjoy!Topography
IE7 seems to be broken thoughPrismoid
If you use AJAX to load the content, setTimeout() may not provide a reliable solution (for example, if the server was slow and took longer than 100ms to load). A better solution would be to use the .ajax() method's callback function to trigger the open. That way it will not open until the page load is complete.Anta
@njbair, the setTimeout method was purely for demo purposes to signify a delay, such as the delay you would get when fetching data via an asynchronous call.Topography
problem with IE8 in compatibility view, the dialog header doesn't span 100% of the container. it shrinks to the size of the title.Breaststroke
Worked for me in FF17, Chrome23, IE8, Opera12 and Safari5. Thanks!Cataplexy
This solution works as long as the height of the content is less than the height of the dialog box. Apparently $.dialog auto width and resize function do not take the scrollbar into consideration.Spodumene
{'width':'auto'} does not work in IE7 and will not be fixed because the {'width':'auto'} option is not supported by jQuery-UI according to scott.gonzalez: "Dialog's don't support auto width. The docs state that the option only accepts a number, which will be used for a pixel size. See jquery-ui-dev thread for a discussion about why we won't support auto width."Tail
S
11

Had the same problem and thanks to you mentioning that the real problem was related to CSS I found the issue:

Having position:relative instead of position:absolute in your .ui-dialog CSS rule makes the dialog and width:'auto' behave strangely.

.ui-dialog { position: absolute;}
Sirreverence answered 15/12, 2011 at 0:29 Comment(0)
H
3

Here's how I did it:

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

Fixing the maxWidth & width: auto bug.

Haehaecceity answered 12/5, 2013 at 16:49 Comment(1)
Could you include some sample code from the linked question?Luteal
U
3

You can avoid the 100% width issue by specifying a maximum width. The maxWidth option does not seem to work; so set the CSS max-width property on the dialog widget instead.

In case you also want to constrain the maximum height, use the maxHeight option. It will correctly show a scrollbar when necessary.

$(function() {
  var $dialog = $("#dialog");
  $dialog.dialog({
    autoOpen: false,
    modal: true,
    width: "auto"
  });
  /*
   * max-width should be set on dialog widget because maxWidth option has known issues
   * max-height should be set using maxHeight option
   */
  $dialog.dialog("widget").css("max-width", $(window).width() - 100);
  $dialog.dialog("option", "maxHeight", $(window).height() - 100);
  $(".test-link").on("click", function(e) {
    e.preventDefault();
    $dialog.html($(this.hash).html());
    // if you change the content of dialog after it is created then reset the left
    // coordinate otherwise content only grows up to the right edge of screen
    $dialog.dialog("widget").css({ left: 0 });
    $dialog.dialog("open");
  });
});
@import url("https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.min.css");
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>

<div id="dialog"></div>

<!-- test links -->

<p>
  <a href="#content-1" class="test-link">Image (Landscape)</a>
  <a href="#content-2" class="test-link">Image (Portrait)</a>
  <a href="#content-3" class="test-link">Text Content (Small)</a>
  <a href="#content-4" class="test-link">Text Content (Large)</a>
</p>
<p>If you are viewing in Stack Snippets > Full page then reload the snippet so that window height is recalculated (Right click > Reload frame).</p>

<!-- sample content -->

<div id="content-1" style="display: none;">
  <img src="https://i.stack.imgur.com/5leq2.jpg" width="450" height="300">
</div>

<div id="content-2" style="display: none;">
  <img src="https://i.stack.imgur.com/9pVkn.jpg" width="300" height="400">
</div>

<div id="content-3" style="display: none;">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam sodales eu urna sit amet fermentum. Morbi ornare, leo ut ornare volutpat, nibh diam mattis elit, eget porta sapien quam eu mi. Nullam sollicitudin, nibh non suscipit commodo, nisi metus bibendum urna, vitae congue nisl risus eu tellus. Praesent diam ligula, hendrerit eget bibendum quis, convallis eu erat. Aliquam scelerisque turpis augue, sit amet dictum urna hendrerit id. Vestibulum luctus dolor quis ex sodales, nec aliquet lacus elementum. Mauris sollicitudin dictum augue eget posuere. Suspendisse diam elit, scelerisque eu quam vel, tempus sodales metus. Morbi et vehicula elit. In sit amet bibendum mi.</p>
</div>

<div id="content-4" style="display: none;">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam sodales eu urna sit amet fermentum. Morbi ornare, leo ut ornare volutpat, nibh diam mattis elit, eget porta sapien quam eu mi. Nullam sollicitudin, nibh non suscipit commodo, nisi metus bibendum urna, vitae congue nisl risus eu tellus. Praesent diam ligula, hendrerit eget bibendum quis, convallis eu erat. Aliquam scelerisque turpis augue, sit amet dictum urna hendrerit id. Vestibulum luctus dolor quis ex sodales, nec aliquet lacus elementum. Mauris sollicitudin dictum augue eget posuere. Suspendisse diam elit, scelerisque eu quam vel, tempus sodales metus. Morbi et vehicula elit. In sit amet bibendum mi.</p>
  <p>Aenean eu magna tempor, pellentesque arcu eget, mattis enim. Cras at volutpat mi. Aenean id placerat felis, quis imperdiet nunc. Aenean a iaculis est, quis lacinia nisl. Sed aliquet sem eget justo convallis congue. Quisque rhoncus nulla sit amet cursus maximus. Phasellus nec auctor urna. Nam mattis felis et diam finibus consectetur. Etiam finibus dignissim vestibulum. In eu urna mattis dui pharetra iaculis. Nam eleifend odio et massa imperdiet, et hendrerit mauris tempor. Quisque sapien lorem, dapibus ut ultricies ut, hendrerit in nulla. Nunc lobortis mi libero, nec tincidunt lacus pretium at. Aliquam erat volutpat.</p>
  <p>Fusce eleifend enim nec massa porttitor tempor a eget neque. Quisque vel augue ac urna posuere iaculis. Morbi pharetra augue ac interdum pulvinar. Duis vel posuere risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut vitae lectus non nisl iaculis volutpat nec vitae ante. Maecenas quis condimentum elit. Sed nisl urna, convallis ut pellentesque sit amet, pellentesque eget quam. Pellentesque ornare sapien ac scelerisque pretium. Pellentesque metus tortor, accumsan in vehicula iaculis, efficitur eget nisi. Donec tincidunt, felis vel viverra convallis, lectus lectus elementum magna, faucibus viverra risus nulla in dolor.</p>
  <p>Duis tristique sapien ut commodo laoreet. In vel sapien dui. Vestibulum non bibendum erat. Etiam iaculis vehicula accumsan. Phasellus finibus, elit et molestie luctus, massa arcu tempor nulla, id hendrerit metus mauris non mi. Morbi a ultricies magna. Proin condimentum suscipit urna eu maximus. Mauris condimentum massa ac egestas fermentum. Praesent faucibus a neque a molestie. Integer sed diam at eros accumsan convallis.</p>
</div>
Uranian answered 11/10, 2013 at 12:43 Comment(0)
C
2

I imagine setting float:left for the dialog will work. Presumably the dialog is absolutely positioned by the plugin, in which case its position will be determined by this, but the side-effect of float - making elements only as wide as they need to be to hold content - will still take effect.

This should work if you just put a rule like

.myDialog {float:left}

in your stylesheet, though you may need to set it using jQuery

Commensurable answered 16/2, 2010 at 0:29 Comment(0)
S
2

I had the same problem when I upgraded jquery UI to 1.8.1 without upgrading the corresponding theme. Only is needed to upgrade the theme too and "auto" works again.

Segregationist answered 3/5, 2010 at 12:13 Comment(0)
P
2

For some reason I kept having this full page width problem with IE7 so I made this hack:

var tag = $("<div></div>");
//IE7 workaround
var w;
if (navigator.appVersion.indexOf("MSIE 7.") != -1)
    w = 400;
else
    w = "auto";

tag.html('My message').dialog({
    width: w,
    maxWidth: 600,
    ...
Prismoid answered 30/3, 2012 at 20:55 Comment(0)
M
1

I had a similar problem.

Setting width to "auto" worked fine for me but when the dialog contained a lot of text it made it span the full width of the page, ignoring the maxWidth setting.

Setting maxWidth on create works fine though:

$( ".selector" ).dialog({
  width: "auto",
  // maxWidth: 660, // This won't work
  create: function( event, ui ) {
    // Set maxWidth
    $(this).css("maxWidth", "660px");
  }
});
Moncton answered 26/11, 2013 at 13:39 Comment(0)
G
1

I had this problem as well.

I got it working with this:

.ui-dialog{
    display:inline-block;
}
Giorgia answered 5/9, 2015 at 11:50 Comment(0)
Z
1

All you need to do is just to add:

width: '65%',
Zephan answered 5/11, 2017 at 23:42 Comment(1)
Based on OP's question, that would not work for all his dialog boxes, and he would still need to set each dialog box individually.Ruinous
L
0

I have the same problem and having position: absolute in your .ui-dialog{} css was not enough. I noticed that position: relative was being set on the actual element's direct style, so the .ui-dialog css definition was getting overwritten. Setting position: absolute on the div I was going to make a dialog statically also did not work.

In the end I changed two placed in my local jQuery to make this work.

I changed the following line in jQuery to be:

elem.style.position = "absolute";

at https://github.com/jquery/jquery/blob/1.8.0/src/offset.js#L62

Also, since my dialog was set to draggable, I had to change this line as well in jQuery-ui to be:

this.element[0].style.position = 'absolute';

at https://github.com/jquery/jquery-ui/blob/1-8-stable/ui/jquery.ui.draggable.js#L48

Perhaps going through the style I have more thoroughly would fix things, but thought I'd share how I got this working.

Latton answered 11/4, 2013 at 14:27 Comment(0)
T
0

If you need it to work in IE7, you can't use the undocumented, buggy, and unsupported {'width':'auto'} option. Instead, add the following to your .dialog():

'open': function(){ $(this).dialog('option', 'width', this.scrollWidth) }

Whether .scrollWidth includes the right-side padding depends on the browser (Firefox differs from Chrome), so you can either add a subjective "good enough" number of pixels to .scrollWidth, or replace it with your own width-calculation function.

You might want to include width: 0 among your .dialog() options, since this method will never decrease the width, only increase it.

Tested to work in IE7, IE8, IE9, IE10, IE11, Firefox 30, Chrome 35, and Opera 22.

Tail answered 25/6, 2014 at 23:7 Comment(0)
A
0

Adding to Vladimir Kornea's answer.

I wanted a way to set the width unless the screen was too small, then a dynamic width. Not truly "responsive" bit works well for most cases.

, 'open': function(){
   var resposive_width = ($( window ).width() > 640) ? 640 : ($( window ).width() - 20);
   $(this).dialog('option', 'width', resposive_width)
 }
Arjun answered 26/9, 2020 at 3:20 Comment(0)
J
-1

edit this bellow:

$("#message").dialog({
	autoOpen:false,
	modal:true,
	resizable: false,
	width:'80%',
Junk answered 6/5, 2019 at 7:45 Comment(1)
Please add some explanation to your code - why should one edit your answer?Austenite

© 2022 - 2024 — McMap. All rights reserved.