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
  • Hi Liga,

    The point of the code in this sample is this: let's say you publish a browser-compatible XSN and want to use this in multiple document libraries. With the out of the box functionality, when you setup a "submit" connection to allow the user to "submit" the completed form, it can only submit to the library which you setup at design time. With this sample, it dynamically determines the library from which the form was launched so it submits the completed form to that library.

    Now, maybe where the confusion is coming in is this: you are correct that when you "Admin" deploy an XSN, the resulting (uploaded and activated) XSN resides in a special "Form Server Templates" library; however, this is *not* where you want to use this form. What you should be doing is creating other libraries where you want to use that XSN, setting the "Allow management of content types" to Yes for those libraries and then adding that XSN from the Content Types list to that library.

    Scott

  • Great! It all makes sense now :-)

    Oh and there's a SaveLocation parameter in the url now, so that's working, too. *happy*

    Unfortunately another part of my solution broke apart while switching to the new multi-purpose library.

    I can't open the new form within an XmlViewControl (within my webpart) anymore.

    I set XsnLocation to the url I get when creating a new form from my library.

    "The following file is not a valid InfoPath form template"

    http://forms.domain.tld/_layouts/FormServer.aspx?XsnLocation=http://forms.domain.tld/FormServerTemplates/SampleSimpleFormWithCode.xsn&SaveLocation=http://forms.domain.tld/test.

    Opening the form directly (without xmlformview control) works perfectly fine.

  • Hi Liga,

    Glad you are making progress! In regard to the XmlViewControl, have you tried setting the XsnLocation to this:

    http://forms.domain.tld/FormServerTemplates/SampleSimpleFormWithCode.xsn

    Scott

  • Hi Scott,

    I tried that. As soon as you add any additional parameters to the XsnLocation property the XmlFormView fails to load the form.

    If I omit the SaveLocation parameter.. guess what.. KeyNotFoundException :-)

    So I guess I'll have to specify the target library prior to deployment rather than figuring it out dynamically :-(

  • Hi liga,

    I have never used the XmlView control (I am assuming this is a SharePoint web part?) so this may not work as you need.

    Scott

  • Hi,

    I'm trying to use this "How to" with Infopath 2010 and SPS 2010, but I always get following error :

    The InfoPath formular could not be transmitted.

    The eventhandler for "OnSubmitRequest" doesn't work correctly.

    The objectlink was not specified to a objectinstance.

    onTestForm_web.FormCode.FormEvents_Submit(Object sender, SubmitEventArgs e)

    on

    Microsoft.Office.InfoPath.Internal.FormEventsHost.OnSubmit(DocReturnEvent

    pEvent)

    on

    Microsoft.Office.Interop.InfoPath.SemiTrust._XDocumentEventSink2_SinkHelper.OnSubmitRequest(DocReturnEvent pEvent)

    (Info: The first three sentences of the message were translated by myself

    (from german to english))

    Any ideas?

    walter

  • Hi Walter,

    I just tested the exact steps in the blog with InfoPath 2010 and SharePoint 2010 and they worked without any modification whatsoever. Now, I did test opening the form in the browser...is this how you tested? If so, did you follow the steps in this post exactly as they are documented?

    Thanks...

    Scott

  • Hi scott

    Thanks for your answer!

    Yes! I followed all the steps which have to be taken in the tutorial. I wasn't able to test the form in the browser, cause I'm currently using 2008 server R2 in German and all the rest (SPS, Infopath,...) in beta (so in english). Thats the reason I can't use InfoPath WebApps at the moment..So I have to test the form with a localy installed InfoPath 2010 beta.

    The test procedure I've done:

    1. upload the form into a form library (manually)

    2. open and fill out the form

    3.  click submit -> the upper error occurs! :(

  • Hi Walter,

    Hmmm...this still works for me...so first concern is your comment: "upload the form into a form library (manually)".

    Not sure what you mean by that but what you should be doing is "publishing" the XSN from within InfoPath and, for testing purposes, let the publishing wizard create a new library for you. If you are indeed just using the SharePoint "upload" functionality to upload the XSN to a library, this will not work in many ways. :)

    When you publish the XSN to your SharePoint site as I have described above you should be able to click on the New button and get a new instance of the form. If the code is working as designed, the 3 text boxes on this sample form will already be completed with the correct information about where the form was published and opened.

    Scott

  • Hi Scott

    Thank you! Now It'works!:)

    I didn't publish the form template but uploaded it! That was the point I misunderstood :(

    Scott, I got another question...

    I should publish an infopath form template to serveral different libraries in different team sites on one sharepoint server.

    Is it possible to automate the publishing procedure? (ps script?)

    Walter

    ps: I currently creating those team sites including their document libraries by using a powershell script.

  • Hi Walter,

    Glad you were able to get it working!

    In regard to publishing - the InfoPath designer does not have an object model so there is really no way to automate this. However, have you considered publishing the XSN as a "Site Content Type?" When you do this, instead of publishing to a specific library you "publish" the XSN to your site and "store" it (the XSN) in a library you create (i.e. MyContentTypes.) Then once you have published the XSN as a "Site Contene Type" then you can add that XSN to any library in that site collection. To do that:

    - Create a library where you want to use the XSN

    - From the Settings button, choose Form (or Document) Library Settings

    - Click Advanced Settings

    - For Allow Management of Content Types, choose Yes and click OK

    - You will now see a "Content Types" section with either a default Form or Document content type - click Add from existing site content types

    - Select the XSN you published as a Site Content Type, click Add and then OK

    - Click on the default Form or Document content type that was there by default and then click Delete this content type (all that does is remove the default type from this library)

    Now when you click New you get a new instance of your XSN just as if you had published it but now you add the added benefit of being able to use that XSN in other libraries in this site collection. :)

    Scott

  • Hi Scott

    Thank you for your detailed explanation about publishing forms! In fact, that is exactly what I need!

    Is it possible to automate the following few steps?

    - From the Settings button, choose Form (or Document) Library Settings

    - Click Advanced Settings

    - For Allow Management of Content Types, choose Yes and click OK

    - You will now see a "Content Types" section with either a default Form or Document content type - click Add from existing site content types

    - Select the XSN you published as a Site Content Type, click Add and then OK

    - Click on the default Form or Document content type that was there by default and then click Delete this content type (all that does is remove the default type from this library)

    ..if so, which classes do I need for each step above?

    Walter

  • Hi Walter,

    Honestly I don't know if there is a way to do this...this functionality is all SharePoint and that is not my area of expertise. You may want to ping a SharePoint forum and see if there is some code you could execute to modify those settings.

    Scott

  • Well, I will looking for those information in a sps forum!

    But anyway I'd like to thank you for supporting me!

    Walter

  • My pleasure Walter!

    Take care,

    Scott

Page 8 of 12 (166 items) «678910»