Automatycznie zmień rozmiar okna dialogowego interfejsu użytkownika jQuery do szerokości treści ładowanej przez ajax

134

Mam duże problemy ze znalezieniem konkretnych informacji i przykładów na ten temat. Mam wiele okien dialogowych interfejsu użytkownika jQuery w mojej aplikacji dołączonych do elementów div, które są ładowane przez wywołania .ajax (). Wszyscy używają tego samego wywołania konfiguracyjnego:

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

Chcę tylko, aby okno dialogowe zmieniło rozmiar do szerokości ładowanej treści. W tej chwili szerokość pozostaje na poziomie 300 pikseli (wartość domyślna) i otrzymuję poziomy pasek przewijania.

O ile wiem, „autoResize” nie jest już opcją w oknach dialogowych i nic się nie dzieje, gdy ją określę.

Staram się nie pisać osobnej funkcji dla każdego okna dialogowego, więc tak .dialog("option", "width", "500")naprawdę nie jest to opcja, ponieważ każde okno dialogowe będzie miało inną szerokość.

Określenie width: 'auto'opcji dialogowych powoduje, że zajmują one 100% szerokości okna przeglądarki.

Jakie mam możliwości? Używam jQuery 1.4.1 z interfejsem jQuery UI 1.8rc1. Wygląda na to, że to powinno być naprawdę łatwe.

EDYCJA: zaimplementowałem niezdarne obejście tego problemu, ale wciąż szukam lepszego rozwiązania.

womp
źródło

Odpowiedzi:

250

Właśnie napisałem małą przykładową aplikację przy użyciu JQuery 1.4.1 i UI 1.8rc1. Wszystko, co zrobiłem, to wskazanie konstruktora jako:

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

Wiem, że powiedziałeś, że zajmuje to 100% szerokości okna przeglądarki, ale tutaj działa świetnie, testowane w FF3.6, Chrome i IE8.

Nie wykonuję wywołań AJAX, po prostu ręcznie zmieniam kod HTML okna, ale nie sądzę, że spowoduje to jakiekolwiek problemy. Czy inne ustawienie CSS może to znokautować?

Jedynym problemem jest to, że sprawia, że ​​szerokość jest poza środkiem, ale znalazłem ten bilet pomocy technicznej, w którym dostarczają obejście polegające na umieszczeniu dialog('open')instrukcji w setTimeout, aby naprawić problem.

Oto zawartość tagu mojej głowy:

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

Pobrałem js i css dla interfejsu użytkownika Jquery ze strony http://jquery-ui.googlecode.com/files/jquery-ui-1.8rc1.zip . i ciało:

<div class='mydialog'></div>
<a href='#' id='one'>test1</a>
<a href='#' id='two'>test2</a>
<a href='#' id='three'>test3</a>
Fermin
źródło
Fermin - dzięki za przykład i post. Okazuje się, że to naprawdę był problem z CSS, chociaż nadal nie jest jasne, na czym dokładnie polegał (z pewnością nie było to oczywiste ze strony Firebuga). Przenosząc wszystkie elementy div w oknie dialogowym na najwyższy poziom i używając domyślnego CSS 1.8.1 (zamiast naszej wersji tematycznej), działa świetnie. Stopniowo przeniosę naszą wersję tematyczną z powrotem do wersji 1.8.1 i znajdę źródło problemu. Dzięki!
womp
Nie ma problemu, cieszę się, że mogłem pomóc. Byłem tam wcześniej, chodzi o przenoszenie 1 instrukcji CSS na raz ... baw się dobrze!
Fermin
2
Wygląda na to, że IE7 jest zepsuty
Alex
2
Jeśli używasz AJAX do ładowania treści, setTimeout () może nie zapewniać niezawodnego rozwiązania (na przykład, jeśli serwer był powolny i ładowanie trwało dłużej niż 100 ms). Lepszym rozwiązaniem byłoby użycie funkcji wywołania zwrotnego metody .ajax () do wywołania otwarcia. W ten sposób nie otworzy się do momentu zakończenia ładowania strony.
njbair
1
{'width':'auto'}nie działa w IE7 i nie zostanie naprawione, ponieważ {'width':'auto'}opcja nie jest obsługiwana przez jQuery-UI według scott.gonzalez: "Okna dialogowe nie obsługują automatycznej szerokości. Dokumenty stwierdzają, że opcja akceptuje tylko liczbę, która będzie używana dla rozmiaru w pikselach. W wątku jquery-ui-dev znajdziesz dyskusję o tym, dlaczego nie obsługujemy automatycznej szerokości ”.
Vladimir Kornea,
11

Miałem ten sam problem i dzięki wspomnieniu, że prawdziwy problem był związany z CSS, znalazłem problem:

Mając position:relativezamiast position:absolutew swojej .ui-dialogregule CSS sprawia, że dialog i width:'auto'dziwnie zachowywać.

.ui-dialog { position: absolute;}
Fortes
źródło
2

Wyobrażam sobie, że ustawienie float: pozostawione dla okna dialogowego zadziała. Przypuszczalnie okno dialogowe jest pozycjonowane absolutnie przez wtyczkę, w którym to przypadku jego pozycja zostanie określona przez to, ale efekt uboczny pływaka - tworzenie elementów tak szerokich, jak muszą być do przechowywania treści - będzie nadal obowiązywał.

To powinno zadziałać, jeśli po prostu ustawisz taką regułę, jak

.myDialog {float:left}

w swoim arkuszu stylów, chociaż może być konieczne ustawienie go za pomocą jQuery

wheresrhys
źródło
2

Miałem ten sam problem, gdy zaktualizowałem interfejs jquery do 1.8.1 bez aktualizacji odpowiedniego motywu. Potrzebne jest tylko do uaktualnienia motywu i "auto" znowu działa.

Jesús Alonso
źródło
2

Z jakiegoś powodu ciągle mam ten problem z pełną szerokością strony w IE7, więc zrobiłem ten 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
źródło
2

Możesz uniknąć problemu ze 100% szerokością, określając maksymalną szerokość. Ta maxWidthopcja wydaje się nie działać; więc max-widthzamiast tego ustaw właściwość CSS w widżecie okna dialogowego.

Jeśli chcesz również ograniczyć maksymalną wysokość, użyj maxHeightopcji. W razie potrzeby poprawnie wyświetli pasek przewijania.

$(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
źródło
1

Miałem podobny problem.

Ustawianie widthsię "auto"działało w porządku dla mnie, ale gdy okno zawierały dużo tekstu to sprawiło, że obejmują całą szerokość strony, ignorując maxWidthustawienie.

Ustawienie maxWidthna createdziała jednak dobrze:

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

Ja też miałem ten problem.

Mam to działające z tym:

.ui-dialog{
    display:inline-block;
}
Ken Q
źródło
1

Wystarczy, że dodasz:

width: '65%',
taggartJ
źródło
Opierając się na pytaniu OP, to nie zadziałałoby dla wszystkich jego okien dialogowych i nadal musiałby ustawiać każde okno dialogowe indywidualnie.
dachy
0

Mam ten sam problem i pozycja: absolutna w twoim .ui-dialog {} css nie wystarczyła. Zauważyłem, że pozycja: względna jest ustawiana na bezpośrednim stylu elementu, więc definicja css .ui-dialog była nadpisywana. Pozycja ustawienia: absolutna na div zamierzałem zrobić dialog statyczny również nie działała.

W końcu zmieniłem dwa umieszczone w moim lokalnym jQuery, aby to działało.

Zmieniłem następujący wiersz w jQuery na:

elem.style.position = "absolute";

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

Ponadto, ponieważ moje okno dialogowe było ustawione na przeciąganie, musiałem również zmienić tę linię w jQuery-ui na:

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

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

Być może dokładniejsze przejrzenie stylu, który mam, naprawiłoby rzeczy, ale pomyślałem, że podzielę się tym, jak to działa.

Scott
źródło
0

Jeśli chcesz, aby działał w IE7, nie możesz użyć opcji nieudokumentowanej, błędnej i nieobsługiwanej {'width':'auto'} . Zamiast tego dodaj do swojego .dialog():

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

To, czy .scrollWidthzawiera wypełnienie po prawej stronie, zależy od przeglądarki (Firefox różni się od Chrome), więc możesz dodać subiektywną „wystarczająco dobrą” liczbę pikseli do .scrollWidthlub zastąpić ją własną funkcją obliczania szerokości.

Możesz chcieć uwzględnić width: 0wśród swoich .dialog()opcji, ponieważ ta metoda nigdy nie zmniejszy szerokości, a jedynie ją zwiększy.

Przetestowano do pracy w IE7, IE8, IE9, IE10, IE11, Firefox 30, Chrome 35 i Opera 22.

Vladimir Kornea
źródło
-1

edytuj poniżej:

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

Karol 256
źródło
3
Dodaj wyjaśnienie do swojego kodu - po co edytować odpowiedź?
Nico Haase