>
Blog
Book
Portfolio
Search

7/19/2006

11629 Views // 0 Comments // Not Rated

InfoPathology - Part 4 - Populating Repeating Tables

Repeating tables are beautiful things. It is the most elegant implementation of dynamic data inputting I've ever seen. However, the beauty quickly fades after going from the UI to the code behind. To start, simply enumerating a table is onerous enough. This entails getting into the InfoPath DOM, and literally looping through the auto-generated XML using an XPath query.

So if we only need to iterate a column in a table looking for a particular value, then this isn't too bad. But consider nested tables. Then consider repeating nested tables. Then consider repeating nested tables in conditional repeating sections. Then consider dropdown lists that need to be filled and button clicks that need to be handled in repeating nested tables in conditional repeating sections. This code will get really messy really fast.

Going up a level, and really coming to the first non-intuitive sub topic here, we have row isolation. If there is a control in a row of a repeating table, and the user creates new rows, InfoPath considers each control to be the same; if a textbox, for example, appears in fifty rows, there will be fifty values in the XML, but only one event handler, one set of rules, and one arrangement of conditional formatting.

This, or course, raises the question: how can it be determined which dropdown list was changed, or which button was clicked? Without a little "InfoPath magic," there is not enough known to properly handle an event. Here is how I isolate a row in a repeating table:

  1. Create your table.  For this brief example, we'll use a textbox and a button.
  2. Create a hidden textbox outside of the table.  This will be our event handler.
  3. Open the rules for the button.  Create a rule that sets the value of the hidden text box equal to the value of the textbox in the table.  You will notice that there is only one entry for this textbox in the field selector.  The context of the button click (or any event) is the row that is in focus.  Therefore, selecting this field is selecting the value of the textbox in the row in which the event occurred.
  4. This will fire the event of the hidden textbox.  Use rules or the event handler for this control to perform whichever action is necessary on the value.  This textbox can be used over and over again to represent any value in that row.  This is how the isolation is performed.
  5. Finally, use the rules or event handler of the button click to update any of the controls in the row with the new value of the hidden textbox.  Remember: rules fire before the event handler, so keep this in mind as you react to events.

Not too bad. Now, the final challenge of repeating tables is their auto-population. Like I said, repeating tables are great for letting users create as many rows as they need. However, can code-behind perform the same feat? Well, it can, but it takes quite an effort. I spent a lot of time digging through the InfoPath API and its documentation, but no obvious solutions presented themselves. I tried adding nodes to the table, manually manipulating the XML, and creating new controls. Nothing worked.

So here is how I auto-populate a repeating table:

Code Listing 1

  1. <data>
  2. <column_1_values>
  3. <column_1_value></column_1_value>
  4. <column_1_value></column_1_value>
  5. </column_1_values>
  6. <column_2_values>
  7. <column_2_value></column_2_value>
  8. <column_2_value></column_2_value>
  9. </column_2_values>
  10. </data>
  • Save it somewhere in the C:\ drive.  I use C:\Temp\Data.xml as my path for this file.
  • Create a data connection to read data from this file.
  • Create a repeating table.
  • Create a hidden textbox of type integer, and set the default value to zero.  Set one rule that queries the data connection from step three.
  • Create a second hidden textbox that takes a string.
  • Rebind each control in the repeating table to an element in the text file's schema.
  • In a web service or by some other mechanism, get the raw data that will fill the table into the form.
  • In the form's OnLoad method, after the raw data has been downloaded, add logic that creates the data file in the path that the InfoPath data connection is looking for.  Then, format the raw data to fit in the XML, write the tags to the file, and save and close it.
  • Add one to the value of the first hidden textbox to fire its rules.  This auto-populates the table.
  • Save the XML string that was written to the file to the second text box.  This will allow us to quickly rebuild the table in future form usage; we only have to download the data once (as long as it doesn't change).
  • If the user will be able add more rows to the table, we need go one step further.  Nest our repeating table into the first row of an outer repeating table.  Format the cell spacing, padding, and borders in both tables to make the separation between them seamless.  Finally, lock down the inner auto-generated table so that the user cannot add rows; they will add rows to the outer table.  
  • Clean up: delete this file upon form submits or closures.
  • No Tags

    No Files

    No Thoughts

    Your Thoughts?

    You need to login with Twitter to share a Thought on this post.


    Loading...