Using the Dialog framework in SharePoint 2010

In chapter 4 of my SharePoint 2010 application development book I provided a brief introduction to the Dialog framework that’s been introduced in SharePoint 2010. Like many of the new client side user interface features, the dialog framework is a JavaScript library that makes it easier for us as developers to utilise standard functionality.

My introduction in chapter 4 is as follows:

Dialogs

Another addition in SharePoint 2010 is the Dialog framework. For the most part, this is encapsulated in the functionality exposed by the SP.UI.Dialog and SP.UI.ModalDialog classes. Although the notifications and status bar functionality is included in the SP.js file, the dialog framework code is included in the SP.UI.Dialog.js file. To get IntelliSense support in Visual Studio when writing JavaScript that targets the dialog framework, add the following reference element to the JavaScript file:

/// <reference path="C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions14TEMPLATELAYOUTSSP.UI.Dialog.debug.js" />

Showing a modal dialog is a relatively straightforward affair. First, we create a DialogOptions object, and then we call the showModalDialog method of the SP.UI.ModalDialog object, as this sample shows:

function ShowDialog_Click() {
var options = { url: 'http://www.chaholl.com',
title: 'My Dialog',
allowMaximize: false,
showClose: true,
width: 150,
height: 150,
dialogReturnValueCallback: SendNotification_Click    };
var did = SP.UI.ModalDialog.showModalDialog(options); }

In this sample, we’re redirecting to an Internet page for the sake of simplicity. In a real-world application, we’d create a custom page that implemented the required functionality. In Chapter 9, you’ll see examples of custom dialogs when we build settings pages for service applications.

The important thing to note about the DialogOptions object is the dialogReturnValueCallback property. This contains details of a callback method that will be called when the dialog is closed. In this callback, we can write code to pick up the dialog result and perform any necessary actions. In this simple example, we’ve generated a notification using our notification sample code.

While this provides a basic introduction to the dialog framework it skips a few broad strokes. This short post will take a look at the dialog framework in more detail and will hopefully fill in some of the gaps in the current MSDN documentation.

Creating a new dialog page

One of the first things we want to do when using the dialog framework is to create a new page that will form our dialog. As the short sample above shows, a dialog can be any web page. However, for the sake of consistency, we’ll create a dialog that uses the look and feel of other SharePoint 2010 dialogs.

Using Visual Studio 2010, create a new Empty SharePoint Project as shown.

image

Set the local site to whatever the url is for your SharePoint 2010 dev server and choose the Deploy as farm solution option.

Currently there is no SPI for creating dialog pages in Visual Studio. I intend to submit one to the CKSDev project in the near future so hopefully this will be resolved soon. In the meantime we can manually configure a dialog page using the Application Page SPI as shown. Add a new application page named MyTestDialog.aspx.

image

Visual Studio will automatically add a mapped folder for the %SPROOT%/Template/Layouts folder and will add our new application page in a folder named after our project. So far, so good!

In SharePoint 2010, all system generated dialogs are based on the dialog.master master page that can be found at %SPROOT%/Template/Layouts/Dialog.master. To ensure consistency with other dialogs we’ll use this master page as the basis for our test dialog.

In the MyTestDialog.aspx page, amend the Page tag as follows:

<%@ Page Language="C#"
    AutoEventWireup="true"
    CodeBehind="MyTestDialog.aspx.cs"
    Inherits="ModalDialogSample.Layouts.ModalDialogSample.MyTestDialog"
    MasterPageFile="~/_layouts/dialog.master" %>

What’s the difference between MasterPageFile and DynamicMasterPageFile?

Notice the use of the MasterPageFile attribute as opposed to the DynamicMasterPageFile attribute that was inserted by default as part of the application page template. The DynamicMasterPageFile attribute can only reference ~masterurl/default.master or ~masterurl/custom.master and provides a mechanism for SharePoint to dynamically alter the master pages that are applied to a page. Since we’re not using this functionality we must use the standard MasterPageFile attribute and a relative path to our dialog.master file.

Since we’ve changed the master page, the content tags present in the application page template will no longer tie up correctly to Placeholder tags in our dialog.master. Delete the default content tags and replace with the following markup:

<asp:Content ID="Content1"
ContentPlaceHolderID="PlaceHolderDialogHeaderPageTitle"
runat="server"> My Test Dialog Title </asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
  <SharePoint:CssRegistration ID="CssRegistration1" runat="server" Name="ows.css" />
  <SharePoint:ScriptLink ID="ScriptLink1" Language="javascript" Name="core.js" runat="server" />
  <SharePoint:FormDigest ID="FormDigest1" runat="server" />
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="PlaceHolderDialogImage" runat="server">
  <img src="/_layouts/images/allcontent32.png" alt="" />
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="PlaceHolderDialogBodyHeaderSection" runat="server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="PlaceHolderDialogDescription" runat="server">
  <div id="selectTermDescription" class="none-wordbreak">
    <table class="ms-dialogHeaderDescription">
      <tbody>
        <tr>
          <td>This is description text for a custom dialog</td>
        </tr>
      </tbody>
    </table>
  </div>
</asp:Content>
<asp:Content ID="Content8" ContentPlaceHolderID="PlaceHolderHelpLink" runat="server">
  <!-- Remove the default help link -->
</asp:Content>
<asp:Content ID="Content6" ContentPlaceHolderID="PlaceHolderDialogBodyMainSection"     runat="server">
  This is the body section of our test dialog
</asp:Content>

A closer look at Dialog.master will reveal that there are other placeholders that can be used and that there is considerable flexibility in how the finished page is constructed. This sample page shows how we can use a few of those placeholder to generate a dialog that fits in with the overall SharePoint 2010 look.

To see how this looks in the browser, deploy the project and then navigate to: http://your-server-url/_layouts/modaldialogsample/mytestdialog.aspx. If all is well, you’ll see something akin to this:

image

Showing our page as a modal dialog

Now that we’ve created a new dialog page the next step is to render it as a custom dialog. In a real world scenario we may show the dialog in response to a control click on a page or a button on the ribbon or maybe an edit action on a custom field control as is the case for Managed Metadata fields. For the sake of simplicity we’ll make use of a custom action to add a link to the ribbon on all document libraries. CKSDev provides an SPI to make the step easier, download it now via the Extension Manager in the Tools menu of Visual Studio 2010. Trust me, it’s worth it!

With CKSDev installed, add a new Custom Action named ShowDialogAction as shown.

image

Complete the Custom Action Settings wizard as shown in these screenshots:

image

image

image

To create a button that will appear in the ribbon, add the following xml within the CustomAction tag in the Elements.xml file in the ShowDialogAction folder.

<CommandUIExtension>
  <CommandUIDefinitions>
    <CommandUIDefinition Location="Ribbon.Templates._children">
      <GroupTemplate Id="ModalDialogSample.Templates.OneLargeControl">
        <Layout Title="Large">
          <Section Type="OneRow">
            <Row>
              <ControlRef TemplateAlias="c1" DisplayMode="Large" />
            </Row>
          </Section>
        </Layout>
      </GroupTemplate>
    </CommandUIDefinition>
    <CommandUIDefinition Location="Ribbon.Library.Scaling._children">
      <MaxSize Id="ModalDialogSample.DocumentLibraryTab.CustomGroup.MaxSize"
               Sequence="55" GroupId="ModalDialogSample.DocumentLibraryTab.CustomGroup" Size="Large" />
    </CommandUIDefinition>
    <CommandUIDefinition Location="Ribbon.Library.Groups._children">
      <Group Id="ModalDialogSample.DocumentLibraryTab.CustomGroup" Sequence="55" Description="A test custom group"
             Title="Test Group" Template="ModalDialogSample.Templates.OneLargeControl">
        <Controls Id="ModalDialogSample.DocumentLibraryTab.CustomGroup.Controls">
          <Button Id="ModalDialogSample.DocumentLibraryTab.CustomGroup.ShowDialog" Command="ModalDialogSample.ShowDialog"
                  Sequence="55" Image16by16="/_layouts/images/allcontent16.png" Image32by32="/_layouts/images/allcontent32.png"
                  Description="Show sample dialog" LabelText="Show Dialog" TemplateAlias="c1" />
        </Controls>
      </Group>
    </CommandUIDefinition>
  </CommandUIDefinitions>
  <CommandUIHandlers>
    <CommandUIHandler Command="ModalDialogSample.ShowDialog"
                      CommandAction="javascript:window.location='{SiteUrl}/_layouts/ModalDialogSample/MyTestDialog.aspx';" />
  </CommandUIHandlers>
</CommandUIExtension>

I won’t get into the details of how this Xml is used to create a button in the ribbon. Chris O’Brien has written up an excellent series of posts on how this all works that can be found here, also for those fortunate enough to have my SP2010 dev book, full coverage can be found in Chapter 3 Smile.

After deploying the project, all document libraries will now feature a new group in the Library tab  including a Show Dialog button that looks a bit like this:

image

Clicking on the button will redirect to our custom dialog although it this point it will appear as a standard page.

Show a page as a Modal Dialog

Now that we have a button that we can use to show our dialog, lets move on to look at how we can make our page appear as a dialog rather than as a standard page. Looking at the Element.xml file in the ShowDialogAction folder, we can see some javascript in the CommandUIHandler node. In effect, this javascript is executed when our button is clicked. We can see that, at the moment, it’s simply redirecting the browser to our dialog page.

Replace the CommandUIHandler for the ModalDialogSample.ShowDialog command with the following xml:

<CommandUIHandler    Command="ModalDialogSample.ShowDialog"
                     CommandAction="Javascript:
                     var options = {url: '{SiteUrl}/_layouts/ModalDialogSample/MyTestDialog.aspx',
                     allowMaximize: false,
                     showClose: true};
                     var did = SP.UI.ModalDialog.showModalDialog(options);" />

We can see that our revised JavaScript is making use of the showModalDialog method in the same way as shown in the example quoted from my book. The process for creating a dialog is: firstly,  create an object of type SP.UI.DialogOptions and then pass that object to the showModalDialog method of the SP.UI.ModalDialog object.

This is where the first documentation weakness comes in – search for SP.UI.DialogOptions in MSDN and all you’ll find are references to the type in various methods. There are no details on exactly what the available options are and what they do. Let’s tackle that here:

SP.UI.DialogOptions

Much of the JavaScript that implements the user interface functionality in SharePoint 2010 is built automatically using a tool known as Script#. This tool allows developers to write C# code and have it compiled into cross-platform Javascript. There are many benefits in this, not least in the fact that the development tooling for C# is light years ahead  of anything for JavaScript. However there is a drawback, although the generated JavaScript is readable, it’s not exactly easy to understand and so getting to the bottom of simple questions such as “what are the members on the SP.UI.DialogOptions class?”, are not as simple as they could be if Microsoft was to provide us with the assemblies that they used to generate the JavaScript. Anyhow, I’ve saved you the pain – here’s the list of members and their functions to the best of my knowledge:

Property Data type Default value Description
allowMaximise boolean (true/false) true Determines whether the maximise button is present on the rendered dialog.
args object We’ll examine this property in more detail later. The args property allows us to pass arbitrary properties into our dialog.
autoSize boolean (true/false) true Determines whether the dialog should be automatically sized to fit within the parent browser window. Where a value has been set for width or height, this value is deemed to be false regardless of the actual setting.
dialogReturnValueCallback function We’ll examine this property in more detail. By passing a function, we can specify a section of script to be executed when the dialog is closed.
height numeric The height of the dialog to be displayed. If this value is not set the dialog is automatically sized to fit the window.
html string Where a Url is passed, an IFRAME tag is rendered pointing to the appropriate Url. AS an alternative to this, it is possible to pass arbitrary HTML instead, in which case, rather than an IFRAME tag, the arbitrary HTML is rendered instead.
showClose boolean (true/false) true Determines whether the close button is visible in the titlebar of the dialog.
showMaximized boolean

(true/false)

false Dictates whether the rendered dialog should fill the available space in the parent window.
title string Specifies the title of the dialog. Where no title is specified, the title of the document referred to by the Url property is used instead.
url string null The url of the page to be shown in the dialog. Where a url is set and IFRAME tag will be rendered by the Dialog framework and the src of the IFRAME will be set to this url.
width numeric The width of the dialog to be displayed. If this value is not set the dialog is automatically sized to fit the window.
x numeric Specifies the starting position of the rendered dialog. If this value is not set the dialog is shown in the middle of the viewing area. This value represents the offset from the left edge of the parent browser window.
y numeric Specifies the starting position of the rendered dialog. If this value is not set the dialog is shown in the middle of the viewing area. This value represents the offset from the bottom of the parent browser window.

So we now have a button that will show our dialog correctly using the Dialog framework. Let’s be honest though, we haven’t really covered anything new here. The original code sample at the top of the page achieved the same result! Let’s move on to look at how we can pass some properties to this custom dialog.

Passing values to a dialog

As the list of properties for the SP.UI.DIalogOptions object indicates, we can use the args property to pass a user defined object that encapsulates any values that we need to pass. So to give an example, if we change our CommandUIHandler code as follows:

<CommandUIHandler Command="ModalDialogSample.ShowDialog"
                  CommandAction="Javascript:   var anObj={objProp1:'red', objProp2:'fish'};
                  var myArgs = {aProperty:'foo', anotherProperty:'bar', yetAnother:23, objProperty:anObj};
                  var options = {url: '{SiteUrl}/_layouts/ModalDialogSample/MyTestDialog.aspx',args:myArgs};
                  var did = SP.UI.ModalDialog.showModalDialog(options);" />

We can see in this code snippet that we can pass practically anything using the args property. The example here is pretty trivial – a dynamically generated object with some values – but we could pass a reference to a DOM object for example, if we wanted to create some kind of builder control. There are many possibilities here. This is another area where the documentation is a bit ropey. At the time of writing I couldn’t find any documentation to explain how to read the value of the args property from the dialog form. Let’s address that here with an example.

Reading values passed using the args property

Add the following script to the MyTestDialog.aspx page that we created earlier:

<script type="text/javascript">
  <!--
  if (typeof (_spBodyOnLoadCalled) == 'undefined' || _spBodyOnLoadCalled) {
  window.setTimeout(TestDialogSetup, 0);         }
  else {
  _spBodyOnLoadFunctionNames.push("TestDialogSetup");
  }
  function TestDialogSetup() {
  SP.SOD.executeFunc("sp.ui.dialog.js", null, showParameters);
  }
  function showParameters() {
  var theDiv = $("#MyBodyDiv");
  var args = SP.UI.ModalDialog.get_childDialog().get_args();
  var html;
  html = "<table><tr><td>Name</td><td>value</td></tr>";
  $.each(args, function (i, n) {
  html+="<tr><td>" + i + "</td><td>" + n + "</td></tr>";
  });
  html+="</table>";
  theDiv.html(html);
  }
  -->
</script>

As you can see, this script makes use of JQuery. Add the following link in the PlaceHolderAdditionalPageHead content control:

<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js" type="text/javascript"></script>

Note that this link makes use of the Microsoft Ajax Content Delivery Network. If you’re trying this on a machine with no internet connectivity you may need to download the JQuery library and reference it locally

Also, so that we can see the output of the script, add a Div in the PlaceHolderDialogBodyMainSection with the Id MyBodyDiv

With these changes in place we can now deploy the solution. This time, clicking on the button in the ribbon will show our dialog together with a table containing the properties that we passed to it.

One thing to note in the script above is the use of SP.SOD.executeFunc. Since SharePoint makes extensive use of JavaScript, a Script-On-Demand model exists, allowing scripts to be loaded as and when required as opposed to having everything loaded unnecessarily. The executeFunc method ensures that the referenced on-demand script is loaded before calling the referenced function. In effect, we’re ensuring that the SP.UI.ModalDialog namespace is available before attempting to call the get_childDialog method.

Receiving a response from a dialog

Now that we’ve seen how to send values to our custom dialog, the next logical step is to look at how the dialog can send back a response to our calling script. The clue here is again in the SP.UI.DialogOptions table. Notice the dialogReturnValueCallback property – this property allows us to specify a callback function. Once the dialog is closed, the callback function will be called with two parameters as we’ll see in the next code sample.

Amend the CommandUIHandler that you created earlier to include the following script:

CommandUIHandler  Command="ModalDialogSample.ShowDialog"
                   CommandAction="Javascript:
                   var anObj={objProp1:'red', objProp2:'fish'};
                   var myArgs = {aProperty:'foo', anotherProperty:'bar', yetAnother:23, objProperty:anObj};
                   var options = {url: '{SiteUrl}/_layouts/ModalDialogSample/MyTestDialog.aspx',
                   args:myArgs,
                   dialogReturnValueCallback:myDialogCallback};
                   var did = SP.UI.ModalDialog.showModalDialog(options);
                   function myDialogCallback(result,response)
                   {
                   switch(result)
                   {
                   case SP.UI.DialogResult.cancel:
                   //do nothing
                   break;
                   case SP.UI.DialogResult.invalid:
                   //do nothing
                   break;
                   case SP.UI.DialogResult.ok:
                   var note=SP.UI.Notify.addNotification(response.message);
                   break;
                   }
                   }
                   " />

As you can see, we’ve defined a new function, myDialogCallback that accepts a result and a response. Result is a numeric value that corresponds to the results defined in the SP.UI.DialogResult enumeration, whereas response is an object and can contain any values that we allocate in much the same way as we did earlier with the args property. Notice that the dialogResultCallback property of our SP.UI.DialogOption object has been set to a reference to our new function.

For the sake of simplicity, we’re using the Notifications framework to display a message passed to our callback from our modal dialog. The Notifications framework is covered in Chapter 4 of my book and a good run through can be found on Waldek Mastykarz site.

Hooking up the Ok and Cancel buttons

With our callback function in place, the next thing we need to do is add the functionality to our dialog to pass back values and dismiss the dialog at the appropriate time. Since we’ve used the out-of-the-box Dialog.master master page, we already have an Ok and Cancel button on the page. Since we want to add some custom functionality when the Ok button is clicked we need to hook it up to a custom script on our page. In the MyTestDialog.aspx.cs code-behind file, add the following code:

public partial class MyTestDialog : LayoutsPageBase {
    protected override void OnLoad(EventArgs e) {
        if (Master is DialogMaster)
        {
            DialogMaster dm = Master as DialogMaster;
            dm.OkButton.Attributes.Add("onclick", "return OkClicked();");
        }
        base.OnLoad(e);
    }
}

All we’re doing here is hooking up the OkClicked script to the onclick event of the Ok button that’s defined in the master page. With that in place, let’s add the script top the page. In MyTestDialog.aspx, add the following JavaScript after the showParameters function that you added earlier:

function OkClicked() {
    var results = {
        message: "A message from the dialog",
        anothervalue: "Something else"
    };
    SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.ok, results);
}

In this short script we’re creating a results object containing a few arbitrary values and then calling teh commonModalDialogClose method of the SP.UI.ModalDialog object. We’re passing the result of SP.UI.DialogResult.ok. As part of it’s internal processing, commonModalDialogClose will call our callback function if one is defined and will pass these two parameters into it.

If we new build and deploy the project we can see the finished dialog. This time when we click on the Ok button, the dialog will be closed and a notification will appear on the screen containing the message text stored in our results object. Clicking the Cancel button will close the dialog and no message will appear.

image

Conclusion

The dialog framework is a useful tool and is used extensively throughout the SharePoint 2010 user interface. For developers building applications on the SharePoint platform, having the ability to easily leverage this functionality with a few lines of code saves much work and given what a lazy lot we all are, it also means that we’re more likely to design user interfaces that are consistent with the out-of-the-box user experience. This post covers the key functionality of the dialog framework, however one area that hasn’t been addressed is using an HTML DOM element as the dialog rather than a separate page. I’ll leave that for somebody else to document although it’s worthwhile pointing out that in the interests of separating concerns and ensuring maintainable code, unless there’s a really good reason to pass a DOM element rather than redirect to a new page (I can’t think of one at the moment!), I’d suggest that the approach documented above is the way to go.

Hope this save some time investigating and wading through .js files! As always comments/criticisms/complaints and corrections are welcome.

Update 17 Nov 2010: Before anybody asks (especially that lazy lot that can’t be bothered cutting and pasting this into a project!), I’ve uploaded the source for this sample to Skydrive

Update 12 May 2011: Bil Simser mentioned that when creating a dialog page that uses code-behind to handle the OkButton click, executing JavaScript as described in this example won’t work.

Thankfully the good folks as Microsoft have provided an answer to this problem – if your dialog is based on the microsoft.sharepoint.webcontrols.layoutspagebase class, there’s a handy method: SendResponseForPopUI that’ll do the deed for you. Thanks for pointing that out Bil!

This entry was posted in Dialog Framework, HowTo, SharePoint 2010. Bookmark the permalink.
  • Andrew G

    here is an error in parameters list for modal dialog. You should change "аllowMaximise" parameter name to "аllowMaximize".

  • http://silvaware.net/ Thiago Silva

    I am using the OpenPopUpPage() function which internally uses the ShowModalDialog(url), with options left as default. I want the dialog to be centered on the window, but it shows up at the top, so I am scrolled down the bottom, and popup, then I have to scroll to top to view the dialog. Is there something I can do to fix that? I was under the impression that if I didn’t set the X/Y options, it would auto center.

  • Ingmar

    The type of the SP.UI.DialogOptions-Property "html" is not "string" – inside of the SP-Js there is a method which checks the nodetype of the passed property (1, if it is a dom-element – a string does not have a nodeType-Property…) – so it should be a dom-element…

  • FDSAFDSAFD
  • http://www.darkpropaganda.com/ Jason

    I am trying to figure out if I can use args to pass a query string value to a dialog box. For example I have a webpart page setup with a links list and a discussion board. As users click an item in the links list the discussion board is filtered so comments about a link can be viewed and added. When my users click on Add new discussion a dialog box opens and they can enter their comments, I would like auto populate a column based off which link item was selected, still looking for an example if this is possible.

  • Tim

    Very neat, but what if I want to call the dialog as a result of listbox event in a web part that also does stuff in the code behind?

  • pranit

    how can i have a blank title for modal dialog?

  • http://sharepoint-tutorial.net/ SharePoint Tutorial

    Fantastic post, thanks a lot…

  • athula

    Hi,
    I used thse function ShowDialog_Click() for pop up.But the pop up is displaying on the top of the page.I want it in the center of window.I tried setting y attribte for this ,but it didnt worked.How can i do this?
    Thanks

  • http://profiles.google.com/ofergal Ofer Gal

    What is the easiest way to take the javascript return values of the dialog and put them into ASP server controls?
    My dialogs need to return values to a user control that will need to save the return values.
    Thanks!

    • chaholl

      Probably the easiest thing to do is store the return value in a hidden text field and pick it up in the server side code

      • http://profiles.google.com/ofergal Ofer Gal

        Do you have a sample? I am not sure how you identify a asp:textbox from javascript. I thought the html name is dynamicly creted on render.

  • http://profiles.google.com/ofergal Ofer Gal

    Here is another problem.
    When firing from a control within a repeater, the rsults always comes back to the last control in the repeater.
    It should come back to the control that sent it.
    Any idea how to do that?

    • chaholl

      What kinda control is it? If it’s a custom control, implementing the INamingContainer should resolve the problem. How are you triggering the postback?

  • Battula Praveen
  • Michael

    When we call a Dialog from a Silverlight application and close the Dialog the Silverlight application is reloaded. We have tried many things to avoid this peculiar behavior, but haven’t yet managed to find a solution to this problem. Any hints?Michael

    • chaholl

      How are you closing the dialog? DO you have a JavaScript handler for the close event on your SilverLight page? Is it being fired?

      • Michael

        Yes, we have tried to use dialogReturnValueCallback, but it didn’t help. We have also asked the MS Partner support and they were able to reproduce the problem and recommended us to use the java method window.focus(), but it didn’t solve the problem.

        • Michael

          Appending this “&IsDlg=1″ to the URL solved the problem.

          Thank you very much for your help.
          Michael

  • Rebecca Gordon

    Thanks so much! This was brilliant, worked first go. Now I can use this knowledge to build up my own custom dialogs.

  • Jag

    Thank you very very much for this article. It gave me the perfect start :-)

  • juswadski

    Thanks very much for taking the time to put this up. This really helped me get a quick understanding and how and context! Appreciated.

  • Nick Umbs

    Hi, Any chance you’ll get the screenshot images back up? I’m trying to complete the Custom Action wizard. Thanks!

  • Faiz Rehman

    Hello, 

    Firstly, thank you very much for this post, it has been helpful in getting a better understanding on this concept of dialogue framework. Secondly, for some reason the images are not visible…?

    Thanks,

  • Pingback: Tips & Tricks: SharePoint 2010 Modal Dialogs « Collabware Blog