Sunday, March 1, 2009

How to dynamically load data in an InfoPath form

An InfoPath form is an XML file. The file contains the data from the form and XML processing instructions that tell Microsoft Windows Explorer or Microsoft Internet Explorer to which application the XML data belongs.

You can dynamically load data into InfoPath by using one of the following three methods:
  • Use the OnLoad event.

    In the OnLoad event, you can call an ASP page or another external data source to retrieve the data and to copy it into the form.
  • Automate the InfoPathExternalApplication object.

    This method creates a new form that is based on the data from an external source.
    Note The Initialize and script ActiveX controls not marked as safe setting in Internet Explorer must be set to Prompt or Enable for this method to work.
    The data from the external source must also be valid InfoPath XML.
  • Create an ASP page.

    The ASP page returns XML data in the correct format for InfoPath to open as a form file. The XML data contains a reference to the InfoPath Form template where the data should be displayed. InfoPath can display the data without a problem.

Create a new virtual directory

  1. Start Microsoft Internet Information Services Manager.
  2. Expand the Web Sites directory in the tree view.
  3. Right-click the Web site where you want to create the new virtual directory, point to New, and then click Virtual Directory.
  4. Follow the steps in the Virtual Directory Creation Wizard to create a new virtual directory.

    Note You must grant Write permission to the virtual directory.

Design an InfoPath form

InfoPath 2007

  1. Start Infopath. In the left pane, click Design a Form Template.
  2. Under Design a new, click to select the Form Template option, click to select the Blank option, and then click OK.
  3. Under Design Tasks, click Controls.
  4. Click Text Box two times to add two Text Box controls to the form.
  5. Save the form.
  6. On the File menu, click Publish.
  7. In the Publishing Wizard, click Next. Click To a network location, and then click Next.
  8. In the Form template path and file name box, type the URL of the virtual directory that you created.
  9. In the Form template name box, type twofield.xsn.

    Note Make sure that the URL resembles the following:
    http://myServer/myVirtualDirectory/twofield.xsn
  10. Click Next, click Publish, and then click Close.
  11. Exit InfoPath.

InfoPath 2003

  1. Start Infopath. In the left pane, click Design a Form.
  2. Under Design a Form, click New Blank Form.
  3. Under Design Tasks, click Controls.
  4. Click Text Box two times to add two Text Box controls to the form.
  5. On the File menu, click Publish.
  6. In the Publishing Wizard, click Next, click To a Web server, and then click Next.
  7. In the Web URL and file name box, type the URL of the virtual directory that you created.
  8. In the Form name box, type twofield.xsn.

    Note Make sure that the URL resembles the following:
    http://myServer/myVirtualDirectory/twofield.xsn
  9. Click Next, click Finish, and then click Close.
  10. Exit InfoPath.

Create the Default.asp page

  1. Click Start, click Run, type notepad, and then click OK.
  2. Paste the following code in Notepad.
    <%@ Language=VBScript %>
    

    <%

    dim serverName, hrefPath, fileNamePos, serverPath

    serverName = Request.ServerVariables("SERVER_NAME")

    hrefPath = Request.ServerVariables("PATH_INFO")

    fileNamePos = InStr( 1, hrefPath, "/Default.asp", 1 )

    hrefPath = Left(hrefPath, fileNamePos )

    serverPath = "http://" + serverName + hrefPath

    %>













  3. Save the file as Default.asp. Save the file in the virtual directory that you created in the "Create a new virtual directory" section.

Create an ASP page to generate a form dynamically

  1. Locate and then double-click the Twofield.xsn form that you just published.
    Note A new blank form is opened for you to fill out.
  2. Click File, and then click Save As.
  3. Save the file as Form1.xml.
  4. Click Start, click Run, type notepad, and then click OK.
  5. Paste the following code in Notepad.
    <%@ Language=VBScript %>
    
    <%
    ' Define the XML namespace for the form.
    Dim strNamespace
    strNamespace = "http://schemas.microsoft.com/office/infopath/2003/myXSD/2003-04-21T15:25:26"

    'Calculate the path of this server directory.
    dim serverName, hrefPath, fileNamePos, serverPath
    serverName = Request.ServerVariables("SERVER_NAME")
    hrefPath = Request.ServerVariables("PATH_INFO")
    fileNamePos = InStr( 1, hrefPath, "/GetData.asp", 1 )
    hrefPath = Left(hrefPath, fileNamePos )
    serverPath = "http://" + serverName + hrefPath

    ' Set our return content type.
    Response.ContentType = "text/xml"

    'Create an XML document to return.
    Dim oXML
    Set oXML = Server.CreateObject("MSXML.DOMDocument")

    'Create the XML header that all XML documents must have.
    dim myPI1
    set myPI1 = oXML.createProcessingInstruction("xml", "version=""1.0"" encoding=""UTF-8""")
    oXML.insertBefore myPI1, oXML.childNodes.item(0)

    'Create the mso-infopathSolution processing instruction that binds the XML from this page to the
    'TwoField.xsn InfoPath form template.
    dim myPI2
    set myPI2 = oXML.createProcessingInstruction("mso-infoPathSolution", "solutionVersion=""1.0.0.1"" productVersion=""11.0.5531"" PIVersion=""1.0.0.0"" href=""" + serverPath + "TwoField.xsn""")
    oXML.insertBefore myPI2, oXML.childNodes.item(1)

    'Create the mso-application processing instruction that marks the XML from this page as an InfoPath form.
    dim myPI3
    set myPI3 = oXML.createProcessingInstruction("mso-application", "progid=""InfoPath.Document""")
    oXML.insertBefore myPI3, oXML.childNodes.item(2)

    'Generate the XML for the form.
    dim myFields
    set myFields = oXML.createNode( 1, "myFields", strNamespace )
    oXML.appendChild myFields

    dim field1
    set field1 = oXML.createNode( 1, "field1", strNamespace )

    dim field2
    set field2 = oXML.createNode( 1, "field2", strNamespace )

    dim requestedData
    requestedData = Request("dataRequest")
    Select Case requestedData
    Case "1"
    field1.text = "test field 1"
    field2.text = "test field 2"
    Case "2"
    field1.text = "test field 3"
    field2.text = "test field 4"
    Case "3"
    field1.text = "test field 5"
    field2.text = "test field 6"
    Case Else
    field1.text = "test field 7"
    field2.text = "test field 8"
    end Select

    myFields.appendChild field1
    myFields.appendChild field2

    'Return the XML to the client.
    Response.Write oXML.XML
    %>
  6. On the File menu, click Save As, type GetData.asp in the File name box, and then click Save.
  7. Start a second instance of Notepad.
  8. On the File menu, click Open, click Form1.xml, and then click Open.
  9. Locate the xmlns:my namespace declaration in Form1.xml, and then copy its value.

    Note The value resembles the following:
    http://schemas.microsoft.com/office/infopath/2003/myXSD/2003-04-21T15:25:26
  10. In the GetData.asp fle, locate the following line:
    strNamespace = "http://schemas.microsoft.com/office/infopath/2003/myXSD/2003-04-21T15:25:26"
  11. Replace the value of the strNamespace variable with the value that you copied in step 9.
  12. Click Save, and then exit Notepad.
  13. Copy the GetData.asp file to the same virtual directory where the Twofield.xsn form template is located.

Add code to the InfoPath form to automatically load data from the ASP page

  1. Start InfoPath.
  2. In InfoPath 2007, click Design a Form Template in the left pane. In InfoPath 2003, click Design a Form in the left pane.
  3. In InfoPath 2007, click On My Computer under Open a form template. In InfoPath 2003, click On My Computer under Open a form in design mode in the Design a Form task pane.
  4. Type the URL of the form template that you published.

    Note The URL resembles the following:
    http://myServer/myVirtualDirectory/twofield.xsn
  5. On the Tools menu, click Programming, and then click OnLoad Event.
  6. Replace the default OnLoad event code with the following code.
    function XDocument::OnLoad(eventObj)
    
    {
    //Only load data if the fields are empty.
    if (XDocument.DOM.selectSingleNode("/my:myFields/my:field1").text == "" )
    {
    //Work out the location of the data file based on the current install directory.
    searchExpression = new RegExp( "TwoField.xsn", "ig" );
    searchResults = XDocument.Solution.URI.match( searchExpression );
    if (searchResults.length == 0)
    return;

    //Clear the "TwoField.xsn" part of the string.
    var targetDirectory = XDocument.Solution.URI.slice(0, searchResults.index );

    //Load the example data into and XML document.
    var objExternalData = new ActiveXObject("MSXML2.DomDocument.5.0");
    objExternalData.async = false;
    objExternalData.validateOnParse = false;
    objExternalData.load( targetDirectory + "getData.asp?dataRequest=3" );

    //Set the SelectionNamespaces property so that we can search the example data.
    var strSelectionNamespaces = XDocument.DOM.getProperty("SelectionNamespaces");
    objExternalData.setProperty("SelectionNamespaces", strSelectionNamespaces );

    //Find the root node in the example data and import it into the InfoPath document.
    var objExternalXML = objExternalData.selectSingleNode("my:myFields");
    var objReplacementXML = XDocument.DOM.importNode( objExternalXML, true );

    //Find the original data in the form and replace it with the example data.
    var objOriginalXML = XDocument.DOM.selectSingleNode("my:myFields");
    XDocument.DOM.replaceChild( objReplacementXML, objOriginalXML );
    }
    }
  7. On the File menu, click Save, and then close the InfoPath form.

Test the InfoPath form

Load data by using the OnLoad event

The TwoField.xsn form OnLoad event loads data from the GetData.asp page if no other data is in the form. To load the data, follow these steps:
  1. Click Start, click Run, type the path of the form, and then click OK. The path that you type resembles the following:
    http://myServer/IPDynamicData/TwoField.xsn
  2. If you are prompted, click Open.
Notice that InfoPath starts, and the TwoField.xsn form opens. Field1 contains "test field 5", and Field2 contains "test field 6". These are the values that GetData.asp returns when its dataRequest parameter is set to "3".

Load a default form by using ExternalApplication.New

The Default.asp page creates client-side script to automate the ExternalApplication object to start InfoPath and then to create a new form. The new form is based on the XML data that is returned by GetData.asp. To create the new form, click Start, click Run, type the path of the Default.asp page, and then click OK. The path that you type resembles the following:
http://myServer/IPDynamicData/default.asp
Note To use this method, you must click Prompt or Enable for the Initialize and script ActiveX controls not marked as safe setting in Internet Explorer.

Notice that InfoPath starts, and the TwoField.xsn form opens. Field1 contains "test field 3", and Field2 contains "test field 4". These are the values that GetData.asp returns when its dataRequest parameter is set to "2".

Load an existing form from an ASP page

The GetData.asp page returns XML in the correct format for InfoPath to open it as a form file. To do this, click Start, click Run, type the path of the GetData.asp page, and then click OK. The path that you type resembles the following:
http://myServer/IPDynamicData/getData.asp?dataRequest=1
Notice that InfoPath starts, and the GetData.asp form opens. Field1 contains "test field 1" and Field2 contains "test field 2". These are the values that GetData.asp returns when its dataRequest parameter is set to "1".

Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.

Tuesday, July 29, 2008