Top Tips for InfoPath form development with SharePoint: Part 1

InfoPath is a great tool that allows you to quickly design and implement browser-based electronic forms which can be delivered as HTML via SharePoint Form Services. Historically there hasn’t been much information available around best practices for development of browser-based InfoPath forms and most organisations have tended to define their own though trial and error.

The purpose of this article is to share some of the tips and tricks that we’ve gathered from developing InfoPath forms over the past few years….. some of them may be obvious, but  if even one of of these tips is new to you, then this article will have been a worth-while exercise. This is just part 1, we intend to do several more articles covering similar tips and tricks so if you like this, watch out for part 2 soon.

The article has been co-authored between Martin Kearn (from Microsoft) and Jay Goodison (from WCI Healthcare and Ascribe Consulting). WCI Healthcare (An Ascribe business) are a Microsoft Gold Partner who maintain specialist knowledge and expertise in designing and implementing SharePoint and InfoPath solutions, Jay brings a lot of invaluable experience to this article.

These tips are mostly in the context of SharePoint based browser enabled forms.

Tip 1: Using the SharePoint object model in browser-based forms

You can implement .net managed code with any InfoPath Form using VSTA (Which is an optional install for the InfoPath client). If you design a form where the target client is only a browser, then effectively all business logic and associated code is executed on the SharePoint web servers, this means that you can directly access and use the SharePoint object model from within the InfoPath form’s code.

Simple instructions to use the SharePoint object model within InfoPath Forms:

1. You’ll need to be developing this on a SharePoint server to do this (as with most SharePoint development)

2. In your form code (InfoPath Design Mode > Tools > Programming > Loading Event) add a reference to the relevant SharePoint DLL that you wish to use. These are located in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\. For the purposes of this example, we’ll be using the very popular Microsoft.SharePoint.dll. You can add a reference by right-clicking on References, choosing Add Reference and then browsing to the DLL you want.

3. At the top of your code (just below using mshtml;) add the following line. This simply provides a shortcut directly to the objects located in the Microsoft.SharePoint.dll to save you typing the entire namespace each time

using Microsoft.SharePoint;

You can now directly access the SharePoint object model. However a word of warning … not all forms are browser-based (this only works in browser-based forms), therefore it is wise to do a check in your code before using and SharePoint API calls. If you wish to design a form which utilises objects from the SharePoint API and can be authored using the InfoPath client you will need to connect to SharePoint web services (because the code is executing on eth client, not the server, therefore the full SharePoint API is not available).

4. Add the following code to your FormEvents_Loading method. This checks whether the form is browser-based or not:

if (this.Application.Environment.IsBrowser)
{
}

Now you can add your SharePoint code.

5. Add your SharePoint code within the if statement you created in step 4. For example this code will get the SPWeb object for the site that the form is being rendered from:

SPWeb web = SPContext.Current.Web;

Tip 2: Using Visual Studio 2008 to develop your forms

In addition to InfoPath 2007, it is now possible to develop develop InfoPath forms using Visual Studio 2008.

Visual Studio added full support for designing and developing InfoPath forms in the 2008 version. There is no major functionality over and above InfoPath 2007, it is just that your form project gets to be in the same Visual Studio solution as everything else and can be subject to the same source control etc and Visual Studio does also give you a slightly nicer development environment to work in.

Another benefit is that Visual Studio works directly with the source files of the form rather than the XSN (which is basically a zip file) this means that it is easier to do advance development where you regularly need to access specific files.

To try this out simply go to Visual Studio 2008 > File > New > Project > Office > InfoPath 2007 Form Template. You will then be presented with the same ‘Design a form template’ wizard that you would see if you had use InfoPath itself to design your form.

Tip 3: Saving a form where it was created by using the SaveLocation URL Parameter

One of the biggest issues with using the default ‘Submit …. To a document library on a SharePoint site’ data connection is that you are forced to hard-code a URL which means that forms will always be submitted to that location. This is fine for some scenarios, however I find it causes the following issues:

  • Complicates Dev > Live deployment
  • Forms often need to get submitted to the library where they were first created. This is especially true if you have published the form as a Content type or Administrator-approved form which can be re-used in multiple locations

Thankfully, using browser-based forms there is a way to get around this. With browser-based forms, there are a range of URL-based Input Parameters that contain parameters including the ‘SaveLocation’ which is the URL to the library where the form was first created. Using this parameter it is possible to intercept the FormEvents_Submit method and actually save the form to the location it was created rather than the hard-coded URL in the data connection.

To do this, follow these steps:

  1. Setup- a ‘Submit …. To a document library on a SharePoint site’ data connection as usual. Set a dummy URL as this will be over-written Call the data connection ‘SharePoint Library Submit’.
  2. Create a property in your form’s main data source called ‘MySaveLocation’. Please not that you could also use the FormState Dictionary to store this value (as outlined in Tip 5). We are only storing as a form property here to show different ways of doing things.
  3. Add the following code to your FormEvents_Loading method. This captures the Input Parameter and stores it in a form property called MySaveLocation.

XPathNavigator xn = this.MainDataSource.CreateNavigator();
XPathNavigator xnSaveLocation = xn.SelectSingleNode("/my:myFields/my:MySaveLocation", this.NamespaceManager);
if (this.Application.Environment.IsBrowser)
{
if (xnSaveLocation.Value == "")
{
xnSaveLocation.SetValue(e.InputParameters["SaveLocation"].ToString());

    }
}

4.Add the following code to your FormEvents_Submit method. This intercepts the operation of the data connection and replaces the URL with the contents of our MySaveLocation property:

XPathNavigator xn = this.MainDataSource.CreateNavigator();
XPathNavigator xnSaveLocation = xn.SelectSingleNode("/my:myFields/my:MySaveLocation", this.NamespaceManager);
FileSubmitConnection fc = (FileSubmitConnection)this.DataConnections["SharePoint Library Submit"]; //replace with with the name of your data connection
fc.FolderUrl = xnSaveLocation.Value.ToString();
fc.Execute();
e.CancelableArgs.Cancel = false;

 

When users submit the form, it will now be saved in the library where it originated, and not the hard-coded URL in the data connection.

Tip 4: Using the Contact Selector Control

Have you have ever wondered how to use the SharePoint Content Selector control in your forms? The guys on the InfoPath team blog wrote an article all about it: https://blogs.msdn.com/infopath/archive/2007/02/28/using-the-contact-selector-control.aspx 

My three pieces of advice are as follows:

1. Watch your case, ALL of this stuff is case sensitive

2. You do not need the context.xml file for browser-based forms

3. If you intend to use the control several times in the same form to store different contact details, you will need to create the data structure once and reference it elsewhere in your data structure. To do this right click on the gpContactSelector folder > Reference > Choose the location where you want to create the referenced properties.

Tip 5: Using the FormState Dictionary to store variables

As with any development projects there is usually a requirement to create member variables to prevent the creation of multiple objects storing the same data.

When you first create your code project to support your InfoPath form you will note a commented section which states member variables are not supported. Below is an example on how to use the FormState Dictionary to store objects which is the supported and recommended alternative to member variables.

In our experience developers do not make best user of the FormState dictionary so here’s a simple example which simple stored the current username as a FormState Dictionary Object:

  1. Create a dictionary object called ‘_currentUserId’. Add this code right beneath you main class declaration

private object _currentUserId
{
get
{
return FormState["_currentUserId"];
}
set
{
FormState["_currentUserId"] = value;
}
}

2. Set the value of the dictionary object. In this example we’ll do this in the FormEvents_Loading method. Add this code to your FormEvents_Loading method.

_currentUserId = this.Application.User.LoginName.ToString();

3. Now the dictionary object is set. you can refer to it in your code. This example simply adds the value to an InfoPath property.

XPathNavigator xn = this.MainDataSource.CreateNavigator();

XPathNavigator xnCurrentUser = xn.SelectSingleNode("//my:CurrentUser", this.NamespaceManager);
xnCurrentUser.SetValue(_currentUserId.ToString());

This is quite a rudimentary example but hopefully demonstrates a real world example of using the FormState Dictionary object. 

 

This article was co-authored by

Martin Kearn Senior Consultant Microsoft Consulting Services UK Martin.Kearn@Microsoft.com

Click here for my bio page

Jay Goodison Senior Consultant  Ascribe (Consulting Division) Jay.Goodison@Ascribe.com