Microsoft InfoPath 2010
The official blog of the Microsoft InfoPath team

Submitting to 'this' document library

Submitting to 'this' document library

Rate This

Have you ever needed to develop an InfoPath form template that submits back to a SharePoint document library but you did not initially know the server or library name when developing the form? Or have a scenario where your InfoPath form template could be published (or added as a content type) to multiple SharePoint document libraries and you need the submit location to be dynamic? Well read on to find out how you can do this!

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:

  1. Add 3 text box controls, all with a data type of text, named as follows: strFormURL, strLocation and strFolderName
  2. Add a “Submit” data connection named “Main submit”:
    • 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
  3. Set the Security Level of the form to Full Trust and sign the form template with a digital certificate
  4. 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.

 

Scott Heim

Support Engineer

Attachment: submitToThisLibrary.zip
Leave a Comment
  • Please add 4 and 1 and type the answer here:
  • Post
  • First of all I would like to say THANK YOU to everyone who came to my sessions last week! I had a wonderful...

  • I think you are missing this line of code from your Submit event:

    FileSubmitConnection fc = (FileSubmitConnection)this.DataConnections["Main submit"];

  • Hi fordhamSteve,

    Thank you for alerting us to the missing line of code - the sample has now been corrected.

    Scott Heim

  • I am getting the following error when i try to preview my form. I have limited experience with javascript.

    Any idea what I might have done wrong? Thanks, Dean

    InfoPath cannot open the selected form because of an error in the form's code.

    The following error occurred:

    Expected ';'

    File:script.js

    Line:8

    private object _strUri

  • Hi Dean,

    Most likely the cause of this problem is the fact that this code is C#.NET and not JScript. If you want to test using the same form and C#, you will need to remove the JScript code first and then set the form to use C#:

        - Open the XSN in Design View

        - From the Tools menu choose Form Options

        - Select the Programming Category

        - Click the Remove Code button to remove the JScript files

        - From the Form Template Code Language box choose C#

    Scott

  • Scott, thanks, When I look at the Form Options, Advanced tab, there is no Programming Category, there is only a Programming Language box with Form Code Language choices of JScript and VB Script. I'm using IP 2003 SP1. How do I make it use C#?

    Dean

  • Ah - 2003...that's a bit different. Do you need to use this form or can you start over with a new form? Either way, you will need to use the Visual Studio Tools for Office InfoPath Toolkit (in conjunction with Visual Studio) to create a managed code solution. If you don't have Visual Studio then the only code options available are JScript and VBScript and you will need to convert the C# code to JScript.

    Scott

  • I was just testing your approach to see how it would work in a dummy form before I tried to implement it in an existing form. I do have VS 2003 with the toolkit. Would it be worthwhile to get VS 2005 if this is the only coding that I'm doing?

    Dean

  • Hi Dean,

    Certainly there are some benefits to moving to VS2005 but although I have not tried it, theoretically the same basic process/code should work using the managed code option with VS2003.

    Scott

  • Scott, is this supposed to work with IP 2003 or 2007? I keep getting compile errors in 2003.

    Dean

  • Hey Dean,

    Although that code is C#, it is specific to the new object model in 2007. To get this to work in 2003, you will need to convert that code to the 2003 object model.

    Scott

  • By popular demand, Scott converted the code used in this article into the InfoPath 2003 managed object model (in C#) and into JScript. You can download the full listing in the attachments section above.

    Alex

  • Thanks for making the conversions Scott, I'm getting closer to getting this to work, but I don't have a Digital Certificate. Is there any workaround available? Dean

  • Hi Dean,

    Glad you hear you are making headway! For testing purposes, you can create a "self-cert" (basically a certificate that does not have a chain of trust, hence it is only valid on the machine in which it was created) by choosing the Create Certificate button in Tools | Form Options | Security and Trust category.

    Scott

  • Hi,

    When I add the code strUri = thisXDocument.Solution.URI; to get the url I get a uniform resource identifier (urn:eLNDTX:Innx). Am I missing something ? Why don't I get a url ??

    Marc

Page 1 of 12 (166 items) 12345»