Wednesday, April 6, 2011

How to remove JQuery Dialogs from the DOM

I have run into a situation where I need to manually remove old dialogs before creating new ones. In another thread, the following method was suggested:

$('.ui-dialog').empty().remove();

And I think this would work, but I do have other dialogs that I do not want to remove from the DOM, and I think this method would get rid of all of them. Inspecting the page with Firebug shows that once JQuery creates a dialog out of the html you provide, it gives it standard wrapper divs, all with the same classes. These are:

ui-dialog ui-widget ui-widget-content ui-corner-all  ui-draggable

So they're pretty generic, and it's hard to find a unique characteristic about the outer wrapper classes that need to go. I'm trying to find a way to only remove the dialogs that I want to remove, and leave the others. Any ideas?

From stackoverflow
  • Create an array on DOM ready and add references to the desired dialogs as you display them. Then, when you wish to remove them, pass the array to jQuery and call remove()

  • Why don't you add a custom class to dialogs that are closed. So when you close a dialog, call:

    thisDialog.addClass("olddialog");
    

    Then you can simply remove them all using:

    $(".olddialog").remove();
    
    BAHDev : I'm not sure what I would add a custom class to. Remember I need to remove the outer wrapper JQuery gives it (not any html I've written), and everything underneath. So if you're suggesting I add a class to the div I originally used to create the dialog, that would just add a class to the html underneath the wrapper. Then when I try to remove it, it would just remove what's underneath the wrapper. I need a way of selecting only the outer wrappers I want. Whether that means selecting them and adding a class or just selecting them and removing them, the problem is still the same. Thanks though.
    Philippe Leybaert : Then you can use has(): $(".ui-dialog:has(.olddialog)").remove();
  • The proper way is $('#yourdialog').dialog('destroy').remove(); presuming your dialog has a proper ID.

    BAHDev : @CalebD, thanks for this response, and I have tried it. But for whatever reason, this is not removing the dialogs that jQuery is creating. I assumed it had something to do with me trying to do a remove() on the original selector instead of on the outer wrappers that JQuery has assigned.
    CalebD : The .dialog('destroy') call should remove all of the wrappers and restore the element to its initial state and then .remove() kicks it out of the DOM. How are you creating the dialogs?
  • EDIT:

    From other comments you made ive gleaned you want to preserve the content but doesnt dialog.destroy just return it to pre-init state ie. minus dynamic outer markup?

    you could give them a unique 'dialogClass' when you create them and reference them that way or you could provide a callback that ads an id - or add the id before you dialog the element.

    Although, personally i only ever use one dialog per page/view and just reset the content as needed.

  • SELF-ANSWER:

    So based on Philippe's answer to my original question I took the following approach, which worked:

    When creating the dialog, usually you're creating it based on an ID, and once JQuery creates the dialog, that html (with the ID) is still underneath the wrappers. To make sure I was removing the correct dialog, I used JQuery's has, like this:

    $('.ui-dialog:has(#' + $myDialogDiv.attr('id') + ')').empty().remove();
    

    This first empties the wrapper's contents, then removes it from the DOM.

    Thanks to Philippe for the ideas.

  • I know this topic is old, but I recently ran into the same situation. For my case, I dynamically create dialogs and use .load(). jQuery really does wacky stuff with the DOM and was causing me significant troubles. There was unnecessary "crap" left in the DOM after closing, and sometimes, removing the dialog. I could not remove the "div" that it was inside of because I actually use the contents of the div to maintain some state information. I came up with the following code and tested it in a limited fashion to verify it worked. It does seem to remove all of the unnecessary baggage that jQuery was leaving behind. I even tested it opening several windows and monitored the state of the DOM during the process to ensure each dialogs' state was maintained correctly. I'll post the entire code here (with the exception of the loaded dialog which was nothing more than a div with some code in it.

        <html>
            <head>
                <link href="css/redmond/jquery-ui-1.8.1.custom.css" type="text/css" rel="stylesheet" media="screen" />
                <script src="js/jquery-1.4.2.min.js" type="text/javascript"></script>
                <script src="js/jquery-ui-1.8.1.custom.min.js" type="text/javascript"></script>
    
                <script type="text/javascript">
                    $(document).ready (function () {
                        $("#openDialog").click (function () {
                            $("<div></div>")
                                .load ("loadDialogTest.php")
                                .appendTo ($("#containingDiv"))
                                .dialog ({
                                autoOpen: 'false',
                                title: 'Test This!',
                                close: function () {
                                    $(this).dialog ('destroy').remove ();
                                }
                            }).dialog ('open');
                        });
                    });
                </script>
            </head>
    
            <body>
                <a href="#" id="openDialog">Open it</a>
    
                <div id="containingDiv">
                </div>
            </body>
    
        </html>
    

0 comments:

Post a Comment