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 5 and 5 and type the answer here:
  • Post
  • Hi Scott

    i finally got through it by adding a System.Web reference to my project and retreiving the list GUID from the url by using the HttpContext.Current.Request.QueryString["List"].ToString() command.

    I don't know if this is the best way to handle this issue, but it did work for me. If there is a better way, please let me know.

    thanks for the support

  • Hi Scott,

    do you have any idea about how i could programmatically retreive the workflow association name from inside the form's code at runtime (the workflow association name is not known at design time? Is it something i could get also from the aspx page?

  • Hi dkarantonis,

    Unfortunately I do not - your best bet would probably be to post that query to a workflow forum or you could open a support case with the SharePoint folks.

    Scott

  • Hello Scott,

    quick question.  In reference to your answer

    # re: Submitting to 'this' document library

    Thursday, July 19, 2007 6:00 PM by infopath

    In reference to putting this code behind a button.   I need to be able to run Rules first and then submit.   This works fine but I can't get my document to Close when submitted.   I have close document in the submit options but I don't think they are being called because you're going directly thru the Data connection.   Is there a way to close the form after your submit code?

  • Hi boverton,

    The easiest way is to simply add a Rule to the same button where you are executing code and the Rule will have just one action: Close the form.

    The code should execute to submit the form and then close.

    Scott

  • Hi,

    I have a InfoPath form with VSTA code embedded to it. In InfoPath development mode, we attach the project file to the .xsn form. So while  publishing the form the .xsn form compiles the project file (in to a .dll file). But how do we manage this situation in the production enviornment? If we try to publish the form (using File -> Publish option of the InfoPath form), using VSTA it will start searching for the project file & try to compile it. But in the production enviornment there wont be Visual Studio installed to map the project file & compile it while publishing the form.

    In the production enviornment how do we manage to publish InfoPath form with with embedded VSTA code?

    Regards,

    Vipul Mehta

  • Hi Vipul,

    As you know, when you compile the VSTA code behind your InfoPath form template (XSN file), the compiled DLL becomes part of the XSN. You are correct that each time you publish we attempt to compile the code; however, when you publish on a machine that does not have the project files you can simply click "Ignore" and the publish process will continue. (Obviously the other option, since you have InfoPath on that machine is to simply copy the project files to that computer and then when you get that message click the 'Browse' button to locate the project file.)

    Scott

  • Scott,

    Firstly, thanks for a very useful post. We are implementing around 100 forms in SharePoint and you sample code helps a lot to make the form submission independent of the form library.

    However, I am having a problem with updating the existing form. I got your latest code you wrote in your comments which will updated an already existing form. I got it working but it has one glitch. The program is raising 'unauthorized exception' unless I use an account with full rights(owner). The user who created the form, is als not able to update it. I worked around it by calling the data connection submit call within SPSecurity.RunWithElevatedPrivileges block. But here is the problem, the sharepoint library columns 'Created By' and 'Modified By' are populated with 'System Account' or the admin account name instead of the current user name.

    So, is there any other work around for this? or Are we missing anything? Is there any explanation for this behaviour(user not able to update)? Thanks for your help.

    -Srinivas

  • Hi Srinivas,

    I had not heard this before so I just tried this on my test site and it seems to work correctly. My "TestUser" has Contribute permissions to my site - I then logged on as that user, created and submitted a new form and then successfully opened that same form, modified data and re-submitted. In this test, the form shows Modified By: TestUser.

    What you may want to look at is doing a Netmon or Fiddler trace to see if you can track down down the cause of the failure - obviously remove your workaround code. :)

    Offhand I cannot think of a reason why...do you have your form set to Full Trust?

    Scott

  • Hi Scott,

    My problem is that by clicking the button in infopath form published on sharepoint site i should open existing form that resides in infopath forms library and one of it's fields should match certain value.How could i do that?Neither i found the opportunity to get the full url of existing form nor the opportunity to request the form with desired field value.

    Will be grateful for any help.

    Best regards,

    Vitaly.

  • Hi Vitaly,

    I am not sure I completely follow the issue but it sounds like you want to open an InfoPath form based on either command-line or query (URL) parameters...is this correct? If so - have you seen these:

    How to: Use Query Parameters to Invoke Browser-Enabled InfoPath Forms

    http://msdn2.microsoft.com/en-us/library/ms772417.aspx

    Command-line switches for InfoPath

    http://office.microsoft.com/en-us/infopath/HP101483281033.aspx

    Scott

  • Scott,

    Thanks for your reply. I just tried copying your code as it is and it worked just fine. Even a user with just the contribute access is able to add and update a form. I will retest the same in my other problematic environment at my work place. I will let you know the result.

    In between, I wonder if a form can be published once and deployed into multipe environments (development, staging, production)? As of now its not possible because we have to give the URL to the sharepoint site to which we publish and so it is hardwired to the form. Technically, I agree that might not be possible because we digitally sign the form for a particular environment. But with a wild card certificate this should not be a problem right?

    Thx,

    Srinivas

  • Hi Scott

    Thanks for reply.

    After looking through these articles I still haven't found the way to open the form with desired value in certain field.It should be made via some CAML query or what?

    Thanks in advance

    Vitaly

  • Srinivas - I am glad to hear the sample works as needed! In regard to publishing once - the answer could be "maybe." <G> Let me explain: If your various sites (dev, prod, etc.) are in the same farm then you could "Admin" deploy the form and then activate it to the appropriate site collections. If your various sits are not under the same farm, you could still perform the "Admin" publish and then simply move that published form where needed and then complete the Admin process of uploading and activating to the appropriate site collection.

    Keep in mind, either of these would still require the solution in this post but the process is indeed possible. The other thing you would need to consider though are data connections. Now again, you may be able to cover this with code but you do need to keep it in mind.

    Vitaly - Unless I am missing something, what you would need to do is open the 2nd form using a command-line or query parameter and then you would have code in the "Loading" event that looked for that parameter and populated the appropriate field (node) in the form.

    Scott

  • Vitaly - here is one more item on command-line/query parameters that may help:

    http://blogs.msdn.com/infopath/archive/2007/02/26/passing-data-into-a-form-input-parameters.aspx

    Scott

Page 6 of 12 (166 items) «45678»