Chapter 17. Dynamically Populate a Repeating Table

This chapter covers the steps necessary to dynamically populate a repeating table. Displaying data from a data source in a repeating table is fairly straightforward using rules and filters. However, in this overall scenario, you need to populate a repeating group in your form with data from a data source. The data is dependent on another selection in your form.

Changing the selection in the form queries the data source based on that selection and populates a repeating table with the data. If the selection changes, the repeating table entries need to be cleared and repopulated with the new set of data.

To clarify the data sources, the external data source is a secondary data source, and the repeating table is bound as a repeating group of fields in the main data source.

Set Up the Initial Form

To set up the initial form, follow these steps:

  1. Design a new form in InfoPath Designer 2010.
  2. Add a drop-down list control to the form and name the field accordingly. (For the example, I used Selection.)
  3. Add a repeating table to the form, selecting the number of columns as appropriate. Rename the fields accordingly. For this example, I kept the default of three columns and renamed only the repeating group to groupRepeat. Your form should now look similar to Figure 17.1.

    Figure 17.1. Adding the controls to the form performs the initial form setup.

    image

  4. Add a data connection to retrieve data for the selection field. Modify the selection field accordingly. For this example, I am retrieving Regions from a SharePoint list.
  5. Add a data connection to retrieve data for the population of the repeating table; let’s call this the dependent data source. For this example, I am retrieving Offices from a SharePoint list.
  6. Add a rule on the selection field such that when the selection changes you set the query field and query the dependent data source that you will use to populate the repeating table. For this example, I set the Region query field of the Offices data source to the selection field, as shown in Figure 17.2, to retrieve the related data.

    Figure 17.2. Setting the query field value retrieves the related data.

    image

  7. For testing purposes, drag the repeating group of the dependent data source onto the form.
  8. Preview the form and ensure that changing the selection changes the data source repeating table, as shown in Figure 17.3.

    Figure 17.3. Changing the selection field changes the data source repeating table.

    image

So now the challenge is to place those entries of the dependent data source into the repeating table of the form.

Create a Changed Event Method

Creating any methods produces code-behind in your form. For the overall scenario of this chapter, you need to generate a changed event method and place the code within that method.

For the example, select the drop-down list control and then click the Changed Event button on the Developer ribbon bar to generate the code-behind method, as shown in Figure 17.4.

Figure 17.4. Clicking Changed Event generates the code-behind method.

image

Note

To use code-behind, you need Microsoft Office Visual Studio Tools for Applications (VSTA) installed. If you do not have this installed, you may change the Microsoft InfoPath 2010 program in the Control Panel and select the VSTA option under Microsoft Office, Microsoft InfoPath, .NET Programmability Support.

The code is generated with an event handler declaration and a blank changed method, as shown in Figure 17.5.

Figure 17.5. Generating the code produces the event handler and changed method.

image

Create a Namespace Variable

Coding with InfoPath involves using XML/XPath objects and methods as well as XPath expressions. A key element in using the XML/XPath methods is the namespace that is used for the XML data retrieval. The NamespaceManager object enables you to look up the namespace. By default, the namespace in InfoPath data is my.

Because the namespace is used throughout various methods in this solution, the first line of code in the changed method is a string variable declaration, as shown in Listing 17.1.

Listing 17.1. Namespace Declaration

//Namespace variable
string myNamespace = NamespaceManager.LookupNamespace("my");

Access the Secondary Data Source

The next step in the overall solution is to declare objects based on the secondary data source. You need the name of the secondary data source and the XPath of the rows that are returned. To retrieve the XPath of the rows returned, follow these steps:

  1. Switch over to your InfoPath form.
  2. In the Fields pane, switch the data source to the secondary data source. (For this example, it is Offices.)
  3. Expand the datafields folder.
  4. Right-click the repeating group under the datafields folder and select Copy XPath to copy the XPath string to the Clipboard, as shown in Figure 17.6.

    Figure 17.6. Selecting Copy XPath places the XPath string into the Clipboard.

    image

  5. Switch back to the code-behind and paste the XPath into the code as needed.

The secondary data source setup code is shown in Listing 17.2. Paste the XPath from the previous steps into the XPathNavigator Select method. Place this block of code after the namespace variable.

Listing 17.2. Secondary Data Source Setup

  //Secondary data source setup
  DataSource ds = DataSources["OFFICES"];
  XPathNavigator domNav = ds.CreateNavigator();
  XPathNodeIterator rows = domNav.Select
("/dfs:myFields/dfs:dataFields/d:SharePointListItem_RW",
NamespaceManager);

Loop Through the Secondary Data Source

The loop is the main component of populating the repeating table. You loop through the secondary data source through the XPathNodeIterator collection (rows) that you defined in the previous section, retrieving the values from each row. The code to perform this is shown in Listing 17.3. Place this after the secondary data source setup. You will add more code to the loop in the next section.

Tip

Check the XPath of the secondary data source fields to determine how to call reference their nodes.

Listing 17.3. Loop Through the Secondary Data Source

//Loop through the secondary data source
while (rows.MoveNext())
{
string office = rows.Current.SelectSingleNode("D:TITLE",
NamespaceManager).Value.ToString();
      string region = rows.Current.SelectSingleNode("D:REGION",
NamespaceManager).Value.ToString();
      string id = rows.Current.SelectSingleNode("D:ID",
NamespaceManager).Value.ToString();
}

Note

The variables defined in the loop should correspond to the fields that are returned from the secondary data source.

Populate the Repeating Table

The repeating table is actually part of the main data source, so you can access that and use the XMLWriter to write the field values from the secondary data source to the table.

You will need the names of the groups and the fields that are bound to the repeating table in the form. In this example, the groups are group1 and groupRepeat, and the fields are field1, field2, and field3.

Place the code in Listing 17.4 within the while loop from the preceding section.

Tip

Copy the XPath from the repeating group to ensure the correct path is entered.

Listing 17.4. Populate the Repeating Table

//Populate the repeating table
using (XmlWriter writer = MainDataSource.CreateNavigator().SelectSingle-
Node("/my:myFields/my:group1", NamespaceManager).AppendChild())
{
     writer.WriteStartElement("groupRepeat", myNamespace);
     writer.WriteElementString("field1",myNamespace,office);
     writer.WriteElementString("field2", myNamespace,region);
     writer.WriteElementString("field3", myNamespace,id);
     writer.WriteEndElement();
     writer.Close();
}

Note

The order in which you write the values to the table should be the order that they appear in the main data source. Otherwise, you will receive a non-datatype schema validation error.

Clear Previous Entries

If you preview the form at this point, you will notice that every time you select a value from the selection drop-down, the repeating table is populated with more and more entries (along with a blank row at the top). You therefore need to clear any previous entries before the repeating table is populated. Place the code listed in Listing 17.4 somewhere before the while loop.

Listing 17.4. Clear Previous Entries

//Clear previous entries
XPathNavigator rTable = MainDataSource.CreateNavigator();
XPathNodeIterator tableRows =
rTable.Select("/my:myFields/my:group1/my:groupRepeat",
NamespaceManager);
if (tableRows.Count > 0)
{
   for (int i = tableRows.Count; i > 0; i--)
  {
     XPathNavigator reTable = MainDataSource.CreateNavigator();
     XPathNavigator reTableRows =
reTable.SelectSingleNode("/my:myFields/my:group1/my:groupRepeat[" + i
+ "]", NamespaceManager);
     reTableRows.DeleteSelf();
   }
}

What Does the Final Solution Look Like?

When all the code has been entered into the method properly, previewing the form populates the repeating table based on the selection in the drop-down, as shown in Figure 17.7.

Figure 17.7. Changing the selection populates the repeating table.

image

Listing 17.5 shows the full code listing for the changed method.

Listing 17.5. Fully Changed Method

public void selection_Changed(object sender, XmlEventArgs e)
        {

            //Namespace variable
            string myNamespace = NamespaceManager.LookupNamespace("my");

            //Clear previous entries
            XPathNavigator rTable = MainDataSource.CreateNavigator();
     XPathNodeIterator tableRows =
rTable.Select("/my:myFields/my:group1/my:groupRepeat",
NamespaceManager);
            if (tableRows.Count > 0)
            {


                for (int i = tableRows.Count; i > 0; i--)
                {
                    XPathNavigator reTable =
                    MainDataSource.CreateNavigator();
                    XPathNavigator reTableRows =

                    reTable.SelectSingleNode
("/my:myFields/my:group1/my:groupRepeat[" + i + "]",
NamespaceManager);
                    reTableRows.DeleteSelf();
                }
            }

            //Secondary data source setup
            DataSource ds = DataSources["Offices"];
            XPathNavigator domNav = ds.CreateNavigator();
            XPathNodeIterator rows = domNav.Select("/dfs:myFields/
dfs:dataFields/d:SharePointListItem_RW", NamespaceManager);


            //Loop through the secondary data source
            while (rows.MoveNext())
            {
                string office =
rows.Current.SelectSingleNode("d:Title",
NamespaceManager).Value.ToString();
                string region = rows.Current.SelectSingleNode("d:Region",
NamespaceManager).Value.ToString();
                string id =

rows.Current.SelectSingleNode("d:ID",
NamespaceManager).Value.ToString();

             //Populate the repeating table
             using (XmlWriter writer =

MainDataource.CreateNavigator().SelectSingleNode("/my:myFields/
my:group1", NamespaceManager).AppendChild())
        {
           writer.WriteStartElement("groupRepeat", myNamespace);
           writer.WriteElementString("field1", myNamespace, office);
           writer.WriteElementString("field2", myNamespace, region);
           writer.WriteElementString("field3", myNamespace, id);
           writer.WriteEndElement();
           writer.Close();
        }

            }

        }

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.248.37