Some situations require asynchronously loaded data. When this data is within a SP dialog, the dialog will have ugly scrollbars. You could try to guess at the size of the dialog ahead of time when you open it, but that would be what people call ‘lame’. What you need is to dynamically resize the dialog once the async load is complete.
Holy Crap: When I searched for this I found some long, half-baked solutions that had more holes than a Toyota pickup truck in the Middle East. Some examples: An MSDN forum post and Some Dude’s Blog – both long, and (sorry fellas) – kind of crappy.
Solution turned out to be kind of easy – here is the pattern:
JavaScript:
function AutosizeDialog(){
//resize dialog if we are in one
var dlg = SP.UI.ModalDialog.get_childDialog();
if (dlg != null) {
dlg.autoSize();
}
}
function LoadPageData(){
//PSEUDOCODE jquery ajax
$.ajax({
url: < web service providing the data >,
/* other ajax options */
async: true,
cache: false,
success: function (data) {
/* load data into element(s) */
AutosizeDialog();
},
error: function (err) {
/* be good and handle errors */
}
});
}
Explanation: The function “LoadPageData” is your function that loads data into your page dynamically. Maybe it loads it from a web service using SPServices, or jQuery ajax (exampled above). Maybe it is just via a client function generating HTML dynamically. Or maybe it’s something really cool I don’t even know about. Whatever the case may be, the important part is that after the HTML has been set, a call to the “AutosizeDialog” function is made. That is where the easy magic happens – all within SharePoint native client methods.
Important note: This is all WITHIN the dialog content. Some examples you see out there try to do resizing from the place where the dialog is created. Usually using some kind of whacked-out timer delay. Avoid this.
Pretty simple after all – no need for any extra junk.
Update #1
So it quickly became obvious that something else is needed after the dialog is resized: The window then should be repositioned so the dialog is nice and centered. Again – no need for any JavaScript craziness, and especially no need for long winded explanation – here is the updated version of AutoSizeDialog:
function AutosizeDialog() {
//resize dialog if we are in one
var dlg = typeof(SP.UI.ModalDialog.get_childDialog) == "function" ? SP.UI.ModalDialog.get_childDialog() : null;
if (dlg != null) {
dlg.autoSize();
var dlgWin = $(".ms-dlgContent", window.parent.document);
dlgWin.css({ top: ($(window.top).height() / 2 - dlgWin.height() / 2) + "px", left: $(window.top).width() / 2 - dlgWin.width() / 2 });
}
}
Just two lines to cover resizing – probably could even be reduced to one. Also added an extra check to for the SP.UI.ModalDialog load state.