Tips & Tricks: SharePoint 2013 Modal Dialogs

In October I posted some tips and tricks with regards to SharePoint 2010 modal dialogs. Now I'm back with some updates for SharePoint 2013.The Dialog API has not changed much from SP2010 to SP2013. Opening, closing, callbacks, etc are the same as before and you can reference my previous post for all that stuff.

Loading Wait Screen and showWaitScreenWithNoClose

The signature for SP.UI.ModalDialog.showWaitScreenWithNoClose has not changed, but MS has updated the rendering for the UI. It no longer looks different than the default loader, so no more private API calls for us!

SharePoint 2013's default loading message.
SharePoint 2013's default loading message.

The default loading message has now changed to this:

You can bring this up by calling:



Calling the method with both title and message:

SP.UI.ModalDialog.showWaitScreenWithNoClose('Loading Title', 'Loading Message Here...');
Loading modal using SP.UI.ModalDialog.showWaitScreenNoClose()
Loading modal using SP.UI.ModalDialog.showWaitScreenNoClose()

Looks like:

Resizing Modal Dialogs

DISCLAIMER: Some of the code below uses private functions/methods of the SP2013 API. I can't guarantee that this will work throughout the life of SP2013 updates.

The internal variables and methods were updated in the 2013 version of SP.UI.ModalDialog. Logic remains the same and here's the updated code:

// 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.$Q_0 - is dialog maximized
    // dlg.get_$b_0() - is dialog a modal

    if (!dlg.$Q_0 && dlg.get_$b_0()) {
      // resize the dialog

      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.$1x(win), // browser x-scroll pos
          yScroll = SP.UI.Dialog.$20(win); // browser y-scroll pos

      //SP.UI.Dialog.$1P(win) - get browser viewport width         
      //SP.UI.Dialog.$1O(win) - get browser viewport height
      //dlg.$3_0 - modal's DOM element

      // calculate x-pos based on viewport and dialog width
      xPos = ((SP.UI.Dialog.$1P(win) - dlg.$3_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; }

      // calculate y-pos based on viewport and dialog height
      yPos = ((SP.UI.Dialog.$1O(win) - dlg.$3_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.$K_0 = xPos;
      dlg.$W_0 = yPos;

      // move dialog to x-y pos
      dlg.$p_0(dlg.$K_0, dlg.$W_0);

      // set dialog title bar text width

      // size down the dialog width/height if it's larger than browser viewport

2010 Experience and Version Detection

When you create a Site Collection in SharePoint 2013, you have the option of using the old 2010 experience. The SP.UI.Dialog.js file that is loaded on the page is different when in 2013 vs 2010 experience mode. Be aware that if you want to use a single artifact for your scripts, you'll need to have different code branches. You can check in JavaScript by referencing SP.OfficeVersion.majorVersion. It will return a string of either "15" when in 2013 mode or "14" in 2010 mode.

function _resizeModalDialog () {
  if (SP.OfficeVersion.majorVersion == "14") {
    // SP2010 code here...
  } else {
    // SP2013 code here...