UPDATE: Check out my follow up post for SharePoint 2013 Modal Dialogs. In this post I'll be presenting some tips and tricks with regards to SharePoint 2010 modal dialogs. I hope these examples will save you some time by not having to reinvent the wheel and help keep your custom components' user experience consistent with the OOTB SharePoint 2010 experience.

DISCLAIMER: Some of the code below uses private functions/methods of the SP2010 API. They have been stable throughout the Service Packs and Cumulative Updates, but nothing is guaranteed. If you're working on stuff for SP2013, you'll also want to read this post as well.

Opening and Closing Modal Dialogs

Opening and closing SharePoint modal dialogs has been blogged to death already so here are a few resources for that:

The first thing that I wanted to point out is the SP.UI.ModalDialog.RefreshPage method. If dialog requires updating information on the parent page, which you may not have access to, you can use this method to force a page refresh if the dialog returns a success value. An example of this is when your dialog results in column values being updated on a SP list view.

function myShowDialog() {
  var options = {
    url: '[YOUR URL HERE]',
    dialogReturnValueCallback: myDialogCallback
  };

  SP.UI.ModalDialog.showModalDialog(options);
}

function myDialogCallback(dialogResult, data) {
  if (dialogResult = SP.UI.DialogResult.OK) {
    //DO YOUR DIALOG SUCCESS STUFF HERE
  }
  
  // this will refresh your page if dialogResult is successful
  SP.UI.ModalDialog.RefreshPage(dialogResult);
}

The second tip around opening a modal is that if you pass in a null value for the title property for any of the open methods, the modal dialog will use the title of the page that is loaded inside of it.

Loading Message & Wait Screen

I see a lot of custom solutions on SharePoint implement their own loading message and interface blockers even though SP2010 already provides this functionality through the SP.UI.ModalDialog client-side API.

showWaitScreenNoClose
showWaitScreenNoClose

SP.UI.ModalDialog.showWaitScreenWithNoClose is a method that allows you to show a loading message of your choice. You can specify the loading message's title, content, height and width. For example:

SP.UI.ModalDialog.showWaitScreenWithNoClose('Loading...',
  'Please wait while the content loads.', 60, 270);
Internal Loading Message
Internal Loading Message

But if you look carefully, you'll notice SharePoint's loading message has a different look!

Spot the differences? Why I need a maximize button on the former is beyond me.

You can display the latter message by calling the private SP.UI.ModalDialog.$2O() method. This gets you the above message and as an added bonus, the text displayed is localized to the user's settings.

You can also replicate the look with your own messsaging by calling another private method with a specific set of parameters. You can create your own wrapper function as such:

function myShowWaitScreenWithNoClose (title, message) {
  return SP.UI.ModalDialog.$1I_1(title, message, false, false, null, null, 270, '12px 12px 4px 6px', 0);
}

myShowWaitScreenWithNoClose('Your Title Here...', 'Your custom loading message.'); 

Displays:

myShowWaitScreen
myShowWaitScreen

Resizing Modal Dialogs

The modal dialog will automatically resize to its content's dimensions if you do not specify width and/or height parameters when opening the modal. However, the SP.UI.ModalDialog API does not provide a method to resize the modal. This is problematic when you have dynamic content or elements within your modal that cause the modal's page dimensions to change. The modal does not resize, and users are either forced to use the scroll bars to view the new content, or they are left with a bunch of white space where content has been removed.

Perhaps my Googling skills are not up to snuff, but I have yet to find a complete example for dynamically resizing a SharePoint 2010 modal. There are a few posts that correctly point to using the dialog object's autoSize() method, but then they fail to reposition the dialog or account for situations such as the resized dialog being larger then the browser view port.

Below is a version of the resize code we use in Collabware CLM. We traced the code found in SP.UI.Dialog.js, and this leverages all of the OOTB code that SharePoint uses for resizing the dialog on page load. I've changed some of the internal variable names from the OOTB names for readability purposes.

// wrapper which ensures SP.UI.Dialog.js is loaded before re-size fires.
// (if you need to trigger a re-size in your init scripts as the JS library is loaded asyncronously)
function resizeModalDialog() {  
  SP.SOD.executeOrDelayUntilScriptLoaded(_resizeModalDialog, 'sp.ui.dialog.js');
}

function _resizeModalDialog () {
  // get the top-most dialog 
  var dlg = SP.UI.ModalDialog.get_childDialog();

  if (dlg != null) {
    // dlg.$S_0 - is dialog maximized
    // dlg.get_$Z_0() - is dialog a modal
    if (!dlg.$S_0 && dlg.get_$Z_0()) {
      // resize the dialog
      dlg.autoSize();

      var xPos, yPos, //x & y co-ordinates to move modal to... 
          win = SP.UI.Dialog.get_$1(), // the very bottom browser window object
          xScroll = SP.UI.Dialog.$24(win), // browser x-scroll pos 
          yScroll = SP.UI.Dialog.$26(win); // browser y-scroll pos

          //SP.UI.Dialog.$1d(win) - get browser viewport width
          //SP.UI.Dialog.$1c(win) - get browser viewport height
          //dlg.$2_0 - modal's DOM element

      // caculate x-pos based on viewport and dialog width
      xPos = ((SP.UI.Dialog.$1d(win) - dlg.$2_0.offsetWidth) / 2) + xScroll;

      // if x-pos is out of view (content too wide), re-position to left edge + 10px
      if (xPos < xScroll + 10) { xPos = xScroll + 10; }

      // caculate y-pos based on viewport and dialog height
      yPos = ((SP.UI.Dialog.$1c(win) - dlg.$2_0.offsetHeight) / 2) + yScroll;
      
      // if x-pos is out of view (content too high), re-position to top edge + 10px
      if (yPos < yScroll + 10) { yPos = yScroll + 10; }

      // store dialog's new x-y co-ordinates
      dlg.$T_0 = xPos;
      dlg.$U_0 = yPos;

      // move dialog to x-y pos
      dlg.$m_0(dlg.$T_0, dlg.$U_0);

      // set dialog title bar text width
      //dlg.$H_0 - dialog title text SPAN
      //dlg.$6_0 - dialog title bar
      dlg.$H_0.style.width = Math.max(dlg.$6_0.offsetWidth - 64, 0) + 'px';

      // size down the dialog width/height if it's larger than browser viewport
      dlg.$2B_0();
    }
  }
}