139

When an ajax operation fails, I create a new div with the errors and then show it as a dialog. When the dialog is closed I would like to completely destroy and remove the div again. How can I do this? My code looks something like this at the moment:

$('<div>We failed</div>')
    .dialog(
    {
        title: 'Error',
        close: function(event, ui)
        {
            $(this).destroy().remove();
        }
    });

When I run this the dialog box shows up correctly, but when I close it the dialog is still visible in the html (using FireBug). What am I missing here? Something I have forgotten?

Update: Just noticed my code gives me an error in the firebug console.

$(this).destroy is not a function

Anyone able to help me out?

Update: If I do just $(this).remove() instead, the item is removed from the html. But is it completely removed from the DOM? Or do I somehow need to call that destroy function first as well?

Liam
  • 27,717
  • 28
  • 128
  • 190
Svish
  • 152,914
  • 173
  • 462
  • 620

7 Answers7

272
$(this).dialog('destroy').remove()

This will destroy the dialog and then remove the div that was "hosting" the dialog completely from the DOM

lomaxx
  • 113,627
  • 57
  • 144
  • 179
  • Note that `.destroy` removes the outer markup added by UI framework (titlebar, closebutton, resizebar etc). Perhaps this is what you meant by _host_. – Salman A May 06 '13 at 09:14
  • 3
    becareful using this with FF and with Firebug opened. It will crash. https://code.google.com/p/fbug/issues/detail?id=6290 I spent hours... to figure what wrong with my code. – Hendry H. May 16 '13 at 07:20
  • 5
    If you are using a div from the DOM, so not dynamically created, use `.empty()`. Then you can reuse it, if you fill the contents again offcourse. – KoalaBear Jul 15 '13 at 21:14
  • I have used $(this).dialog('destroy') because I dont want to remove the entire div (I need it again for reloading) . This cleasr the dom of chrome but does not work for firefox.Here is my code close: function(event, ui) { $(this).dialog('destroy'); } – Chetan Jul 18 '13 at 14:07
  • 2
    @HendryH., that no longer seems to be a problem with Firefox 23.0 and Firebug 1.11.4. – cjm Aug 19 '13 at 15:17
  • do you have a JSFiddle ? – Francisco Corrales Morales Jan 19 '14 at 17:05
  • 2
    Is `destroy` necessary? Won't removing the element also destroy the dialog? – Druska Aug 13 '14 at 21:07
  • 3
    See: http://stackoverflow.com/questions/9124389/jquery-ui-how-to-remove-dynamic-element-after-dialog-closes – new name Dec 11 '14 at 23:40
  • 1
    While this does work, it is horribly inefficient. the destroy method will attempt to [preserve the content of the dialog.](https://api.jqueryui.com/dialog/#method-destroy) If you have a complicated dialog with lots of bindings on elements that were inside it, it can actually take *a few seconds* to destroy and remove the dialog. The solution is to run: `$(this).empty();` *immediately before* destroying the dialog and then removing the div. This reduces the time you would potentially have to wait to *zero*. – Skeets Oct 05 '16 at 08:43
11

Why do you want to remove it?

If it is to prevent multiple instances being created, then just use the following approach...

$('#myDialog') 
    .dialog( 
    { 
        title: 'Error', 
        close: function(event, ui) 
        { 
            $(this).dialog('close');
        } 
    }); 

And when the error occurs, you would do...

$('#myDialog').html("Ooops.");
$('#myDialog').dialog('open');
Igor
  • 33,276
  • 14
  • 79
  • 112
Fiona - myaccessible.website
  • 14,481
  • 16
  • 82
  • 117
  • I just thought it would be easier, since it will contain different content depending on what I get back from an ajax call. And also the div isn't static like I showed in my example but rendered by the http://github.com/nje/jquery-tmpl plugin. If you have a good way of swapping out the contents of the dialog I would be interested in seeing that though :) – Svish May 19 '10 at 11:19
  • Well, in my example, I went with the extremely simple option of just dumping a string withing the dialog div: $('#myDialog').html("Ooops."); You could modify this to change the content of any sub-controls in the dialog div as well. – Fiona - myaccessible.website May 19 '10 at 12:13
  • This is not a great approach as all dialogOptions will remain on the #myDialog unless you override them specifically. The second dialog should not (always) have the same buttons, height, etc.. as the first one. – Michiel Cornille May 18 '16 at 14:12
8
$(dialogElement).empty();

$(dialogElement).remove();

this fixes it for real

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
Ghost1
  • 320
  • 3
  • 5
5

This is worked for me

$('<div>We failed</div>')
    .dialog(
    {
        title: 'Error',
        close: function(event, ui)
        {
            $(this).dialog("close");
            $(this).remove();
        }
    });

Cheers!

PS: I had a somewhat similar problem and the above approach solved it.

DMv2
  • 198
  • 1
  • 12
  • 3
    You're calling the close method from within the close callback! jQuery UI is smart enough to prevent the infinite loop that is suggested by this, but it's still redundant, and I definitely wouldn't consider it elegant. – Elezar Aug 04 '16 at 03:42
  • At the time of writing the answer, without the `$(this).dialog("close");`, the dialog simply wouldn`t go away. jQuery at times is very weird. – DMv2 Aug 26 '16 at 08:26
2

An ugly solution that works like a charm for me:

$("#mydialog").dialog(
    open: function(){
        $('div.ui-widget-overlay').hide();
        $("div.ui-dialog").not(':first').remove();
}
});
cesar
  • 45
  • 3
1

You can do use

$(dialogElement).empty();    
$(dialogElement).remove();
Mike Szyndel
  • 10,461
  • 10
  • 47
  • 63
0

I use this function in all my js projects

You call it: hideAndResetModals("#IdModalDialog")

You define if:

function hideAndResetModals(modalID)
{
    $(modalID).modal('hide');
    clearValidation(modalID); //You implement it if you need it. If not, you can remote this line
    $(modalID).on('hidden.bs.modal', function () 
    {
        $(modalID).find('form').trigger('reset');  
    });
}
Sterling Diaz
  • 3,789
  • 2
  • 31
  • 35