Redimensione automaticamente a caixa de diálogo jQuery UI para a largura do conteúdo carregado pelo ajax

134

Estou com muita dificuldade para encontrar informações e exemplos específicos sobre isso. Eu tenho várias caixas de diálogo da interface do usuário do jQuery no meu aplicativo anexadas a divs carregadas com chamadas .ajax (). Todos eles usam a mesma chamada de configuração:

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

Eu só quero que a caixa de diálogo seja redimensionada para a largura do conteúdo que é carregado. No momento, a largura fica em 300px (o padrão) e recebo uma barra de rolagem horizontal.

Até onde eu sei, "autoResize" não é mais uma opção para caixas de diálogo, e nada acontece quando eu a especifique.

Estou tentando não escrever uma função separada para cada caixa de diálogo, por isso .dialog("option", "width", "500")não é realmente uma opção, pois cada caixa de diálogo terá uma largura diferente.

A especificação width: 'auto'das opções de diálogo apenas faz com que as caixas de diálogo ocupem 100% da largura da janela do navegador.

Quais são as minhas opções? Estou usando o jQuery 1.4.1 com jQuery UI 1.8rc1. Parece que isso deve ser algo realmente fácil.

Edição: Eu implementei uma solução alternativa kludgy para isso, mas ainda estou procurando uma solução melhor.

womp
fonte

Respostas:

250

Acabei de escrever um pequeno aplicativo de amostra usando o JQuery 1.4.1 e a interface do usuário 1.8rc1. Tudo o que fiz foi especificar o construtor como:

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

Sei que você disse que isso ocupa 100% da largura da janela do navegador, mas funciona bem aqui, testado em FF3.6, Chrome e IE8.

Não estou fazendo chamadas AJAX, apenas alterando manualmente o HTML da caixa de diálogo, mas acho que isso não causará nenhum problema. Alguma outra configuração de CSS pode estar nocauteando isso?

O único problema com isso é que ele torna a largura descentralizada, mas eu encontrei esse tíquete de suporte onde eles fornecem uma solução alternativa para colocar a dialog('open')instrução em um setTimeout para corrigir o problema.

Aqui está o conteúdo da minha tag head:

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

Fiz o download dos js e css da interface do usuário do Jquery em http://jquery-ui.googlecode.com/files/jquery-ui-1.8rc1.zip . e o corpo:

<div class='mydialog'></div>
<a href='#' id='one'>test1</a>
<a href='#' id='two'>test2</a>
<a href='#' id='three'>test3</a>
Fermin
fonte
Fermin - obrigado pelo seu exemplo e publicação. Acontece que realmente houve um problema com o CSS, embora ainda não esteja claro qual era o problema exato (certamente não era óbvio pelo Firebug). Movendo todas as divs do meu diálogo para o nível superior e usando o CSS 1.8.1 padrão (em vez de nossa versão temática), ele funciona muito bem. Gradualmente, voltarei a mudar nossa versão temática quando a versão 1.8.1 for lançada e encontrar a raiz do problema. Obrigado!
Womp
Sem problemas, feliz por poder ajudar. Eu já estive lá antes, é um caso de mover uma instrução css de cada vez .... divirta-se!
Fermin
2
IE7 parece estar quebrado embora
Alex
2
Se você usar o AJAX para carregar o conteúdo, setTimeout () poderá não fornecer uma solução confiável (por exemplo, se o servidor estiver lento e levar mais de 100 ms para carregar). Uma solução melhor seria usar a função de retorno de chamada do método .ajax () para acionar a abertura. Dessa forma, ele não será aberto até que o carregamento da página esteja completo.
Njbair 01/06
1
{'width':'auto'}não funciona no IE7 e não será corrigido porque a {'width':'auto'}opção não é suportada pela jQuery-UI de acordo com scott.gonzalez: "Os diálogos não suportam largura automática. Os documentos afirmam que a opção aceita apenas um número, que será usado para um tamanho de pixel. Consulte o tópico jquery-ui-dev para obter uma discussão sobre por que não suportamos largura automática. "
Vladimir Kornea
11

Tive o mesmo problema e, graças a você mencionando que o problema real estava relacionado ao CSS, encontrei o problema:

Tendo em position:relativevez de position:absoluteem sua .ui-dialogregra CSS faz com que o diálogo width:'auto'se comporte de maneira estranha.

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

Eu imagino definir float: esquerda para a caixa de diálogo funcionará. Presumivelmente, a caixa de diálogo é absolutamente posicionada pelo plug-in; nesse caso, sua posição será determinada por isso, mas o efeito colateral do float - tornando os elementos tão amplos quanto eles precisam para manter o conteúdo - ainda terá efeito.

Isso deve funcionar se você apenas colocar uma regra como

.myDialog {float:left}

na sua folha de estilo, embora seja necessário configurá-lo usando jQuery

wheresrhys
fonte
2

Eu tive o mesmo problema ao atualizar a interface do usuário do jquery para a 1.8.1 sem atualizar o tema correspondente. Apenas é necessário atualizar o tema também e "auto" funciona novamente.

Jesús Alonso
fonte
2

Por alguma razão, eu continuava tendo esse problema de largura de página completa com o IE7, então fiz esse 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,
    ...
Alex
fonte
2

Você pode evitar o problema de largura de 100% especificando uma largura máxima. A maxWidthopção não parece funcionar; então defina a max-widthpropriedade CSS no widget de diálogo.

Caso você também queira restringir a altura máxima, use a maxHeightopção Ele mostrará corretamente uma barra de rolagem quando necessário.

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

Eu tive um problema parecido.

Definir widtha "auto"fina trabalhou para mim, mas quando o diálogo continha uma grande quantidade de texto que ele fez abrangem toda a largura da página, ignorando a maxWidthconfiguração.

Definir maxWidthem createfina funciona embora:

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

Eu tive esse problema também.

Eu trabalhei com isso:

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

Tudo que você precisa fazer é apenas adicionar:

width: '65%',
taggartJ
fonte
Com base na pergunta do OP, isso não funcionaria para todas as suas caixas de diálogo e ele ainda precisaria definir cada caixa de diálogo individualmente.
Roelofs
0

Eu tenho o mesmo problema e posição: absoluto no seu .ui-dialog {} css não foi suficiente. Percebi essa posição: o relativo estava sendo definido no estilo direto do elemento real, portanto a definição de .ui-dialog css estava sendo substituída. Definir posição: absoluto na div que eu ia criar estaticamente também não funcionou.

No final, mudei duas colocadas no meu jQuery local para fazer isso funcionar.

Alterei a seguinte linha no jQuery para:

elem.style.position = "absolute";

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

Além disso, como meu diálogo estava definido como arrastável, eu tive que alterar essa linha também no jQuery-ui para ser:

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

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

Talvez seguir o estilo que eu tenho mais detalhadamente consertaria as coisas, mas pensei em compartilhar como consegui esse trabalho.

Scott
fonte
0

Se você precisar que ele funcione no IE7, não poderá usar a opção não documentada, com erros e sem suporte {'width':'auto'} . Em vez disso, adicione o seguinte ao seu .dialog():

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

A .scrollWidthinclusão do preenchimento do lado direito depende do navegador (o Firefox difere do Chrome); portanto, você pode adicionar um número subjetivo de pixels "bons o suficiente" .scrollWidthou substituí-lo por sua própria função de cálculo de largura.

Você pode incluir width: 0entre suas .dialog()opções, pois esse método nunca diminuirá a largura, apenas aumentará.

Testado para funcionar no IE7, IE8, IE9, IE10, IE11, Firefox 30, Chrome 35 e Opera 22.

Vladimir Kornea
fonte
-1

edite este abaixo:

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

Carl 256
fonte
3
Por favor, adicione algumas explicações ao seu código - por que alguém deve editar sua resposta?
Nico Haase