JQuery Dialog: How to do partial page refresh and get new dialogs each time

BAHDev picture BAHDev · Jan 19, 2010 · Viewed 9.1k times · Source

I'm having a workflow issue with my JQuery dialogs when trying to create the dialogs and then doing a partial page render. I'll try to go through a sample scenario, and my apologies in advance for the long problem description:

The page loads, with the html that I would like to be turned into JQuery dialogs. The dialogs are created on document.ready (using .dialog()), but the autoOpen property is set to false. When JQuery creates the dialogs (if I'm using Firebug to inspect the page), the dialog html is actually stripped from its normal location and stuck at the very end of the document, with some wrapper classes around it. The user opens the dialogs by clicking a link that just does a $dialogDiv.dialog('open').

So that all works fine. The problem is that there are times when I am doing a partial page reload using AJAX (using ASP.NET MVC RenderPartial). The part of the page I'm refreshing happens to have all of the dialog html in it, so that gets re-written out. But remember the dialog (with all of the JQuery wrapper classes, etc) is already there a the bottom of the document. That html wasn't part of the page refresh, so now I'm stuck with two sets of dialog html. This is giving me all sorts of problems because I have duplicate id's on the page, and the jQuery behavior on these html elements becomes unpredictable. It's even worse when I start doing 3, 4, 5 partial page refreshes, because then I have 3, 4, 5 sets of dialog html (with only one real dialog having been made on document.ready).

I'm thinking that I might need to destroy the dialogs or something at some point, but I haven't had any luck with this approach. Does anyone have any ideas?

Thanks very much.

Answer

czarchaic picture czarchaic · Jan 19, 2010

According to the docs destroying a dialog removes dialog functionality and restores it to it's pre-init state but does not remove it from the DOM.

Since you are replacing the content and the dialog you could just remove the old ones.

$.ajax({
  url: '/some/url/',
  success:function(data){
    $('.ui-dialog').empty().remove();
    //add the new html and make the dialogs
  }
});

In response to you comment

I haven't seen you code, so I'm not exactly sure how you're settings up the dialogs, but in a general sense I would populate a variable with only the dialogs that will be replaced.

//inside document.ready
  var myDialog=$('#myDialog').dialog(),
  myOtherDialog=$('#myOtherDialog').dialog(),
  permanentDialog=$('#permanentDialog').dialog(),
  destroyableDialogs=[myDialog, myOtherDialog];

//ajax callback
success: function(data){
  $.each(destroyableDialogs, function(i,n){
    n.empty().remove();
  });
}