InfoPath - Get the row being edited in a repeating table programmatically
I recently came across an issue with an InfoPath Form, where an XML Document was being constructed in the background when certain fields were updated in the form template. The XML being generated was a CAML template to be submitted to SharePoint via web services, and contains a separate method for each row of a repeating table in the main data source of the form template. When a new row is added, a new "Method" element with a series of "Field" child elements are added to the XML document. As values of fields in the new row of the repeating table are updated, the fields within the corresponding "Method" element in the CAML template are updated with the new value. When an existing row in the repeating table is updated, the CAML template is also updated by finding the corresponding Method element and setting the new field values.
The issue I faced, was that I needed to know which row was being updated so that I could pass an identifier to the function that updates the CAML template. The first field in a row of the repeating table contains the value that uniquely identifies the current row, but is not always the field that has been updated.
My first attempt was to configure an event handler on the (non repeating) group in the main data source that contained the repeating table elements. Using this method, I was able to get the new value of a field that was updated, but not a reference to the row or field that was updated.
My solution was to add event handlers to each of the fields in a row of the repeating table, which then called a function that returns the value of the first (identifier) field. As the event handler was fired on the field that was updated, and not the row or repeating table container, I was able to move to the parent node using the XPathNavigator object, which was the row containing the updated field. From here, I was able to obtain the value of the first identifier field in the current row of the repeating table.
As I needed to incorporate the same logic in the event handler for each field in the repeating table, I wrote a separate function which is called by the event handlers, passing the XmlEventArgs object as a parameter. This meant that the event handler for each field could call the function instead of including a copy of the code in each. The value of the identifier field in this case is a string of characters and numbers.
C#: Function to get the value of a different field in the current/updated row of a repeating table.
public String getRowIdentifier(XmlEventArgs e)
{
if (e.Operation == XmlOperation.ValueChange)
{
XPathNavigator tmpNavigator = e.Site;
tmpNavigator.MoveToParent();
XPathNavigator tmpField =
xNavigator.SelectSingleNode("my:intID", NamespaceManager);
return tmpField.Value.ToString();
}
return "";
}
The event handlers then called the function as follows:
public void intItemUnits_Changed(object sender, XmlEventArgs e)
{
// Write your code here to change the main data source.
updateCAML(getRowIdentifier(e));
}
The Result:
When the event handler is fired for one of the fields in a row of the repeating table, the event handler calls the getRowIdentifier() function, passing the XmlEventArgs object. The getRowIdentifier() returns the value of the identifier field in the current/updated row of the repeating table, which is then used to find the corresponding "Method" element in the CAML template to update.
The updateCAML() function loops through each "Method" element in the XML document until it finds one that corresponds the the updated row of the repeating table by matching the identifier value. If found, each child element with the CAML "Method" element are updated to include the value from the corresponding field in the repeating table row. If the CAML template doesn't yet have a "Method" element for the modified row in the table, a new one is created and appended to the CAML template (XML Document).
For more information, see: Get the row being edited in a repeating table
SharePoint Workflow Development
Submit a review:
Login required.