InfoPathDev is a free resource, dedicated to bringing Microsoft InfoPath users the information and tools they need to be successful in their projects.
You can also follow InfoPathDev on Twitter.
This week’s post continues the theme of SharePoint list customization. In this short video demo, Roberto Taboada from the InfoPath program management team shows how you can quickly and easily re-use your customized SharePoint lists by packaging them as SharePoint list templates. This is a really powerful feature as it allows you to build and customize your SharePoint solutions once and re-use them as many times as you want.
To learn more about customizing your SharePoint list forms in InfoPath, check out our earlier blog posts on the subject.
This week’s cool InfoPath form is a browser form used to run a bracket tournament at Microsoft. The form uses filtered dropdowns to let users make their picks for NCAA March Madness 2010, and uses conditional formatting to show correct and incorrect picks as the tournament progresses. There’s also a printable view that shows the full bracket on one page, making it easy to print your bracket and show it off to your co-workers.
The form contains several data connections to SharePoint lists containing participants and results, which means that updating the results is as simple as editing a SharePoint list item, and doesn’t involve changing the form at all.
Edit View (click to see larger image):
Display View (click to see larger image):
Print View (click to see larger image):
For details on how we created the filtered dropdowns in this form, see Use Rules and Filters to Create Cascading Dropdowns.
If you have a “cool” form that you would like to share with us, please send an e-mail with the following details to coolform@microsoft.com -
The most popular submissions will be featured on our blog in future posts.
Check out other Cool Forms! here.
Hello, my name is Christopher Brotsos, and I’m a Program Manager on the InfoPath team. In this post, I’m going to show you how to add business logic to your forms using managed code.
Imagine a scenario where the accounting department at Contoso, Inc. tracks corporate assets through an Asset Management System built on SharePoint. One module in the system allows employees to order office equipment such as laptops, conference phones, and ergonomic chairs through an InfoPath form. At first, the order form was built using only declarative logic. It could enforce required fields, surface validation messages, and submit the form to SharePoint without any code.
As the ordering process grew more complex, users started adding additional requirements to the system. The variety of inventory available to employees increased, so they wanted a way sort items by name and description real-time in the order form. Contoso also started shipping their office equipment out of three warehouses. This prevented the warehouse crew from fulfilling complete orders, and as such, the system needed to track shipping status and quantity of individual items in the order. To meet the new requirements, Contoso added the following features to the form:
Sort interfaces, sophisticated submit routines, and database (i.e. list) management are common requirements for forms. Fortunately, this functionality can be added to InfoPath forms with a few lines of code. Let me explain these features, the code required to build them, and the prerequisites for developing managed code in InfoPath in more detail.
The Equipment Request Form enables users to sort through Contoso’s available inventory and submit a request to the warehouse for shipping.
The order form is a repeating table, where each row in the table represents the name, description, and quantity of the item being ordered.
The Equipment Order Form has a Picture Button Control displaying an arrow next to each of the column labels.
The buttons are used to sort the order items in ascending order by the respective column. When the user clicks the button, the values in the selected column are compared, and the rows of data are sorted based on the comparison result.
The sorting routine in this example is based on a complete solution provided by Hagen Green. Read through his post to learn how to provide a descending sort which also takes localization and data types into consideration.
private string GetValue(string xpath) { // return the value of the specified node XPathNavigator myNav = this.MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager); if (myNav != null) return myNav.Value; else return ""; } private void Swap(string xpath1, string xpath2) { // swap two rows of the table XPathNavigator item1 = this.MainDataSource.CreateNavigator().SelectSingleNode(xpath1, NamespaceManager); XPathNavigator item2 = this.MainDataSource.CreateNavigator().SelectSingleNode(xpath2, NamespaceManager); if (item1 != null && item2 != null) { // Make a copy of item1 // Move item2 to item1 // Make the original item2 be item1 that we cloned earlier XPathNavigator item1Clone = item1.Clone(); item1.ReplaceSelf(item2); item2.ReplaceSelf(item1Clone); } } private void SortOrder(string sortBy) { string itemsToSort = "/my:myFields/my:Order/my:OrderItem"; XPathNodeIterator items = this.MainDataSource.CreateNavigator().Select(itemsToSort, NamespaceManager); if (items != null) { int numItems = items.Count; // basic bubble sort implementation for (int i = 1; i < numItems; i++) // xpath is 1-based { for (int j = i + 1; j <= numItems; j++) { // swap (i,j) if necessary string iValue = GetValue(itemsToSort + "[" + i + "]" + sortBy); string jValue = GetValue(itemsToSort + "[" + j + "]" + sortBy); if (String.Compare(iValue, jValue, true) > 0) Swap(itemsToSort + "[" + i + "]", itemsToSort + "[" + j + "]"); } } } } public void ItemNameSort_Clicked(object sender, ClickedEventArgs e) { // Sort order by ItemName // Repeat this code for the other buttons string sortBy = "/my:ItemName"; SortOrder(sortBy); }
private string GetValue(string xpath)
{
// return the value of the specified node
XPathNavigator myNav = this.MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);
if (myNav != null)
return myNav.Value;
else
return "";
}
private void Swap(string xpath1, string xpath2)
// swap two rows of the table
XPathNavigator item1 = this.MainDataSource.CreateNavigator().SelectSingleNode(xpath1, NamespaceManager);
XPathNavigator item2 = this.MainDataSource.CreateNavigator().SelectSingleNode(xpath2, NamespaceManager);
if (item1 != null && item2 != null)
// Make a copy of item1
// Move item2 to item1
// Make the original item2 be item1 that we cloned earlier
XPathNavigator item1Clone = item1.Clone();
item1.ReplaceSelf(item2);
item2.ReplaceSelf(item1Clone);
private void SortOrder(string sortBy)
string itemsToSort = "/my:myFields/my:Order/my:OrderItem";
XPathNodeIterator items = this.MainDataSource.CreateNavigator().Select(itemsToSort, NamespaceManager);
if (items != null)
int numItems = items.Count;
// basic bubble sort implementation
for (int i = 1; i < numItems; i++) // xpath is 1-based
for (int j = i + 1; j <= numItems; j++)
// swap (i,j) if necessary
string iValue = GetValue(itemsToSort + "[" + i + "]" + sortBy);
string jValue = GetValue(itemsToSort + "[" + j + "]" + sortBy);
if (String.Compare(iValue, jValue, true) > 0)
Swap(itemsToSort + "[" + i + "]", itemsToSort + "[" + j + "]");
public void ItemNameSort_Clicked(object sender, ClickedEventArgs e)
// Sort order by ItemName
// Repeat this code for the other buttons
string sortBy = "/my:ItemName";
SortOrder(sortBy);
public void FormEvents_Submit(object sender, SubmitEventArgs e) { // Loop through each item-quantity pair in the order form. // Submit pairs to the Equipment Shipping list. // Note: Workflow will handle updating item quantities and track shipping status. using (SPSite mySite = new SPSite(ServerInfo.SharePointSiteUrl.ToString())) { using (SPWeb myWeb = mySite.OpenWeb()) { XPathNodeIterator orderItems; if (myWeb != null && myWeb.Lists["Equipment Shipping"] != null) { SPList shippingList = myWeb.Lists["Equipment Shipping"]; myWeb.AllowUnsafeUpdates = true; orderItems = this.MainDataSource.CreateNavigator().Select("/my:myFields/my:Order/my:OrderItem", NamespaceManager); if (orderItems != null) { while (orderItems.MoveNext()) { // Add rows from the form where user selected an item and specified a quantity. string itemName = orderItems.Current.SelectSingleNode("./my:ItemName", NamespaceManager).Value; string itemQuantity = orderItems.Current.SelectSingleNode("./my:ItemQuantity", NamespaceManager).Value; if (itemName != string.Empty && itemQuantity != string.Empty) { SPListItem shipItem = shippingList.AddItem(); shipItem["Title"] = itemName; shipItem["Quantity"] = itemQuantity; shipItem.Update(); } } } //cleanup //signal successful submit //return myWeb.AllowUnsafeUpdates = false; e.CancelableArgs.Cancel = false; return; } } } }
public void FormEvents_Submit(object sender, SubmitEventArgs e)
// Loop through each item-quantity pair in the order form.
// Submit pairs to the Equipment Shipping list.
// Note: Workflow will handle updating item quantities and track shipping status.
using (SPSite mySite = new SPSite(ServerInfo.SharePointSiteUrl.ToString()))
using (SPWeb myWeb = mySite.OpenWeb())
XPathNodeIterator orderItems;
if (myWeb != null && myWeb.Lists["Equipment Shipping"] != null)
SPList shippingList = myWeb.Lists["Equipment Shipping"];
myWeb.AllowUnsafeUpdates = true;
orderItems = this.MainDataSource.CreateNavigator().Select("/my:myFields/my:Order/my:OrderItem", NamespaceManager);
if (orderItems != null)
while (orderItems.MoveNext())
// Add rows from the form where user selected an item and specified a quantity.
string itemName = orderItems.Current.SelectSingleNode("./my:ItemName", NamespaceManager).Value;
string itemQuantity = orderItems.Current.SelectSingleNode("./my:ItemQuantity", NamespaceManager).Value;
if (itemName != string.Empty && itemQuantity != string.Empty)
SPListItem shipItem = shippingList.AddItem();
shipItem["Title"] = itemName;
shipItem["Quantity"] = itemQuantity;
shipItem.Update();
//cleanup
//signal successful submit
//return
myWeb.AllowUnsafeUpdates = false;
e.CancelableArgs.Cancel = false;
return;
Along with the features covered above, you’ll find that code is useful for implementing complex data validation logic and managing content from multiple data sources. Such requirements are especially common when your forms are part of an advanced application. You can learn more about validation and working with the InfoPath DOM in our MSDN XmlEvent.Validating documentation and our post on working with InfoPath data sources programmatically. You can also review the InfoPath and SharePoint object models on MSDN for a more granular view into programming with InfoPath 2010.
If you’d like to get started with programming in InfoPath, then please read on. The rest of this post introduces our system requirements, integrated development environment, and programmability user experience.
To add code to an InfoPath form:
The minimum system requirement to get started with InfoPath 2010 development is Microsoft .NET Framework 2.0, but we suggest you install Microsoft .NET Framework 3.5 SP1 if you’re developing for the SharePoint platform. You can install all versions of Microsoft .NET Framework from http://www.microsoft.com/downloads.
Visual Studio Tools for Applications (VSTA) is an optional installation component available in Microsoft Office 2010 setup. To install VSTA:
InfoPath 2010 allows you to program in C# and Visual Basic .NET. If you want to program with Visual Basic, you do not need to do anything to select your programming language when designing InfoPath 2010 compatible forms. If you plan on programming with C#, or adding code to InfoPath 2007/2003 compatible forms, you can change the programming language by clicking the Language button in the Code group of the Developer tab.
After you click the Language button, you can change your programming language by using the Form template code language drop down:
Hint: You can change the default language for InfoPath 2010 compatible forms by using the Options menu in the Backstage.
The Developer tab is the primary entry point for programming in InfoPath 2010. It’s designed to help you add event handlers compatible with the controls and mode of the form you are designing. For example, if you don’t have a control selected on your form view, then you’ll only be able to select the events that apply to the entire form. Notice that the Loading and View Switched event below are enabled, but the entire Control Events group is disabled.
But, as soon as I select a text box on the form, the Control Events group lights up.
Notice that the Sign, Context Changed, and Changing events are disabled in both screenshots of the Developer tab. That’s because I’m working with a browser compatible form, and those events are only available for InfoPath Filler forms.
Note: You’ll find a table of all events, and their compatibility, towards the end of this section.
Certain control and form programming events can be accessed through buttons on other tabs in the ribbon. If you add a Picture Button control on the form view, highlight the button, and then click on the Properties tab then you’ll find the Custom Code button enabled. Clicking the Custom Code button in the ribbon will add an OnClick event for the Picture Button control.
In the Equipment Order Request form, we added a Submit event handler to add items to a SharePoint list. To do this, navigate to the Data tab, and click the Submit Options button in the Submit Form group.
This will launch the Submit Options dialog where you can check “Allow users to submit this form”, “Perform custom action using Code”, and then click the Edit Code button.
The Fields task pane is another main entry point to add event handlers. In the next screenshot, I access the Validating and Changed events for ItemDescription by right clicking the field in the Fields task pane and scrolling through its context menu.
The following tables provide a list of all events and compatibility in InfoPath 2010. Note that InfoPath forms trigger three types of events: Form Events, Data Events, and Button Events. Aside from the button event, InfoPath event handling is different from other web programming paradigms (e.g. WinForm and HTML forms); events are fired when the data changes, not when control state changes. As such, you should consider the optimal configuration for your forms’ post-back settings to provide the best performance while still ensuring that events get fired when necessary. See our performance post on MSDN to learn more about general performance and event handler post-backs.
After you’ve designed your form and authored the source code, the final step is to publish the form. Your InfoPath form with code can be published to SharePoint and to client machines, but you need to make a security decision before you publish: configure the form as domain trust or full trust.
Domain trust forms can be published to SharePoint as Sandboxed Solutions directly from the InfoPath 2010 Designer. With Sandboxed Solutions, SharePoint Server farm administrators can restrict the resources available to the code and developers cannot access resources subject to operating system security. This establishes a safe environment where Site Collection administrators can publish code to SharePoint without the overhead of administrator approval! For more details about Sandbox Solutions (and another method for sorting repeating tabular data), see our Introduction to Sandboxed Solutions post from Phil Newman.
Note: Publishing full trust forms to a client-side environment requires that the form is signed with a code-signing certificate or installed through a custom MSI built in Visual Studio. Publishing a full trust form to SharePoint requires a farm administrator to activate the solution through the SharePoint Central Administration portal.
Best Practice: You should always use the lowest level of trust possible when publishing forms.
Most forms you design with InfoPath 2010 are not going to require code, but when they do, just install Visual Studio Tools for Applications and you’re ready to start programming. To add code, select the language of your choice, and use entry points in the Ribbon and Fields task pane to automatically insert event handlers. Finally, decide whether or not your form requires full-trust, and publish it to SharePoint or a client environment accordingly. If you’re interested in learning more about the InfoPath and SharePoint programmability, please visit http://www.msdn.com and keep checking for updates here on the InfoPath blog.
In this week's “5 for forms” video demo, Trey Brumley, a software design engineer in test shows how you can use InfoPath to customize the form for an external list on SharePoint that connects to a SQL Employee database through Business Connectivity Services.
This week’s cool InfoPath form is a simple form that we’re using for each team in Office to sign off that Office 2010 is ready to ship. One of the neat things about this form is that it makes the signoff process a visual experience by using conditional formatting to show and hide pictures based on the status.
The form also contains rules to enforce that final signoff can only happen once both bug and testing signoffs have been completed.
Thanks!
The InfoPath Team
The InfoPath Solution Video Contest is over! We assembled the team last Friday, and screened the final submissions, debated, re-watched, debated, re-screened again, and finally voted to determine the winners.
Before we announce the winners, let’s review the contestants. At final count at the close of the contest (midnight on March 1st ), we had received three submissions:
Author: Clayton Cobb
Company: Planet Technologies
Clay’s solution allows members of his “company” (including his 3 year old son!) to submit a request for time off. Employee information, including vacation balances, are stored in a SQL server database, which is modelled in Business Connectivity Services and exposed on SharePoint as an External List. Clay used an InfoPath Form Library form, which queries data from the external list using a SharePoint List data connection. A SharePoint workflow routes approval and other notifications via e-mail, and then updates the External list with a new vacation balance once the request is approved.
Click the image to view Clay’s submission
Author: Eric Raarup
Company: Inetium
Elle is a knowledge management solution which uses a cool Silverlight interface to knit together a complex solution involving projects in Dynamics CRM and employees in Dynamics GP, exposed in SharePoint using Business Connectivity Services, with InfoPath forms for data input.
Click to view the Inetium submission:
Author: Estyn Edwards
Company: Iomer Internet Solutions
Estyn’s submission is a prototype created for a client of the Edmonton-based Iomer solutions. The grant proposal system features a multi-view InfoPath form, and a Word document which uses content controls to populate a custom XML document in an OpenXML file. The Word document allows users to author large amounts of rich content, including ad-hoc commenting and change tracking. At the end of the process, custom code in SharePoint shreds the XML out of the Word document and injects the content into the InfoPath form for final verification and printing.
Click below to view Estyn’s submission:
After several viewings and a lively discussion, 17 InfoPath team members voted on the three submissions to determine the final prizes. There were passionate proponents of each of the submitted videos. When the votes were tallied up, the standings were as follows:
Eric Raarup of Inetium takes the top prize and walks away with the Xbox 360 Elite! The slick presentation of the video, the impressive solution to the knowledge-mining problem, and the clean integration of a bewildering array of Microsoft technologies makes Inetium the clear winner here.
Clayton Cobb of Planet Technologies takes this prize for his clever integration of external lists with SharePoint workflow and InfoPath forms. Because Clay was the runner-up in two categories, he takes his choice of either an InfoPath-branded North Face jacket, or a Zune HD.
Estyn Edwards takes this prize for his attractive InfoPath forms and the innovative use of Word to enable collaborative authoring of a large volume of rich text. Estyn will have second choice of either the InfoPath-branded North Face jacket or the Zune HD.
Thanks to our three participants, and congratulations!
For those of you who did not submit a video for the contest, we’re still interested in seeing the great solutions you build using InfoPath and SharePoint 2010. Post your videos on any public video hosting site, and send a pointer to the e-mail address listed in the official contest rules. The best videos will be showcased in this blog.
-Nick Dallett
Program Manager Lead
Microsoft InfoPath
Hi, my name is Anson Hidajat and I’m a program manager on the InfoPath team. In this week's “5 for forms” video demo, I will show how you can use rules and filters to create cascading dropdown lists in a tennis tournament bracket application.
Enjoy and please send us your feedback!