Pass Parameters to InfoPath - Jim Cantwell
in

InfoPath Dev

Jim Cantwell

Pass Parameters to InfoPath

There is sometimes the need to pass arguments to InfoPath when opening a form. You either want to switch to a specific view, or maybe want to turn on a diagnostic feature in your code. By leveraging the merge functionality of InfoPath, you can pass simple arguments or a complex set of data to your form.

Define A Parameters Schema

You will need to define a schema for your parameters. The example uses a simple repeating Param element containing name/value pairs like this:

<Params>
    <Param name="" value="" />
</Params>

Enable Merge Functionality

The next step is to enable the necessary merge functionality for your form. This is accomplished by editing the manifest.xsf as follows:

<xsf:importParameters enabled="yes" useScriptHandler="yes"></xsf:importParameters>

The enabled and useScriptHandler attributes of the importParameters element should be set to yes.

Add OnMergeRequest/OnAfterImport Code

The OnMergeRequest event is fired whenever a merge request is executed and merging is enabled in your form. If your form supports merges other than for parameter passing, this code will need modification to support that. This example expects a specific schema, and will just silently ignore any merge requests that do not use the expected schema. It is recommended to perform most work in OnAfterImport, as things like switching views cannot be done in the OnMergeRequest event.

var g_fArgumentsPassed = false;
var g_argsDOM = null;

function XDocument::OnMergeRequest(eventObj)
{
    var dom = eventObj.DOM;

    // Add your validation here that the DOM passed is the
    // schema expected, and only set eventObj.ReturnStatus to true
    // if a valid schema.
    if (dom.selectNodes("/Params/Param").nextNode())
    {
        g_fArgumentsPassed = true;
        g_argsDOM = dom;
    }
    // We silently ignore any bad requests by always setting the ReturnStatus to true
    eventObj.ReturnStatus = true;
}

function XDocument::OnAfterImport(eventObj)
{
    if (g_fArgumentsPassed)
    {
        var nodes;
        var node;
        var paramName, paramValue;
       
        nodes = g_argsDOM.selectNodes("/Params/Param");

        while (node = nodes.nextNode())
        {
            paramName = node.selectSingleNode("@name").text;
            paramValue = node.selectSingleNode("@value").text;
            if (paramName == "Cancel")
            {
                // Switch to cancellation view
                XDocument.View.SwitchView("Cancel Order"); 
            }
            else if (paramName == "view")
            {
                // Switch to requested view
                XDocument.View.SwitchView(paramValue); 
            }
        }
        // Clear flag, as this could be called again if another merge is performed
        g_fArgumentsPassed = false;
    }
}


Test Your OnMergeRequest/OnAfterImport Code

The simplest way to test your code is to use File | Merge Forms menu command. This menu option will be enabled after modifying your form's manifest.xsf as done above. If you are using the example parameter schema, create an XML file containing the content below, and select the file in the dialog presented when you use the Merge Forms command.

<?xml version="1.0" encoding="UTF-8" ?>
<Params>
    <Param name="Cancel" value="" />
</Params>

Opening a Document and Passing Parameters From a Web Page

Installed with Microsoft Office is the "SharePoint.OpenXMLDocuments" object. The MergeDocuments2 method can be used to open a document or template and pass the URLs as merge files, which in this case will be a parameters file.

This script below works in conjunction with a merge view of a SharePoint form library. When a single merge checkbox is selected, it will open the document using MergeDocuments2. A URL to the CancelParams.xml file containing the arguments to be passed as an argument to MergeDocuments2.

<script>
function CancelOrder()
{
    var cItemsChecked = 0;
    var selectedOrder;

    var chkCombineCollection = document.all.chkCombine;
    for (i=0; i<chkCombineCollection.length; i++)
    {
        if (chkCombineCollection[i].checked)
        {
            selectedOrder = chkCombineCollection[i];
            cItemsChecked++;
        }
    }

    // Single item selected will not be a collection and can be determined when
    // the checked property is true
    if (cItemsChecked == 0 && document.all.chkCombine.checked)
    {
        selectedOrder = document.all.chkCombine;
        cItemsChecked = 1;
    }

    if (cItemsChecked != 1)
    {
        alert("Please select exactly one order to cancel.");
        return;
    }

    xmlDocObject = new ActiveXObject("SharePoint.OpenXMLDocuments");

    if (xmlDocObject)
    {
      var strTempLoc = "
http://servername/Order Form/Forms/template.xsn"
      var strSaveLoc = "
http://servername/Order Form";

      // This is the document collection which the MergeDocuments2 call takes
      // In this case, we are only passing one file containing the arguments
      var docCol = Array( {checked:true, HREF:"
http://servername/Parameters/CancelOrder.xml"} );

      // Declare an iterator function for the collection of documents.
      function item(index)
      {
         return docCol[index];
      }

      // wrap the collection and the interator into an object suitable
      // for MergeDocuments2 call.
      var docWrap = {length:docCol.length, item:item};

      // If opening a new file, pass the url to the template instead of the document url
      xmlDocObject.MergeDocuments2(window, selectedOrder.HREF, docWrap, strSaveLoc);
    }

}
</script>

Pass Parameters to InfoPath From the Command Line

To pass parameters to InfoPath from the command line, you use the optional /aggregate switch. You may pass in multiple forms to the template, separating them with the pipe character: "|". You may use optional quotes around the entire list of forms, but not around each individual form.

An example command line would look like the following:

InfoPath.exe /aggregate "ParamFile1.xml|ParamFile2.xml|ParamFile3.xml" MyFormTemplate.xsn

Comments

 

can i open a new form from current form and pass values? | keyongtech said:

Pingback from  can i open a new form from current form and pass values? | keyongtech

January 21, 2009 11:19 PM
 

augurer said:

I've tried implementing this, and the MergeDocuments call returns false every time.  I've tried setting the merge document parameter to null, as well.  If I use the same window, selectedOrder.HREF, and strSaveLoc parameters in a CreateNewDocument call, it works fine.

Any ideas what might be happening?  I've verified importing is enabled, and the code-behind in the InfoPath form works.

March 6, 2009 8:37 AM
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.