Cambiar automáticamente el tamaño del cuadro de diálogo jQuery UI al ancho del contenido cargado por ajax

134

Tengo muchos problemas para encontrar información específica y ejemplos sobre esto. Tengo una serie de diálogos de jQuery UI en mi aplicación adjuntos a divs que están cargados con llamadas .ajax (). Todos usan la misma llamada de configuración:

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

Solo quiero que el cuadro de diálogo cambie de tamaño al ancho del contenido que se carga. En este momento, el ancho solo permanece en 300px (el valor predeterminado) y obtengo una barra de desplazamiento horizontal.

Por lo que puedo decir, "autoResize" ya no es una opción para los cuadros de diálogo, y no sucede nada cuando lo especifico.

Estoy tratando de no escribir una función separada para cada cuadro de diálogo, por .dialog("option", "width", "500")lo que no es realmente una opción, ya que cada cuadro de diálogo tendrá un ancho diferente.

Especificar width: 'auto'las opciones de diálogo solo hace que los diálogos ocupen el 100% del ancho de la ventana del navegador.

¿Cuáles son mis opciones? Estoy usando jQuery 1.4.1 con jQuery UI 1.8rc1. Parece que esto debería ser algo que sea realmente fácil.

EDITAR: he implementado una solución alternativa para esto, pero todavía estoy buscando una mejor solución.

womp
fuente

Respuestas:

250

Acabo de escribir una pequeña aplicación de muestra usando JQuery 1.4.1 y UI 1.8rc1. Todo lo que hice fue especificar el constructor como:

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

Sé que dijiste que esto hace que ocupe el 100% del ancho de la ventana del navegador, pero funciona bien aquí, probado en FF3.6, Chrome e IE8.

No estoy haciendo llamadas AJAX, solo cambiando manualmente el HTML del cuadro de diálogo, pero no creo que eso cause ningún problema. ¿Podría alguna otra configuración de CSS estar eliminando esto?

El único problema con esto es que hace que el ancho esté descentrado, pero encontré este ticket de soporte donde proporcionan una solución alternativa para colocar la dialog('open')declaración en un setTimeout para solucionar el problema.

Aquí está el contenido de mi etiqueta de cabeza:

<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>

Descargué el js y el css para Jquery UI de http://jquery-ui.googlecode.com/files/jquery-ui-1.8rc1.zip . y el cuerpo:

<div class='mydialog'></div>
<a href='#' id='one'>test1</a>
<a href='#' id='two'>test2</a>
<a href='#' id='three'>test3</a>
Fermín
fuente
Fermín: gracias por tu ejemplo y publicación. Resulta que realmente fue un problema con el CSS, aunque todavía no está claro cuál era el problema exacto (de todos modos, no era obvio en Firebug). Al mover todos mis divs de diálogo al nivel superior y usar el CSS 1.8.1 predeterminado (en lugar de nuestra versión temática) funciona muy bien. Poco a poco moveré nuestra versión temática cuando la versión 1.8.1 caiga, y encontraré la raíz del problema. ¡Gracias!
womp
No hay problema, me alegro de poder ayudar. He estado allí antes, es un caso de mover 1 declaración CSS a la vez ... ¡disfruta!
Fermín
2
Sin embargo
Alex
2
Si usa AJAX para cargar el contenido, setTimeout () puede no proporcionar una solución confiable (por ejemplo, si el servidor fue lento y tardó más de 100 ms en cargarse). Una mejor solución sería utilizar la función de devolución de llamada del método .ajax () para activar la apertura. De esa manera no se abrirá hasta que se complete la carga de la página.
njbair
1
{'width':'auto'}no funciona en IE7 y no se solucionará porque jQuery-UI no admite la {'width':'auto'}opción de acuerdo con scott.gonzalez: "Los cuadros de diálogo no admiten el ancho automático. Los documentos indican que la opción solo acepta un número, que se utilizará para un tamaño de píxel. Vea el hilo jquery-ui-dev para una discusión sobre por qué no admitiremos el ancho automático ".
Vladimir Kornea
11

Tuve el mismo problema y gracias a que mencionaste que el problema real estaba relacionado con CSS, encontré el problema:

Tener en position:relativelugar de position:absoluteen su .ui-dialogregla CSS hace que el diálogo y se width:'auto'comporte de manera extraña.

.ui-dialog { position: absolute;}
Fortes
fuente
2

Me imagino que establecer flotante: izquierda para el diálogo funcionará. Presumiblemente, el cuadro de diálogo está absolutamente posicionado por el complemento, en cuyo caso su posición estará determinada por esto, pero el efecto secundario del flotador, que hace que los elementos solo sean tan amplios como sea necesario para contener el contenido, aún tendrá efecto.

Esto debería funcionar si solo pones una regla como

.myDialog {float:left}

en su hoja de estilo, aunque es posible que deba configurarlo usando jQuery

Wheresrhys
fuente
2

Tuve el mismo problema cuando actualicé jquery UI a 1.8.1 sin actualizar el tema correspondiente. Solo es necesario para actualizar el tema también y "auto" funciona nuevamente.

Jesús Alonso
fuente
2

Por alguna razón, seguía teniendo este problema de ancho de página completo con IE7, así que hice este truco:

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,
    ...
Alex
fuente
2

Puede evitar el problema del ancho del 100% especificando un ancho máximo. La maxWidthopción no parece funcionar; configura la max-widthpropiedad CSS en el widget de diálogo.

En caso de que también desee restringir la altura máxima, use la maxHeightopción Mostrará correctamente una barra de desplazamiento cuando sea necesario.

$(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>

Salman A
fuente
1

Tuve un problema similar.

Ajuste widtha "auto"bien trabajado para mí, pero cuando el diálogo contenía una gran cantidad de texto que lo hizo abarcan todo el ancho de la página, haciendo caso omiso de la maxWidthconfiguración.

Configuración maxWidthde createbien funciona sin embargo:

$( ".selector" ).dialog({
  width: "auto",
  // maxWidth: 660, // This won't work
  create: function( event, ui ) {
    // Set maxWidth
    $(this).css("maxWidth", "660px");
  }
});
tsi
fuente
1

Yo tuve este problema también.

Lo tengo trabajando con esto:

.ui-dialog{
    display:inline-block;
}
Ken Q
fuente
1

Todo lo que necesitas hacer es agregar:

width: '65%',
taggartJ
fuente
Según la pregunta de OP, eso no funcionaría para todos sus cuadros de diálogo, y todavía necesitaría configurar cada cuadro de diálogo individualmente.
Roelofs
0

Tengo el mismo problema y tener posición: absoluta en su .ui-dialog {} css no fue suficiente. Noté esa posición: relativa se estaba configurando en el estilo directo del elemento real, por lo que la definición .ui-dialog css se sobrescribía. Posición de configuración: absoluta en el div. Iba a hacer un diálogo estáticamente tampoco funcionó.

Al final cambié dos puestos en mi jQuery local para que esto funcione.

Cambié la siguiente línea en jQuery para que sea:

elem.style.position = "absolute";

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

Además, dado que mi cuadro de diálogo estaba configurado como arrastrable, tuve que cambiar esta línea también en jQuery-ui para ser:

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

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

Tal vez siguiendo el estilo que tengo más a fondo arreglaría las cosas, pero pensé en compartir cómo lo hice funcionar.

Scott
fuente
0

Si necesita que funcione en IE7, no puede usar la opción no documentada, con errores y sin soporte {'width':'auto'} . En su lugar, agregue lo siguiente a su .dialog():

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

Si .scrollWidthincluye el relleno del lado derecho depende del navegador (Firefox difiere de Chrome), por lo que puede agregar un número subjetivo "suficientemente bueno" de píxeles .scrollWidtho reemplazarlo con su propia función de cálculo de ancho.

Es posible que desee incluir width: 0entre sus .dialog()opciones, ya que este método nunca disminuirá el ancho, solo lo aumentará.

Probado para trabajar en IE7, IE8, IE9, IE10, IE11, Firefox 30, Chrome 35 y Opera 22.

Vladimir Kornea
fuente
-1

edite este siguiente:

$("#message").dialog({
	autoOpen:false,
	modal:true,
	resizable: false,
	width:'80%',

Carl 256
fuente
3
Agregue alguna explicación a su código. ¿Por qué debería uno editar su respuesta?
Nico Haase