When you create an InfoPath form template that needs to be able to submit to a SharePoint document library, you need to specify that connection in the initial design of the form template. However, at run time you can use managed code to determine the server and library name where the form was launched and then modify the “FolderUrl” property of the submit data connection so the form is submitted to the appropriate library.
So let’s get started setting up this sample. The C# walkthrough below uses the new InfoPath 2007 managed object model; below, you will find attached the same logic implemented in InfoPath 2003 managed object model and in InfoPath 2003 JScript.
Step 1: Create a sample InfoPath Form Template
Create a browser-compatible form template as following:
- Add 3 text box controls, all with a data type of text, named as follows: strFormURL, strLocation and strFolderName
- Add a “Submit” data connection named “Mainsubmit”:
- Set the document library name to a dummy SharePoint document library (i.e. http://server/dummyLib)
- Use the concat function to concatenate the strFolderName field and _Test for the File Name property: concat(my:strFolderName, "_Test")
- Enable the Allow overwrite if file exists property
- Set the Security Level of the form to Full Trust and sign the form template with a digital certificate
- Enable the Submit functionality (Tools | Submit Options) and choose the “Perform custom action using code” option
Now that we have the form, controls and submit functionality, let’s add the code to make this process work:
Step 2: Add the code
- Click the Edit Code button on the Submit Options dialog
- Create the following FormState Dictionary object – this will be used to store the form’s location when the form is initially opened:
private object _strUri
{
get { return FormState["_strUri"];
set { FormState["_strUri"] = value; }
}
- Add the following code to the Forms Loading event:
// Get the Uri (or SaveLocation in a browser form) of where
// the form was opened.
// See if the form was opened in the browser
Boolean OpenedInBrowser = Application.Environment.IsBrowser;
// If so, we will get the "SaveLocation" from the InputParameters
if (OpenedInBrowser)
_strUri = e.InputParameters["SaveLocation"].ToString();
else
//If it was opened in the client, we will get the Uri
_strUri = this.Template.Uri.ToString();
// Populate the fields on the form - keep in mind, this
// not necessary - this is simply to see the results
PopulateLibInfo(OpenedInBrowser);
- Add the following procedure to the Forms class:
private void PopulateLibInfo(Boolean OpenedInBrowser)
{
// Create a Navigator object for the main DOM
XPathNavigator xnDoc = this.MainDataSource.CreateNavigator();
// Create Navigator objects for each field
XPathNavigator xnFormURL = xnDoc.SelectSingleNode("my:myFields/my:strFormURL", this.NamespaceManager);
XPathNavigator xnLocation = xnDoc.SelectSingleNode("my:myFields/my:strLocation", this.NamespaceManager);
XPathNavigator xnFolderName = xnDoc.SelectSingleNode("my:myFields/my:strFolderName", this.NamespaceManager);
// Get the Uri stored in the FormState Dictionary variable
string strUri = _strUri.ToString();
// Create a variable to store the path (URL) to the document library
string strPath = "";
if (OpenedInBrowser == true) {
//If we are open in the browser, the strUri value is just
//the server name and library - so we just need to get
//the URL without the last "/"
strPath = strUri.Substring(0, strUri.LastIndexOf("/"));
} else {
// Parse just the path to the document library -
// this would return something like this:
// http://server/library
strPath = strUri.Substring(0, strUri.IndexOf("Forms") - 1);
}
// Now, parse the URL to where the document library resides;
// this would return something like:
// http://server or http://server/site
string strLoc = strPath.Substring(0, strPath.LastIndexOf("/"));
// Lastly, parse the URL to return just the document library name -
// in this case,we are looking for the last "/" character
// knowing that what comes after this is the document library name
string strFolder = strPath.Substring(strPath.LastIndexOf("/") + 1);
// Populate the fields on the form – we will use these
// values in the Submit process
xnFormURL.SetValue(strUri);
xnLocation.SetValue(strLoc);
xnFolderName.SetValue(strFolder);
}
- Add the following code to the form’s Submit event:
// Create a Navigator object for the main DOM
XPathNavigator xnDoc = this.MainDataSource.CreateNavigator();
// Create Navigator objects for the fields we will
// use to modify the FolderUrl
XPathNavigator xnLocation = xnDoc.SelectSingleNode("my:myFields/my:strLocation", this.NamespaceManager);
XPathNavigator xnFolderName = xnDoc.SelectSingleNode("my:myFields/my:strFolderName", this.NamespaceManager);
// Get a reference to the submit data connection
FileSubmitConnection fc = (FileSubmitConnection)this.DataConnections["Main submit"];
// Modify the URL we want to submit to by concatenating the
// xnLocation and xnFolderName values
fc.FolderUrl = xnLocation.Value + "/" + xnFolderName.Value;
// Execute the submit connection
try
{
fc.Execute();
e.CancelableArgs.Cancel = false;
}
catch (Exception ex)
{
e.CancelableArgs.Cancel = true;
}
- Build and save the project
- Publish and test
And that is it! You now have an InfoPath form template that will submit to whatever document library the form was opened from so you do not need to know this information when designing the template.
No comments:
Post a Comment