Open a SharePoint Modal Dialog from an InfoPath Form: Part 2 of 5 (Vivek Soni)

We are developing an example application in five steps.  We completed step one in Part 1. Today we move on to step two.

Here is the roadmap for the entire development process:

  1. Create a Search Application Page.   In this step, we design the user interface for the page that the modal dialog displays, and we write code to perform the search.
  2. Add JavaScript for the Modal Dialog. In this step, we create a JavaScript file with code to open the search application page in a popup modal dialog. The function that opens the modal dialog specifies a callback function that returns information about the document that the user has selected to the page that opened the dialog.
  3. Design the InfoPath Form. In this step, we create a form template that includes a Search button, and we write form code that notifies the form's host when a user clicks the button.
  4. Create a Web Part to Host the Form. In this step, we write a custom Web Part that uses an XMLFormView control to host the InfoPath form.
  5. Connect the Components. In this step, we bolt everything together. We write Web Part code that handles the NotifyHost event, code that invokes the modal dialog, and code that uses the dialog result to update the InfoPath form.

We cover each step in a separate post.

Step 2: Add JavaScript for the Modal Dialog

In Step 1, we created an application page that allows a user to search for and select a document. The development task for today is to write JavaScript to open the search application page in a popup modal dialog. When the dialog closes, we want a callback function to return information about the document that the user has selected to the page that opened the dialog.

For this task, we will use the SP.UI.ModalDialog class in the SharePoint 2010 ECMAScript Class Library. We will also reference the jQuery library version jquery-1.5.min.js. You can download jquery-1.5.min.js from from the jQuery portal.

Note: The example code references a particular version of the jQuery library. You can use a later version provided that you change all references in the example code to the version of the library that you are using. A simpler alternative might be to rename the file that you have downloaded to jquery-1.5.min.js.

To create the modal dialog script
  1. In Solution Explorer, select the ModalHost.ApplicationPages folder below the Layouts folder. Right-click, point to Add, then click New Folder. Name the new folder scripts.

  2. Right-click the scripts folder, point to Add, click Existing Item. Navigate to the downloaded jquery-1.5.min.js file. Click Add.

  3. Right-click the scripts folder, point to Add, click New Item. Select Visual C#, General. Then select the Text File template. Name the file ModalHost.js. Then click Add.

  4. Copy the following code and paste it into ModalHost.js:

     //  When invoked open the modal dialog.
    //  We will call this function from the Web Part's page.
    function popupmodalui(url) {
        // Set the required properties.
        var options = { autoSize: true,
                        title: "Search documents",
                        showClose: true,
                        allowMaximize: true 
                      };
        // Pop up the application page in the modal window, 
        // and pass the site url as a query string to the application page.
          SP.UI.ModalDialog.commonModalDialogOpen("../_layouts/ModalHost.ApplicationPages/ModalHost.aspx?url=" + url, 
                                                   options, closecallback, null);
    }
    
    // Handles the click event for OK button on the modal dialog.
    // This function runs in the context of the application page.
    function ModalOk_click() {
        // Get the value of the hidden textbox on the modal dialog.
        var value = getValueByClass('.modalhiddenfield');
        // Pass the hidden textbox value to the callback and close the modal dialog.
        SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, value);
    }
    
    // Handles the click event for the Cancel button on the modal dialog.
    function ModalCancel_click() {
        // Set the dialog result property to Cancel and close the modal dialog.
        SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.cancel, 'Cancel clicked');
    }
    
    // Executes when the modal dialog is closed.
    // This function runs in the context of the Web Part's page.
    function closecallback(result, value) {
        // Check if OK button was clicked.
        if (result === SP.UI.DialogResult.OK) {
            // Set the value of the hidden textbox on the web part 
            // with the value passed by the OK button event.
            var ispostback = setValue('.webparthiddenfield', value);
            if (ispostback == true) {
                // Postback the page so the web part lifecycle is reinitiated.
                postpage();
            }
        }
    }
    
    // Finds a control by css class name and retrieves its value.
    function getValueByClass(className) {
        formtextBox = $(className);
        if (formtextBox != null) {
            return formtextBox.val();
        }
    }
    
    // Finds a control by css class name and sets its value.
    // This function runs in the context of the Web Part's page.
    function setValue(className, value) {
        hiddenfieldid = $(className);
        if (hiddenfieldid != null) {
            hiddenfieldid.val(value);
            /*For testing the modal dialog with the CEWP. Can be removed.*/
            if (hiddenfieldid.css('visibility') == "visible") {
                return false;
            }
            /*--*/
            return true;
        }
    }
    
    // Check if the hidden text box on the modal dialog is empty.
    function checkTextChange() {
        value = jQuery.trim(getValueByClass('.modalhiddenfield'));
        // Enable the OK button on the modal window if the hidden textbox has a value.
        if (value) {
            $('#btnModalOK').removeAttr('disabled');
        }
        // Disable the OK button on the modal window if the hidden textbox does not have a value.
        else {
            $('#btnModalOK').attr("disabled", "true");
        }
    }
    
    // Postback the page to reinitiate the web part life cycle.
    function postpage() {
        document.forms[0].submit();
    }
    
    // Look for a change every time the page is loaded.
    $(document).ready(function () {
        checkTextChange();
    });
    

Let's review the code.

-

**popupmodalui**. This function opens the modal dialog that displays the search application page. It does this by calling the [SP.UI.ModalDialog.commonModalDialogOpen](https://msdn.microsoft.com/en-us/library/ff409609.aspx) function and passing in the relative URL of the application page with the website URL appended in a query string parameter. As you recall, the code behind the application page has a method to retrieve the URL from the query string.

  
  

Later in the project we will write code that invokes the popupmodalui function from a Web Part that hosts an InfoPath form.

  
  • closecallback. This function is called after the modal dialog closes and it executes in the context of the page that called commonModalDialogOpen. If the user clicked OK to close the dialog, the value argument is passed to the "webparthiddenfield" text box on the parent page. Later in the project, we will create this hidden text box in the Web Part that invokes the popmodalui function.

  • checkTextChange. This function checks if the "modalhiddenfield" text box on the application page has a value. (This is the text box whose ID is DialogValue.) If the text box does have a value, the function enables the OK button. Otherwise, it disables the button.

  • ModalOk_click. This function first retrieves the value of the "modalhiddenfield" text box. Then it closes the dialog by calling commonModalDialogClose with two arguments: a value that indicates OK was clicked; and the value taken from the "modalhiddenfield" text box. (Note: The search application page does not yet have a button to raise the event that this function handles.)

  • ModalCancel_click. This function closes the dialog and passes a value that indicates Cancel was clicked. (Note: The search application page does not yet have a button to raise the event that this function handles. Coming soon.)

  • postpage. Submits the parent page, causing a partial page postback. This reinitiates the page life cycle. Later, we write code for a Web Part that reads the value in the hidden text box in its OnPreRender event handler.

Before we go on, we should clarify how the application is using hidden text boxes. The completed project will have two of them, both used for temporary storage of metadata from the document that the user selects in the modal dialog. So far, we have created just one hidden text box, the DialogValue control on the application page. (We have not yet actually made the text box invisible. We will do that very soon.) The markup attaches the CssClass "modalhiddenfield" to the first hidden text box. This is a dummy class used to make it easier to locate the element in the page's element tree. Later in the project we create a second hidden text box, this one on a Web Part. It will be identified by the CssClass attribute "webparthiddenfield".

When the user makes a selection in the modal dialog, code behind the search application page stores metadata for the document in the "modalhiddenfield" text box on the application page. The click event handler for the modal dialog's OK button passes the value stored in this text box to the callback function. The callback function executes in the context of the parent page, the Web Part, and stores the value that it receives in the Web Part's "webparthiddenfield" text box. Code for the Web Part reads the "webparthiddenfield" text box and uses its value to update a hyperlink field on the InfoPath form.

Now that we have written JavaScript for the modal dialog, we need to link to the script in the markup for the application page. While we are amending the page, we can also add markup to hide the "modalhiddenfield" text box that has, until now, been visible. And we can finish up by adding OK and Cancel buttons to close the dialog.

To complete the search application page
  1. In Visual Studio, open ModalHost.aspx.

  2. Locate ContentPlaceHolderID="PlaceHolderAdditionalPageHead". Place the insertion point on a blank line above the closing </asp:Content> tag. Then copy the following markup and paste it at the insertion point:

     <script src="/_layouts/ModalHost.ApplicationPages/scripts/jquery-1.5.min.js" type="text/javascript"></script>
    
     <script src="/_layouts/ModalHost.ApplicationPages/scripts/ModalHost.js" type="text/javascript"></script>
    

    This markup registers the jQuery library and the modal dialog script on the page.

  3. Locate the following markup:

     <asp:TextBox runat="server" ID="Dialogvalue" CssClass="modalhiddenfield"></asp:TextBox>
    

    Replace it with the following:

     <asp:TextBox runat="server" ID="Dialogvalue" CssClass="modalhiddenfield" 
         onchange="checkTextChange();" Style="display: none; visibility: hidden;">
    </asp:TextBox>
    

    The revised markup adds a handler for the onchange event and hides the text box.

  4. Locate the following comment:

     <!-- Insert the modal dialog OK and Cancel buttons here--->
    

    Replace it with the following markup:

     <div style="padding-top: 10px">
        <input type="button" name="BtnOK" id="btnModalOK" value="OK" onclick="ModalOk_click();" /> &nbsp;&nbsp;
        <input type="button" name="BtnCancel" id="btnModalCancel" value="Cancel" onclick="ModalCancel_click();" />
    </div>
    

    This markup defines the OK and Cancel buttons and attaches event handlers to both.

  5. In Solution Explorer, right-click the solution's node and then click Deploy.

Testing the Modal Dialog

At this point we can do a quick test of what we have developed so far. We can use the SharePoint Content Editor Web Part (CEWP) for this purpose.

To test the modal dialog
  1. Open your browser and navigate to your SharePoint site.

  2. On the ribbon, click Site Actions and then More Options.

  3. Under Filter By, select Page. Then select Web Part Page. Click Create.

  4. Name the page ModalDialogSearchPage. Under Document Library, select Site Pages. Then click Create.

  5. Click Add a Web Part in any of the columns.

  6. Under Categories, select Media and Content. Under Web Parts, select Content Editor. Then click Add.

  7. In the Content Editor, click Click here to add new content.

    image6

  8. On the ribbon, click the Format Text tab. Select HTML, and then click Edit HTML Source.

    image7

  9. Copy the following markup and paste it into the HTML Source dialog.

     <script src="../_layouts/ModalHost.ApplicationPages/scripts/jquery-1.5.min.js" type="text/javascript"></script>
    <script src="../_layouts/ModalHost.ApplicationPages/scripts/ModalHost.js" type="text/javascript"></script>
    <div>
        <input class="webparthiddenfield" type="text" style="visibility: visible" />
        <input onclick="popupmodalui('https://teamsite');" type="button" value="Show Dialog" />
    </div>
    
  10. In the markup that you just pasted, locate the call to the popupmodalui function. Change the URL to the URL for your website. Then click OK to close the dialog.

    The Web Part should look like the following image:

    image8

  11. Click Show Dialog.

    The modal dialog should display. Note that the OK button is not enabled.

  12. Type a search term such as "IT". Then click the image button.

    Search results should display in the results grid.

  13. Select any row in the results grid.

    The selected row should be highlighted, and the OK button should be enabled.

  14. Click OK.

    The modal dialog should close.

  15. Examine the string in the text box. It should consist of the URL for the selected document plus a semicolon and then the name of the document as in the following example.

     https://teamsite/Shared%20Documents/IT%20Department%20Annual%20Report.docx;IT Department Annual Report
    

Next Steps

In Part 3 we design the InfoPath form that will invoke the modal dialog.