5

I am using multiple jQuery UI dialog themes on a single page, and I have bug.

[jQuery 1.3.2] [jQuery UI 1.7.2]

Here is a screenshot (vs custom CSS scope):

Enter image description here

Alone on the page 1)

vs native 2)

How can I fix this?

6 Answers 6

12

I hit the same problem today. It seems that any dialog you create is taken out of its current hierarchy and placed at the end of the body element, which means that it isn't covered by a custom CSS scope.

The "dialogClass" option is of no help as well, since it sets the class of the dialog element, but you need the dialog to be a descendant of an element with your custom class.

One way to make it work is to set the custom class on the body tag. That, however, means that the whole document is affected and you cannot use different themes on one page anymore.

The way I ended up with is a little workaround to put the dialog element back into an element with your custom scope. Presuming that there's a div with class "myCustomScope" that contains everything the custom theme should apply to; and the div with id "myDialogContent" that should become the dialog:

// Create the dialog, but don't open it yet
var d = $('#myDialogContents').dialog({
    autoOpen: false
    // Other dialog options
});
// Take the whole dialog and put it back into the custom scope.
d.parent('.ui-dialog').appendTo('.myCustomScope');
// Open the dialog (if you want autoOpen).
d.dialog('open');
Sign up to request clarification or add additional context in comments.

Comments

4

You should 1) Wrap .ui-dialog element after creating of dialog. 2) Wrap .ui-widget-overlay element after opening of dialog. Since .ui-widget-overlay element is created/destroyed every time when dialog is opened/closed, you should also 3) Remove empty wraper of .ui-widget-overlay when dialog is closed (otherwise you will get many empty wrappers).

$(function() {
$("#dialog").dialog({
    position: "center",
    autoOpen: false,
    modal: true,
    create: function(event, ui){
        $('.ui-dialog').wrap('<div class="your-class" />');
    },
    open: function(event, ui){
        $('.ui-widget-overlay').wrap('<div class="your-class" />');
    },
    close: function(event, ui){
        $(".your-class").filter(function(){
            if ($(this).text() == "")
            {
                return true;
            }
            return false;
        }).remove();
        }
    });
});

Tested in JQuery UI 1.8.13.

1 Comment

This solution can be buggy when two or more dialogs open at the same time. Selectors need to be updated...
3

There are other jQuery UI elements that get taken out of the normal HTML flow, in addition to the dialogs. The autocomplete widget, for example.

I've found that something along these lines seems to do the trick:

$(window).load(function() {
 $('.ui-autocomplete').wrap('<div class="css_scope_selector" />');
});

Although doing this on window.load may not be ideal.

2 Comments

Thank you, soupenvy for your answer
Combining this and Andreas' answer got me where I needed to be. But this got the vote as $.wrap is better I thought :-)
1

The dialog widget is appended to the body by design. If you feel uncomfortable moving it someplace else in the DOM that is not going to be anticipated by the jQuery UI dev team, one solution might be to simply apply your scope to the dialog in the same way you apply it to other elements that use it, by simply wrapping it in a div tag with your theme's scope as the class:

$("#mydialog").dialog().parent(".ui-dialog").wrap("<div class='custom-theme-css-scope'></div>");

Comments

0
//Try this to fix problem
//note: jquery-ui-1.7.2

var dwrap = [false, false];
//0 - dialog1 flag(modal: true)
//1 - dialog2 flag(modal: false)

//?dialog1 = your dialog id
// example: mytest-dialog1
//?dialog2 = your dialog id
// example: mytest-dialog2

//?custom css scope = your custom css scope
// example: .my-dialog-themes

 function DialogTheme(dialog){
    switch (dialog){
     case 0 :
      if( !dwrap[0] ){ 
       $("div[aria-labelledby*='ui-dialog-title-?dialog1']").wrap("<div class='?custom css scope'></div>"); 
       dwrap[0] = true; 
      }
      //for overlay no good way but i dont see another
     $(".ui-widget-overlay").wrap("<div class='?custom css scope'></div>"); 
     break; 
     case 1 : 
      if( !dwrap[1] ){
       $("div[aria-labelledby*='ui-dialog-title-?dialog2']").wrap("<div class='?custom css scope'></div>"); 
       dwrap[1] = true; 
       }
     break; 
     default : 
     break; 
    }
 }

//Use:
//after open dialog call DialogTheme(0) for modal and DialogTheme(1) for none modal
//example:

 $("#?dialog1").dialog('open');
 DialogTheme(0);

//This way work correct on the page except overlay, 
//note you must have jquery-ui-1.7.2 other versions not tested
//It's all

Thankyou Andreas for your answer

Comments

0

Andrea's answer led me to this for iframes and modals with the overlay working. Had to set the width and height after opening and append the overlay to the scoped div as well.

var d = $("<iframe src=\"" + src + "\" id=\"upload_iframe\" />")
.dialog(
{
    title: "Import",
    autoOpen: false,
    width: 1000,
    height: 600,
    modal: true,
    resizable: false,
    draggable: false
});

var scope = $("<div>").addClass("jquery-ui-scope").appendTo("body");

d.parent(".ui-dialog").appendTo(scope);
d.dialog("open").width(990).height(590);
$(".ui-widget-overlay").appendTo(scope);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.