In this short video demo, I show how you can add the ability to sort repeating tables in your forms using code. I use picture buttons in the heading of the repeating table to trigger the code which sorts the table based on the values in the columns.
About the Code
In a nutshell, the code puts the XML from the repeating table into an array, sorts the array using built-in .Net functionality, and then writes back into the XML to update the table.
//Sorts a repeating table. Takes the parent group node and the index of the column to sort by.
private void SortTable(string xpathToSort, int columnToSortBy)
{
//get the values in an array
string[][] ValuesToSort = GetRepeatingTableValues(xpathToSort);
//sort the array
Array.Sort(ValuesToSort, new StringArrayComparer(columnToSortBy));
//write the values back to the xml
SetRepeatingTableValues(xpathToSort, ValuesToSort);
}
//Takes an array of arrays and inserts it into a repeating table
//Assumes that the array and table are the same size
private void SetRepeatingTableValues(string xpathToSet, string[][] tableValues)
//Create a navigator on main node supplied in the parameters
XPathNavigator mainGroup = this.CreateNavigator().SelectSingleNode(xpathToSet, this.NamespaceManager);
//Clone the first child node of the main navigator and populate it with data
XPathNodeIterator tableRows = mainGroup.SelectChildren(XPathNodeType.Element);
//iterate through the existing XML and update the values from the sorted array
for (int i = 0; i < tableValues.Length; i++)
tableRows.MoveNext();
XPathNodeIterator thisRow = tableRows.Current.SelectChildren(XPathNodeType.Element);
for (int j = 0; j < tableValues[0].Length; j++)
thisRow.MoveNext();
thisRow.Current.InnerXml = tableValues[i][j];
//Returns an array of arrays of strings representing the values in a repeating table
private string[][] GetRepeatingTableValues(string xpathToGet)
XPathNavigator myNav = this.CreateNavigator();
int rows, cols;
XPathNodeIterator tableNodes;
//figure out the dimensions of the table
tableNodes = myNav.SelectSingleNode(xpathToGet, this.NamespaceManager).SelectChildren(XPathNodeType.Element);
rows = tableNodes.Count;
//move to the first row to count the columns
tableNodes.MoveNext();
cols = tableNodes.Current.SelectChildren(XPathNodeType.Element).Count;
//create an array to store the values
string[][] tableValues = new string[rows][];
//get all the rows in the table
//iterate through the rows and write the inner xml of each element in each row to the array
for (int i = 0; i < rows; i++)
XPathNodeIterator childNodes = tableNodes.Current.SelectChildren(XPathNodeType.Element);
string[] rowValues = new string[cols];
for (int j = 0; j < cols; j++)
childNodes.MoveNext();
rowValues[j] = childNodes.Current.InnerXml;
tableValues[i] = rowValues;
return tableValues;
//Comparison implementation for array or arrays
class StringArrayComparer : IComparer
private int iColumn;
public StringArrayComparer(int iColumn)
this.iColumn = iColumn;
int IComparer.Compare(Object x, Object y)
string[] xAsString = (string[])x;
string[] yAsString = (string[])y;
return xAsString[iColumn].CompareTo(yAsString[iColumn]);
Requirements for publishing your forms with code as Sandboxed solutions:
Complete sandboxed solution documentation is available here. Note that InfoPath takes care of packaging and activating the solution, all you need to do is publish your form to a document library or as a site content type.
I look forward to hearing your comments about this new feature. Let me know what you think!
Phil
Nice post.
I am working InfoPath 2010/SharePoint 2010 project, however, after adding developer tab, every menu items under developer tab is inactivate, gray-ed out.
Any idea ? Thanks.
Is it possible that you have not selected a programming language? If the "Language" button is enabled on the developer tab, try clicking it and selecting either C# or VB. Once you have selected a language, the buttons should be enabled. Let me know if that doesn't do the trick.
If you haven't selected a language, you might also not be using an InfoPath 2010 form template. For your form to be published as a Sandboxed solution, make sure the form template compatibility is set to "Web browser form" and not "Web Browser form (InfoPath 2007)" in the form options dialog. You'll also need to be sure you are using either C# or VB as the programming language and not the InfoPath 2007 versions. You can change this by clicking the language button in the ribbon or by going into the form options dialog.
Thanks Phil for your reply.
The problem as I just discovered that if your form template is SharePoint List, the developer tab does not work, however it works for SharePoint Form Library. so for SharePoint List template, there is no way to have managed code behind ?
I am working for BI consultant firm. I see InfoPath is a great way for data collection. without managed code behind, I see a hug limitation.
Thanks
Max
Unfortunately we were not able to support code behind list forms in InfoPath 2010. You could work around this by writing a Web service and calling it from the form or using sandboxed event handlers on the list if your code only needs to be run when an item is created or updated in the list.
Hi Phil, I tried your code but it crashes on the first compare when I try to preview the form. Should this work in preview or do I need to run it from the server? Also, does the data need to be submitted first?
Hello Phil,
First thank you for your effort in this article, second i have a problem to run this video.. Any idea to run it? sure i have silverlight installed on my machine and i have added silverlight.net in the trusted sites for the IE :(..
In fact I am a beginner in the sharepoint and infopath world, but I have good knowledge to work on it.
I was started with infopath and sharepoint 2007, and now I have upgrade to 2010 in both. I think cause I am a developer I like to develop my life with Code really I am very happy cause this feature is added to infopath ad sharepoint 2010. But I need a short and an effective way to get and collect knowledge in this feature if you can help me to get the best resource that can I use.
I look forward to hearing your comments about this
And thank you again….
Hello,
Nice post. I am trying to deploy an InfoPath browser enabled form using features as a sandbox solution and I am having some problems. Please see social.msdn.microsoft.com/.../76b28eec-0460-4d43-b6fe-9210d28b0dbc for more details. If you could help, I would be greatly appreciated.
Thanks,
Miguel
Written by an it'er
click, blabla, click, click