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 |