Monday, May 5, 2014

SharePoint InfoPath 2010: C# populate rows in a repeating table

I had an InfoPath form where I needed to have 2 views. In the 2nd view, some information in the repeating table would be automatically populated based on the information entered in the first view.

Initially I wanted to use a rule-only approach but it ended up being too cumbersome; I had to resort to code :(

I will use a time card with date range as an example here. The repeating table will have one row for each day within the date range I have selected.



Structure of my repeating table:


Here is the code that does all the magic. I have created it as an event triggered when a view is switched.

Function to append a child node:

     public void AddDetailField(XmlDocument doc, XmlNode group, string fieldName, string fieldValue)  
     {  
       XmlNode field = doc.CreateElement(fieldName, NamespaceManager.LookupNamespace("my"));  
       XmlNode node = group.AppendChild(field);  
       node.InnerText = fieldValue;  
     }  

Function to populate the repeating rows in infopath form. Take note that the first child node needs to be removed.

     public void AutoPopulateTimeSheet(XPathNavigator nav)  
     {  
       string start = nav.SelectSingleNode("/my:myFields/my:Data/my:StartDate", this.NamespaceManager).Value;  
       string end = nav.SelectSingleNode("/my:myFields/my:Data/my:EndDate", this.NamespaceManager).Value;  
       DateTime dtStart = Convert.ToDateTime(start);  
       DateTime dtEnd = Convert.ToDateTime(end);  
 
       // Delete first row  
       XPathNavigator itemNav = nav.SelectSingleNode(  
         "/my:myFields/my:Details/my:Detail[1]", NamespaceManager);  
       // Delete the row  
       if (itemNav != null)  
         itemNav.DeleteSelf();  
       foreach (DateTime day in EachDay(dtStart, dtEnd))  
       {  
         // Create group  
         XmlDocument doc = new XmlDocument();  
         XmlNode group = doc.CreateElement("Detail", NamespaceManager.LookupNamespace("my"));  
         // Add fields  
         string dayOfWeek = GetDay(day);  
         AddDetailField(doc, group, "Date", day.ToString("yyyy-MM-dd"));  
         AddDetailField(doc, group, "Day", dayOfWeek);  
         if (regular.ToLower().Equals("true") && !(dayOfWeek.Equals("Sat") || dayOfWeek.Equals("Sun")))  
         {  
           AddDetailField(doc, group, "Regular", "8");   
         }  
         else  
         {  
           AddDetailField(doc, group, "Regular", "0");  
         }  
         AddDetailField(doc, group, "Makeup", "0");  
         AddDetailField(doc, group, "DoubleTime", "0");  
         AddDetailField(doc, group, "OverTime", "0");  
         AddDetailField(doc, group, "Vacation", "0");  
         AddDetailField(doc, group, "PTO", "0");  
         AddDetailField(doc, group, "Holiday", "0");  
         AddDetailField(doc, group, "Bereavement", "0");  
         AddDetailField(doc, group, "Jury", "0");  
         AddDetailField(doc, group, "TimeWOPay", "0");  
         AddDetailField(doc, group, "WorkComp", "0");  
         AddDetailField(doc, group, "ServiceAward", "0");  
         AddDetailField(doc, group, "Total", "0");  
         doc.AppendChild(group);  
         nav.SelectSingleNode(  
           "/my:myFields/my:Details",  
           NamespaceManager).AppendChild(doc.DocumentElement.CreateNavigator());  
       }  
     }  

Lastly, the view switched event:

     public void FormEvents_ViewSwitched(object sender, ViewSwitchedEventArgs e)  
     {  
       XPathNavigator nav = this.MainDataSource.CreateNavigator();  
       string company = nav.SelectSingleNode("/my:myFields/my:Controls/my:Company", this.NamespaceManager).Value;  
       // if workflow has not kicked off and filled this hidden value, means user is submitting for the first time  
       if (string.IsNullOrEmpty(company) && this.CurrentView.ViewInfo.Name.Equals("Details"))  
       {  
         AutoPopulateTimeSheet(nav);  
       }  
     }  

Note: Including code-behind in InfoPath will elevate them to administrator approved forms. You can't publish them directly to a Form library. You will need to upload the form using Central Administration.

No comments:

Related Posts Plugin for WordPress, Blogger...