Greg Collins
in

InfoPath Dev

Qdabra® qRules

This Blog

Syndication

Greg Collins

  • Swap the AD Alias and Name Fields in Place

    In this tutorial you will learn how to use perform an in-place swap of an Active Directory alias and display name so as to conserve space in the view. This sample uses a text field and a button along with conditional formatting, rules and data validation to keep things running smoothly.

     

     

    While this solution is not for everyone, it will come in very handy for some of you with tight space requirements.

    Start a new form:

    1.       Create a new blank form.

    2.       Add a Receive data connection to the GetUserInfo method of the Qdabra AD Web Service.

    a.       Set it to NOT automatically retrieve data when the form is opened.

     

    Create the schema:

    1.       In the Data Source task pane, add the following text fields: Title, Subtitle, Author, Coauthor, Year, and Description.

    2.       Add the following text and Boolean attributes to Author and Coauthor schema nodes: displayName, isEditing (default to TRUE).

     

    Design the view:

     

    1.       Drag myFields into the view and select Controls In Layout Table.

    2.       Edit the properties for both Author and Coauthor fields to:

    a.       Add data validation to show the ScreenTip “Invalid Alias” when isEditing is FALSE and displayName is blank and respective Author and Coauthor is not blank.

    b.      Add a rule to set the GetUserInfo username query field with the value from Author and Coauthor respectively.

    c.       Add a rule to query GetUserInfo.

    d.      Add a rule to set displayName with Value (from the GetUserInfo data connection) filtered on Key=“displayName”.

    e.      Add a rule to set isEditing to “false”.

    f.        Add conditional formatting to hide the field when the isEditing is FALSE and displayName is not blank.

    3.       Add buttons below the Author and Coauthor fields in the table and edit their properties to:

    a.       Set the respective label with the values of the Author/displayName and Coauthor/displayName.

    b.      Name the respective ID value to btnEditAuthor and btnEditCoauthor.

    c.       Add a rule to clear the respective Author and Coauthor value.

    d.      Add a rule to set the respective isEditing to “true”.

    e.      Add conditional formatting to hide the button when the respective isEditing is TRUE.

    f.        Add conditional formatting to hide the button when the respective isEditing is FALSE and displayName is blank.

    g.       Set the width to 100%.

     

    Preview the form and test. You can apply other formatting to the button as you like, such as removing the border and background shade, and manually left-justifying the text in the expanded view .XSL file.

     

     

    You can download the sample form I created for this article from here: http://www.infopathdev.com/files/folders/examples/entry47771.aspx

  • Create a Split Public/Private Form

    There is sometimes a need to have a form that works differently for public (external) vs. private (internal) use. As an example, you might want to make a simple form to be sent out via email or downloaded from a website and submits back to you via email. This could be a survey, an order form, a signup, or whatever. But once you get it back, you want to have more functionality available to you, including the ability to submit to an internal database, etc.

    In essense you have two separate forms, one for public consumption, and one for private. These can have different security modes. The public form can be restricted security, while the private form can be domain or full trust security. For this to work, InfoPath needs to consider these two forms one-and-the-same. Let's look at how you would do this.

    In the form properties dialog box (File | Properties), in the Form Template Properties section, you will find fields for Name, ID and Description. The ID is used to determine which template a form will be opened with. But this ID is dynamic. As the Name changes, so does the ID. And every time you do a Save As the Name and ID are changed. Publishing the form, however, doesn't affect the Name and ID.

    The key is that both forms have the same ID and that your private form has a higher form version number than the public form. After you've created both versions of your form, you will tell InfoPath they are the same form by setting both of their IDs to the same value. Ensure that your private form has a higher version number by updating it from 1.0.0.x to 1.0.1.x. This will ensure that your private form is always newer than your public form, and InfoPath will try to upgrade the public form to the private form because of its newer version.

    Then you can send the public form out via email or post it for download. When the user submits via email, you will click the Open Form button at the top of the Outlook message, which will open the form using the internal template. You might be presented with a dialog notifying you of a form template conflict. This will occur if you've had both forms open on your computer--since both have the same id. You can choose which template to open the form with--which will be the internal form to further process the data sent by the public user.

  • Display a Save As Dialog Box

    If your form template is set to full trust security, InfoPath provides the Save() and SaveAs() methods for you to save your form via code. Although InfoPath does not provide a method for you to display the Save As dialog box to the user, it is possible to do this using managed code and the .NET Framework.

    In this task, we will create a simple full trust form with a button that will display a standard Save As dialog box, and then save the form. To complete this task, you will need to have installed a copy of Visual Studio .NET, the InfoPath Toolkit for Visual Studio .NET, and the InfoPath Software Development Kit. We will use RegForm.exe to create a full trust installation package for our form template.

    Create a new InfoPath managed code project:

    1. Launch Visual Studio.
    2. Choose New | Project from the File menu.
    3. In the Project Types tree of the New Project dialog box, expand Microsoft Office InfoPath Projects, and then select Visual C# Projects.
    4. In the Templates list, select InfoPath Form Template.
    5. Name your project SaveAsDialog (as shown in Figure 1), click OK, and then click Finish.


    Figure 1: Creating a new InfoPath Visual C# managed code project.

    Design the view:

    1. Type Full Name:, and then press Enter.
    2. Open the Controls task pane.
    3. Insert a Text Box and a Button into the view.

    Set the form template to full trust security:

    1. Choose Form Options from the Tools menu.
    2. On the Security tab of the Form Options dialog box, clear the Automatically Determine Security Level check box, select Full Trust, and then click OK.

    Prepare the Save As button:

    1. Double-click the button.
    2. In the Button Properties dialog box, change the Label to Save As.
    3. Change the ID to btnSaveAs (as shown in Figure 2).
    4. Click Edit Form Code.


    Figure 2. The completed view.

    Add a .NET component reference:

    1. In the Solution Explorer pane, right-click References, and then choose Add Reference (refer to Figure 3).


    Figure 3: Adding a new reference.

    1. On the .NET tab of the Add Reference dialog box, select System.Windows.Forms.dll, click Select (as shown in Figure 4), and then click OK.


    Figure 4: Adding a reference to System.Windows.Forms.dll

    1. At the top of the FormCode.cs file, add the following line of code:

    using System.Windows.Forms;

    System.Windows.Forms includes an Application object. Adding this reference causes an ambiguity conflict in our existing code that must be fixed.

    Update conflicting references to the Application object:

    1. Replace the variable declaration for thisApplication with the following line:

    private Microsoft.Office.Interop.InfoPath.SemiTrust.Application thisApplication;

    1. Replace the _Startup function declaration with the following line:

    public void _Startup(Microsoft.Office.Interop.InfoPath.SemiTrust.Application app, XDocument doc)

    Add code behind the Save As button:

    1. Replace the contents of the btnSaveAs_OnClick function with the following code:

    string sFullName = thisXDocument.DOM.selectSingleNode("/my:myFields/my:field1").text;
    FileDialog oDialog = new SaveFileDialog();
    oDialog.DefaultExt = "xml";
    oDialog.FileName = "My Form - " + sFullName;
    oDialog.Filter = "InfoPath Form (*.xml)|*.xml";
    if(oDialog.ShowDialog() == DialogResult.OK)
    {
        string sFilename = oDialog.FileName;
        thisXDocument.SaveAs(sFilename);
    }

    Save the form template:

    1. Switch back to the InfoPath designer.
    2. Choose Publish from the File menu.
    3. In the Publishing Wizard dialog box, click Next.
    4. Select To A Shared Folder, and then click Next.
    5. Set the filename to C:\SaveAsDialog.xsn, and then click Next, click Finish, and then click Close.
    6. Exit Visual Studio.

    Create a full trust installation package for the form template:

    1. Open a command prompt (usually available from Start | All Programs | Accessories).
    2. Change directories to C:\.
    3. Type the following command:

    regform SaveAsDialog.xsn /MSI /T Yes

    1. After the successful build of your install package, type the following command:

    SaveAsDialog.msi

    1. Follow the instructions of the SaveAsDialog Setup Wizard to install your full trust form template.

    Try it:

    1. Launch InfoPath.
    2. In the Fill Out A Form dialog box, double-click SaveAsDialog.
    3. Type your full name, and then click Save As.
    4. Choose a location to save your form (as shown in Figure 5), and then click Save.


    Figure 5: The Save As dialog box as launched from a form button.

    1. Close InfoPath.
    2. Open Windows Explorer, locate the form you just saved, and double-click it.

    The form you saved opens in InfoPath with your name filled out in the Full Name field. If you desire, there are a few other settings you can change on the Save As dialog that you display.

    ©2006 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Highlight the Active Field

    To make the active field more visible to the form user, you can use conditional formatting, the OnContextChange event, and named node properties. This technique will not work for the following editable controls: Radio Button, Check Box, Bulleted List, Numbered List, Plain List, and Button. This technique can be used with Sections and other container controls.

    In this task we will create a simple form with various types of controls. We will add functionality to highlight the active control, or the control with the active focus, using yellow shading. Because of InfoPath security restrictions, there is no way to directly modify a control in the view using code; therefore, conditional formatting must be used to accomplish this task. Let's start by designing a new blank form.

    Design the view:

    1. Open the Controls task pane.
    2. Click Text Box, Drop-Down List Box, Date Picker, and then press Enter.
    3. Click Repeating Table, and then click OK to accept the default number of columns.

    Add the OnContextChange event handler code:

    1. Choose Programming | On Context Change Event from the Tools menu.
    2. In the Microsoft Script Editor, replace any generated code in the event handler with the following code:

    if (eventObj.Type != "ContextNode" || eventObj.IsUndoRedo)
        return;
     
    try
    {
        XDocument.SetNamedNodeProperty(oActiveContext, "active", "0");
    }
    catch(e){} // Ignore exceptions. Field might have been deleted.

    oActiveContext = eventObj.Context;
    XDocument.SetNamedNodeProperty(oActiveContext, "active", "1");

    1. Add the following global variable outside of the OnContextChange function:

    var oActiveContext = null;

    1. Save the code, and then exit the Microsoft Script Editor.

    We make use of the SetNamedNodeProperty and GetNamedNodeProperty methods to keep track of which field is active. These methods allow us to store a custom value on a custom property and associate it with any node in our main DOM. Our property is named active and we store the value of 1 if the field has focus, and return the value to 0 when the focus changes.

    Add conditional formatting to each control:

    1. Double-click the Text Box in the view.
    2. On the Display tab of the Text Box Properties dialog box, click Conditional Formatting, and then click Add.
    3. In the Conditional Format dialog box, select The Expression from the first drop-down list, and then type the following expression:

    xdXDocument:GetNamedNodeProperty(my:field1, "active", "0") = "1"

    1. Choose the light yellow shading, as shown in Figure 1.

    Figure 1. Choose the light yellow shading.

    1. Click OK four times to close all open dialog boxes.
    2. Add similar conditional formatting to each of the other controls in the view, replacing my:field1 with the name of the field you are modifying (i.e. my:field2, my:field3, etc).

    It is interesting to note that you use the element name in the conditional formatting instead of the context node (i.e. ".", which is the abbreviated syntax for self::node()). This is different from most conditional formatting where you can use the context node to refer to the current field. If we were to use the condition xdXDocument:GetNamedNodeProperty(., "active", "0") = "1", the context node would, in this method, refer to the container rather than the field.

    Try it:

    Preview the form and tab between the controls. As each control receives focus, the shading changes to light yellow, and as the control loses focus, the shading is restored to its default.

    You might find some strange selection behavior for the List Box and Drop-Down List Box controls. We are not sure, at this time how to correct these irregularities.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Use the SharePoint '[Me]' Filter with a Promoted Property

    When saving InfoPath forms to SharePoint document libraries you might need to limit the forms users see. For example, if you have an established workflow, you might want to limit users to see only those forms that are assigned to them.

    SharePoint provides a special filter so that users can see, for example, only those items that they created or modified, for example. This is known as the 'Me' filter. Attempting to use this filter with promoted properties, such as the user name, fails, and the SharePoint view renders the text <!-- #RENDER FAILED -->. This is because the 'Me' filter only works with SharePoint user IDs, not user names.

    In this task, we will create a simple InfoPath form that will present a list of SharePoint users and promote the selected user name and ID. We will publish the form to a SharePoint form library and then modify the default view to filter the list based on the logged in user. You will need access and rights to an available SharePoint to complete this task.


    THE INFOPATH FORM

    First we will create a very basic InfoPath form that allows you to assign the form to a SharePoint user. To get the list of SharePoint users we need to manually modify the form manifest as the SharePoint user list is not available via the designer. Let's start by designing a new blank form.

    Create the schema:

    1. Open the Data Source task pane.
    2. Add a two Text fields named FormTitle, AssignedTo.
    3. Select AssignedTo, and add a Text Attribute field named id.

    Create the view:

    1. Right-click FormTitle, choose Text Box, and then press Enter.
    2. Right-click AssignedTo, and then choose Drop-Down List Box.

    Add a SharePoint list data connection:

    1. Double-click the drop-down list box.
    2. Select Look Up Values In A Data Connection, and then click Add.
    3. In the Data Connection Wizard, select SharePoint Library Or List, and then click Next.
    4. Type the URL to your SharePoint site, and then click Next.
    5. Select any list or library, and then click Next.

    It does not matter which list or library you select as we will be manually modifying it later to get the list of SharePoint users.

    1. Ensure that only the ID and Title check boxes are selected, and then click Next.
    2. Name the data connection SharePoint Users, and then click Finish.

    Populate the drop-down list box using the new data connection:

    1. Click the Select XPath button to the right of the Entries text box.
    2. Select :Title, and then click OK.

    Set the ID when Assigned To changes:

    1. Click Rules, and then click Add.
    2. Name the rule Set ID, and then click Add Action.
    3. In the Action dialog box, select Set A Field's Value from the Action drop-down list.
    4. Click the Select XPath button to the right of the Field text box, select AssignedTo/id, and then click OK.
    5. Click the Insert Formula button to the right of the Value text box, and then click Insert Field Or Group.
    6. In the Select A Field Or Group dialog box, select SharePoint Users from the Data Source drop-down list.
    7. Select :ID, click Filter Data, and then click Add.
    8. In the Specify Filter Conditions dialog box, select Title from the first drop-down list, and then select Select A Field Or Group from the third drop-down list.
    9. In the Select A Field Or Group dialog box, select Main from the Data Source drop-down list, and then select AssignedTo.
    10. Click OK nine times to close all the open dialog boxes.

    Promote the form fields to SharePoint:

    1. Select Form Options from the Tools menu.
    2. On the Form Library Columns tab of the Form Options dialog box, click Add.
    3. Select FormTitle, and then click OK.
    4. Click Add, select AssignedTo, name the column Assigned To, and then click OK.
    5. Click Add, select AssignedTo/id, and then name the column Assigned To ID.
    6. Click OK twice to close all to close the open dialog boxes.

    Extract the form files:

    1. Choose Extract Form Files from the File menu.
    2. Select a location to save your extracted form files to, and then click OK.
    3. Close InfoPath to release the lock it places on your form files.
    4. Using a text editor, open your manifest.xsf file.
    5. Search for the text sharepointGuid.

    This is an attribute on an xsf:sharepointListAdapter object with the attribute name="SharePoint Users".

    1. Change the value of the sharepointGuid attribute to UserInfo. The updated attribute should look like the following:

    sharepointGuid="UserInfo"

    1. Save the manifest.xsf file, and then close the text editor.
    2. Reopen your form template by right-clicking the manifest.xsf file and choosing Design.

    You have now a drop-down list box populated with a list of SharePoint users. Preview your form to test it. You might find some systems users such as NT AUTHORITY\NETWORK SERVICE in your list. These can be hidden by adding a filter to your drop-down list box.

    Publish your form to your SharePoint, close your form, and then open your form from its published location.


    THE SHAREPOINT FORM LIBRARY

    Fill out the form a few times, assigning each to different users and saving back to the form library. Finally, click All Forms to refresh the view. You should now see each of the forms you just saved, including the promoted properties for Title, Assigned To and Assigned To ID. Now let's update the default view so that it does not show the Assigned To ID field and only displays forms assigned to you.

    Update the default SharePoint view:

    1. Click Modify Settings And Columns.
    2. Click All Forms in the Views section.
    3. In the Columns section, clear the Assigned To ID check box.
    4. In the Filter section, select Assigned To ID from the first drop-down list, and then type [Me] in the text box.
    5. Click OK, and then click the Go Back To link at the top of the page.

    The default SharePoint view now automatically filters items to only show those assigned to the currently logged in user—you in this case.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Create a Repeating Cascading List from a Hierarchical Data Source

    It is common to need two or more list boxes where the choices in one are dependant on the value of another. This is known as a cascading list. A cascade can occur with as few as two levels up to any number of levels. Some common scenarios which require cascading lists are:

    • Location: State / City
    • Vehicle: Year / Make / Model
    • School: Year / Semester / Class / Instructor

    As the number of levels in the cascade increases, so does the complexity of the process and work involved. Also, if the cascading list is presented inside of a repeating table or repeating section you must account for another issue: data crossover. Data crossover means that the options presented in a cascade on a given row will be affected by earlier selected values from other rows—thus destroying the true cascading effect.

    In this task we will create a hierarchical secondary data source containing the values used to populate our lists. We will then create a three-level repeating cascading list using drop-down list boxes. We create three levels of cascade to reveal the compounding complexity involved for level three and beyond. We will resolve the issue regarding data crossover using the current function. And finally, we ensure valid selection combinations by clearing selected list values as selections earlier in the cascade are changed.


    THE HIERARCHICAL SECONDARY DATA SOURCE

    Hierarchical data sources are commonly created for use in XML, and are typically more structured and organized than a flat data source. There are numerous ways to organize the hierarchy; we have arbitrarily chosen a structure that suits this task. The hierarchical structure normally ensures that only unique values appear each list. If, however, you find that filtering for unique values is still needed, refer to Display Only Unique Options in a List. Let's start by creating the hierarchical secondary data source.

    Create the hierarchical secondary data source:

    Copy the following code into a text editor, and then save the file as Vehicles - Hierarchical Data Source.xml. This file will be used as a secondary data source in our form.

    <?xml version="1.0" encoding="UTF-8"?>
    <Vehicles>
        <Year value="1963">
            <Make value="Chevrolet">
                <Model value="Corvette"/>
                <Model value="Nova"/>
            </Make>
            <Make value="Porsche">
                <Model value="356"/>
                <Model value="Carrera"/>
            </Make>
        </Year>
        <Year value="1973">
            <Make value="Ford">
                <Model value="Bronco"/>
                <Model value="Mustang"/>
                <Model value="Pinto"/>
            </Make>
            <Make value="Toyota">
                <Model value="Celica"/>
                <Model value="Land Cruiser"/>
            </Make>
        </Year>
        <Year value="1979">
            <Make value="Jaguar">
                <Model value="XJ6"/>
            </Make>
            <Make value="Pontiac">
                <Model value="Trans Am"/>
            </Make>
            <Make value="Volvo">
                <Model value="240"/>
                <Model value="244DL"/>
            </Make>
        </Year>
        <Year value="1987">
            <Make value="Dodge">
                <Model value="Ram Charger"/>
                <Model value="Grand Caravan"/>
            </Make>
            <Make value="Honda">
                <Model value="Civic"/>
                <Model value="Prelude"/>
            </Make>
            <Make value="Nissan">
                <Model value="300ZX"/>
                <Model value="Pulsar"/>
                <Model value="Sentra"/>
            </Make>
        </Year>
        <Year value="1999">
            <Make value="GMC">
                <Model value="Jimmy"/>
                <Model value="Sierra 2500 HD"/>
                <Model value="Yukon"/>
            </Make>
            <Make value="Honda">
                <Model value="Passport"/>
                <Model value="Prelude"/>
                <Model value="CR-V"/>
            </Make>
            <Make value="Jeep">
                <Model value="Cherokee"/>
            </Make>
            <Make value="Mercury">
                <Model value="Grand Marquis"/>
                <Model value="Sable"/>
                <Model value="Villager"/>
            </Make>
            <Make value="Pontiac">
                <Model value="Firebird"/>
                <Model value="Montana"/>
                <Model value="Sunfire"/>
            </Make>
        </Year>
        <Year value="2003">
            <Make value="Dodge">
                <Model value="Dakota"/>
                <Model value="Caravan"/>
                <Model value="Ram Charger"/>
                <Model value="Viper"/>
            </Make>
            <Make value="Mercury">
                <Model value="Sable"/>
            </Make>
        </Year>
        <Year value="2004">
            <Make value="Dodge">
                <Model value="Stratus"/>
                <Model value="Viper"/>
            </Make>
            <Make value="Ford">
                <Model value="Crown Victoria"/>
                <Model value="F250"/>
                <Model value="Thunderbird"/>
            </Make>
            <Make value="GMC">
                <Model value="Sierra 3500"/>
            </Make>
            <Make value="Jeep">
                <Model value="Grand Cherokee"/>
                <Model value="Liberty"/>
            </Make>
        </Year>
    </Vehicles>


    THE FORM

    Now that we have our hierarchical secondary data source we are ready to create our form. First we will design a simple schema to support a three-level repeating cascading list. Then we will design the layout using drop-down list boxes in a repeating table. When the layout is complete we will focus on creating the repeating cascade.

    Add the secondary data source to a form:

    1. Design a new blank form.
    2. Choose Data Connections from the Tools menu, and then click Add.
    3. In the Data Connection Wizard, select Receive Data, and then click Next.
    4. Select XML Document, and then click Next.
    5. Click Browse, locate and select the Vehicles - Hierarchical Data Source.xml file, click Open, and then click Next.
    6. Click Finish, click Yes, and then click Close.

    Create the schema:

    1. Open the Data Source task pane.
    2. Add a Group named Vehicles.
    3. Select the Vehicles group, and then add a Repeating Group named Vehicle.
    4. Select the Vehicle group, and then add three Text Fields named Year, Make, and Model.

    Design the view:

    1. Right-click Vehicle, and then choose Repeating Table.
    2. Select all three header row cells, and then set the font size to 8.
    3. Right-click each of the three text boxes, and then choose Change To | Drop-Down List Box. The results are shown in Figure 1.


    Figure 1. Layout of the repeating cascading drop-down list boxes.

    1. Double-click the repeating table label.
    2. On the Data tab of the Repeating Table Properties dialog box, change the insert button hint text to Insert Vehicle, and then click OK.


    THE CASCADING LISTS

    With the form layout complete we will now turn our attention to the meat of the task: making one repeating list cascade off of another. The process is not very difficult, but can become increasingly complex as the number of cascade levels increases. Creating a cascade requires the use of filters. The options displayed in one list box are filtered based on values selected in earlier list boxes. Because our cascade is in a repeating structure, we must use the current function to ensure the filter does not crossover to values in other rows. Let's populate each drop-down list box using our secondary data source and create the cascade filters.

    Populate the Year drop-down list:

    1. Double-click the Year drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Hierarchical Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, select Vehicles/Year/value, and then click OK twice to close the open dialog boxes.

    Populate the Make drop-down list:

    1. Double-click the Make drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Hierarchical Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, and then select Vehicles/Year/Make/value.

    Filter the Make drop-down list based on the selected Year in the current row:

    1. Click Filter Data, and then click Add.
    2. In the Specify Filter Conditions dialog box, select Select A Field Or Group from the first drop-down list.
    3. In the Select A Field Or Group dialog box, select Vehicles/Year/value, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Use A Formula.
    6. Type the following formula (as shown in Figure 2):

    current()/my:Year


    Figure 2. Filtering to compare the Year to the value on the current row.

    1. Click OK five times to close all open dialog boxes.

    We mentioned you would encounter the issue of data crossover. An example of data crossover is shown in the difference between Figure 3 and 4. Without using the current function the vehicle make will be filtered on all years currently selected in the repeating table, presenting the user with invalid choice combinations. Thus if you have 3 rows with the years 1963, 1979 and 2004 selected, each of the Make drop-down lists will contain a list of makes for all three of those selected years, as shown in Figure 4. By properly using the current function, we avoid data crossover by limiting the choices in the Make drop-down list to only those of the selected Year on the same row, as shown in Figure 3.


    Figure 3. Vehicle makes filtered by year using the current function.


    Figure 4. Vehicle makes filtered by year without using the current function.

    At this point you have created a two-level repeating cascade. The options in the Make drop-down list are filtered based on the selected Year in the current row. You can test this by previewing your form. Now let's create the level-three repeating cascade, which will reveal the compounding complexity involved in creating each additional level of cascade from here.

    Populate the Model drop-down list:

    1. Double-click the Model drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Hierarchical Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, and then select Vehicles/Year/Make/Model/value.

    Filter the Model drop-down list based on the selected Year in the current row:

    1. Click Filter Data, and then click Add.
    2. In the Specify Filter Conditions dialog box, select Select A Field Or Group from the first drop-down list.
    3. In the Select A Field Or Group dialog box, select Vehicles/Year/value, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Use A Formula.
    6. In the Insert A Formula dialog box, type the following formula:

    current()/my:Year

    1. Click OK.

    Filter the Model drop-down list based on the selected Make in the current row:

    1. Click And to create a second filter condition.
    2. In the first drop-down list of the second filter condition, select Select A Field Or Group.
    3. In the Select A Field Or Group dialog box, select Vehicles/Year/Make/value, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Use A Formula.
    6. In the Insert A Formula dialog box, type the following formula:

    current()/my:Make

    1. Click OK. The two filter conditions are shown in Figure 5.


    Figure 5. Filtering the third level of a repeating cascading list.

    1. Click OK four times to close all open dialog boxes.

    You have now created a three-level repeating cascade. Preview the form and test the functionality of the drop-down list boxes. You may discover an issue: you can create invalid selection combinations. We will resolve this issue in the next section.


    CLEARING SELECTIONS AFTER CHANGES

    One issue with cascading lists that needs to be addressed is that when a selection is changed in an earlier level the selections following that change are likely to be invalid. For example, if you select year 1963 and model Chevrolet, and then select year 1973, Chevrolet remains the selected model, even though our data source does not list it as a model for 1973. The old value needs to be cleared so that invalid selection combinations cannot exist. This can be easily corrected with Rules.

    With some extra work, you can probably determine whether the following selected values are still valid and clear only invalid ones, but there are advantages to just clearing each following selected value. One advantage is that rules can cascade as well—like a Domino effect. As one value is changed, the next value is cleared; clearing that value triggers the next value to clear, and so on. Rules automatically affect the current row, so there is no need to filter using the current function in the rule.

    The rules we create will have no condition so that they will be processed every time the selected value changes. To clear the selected value of a field, we leave the Value text box of the rule blank.

    Clear the selected Make when the selected Year changes:

    1. Double-click the Year drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click Rules, and then click Add.
    3. Name the rule Clear Make, and then click Add Action.
    4. In the Action dialog box, select Set A Field's Value from the Action drop-down list.
    5. Click the Select XPath button to the right of the Field text box, and then select myFields/Vehicles/Vehicle/Make in the Main data source.
    6. Click OK five times to close all open dialog boxes.

    Clear the selected Model when the selected Make changes:

    1. Double-click the Make drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click Rules, and then click Add.
    3. Name the rule Clear Model, and then click Add Action.
    4. In the Action dialog box, select Set A Field's Value from the Action drop-down list.
    5. Click the Select XPath button to the right of the Field text box, and then select myFields/Vehicles/Vehicle/Model in the Main data source.
    6. Click OK five times to close all open dialog boxes.

    Try it:

    You have now created a three-level repeating cascading list that prevents invalid selection combinations. Preview the form and try various selection combinations.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Create a Repeating Cascading List from a Flat Data Source

    It is common to need two or more list boxes where the choices in one are dependant on the value of another. This is known as a cascading list. A cascade can occur with as few as two levels up to any number of levels. Some common scenarios which require cascading lists are:

    • Location: State / City
    • Vehicle: Make / Model / Trim
    • School: Year / Semester / Class / Instructor

    As the number of levels in the cascade increases, so does the complexity of the process and work involved. Also, if the cascading list is presented inside of a repeating table or repeating section you must account for another issue: data crossover. Data crossover means that the options presented in a cascade on a given row will be affected by earlier selected values from other rows—thus destroying the true cascading effect.

    In this task we will create a flat secondary data source containing the values used to populate our lists. We will then create a three-level repeating cascading list using drop-down list boxes. We create three levels of cascade to reveal the compounding complexity involved for level three and beyond. Because of the nature of the flat data source, we will filter each list to ensure that only unique values are displayed. We will resolve the issue regarding data crossover using the current function. And finally, we ensure valid selection combinations by clearing selected list values as selections earlier in the cascade are changed.


    THE FLAT SECONDARY DATA SOURCE

    Flat data sources are commonly returned from databases, Web services, and SharePoint. A flat data source has no hierarchy in the structure; it is simply a list of identical elements, each with an identical set of attributes. Only the values of the attributes change. Flat data sources also require additional filtering to ensure that only unique values appear in the drop-down lists. Let's start by creating the flat secondary data source.

    Create the flat secondary data source:

    Copy the following code into a text editor, and then save the file as Vehicles - Flat Data Source.xml. This file will be used as a secondary data source in our form.

    <?xml version="1.0" encoding="UTF-8"?>
    <Vehicles>
        <Vehicle year="1963" make="Chevrolet" model="Corvette"/>
        <Vehicle year="1963" make="Chevrolet" model="Nova"/>
        <Vehicle year="1963" make="Porsche" model="356"/>
        <Vehicle year="1963" make="Porsche" model="Carrera"/>
        <Vehicle year="1973" make="Ford" model="Bronco"/>
        <Vehicle year="1973" make="Ford" model="Mustang"/>
        <Vehicle year="1973" make="Ford" model="Pinto"/>
        <Vehicle year="1973" make="Toyota" model="Celica"/>
        <Vehicle year="1973" make="Toyota" model="Land Cruiser"/>
        <Vehicle year="1979" make="Jaguar" model="XJ6"/>
        <Vehicle year="1979" make="Pontiac" model="Trans Am"/>
        <Vehicle year="1979" make="Volvo" model="240"/>
        <Vehicle year="1979" make="Volvo" model="244DL"/>
        <Vehicle year="1987" make="Dodge" model="Ram Charger"/>
        <Vehicle year="1987" make="Dodge" model="Grand Caravan"/>
        <Vehicle year="1987" make="Honda" model="Civic"/>
        <Vehicle year="1987" make="Honda" model="Prelude"/>
        <Vehicle year="1987" make="Nissan" model="300ZX"/>
        <Vehicle year="1987" make="Nissan" model="Pulsar"/>
        <Vehicle year="1987" make="Nissan" model="Sentra"/>
        <Vehicle year="1999" make="GMC" model="Jimmy"/>
        <Vehicle year="1999" make="GMC" model="Sierra 2500 HD"/>
        <Vehicle year="1999" make="GMC" model="Yukon"/>
        <Vehicle year="1999" make="Honda" model="Passport"/>
        <Vehicle year="1999" make="Honda" model="Prelude"/>
        <Vehicle year="1999" make="Honda" model="CR-V"/>
        <Vehicle year="1999" make="Jeep" model="Cherokee"/>
        <Vehicle year="1999" make="Mercury" model="Grand Marquis"/>
        <Vehicle year="1999" make="Mercury" model="Sable"/>
        <Vehicle year="1999" make="Mercury" model="Villager"/>
        <Vehicle year="1999" make="Pontiac" model="Firebird"/>
        <Vehicle year="1999" make="Pontiac" model="Montana"/>
        <Vehicle year="1999" make="Pontiac" model="Sunfire"/>
        <Vehicle year="2003" make="Dodge" model="Dakota"/>
        <Vehicle year="2003" make="Dodge" model="Caravan"/>
        <Vehicle year="2003" make="Dodge" model="Ram Charger"/>
        <Vehicle year="2003" make="Dodge" model="Viper"/>
        <Vehicle year="2003" make="Mercury" model="Sable"/>
        <Vehicle year="2004" make="Dodge" model="Stratus"/>
        <Vehicle year="2004" make="Dodge" model="Viper"/>
        <Vehicle year="2004" make="Ford" model="Crown Victoria"/>
        <Vehicle year="2004" make="Ford" model="F250"/>
        <Vehicle year="2004" make="Ford" model="Thunderbird"/>
        <Vehicle year="2004" make="GMC" model="Sierra 3500"/>
        <Vehicle year="2004" make="Jeep" model="Grand Cherokee"/>
        <Vehicle year="2004" make="Jeep" model="Liberty"/>
    </Vehicles>


    THE FORM

    Now that we have our flat secondary data source we are ready to create our form. First we will design a simple schema to support a three-level repeating cascading list. Then we will design the layout using drop-down list boxes in a repeating table. When the layout is complete we will focus on creating the repeating cascade.

    Add the secondary data source to a form:

    1. Design a new blank form.
    2. Choose Data Connections from the Tools menu, and then click Add.
    3. In the Data Connection Wizard, select Receive Data, and then click Next.
    4. Select XML Document, and then click Next.
    5. Click Browse, locate and select the Vehicles - Flat Data Source.xml file, click Open, and then click Next.
    6. Click Finish, click Yes, and then click Close.

    Create the schema:

    1. Open the Data Source task pane.
    2. Add a Group named Vehicles.
    3. Select the Vehicles group, and then add a Repeating Group named Vehicle.
    4. Select the Vehicle group, and then add three Text Fields named Year, Make, and Model.

    Design the view:

    1. Right-click Vehicle, and then choose Repeating Table.
    2. Select all three header row cells, and then set the font size to 8.
    3. Right-click each of the three text boxes, and then choose Change To | Drop-Down List Box. The results are shown in Figure 1.


    Figure 1. Layout of the repeating cascading drop-down list boxes.

    1. Double-click the repeating table label.
    2. On the Data tab of the Repeating Table Properties dialog box, change the insert button hint text to Insert Vehicle, and then click OK.


    THE CASCADING LISTS

    With the form layout complete we will now turn our attention to the meat of the task: making one list cascade off of another. The process is not very difficult, but can become increasingly complex as the number of cascade levels increases. Creating a cascade requires the use of filters. The options displayed in one list box are filtered based on values selected in earlier list boxes. Because our cascade is in a repeating structure, we must use the current function to ensure the filter does not crossover to values in other rows. Let's populate each drop-down list box using our secondary data source and create the cascade filters.

    Populate the Year drop-down list:

    1. Double-click the Year drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Flat Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, select Vehicles/Vehicle/year, and then click OK twice to close the open dialog boxes.

    Populate the Make drop-down list:

    1. Double-click the Make drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Flat Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, and then select Vehicles/Vehicle/make.

    Filter the Make drop-down list based on the selected Year in the current row:

    1. Click Filter Data, and then click Add.
    2. In the Specify Filter Conditions dialog box, select Select A Field Or Group from the first drop-down list.
    3. In the Select A Field Or Group dialog box, select Vehicles/Vehicle/year, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Use A Formula.
    6. Type the following formula (as shown in Figure 2):

    current()/my:Year


    Figure 2. Filtering to compare the Year to the value on the current row.

    1. Click OK five times to close all open dialog boxes.

    We mentioned you would encounter the issue of data crossover. An example of data crossover is shown in the difference between Figure 3 and 4 (please note that Figures 3 and 4 already account for unique value filtering). Without using the current function the vehicle make will be filtered on all years currently selected in the repeating table, presenting the user with invalid choice combinations. Thus if you have 3 rows with the years 1963, 1979 and 2004 selected, each of the Make drop-down lists will contain a list of makes for all three of those selected years, as shown in Figure 4. By properly using the current function, we avoid data crossover by limiting the choices in the Make drop-down list to only those of the selected Year on the same row, as shown in Figure 3.


    Figure 3. Vehicle makes filtered by year using the current function.

    Figure 4. Vehicle makes filtered by year without using the current function.

    At this point you have created a two-level repeating cascade. The options in the Make drop-down list are filtered based on the selected Year in the current row. You can test this by previewing your form. You will notice that each drop-down list contains repeated values. This is a byproduct of using a flat data source and will be corrected in the next section when we filter for unique values. Now let's create the level-three cascade, which will reveal the compounding complexity involved in creating each additional level of cascade from here.

    Populate the Model drop-down list:

    1. Double-click the Model drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Flat Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, and then select Vehicles/Vehicle/model.

    Filter the Model drop-down list based on the selected Year in the current row:

    1. Click Filter Data, and then click Add.
    2. In the Specify Filter Conditions dialog box, select Select A Field Or Group from the first drop-down list.
    3. In the Select A Field Or Group dialog box, select Vehicles/Vehicle/year, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Use A Formula.
    6. In the Insert A Formula dialog box, type the following formula:

    current()/my:Year

    1. Click OK.

    Filter the Model drop-down list based on the selected Make in the current row:

    1. Click And to create a second filter condition.
    2. In the first drop-down list of the second filter condition, select Select A Field Or Group.
    3. In the Select A Field Or Group dialog box, select Vehicles/Vehicle/make, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Use A Formula.
    6. In the Insert A Formula dialog box, type the following formula:

    current()/my:Make

    1. Click OK. The two filter conditions are shown in Figure 5.


    Figure 5. Filtering the third level of a repeating cascading list.

    1. Click OK four times to close all open dialog boxes.

    You have now created a three-level repeating cascade. Preview the form and test the functionality of the drop-down list boxes. You may discover two issues: first, the list options are not unique, and second, you can create invalid selection combinations. We will resolve these two issues in the next two sections.


    FILTERING LISTS FOR UNIQUE VALUES

    Values in flat data sources are usually repeated. Although this is important given the XML structure, it can lead to option bloat in your list box. It can only serve to confuse and frustrate the user to present them with numerous identical options. The answer is to filter the list to display only unique values. This can be done using XPath.

    It should be mentioned that just as the complexity of the cascade filters compounded with each additional cascade level, so do the complexity of the uniqueness filters. You will see this in the expression used to filter the Model drop-down list for unique values.

    Add a uniqueness filter to the Year drop-down list:

    1. Double-click the Year drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click the Select XPath button to the right of the Entries text box.
    3. In the Select A Field Or Group dialog box, click Filter Data, and then click Add.
    4. In the Specify Filter Conditions dialog box, select The Expression from the first drop-down list, and then type the following expression (as shown in Figure 6):

    not(. = ../preceding-sibling::Vehicle/@year)


    Figure 6. Filtering list options to display only unique values.

    1. Click OK four times to close all open dialog boxes.

    Add a uniqueness filter to the Make drop-down list:

    At each cascade level beyond the initial list box, your uniqueness filter must take into consideration the selection from each of the previous levels. Due to the nature of this filter, if you do not take the previous selections into consideration, you may inadvertently completely filter out all valid options.

    For example, in our sample secondary data source, vehicle years 1987 and 1999 both include the Honda make. If we did not account for the selected year, the Honda make would not appear as an option when year 1999 was selected. This is because the filter would identify that the Honda make appeared earlier in the secondary data source. The Dodge make in years 2003 and 2004 would also be completely filtered out because Dodge appears earlier, in year 1987. There are a few other makes and models in the sample secondary data source that would encounter this issue.

    1. Double-click the Make drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click the Select XPath button to the right of the Entries text box.
    3. In the Select A Field Or Group dialog box, click Filter Data, and then click Add.
    4. In the Specify Filter Conditions dialog box, select The Expression from the first drop-down list, and then type the following expression:

    not(. = ../preceding-sibling::Vehicle[@year = current()/my:Year]/@make)

    Note that compared with the uniqueness filter we placed on the Year drop-down list box, there is an additional subfilter specified on the Vehicle node. The subfilter [@year = current()/my:Year] constrains the main filter to verify that we display unique values for each make within the selected year.

    1. Click OK four times to close all open dialog boxes.

    Add a uniqueness filter to the Model drop-down list:

    1. Double-click the Model drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click the Select XPath button to the right of the Entries text box.
    3. In the Select A Field Or Group dialog box, click Filter Data, and then click Add.
    4. In the Specify Filter Conditions dialog box, select The Expression from the first drop-down list, and then type the following expression:

    not(. = ../preceding-sibling::Vehicle[@year = current()/my:Year and @make = current()/my:Make]/@model)

    Just as we did with the uniqueness filter for the Make drop-down list above, here we have added an additional subfilter to guarantee that we are only eliminating repeated options from the list of models within the selected year and selected make.

    1. Click OK four times to close all open dialog boxes.

    If you can guarantee that the values, at any level of cascade, will always and forever be unique then you do not need to add the uniqueness filter. If, however, there is any doubt, it is always safer to add it. For more information on filtering lists for unique values, refer to Display Only Unique Options in a List.


    CLEARING SELECTIONS AFTER CHANGES

    One issue with cascading lists that needs to be addressed is that when a selection is changed in an earlier level the selections following that change are likely to be invalid. For example, if you select year 1963 and model Chevrolet, and then select year 1973, Chevrolet remains the selected model, even though our data source does not list it as a model for 1973. The old value needs to be cleared so that invalid selection combinations cannot exist. This can be easily corrected with Rules.

    With some extra work, you can probably determine whether the following selected values are still valid and clear only invalid ones, but there are advantages to just clearing each following selected value. One advantage is that rules can cascade as well—like a Domino effect. As one value is changed, the next value is cleared; clearing that value triggers the next value to clear, and so on. Rules automatically affect the current row, so there is no need to filter using the current function in the rule.

    The rules we create will have no condition so that they will be processed every time the selected value changes. To clear the selected value of a field, we leave the Value text box of the rule blank.

    Clear the selected Make when the selected Year changes:

    1. Double-click the Year drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click Rules, and then click Add.
    3. Name the rule Clear Make, and then click Add Action.
    4. In the Action dialog box, select Set A Field's Value from the Action drop-down list.
    5. Click the Select XPath button to the right of the Field text box, and then select myFields/Vehicles/Vehicle/Make in the Main data source.
    6. Click OK five times to close all open dialog boxes.

    Clear the selected Model when the selected Make changes:

    1. Double-click the Make drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click Rules, and then click Add.
    3. Name the rule Clear Model, and then click Add Action.
    4. In the Action dialog box, select Set A Field's Value from the Action drop-down list.
    5. Click the Select XPath button to the right of the Field text box, and then select myFields/Vehicles/Vehicle/Model in the Main data source.
    6. Click OK five times to close all open dialog boxes.

    Try it:

    You have now created a three-level repeating cascading list that filters for unique values and prevents invalid selection combinations. Preview the form and try various selection combinations.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Create a Cascading List from a Hierarchical Data Source

    It is common to need two or more list boxes where the choices in one are dependant on the value of another. This is known as a cascading list. A cascade can occur with as few as two levels up to any number of levels. Some common scenarios which require cascading lists are:

    • Location: State / City
    • Vehicle: Year / Make / Model
    • School: Year / Semester / Class / Instructor

    As the number of levels in the cascade increases, so does the complexity of the process and work involved. Also, if the cascading list is presented inside of a repeating table or repeating section you must account for another issue: data crossover. Repeating cascading lists are covered in Create a Repeating Cascading List from a Flat Data Source and Create a Repeating Cascading List from a Hierarchical Data Source.

    In this task we will create a hierarchical secondary data source containing the values used to populate our lists. We will then create a three-level non-repeating cascading list using drop-down list boxes. We create three levels of cascade to reveal the compounding complexity involved for level three and beyond. And finally, we ensure valid selection combinations by clearing selected list values as selections earlier in the cascade are changed.


    THE HIERARCHICAL SECONDARY DATA SOURCE

    Hierarchical data sources are commonly created for use in XML, and are typically more structured and organized than a flat data source. There are numerous ways to organize the hierarchy; we have arbitrarily chosen a structure that suits this task. The hierarchical structure normally ensures that only unique values appear each list. If, however, you find that filtering for unique values is still needed, refer to Display Only Unique Options in a List. Let's start by creating the hierarchical secondary data source.

    Create the hierarchical secondary data source:

    Copy the following code into a text editor, and then save the file as Vehicles - Hierarchical Data Source.xml. This file will be used as a secondary data source in our form.

    <?xml version="1.0" encoding="UTF-8"?>
    <Vehicles>
        <Year value="1963">
            <Make value="Chevrolet">
                <Model value="Corvette"/>
                <Model value="Nova"/>
            </Make>
            <Make value="Porsche">
                <Model value="356"/>
                <Model value="Carrera"/>
            </Make>
        </Year>
        <Year value="1973">
            <Make value="Ford">
                <Model value="Bronco"/>
                <Model value="Mustang"/>
                <Model value="Pinto"/>
            </Make>
            <Make value="Toyota">
                <Model value="Celica"/>
                <Model value="Land Cruiser"/>
            </Make>
        </Year>
        <Year value="1979">
            <Make value="Jaguar">
                <Model value="XJ6"/>
            </Make>
            <Make value="Pontiac">
                <Model value="Trans Am"/>
            </Make>
            <Make value="Volvo">
                <Model value="240"/>
                <Model value="244DL"/>
            </Make>
        </Year>
        <Year value="1987">
            <Make value="Dodge">
                <Model value="Ram Charger"/>
                <Model value="Grand Caravan"/>
            </Make>
            <Make value="Honda">
                <Model value="Civic"/>
                <Model value="Prelude"/>
            </Make>
            <Make value="Nissan">
                <Model value="300ZX"/>
                <Model value="Pulsar"/>
                <Model value="Sentra"/>
            </Make>
        </Year>
        <Year value="1999">
            <Make value="GMC">
                <Model value="Jimmy"/>
                <Model value="Sierra 2500 HD"/>
                <Model value="Yukon"/>
            </Make>
            <Make value="Honda">
                <Model value="Passport"/>
                <Model value="Prelude"/>
                <Model value="CR-V"/>
            </Make>
            <Make value="Jeep">
                <Model value="Cherokee"/>
            </Make>
            <Make value="Mercury">
                <Model value="Grand Marquis"/>
                <Model value="Sable"/>
                <Model value="Villager"/>
            </Make>
            <Make value="Pontiac">
                <Model value="Firebird"/>
                <Model value="Montana"/>
                <Model value="Sunfire"/>
            </Make>
        </Year>
        <Year value="2003">
            <Make value="Dodge">
                <Model value="Dakota"/>
                <Model value="Caravan"/>
                <Model value="Ram Charger"/>
                <Model value="Viper"/>
            </Make>
            <Make value="Mercury">
                <Model value="Sable"/>
            </Make>
        </Year>
        <Year value="2004">
            <Make value="Dodge">
                <Model value="Stratus"/>
                <Model value="Viper"/>
            </Make>
            <Make value="Ford">
                <Model value="Crown Victoria"/>
                <Model value="F250"/>
                <Model value="Thunderbird"/>
            </Make>
            <Make value="GMC">
                <Model value="Sierra 3500"/>
            </Make>
            <Make value="Jeep">
                <Model value="Grand Cherokee"/>
                <Model value="Liberty"/>
            </Make>
        </Year>
    </Vehicles>


    THE FORM

    Now that we have our hierarchical secondary data source we are ready to create our form. First we will design a simple schema to support a three-level cascading list. Then we will design the layout using drop-down list boxes. When the layout is complete we will focus on creating the cascade.

    Add the secondary data source to a form:

    1. Design a new blank form.
    2. Choose Data Connections from the Tools menu, and then click Add.
    3. In the Data Connection Wizard, select Receive Data, and then click Next.
    4. Select XML Document, and then click Next.
    5. Click Browse, locate and select the Vehicles - Hierarchical Data Source.xml file, click Open, and then click Next.
    6. Click Finish, click Yes, and then click Close.

    Create the schema:

    1. Open the Data Source task pane.
    2. Add a Group named Vehicle.
    3. Select the Vehicle group, and then add three Text Fields named Year, Make, and Model.

    Design the view:

    1. Insert a 1x3 layout table into the view.
    2. From left to right, insert the Year, Make, and Model fields as Drop-Down List Boxes into the cells of the layout table, as shown in Figure 1.


    Figure 1. Layout of the cascading drop-down list boxes.


    THE CASCADING LISTS

    With the form layout complete we will now turn our attention to the meat of the task: making one list cascade off of another. The process is not very difficult, but can become increasingly complex as the number of cascade levels increases. Creating a cascade requires the use of filters. The options displayed in one list box are filtered based on values selected in earlier list boxes. Let's populate each drop-down list box using our secondary data source and create the cascade filters.

    Populate the Year drop-down list:

    1. Double-click the Year drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Hierarchical Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, and then select Vehicles/Year/value, and then click OK twice to close the open dialog boxes.

    Populate the Make drop-down list:

    1. Double-click the Make drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Hierarchical Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, and then select Vehicles/Year/Make/value.

    Filter the Make drop-down list based on the selected Year:

    1. Click Filter Data, and then click Add.
    2. In the Specify Filter Conditions dialog box, select Select A Field Or Group from the first drop-down list.
    3. In the Select A Field Or Group dialog box, select Vehicles/Year/value, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Select A Field Or Group.
    6. In the Select A Field Or Group dialog box, select Main from the Data Source drop-down list, select myFields/Vehicle/Year, and then click OK (refer to Figure 2).


    Figure 2. Filtering the second level of a cascading list.

    1. Click OK four times to close all open dialog boxes.

    At this point you have created a two-level cascade. The options in the Make drop-down list are filtered based on the selected Year. You can test this by previewing your form. Now let's create the level-three cascade, which will reveal the compounding complexity involved in creating each additional level of cascade from here.

    Populate the Model drop-down list:

    1. Double-click the Model drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Hierarchical Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, and then select Vehicles/Year/Make/Model/value.

    Filter the Model drop-down list based on the selected Year:

    1. Click Filter Data, and then click Add.
    2. In the Specify Filter Conditions dialog box, select Select A Field Or Group from the first drop-down list.
    3. In the Select A Field Or Group dialog box, select Vehicles/Year/value, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Select A Field Or Group.
    6. In the Select A Field Or Group dialog box, select Main from the Data Source drop-down list, select myFields/Vehicle/Year, and then click OK.

    Filter the Model drop-down list based on the selected Make:

    1. Click And to create a second filter condition.
    2. In the first drop-down list of the second filter condition, select Select A Field Or Group.
    3. In the Select A Field Or Group dialog box, select Vehicles/Year/Make/value, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Select A Field Or Group.
    6. In the Select A Field Or Group dialog box, select Main from the Data Source drop-down list, select myFields/Vehicle/Make, and then click OK (refer to Figure 3).


    Figure 3. Filtering the third level of a cascading list.

    1. Click OK four times to close all open dialog boxes.

    You have now created a three-level cascade. Preview the form and test the functionality of the drop-down list boxes. You may discover an issue: you can create invalid selection combinations. We will resolve this issue in the next section.


    CLEARING SELECTIONS AFTER CHANGES

    One issue with cascading lists that needs to be addressed is that when a selection is changed in an earlier level the selections following that change are likely to be invalid. For example, if you select year 1963 and model Chevrolet, and then select year 1973, Chevrolet remains the selected model, even though our data source does not list it as a model for 1973. The old value needs to be cleared so that invalid selection combinations cannot exist. This can be easily corrected with Rules.

    With some extra work, you can probably determine whether the following selected values are still valid and clear only invalid ones, but there are advantages to just clearing each following selected value. One advantage is that rules can cascade as well—like a Domino effect. As one value is changed, the next value is cleared; clearing that value triggers the next value to clear, and so on.

    The rules we create will have no condition so that they will be processed every time the selected value changes. To clear the selected value of a field, we leave the Value text box of the rule blank.

    Clear the selected Make when the selected Year changes:

    1. Double-click the Year drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click Rules, and then click Add.
    3. Name the rule Clear Make, and then click Add Action.
    4. In the Action dialog box, select Set A Field's Value from the Action drop-down list.
    5. Click the Select XPath button to the right of the Field text box, and then select myFields/Vehicle/Make in the Main data source.
    6. Click OK five times to close all open dialog boxes.

    Clear the selected Model when the selected Make changes:

    1. Double-click the Make drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click Rules, and then click Add.
    3. Name the rule Clear Model, and then click Add Action.
    4. In the Action dialog box, select Set A Field's Value from the Action drop-down list.
    5. Click the Select XPath button to the right of the Field text box, and then select myFields/Vehicle/Model in the Main data source.
    6. Click OK five times to close all open dialog boxes.

    Try it:

    You have now created a three-level cascading list that prevents invalid selection combinations. Preview the form and try various selection combinations.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Create a Cascading List from a Flat Data Source

    It is common to need two or more list boxes where the choices in one are dependant on the value of another. This is known as a cascading list. A cascade can occur with as few as two levels up to any number of levels. Some common scenarios which require cascading lists are:

    • Location: State / City
    • Vehicle: Make / Model / Trim
    • School: Year / Semester / Class / Instructor

    As the number of levels in the cascade increases, so does the complexity of the process and work involved. Also, if the cascading list is presented inside of a repeating table or repeating section you must account for another issue: data crossover. Repeating cascading lists are covered in Create a Repeating Cascading List from a Flat Data Source and Create a Repeating Cascading List from a Hierarchical Data Source.

    In this task we will create a flat secondary data source containing the values used to populate our lists. We will then create a three-level non-repeating cascading list using drop-down list boxes. We create three levels of cascade to reveal the compounding complexity involved for level three and beyond. Because of the nature of the flat data source, we will filter each list to ensure that only unique values are displayed. And finally, we ensure valid selection combinations by clearing selected list values as selections earlier in the cascade are changed.


    THE FLAT SECONDARY DATA SOURCE

    Flat data sources are commonly returned from databases, Web services, and SharePoint. A flat data source has no hierarchy in the structure; it is simply a list of identical elements, each with an identical set of attributes. Only the values of the attributes change.  Flat data sources also require additional filtering to ensure that only unique values appear in the drop-down lists. Let's start by creating the flat secondary data source.

    Create the flat secondary data source:

    Copy the following code into a text editor, and then save the file as Vehicles - Flat Data Source.xml. This file will be used as a secondary data source in our form.

    <?xml version="1.0" encoding="UTF-8"?>
    <Vehicles>
        <Vehicle year="1963" make="Chevrolet" model="Corvette"/>
        <Vehicle year="1963" make="Chevrolet" model="Nova"/>
        <Vehicle year="1963" make="Porsche" model="356"/>
        <Vehicle year="1963" make="Porsche" model="Carrera"/>
        <Vehicle year="1973" make="Ford" model="Bronco"/>
        <Vehicle year="1973" make="Ford" model="Mustang"/>
        <Vehicle year="1973" make="Ford" model="Pinto"/>
        <Vehicle year="1973" make="Toyota" model="Celica"/>
        <Vehicle year="1973" make="Toyota" model="Land Cruiser"/>
        <Vehicle year="1979" make="Jaguar" model="XJ6"/>
        <Vehicle year="1979" make="Pontiac" model="Trans Am"/>
        <Vehicle year="1979" make="Volvo" model="240"/>
        <Vehicle year="1979" make="Volvo" model="244DL"/>
        <Vehicle year="1987" make="Dodge" model="Ram Charger"/>
        <Vehicle year="1987" make="Dodge" model="Grand Caravan"/>
        <Vehicle year="1987" make="Honda" model="Civic"/>
        <Vehicle year="1987" make="Honda" model="Prelude"/>
        <Vehicle year="1987" make="Nissan" model="300ZX"/>
        <Vehicle year="1987" make="Nissan" model="Pulsar"/>
        <Vehicle year="1987" make="Nissan" model="Sentra"/>
        <Vehicle year="1999" make="GMC" model="Jimmy"/>
        <Vehicle year="1999" make="GMC" model="Sierra 2500 HD"/>
        <Vehicle year="1999" make="GMC" model="Yukon"/>
        <Vehicle year="1999" make="Honda" model="Passport"/>
        <Vehicle year="1999" make="Honda" model="Prelude"/>
        <Vehicle year="1999" make="Honda" model="CR-V"/>
        <Vehicle year="1999" make="Jeep" model="Cherokee"/>
        <Vehicle year="1999" make="Mercury" model="Grand Marquis"/>
        <Vehicle year="1999" make="Mercury" model="Sable"/>
        <Vehicle year="1999" make="Mercury" model="Villager"/>
        <Vehicle year="1999" make="Pontiac" model="Firebird"/>
        <Vehicle year="1999" make="Pontiac" model="Montana"/>
        <Vehicle year="1999" make="Pontiac" model="Sunfire"/>
        <Vehicle year="2003" make="Dodge" model="Dakota"/>
        <Vehicle year="2003" make="Dodge" model="Caravan"/>
        <Vehicle year="2003" make="Dodge" model="Ram Charger"/>
        <Vehicle year="2003" make="Dodge" model="Viper"/>
        <Vehicle year="2003" make="Mercury" model="Sable"/>
        <Vehicle year="2004" make="Dodge" model="Stratus"/>
        <Vehicle year="2004" make="Dodge" model="Viper"/>
        <Vehicle year="2004" make="Ford" model="Crown Victoria"/>
        <Vehicle year="2004" make="Ford" model="F250"/>
        <Vehicle year="2004" make="Ford" model="Thunderbird"/>
        <Vehicle year="2004" make="GMC" model="Sierra 3500"/>
        <Vehicle year="2004" make="Jeep" model="Grand Cherokee"/>
        <Vehicle year="2004" make="Jeep" model="Liberty"/>
    </Vehicles>


    THE FORM

    Now that we have our flat secondary data source we are ready to create our form. First we will design a simple schema to support a three-level cascading list. Then we will design the layout using drop-down list boxes. When the layout is complete we will focus on creating the cascade.

    Add the secondary data source to a form:

    1. Design a new blank form.
    2. Choose Data Connections from the Tools menu, and then click Add.
    3. In the Data Connection Wizard, select Receive Data, and then click Next.
    4. Select XML Document, and then click Next.
    5. Click Browse, locate and select the Vehicles - Flat Data Source.xml file, click Open, and then click Next.
    6. Click Finish, click Yes, and then click Close.

    Create the schema:

    1. Open the Data Source task pane.
    2. Add a Group named Vehicle.
    3. Select the Vehicle group, and then add three Text Fields named Year, Make, and Model.

    Design the view:

    1. Insert a 1x3 layout table into the view.
    2. From left to right, insert the Year, Make, and Model fields as Drop-Down List Boxes into the cells of the layout table, as shown in Figure 1.


    Figure 1. Layout of the cascading drop-down list boxes.


    THE CASCADING LISTS

    With the form layout complete we will now turn our attention to the meat of the task: making one list cascade off of another. The process is not very difficult, but can become increasingly complex as the number of cascade levels increases. Creating a cascade requires the use of filters. The options displayed in one list box are filtered based on the values selected in earlier list boxes. Let's populate each drop-down list box using our secondary data source and create the cascade filters.

    Populate the Year drop-down list:

    1. Double-click the Year drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Flat Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, select Vehicles/Vehicle/year, and then click OK twice to close the open dialog boxes.

    Populate the Make drop-down list:

    1. Double-click the Make drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Flat Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, select Vehicles/Vehicle/make.

    Filter the Make drop-down list based on the selected Year:

    1. Click Filter Data, and then click Add.
    2. In the Specify Filter Conditions dialog box, select Select A Field Or Group from the first drop-down list.
    3. In the Select A Field Or Group dialog box, select Vehicles/Vehicle/year, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Select A Field Or Group.
    6. In the Select A Field Or Group dialog box, select Main from the Data Source drop-down list, select myFields/Vehicle/Year, and then click OK (refer to Figure 2).


    Figure 2. Filtering the second level of a cascading list.

    1. Click OK four times to close all open dialog boxes.

    At this point you have created a two-level cascade. The options in the Make drop-down list are filtered based on the selected Year. You can test this by previewing your form. Now let's create the level-three cascade, which will reveal the compounding complexity involved in creating each additional level of cascade from here.

    Populate the Model drop-down list:

    1. Double-click the Model drop-down list box.
    2. In the Drop-Down List Box Properties dialog box select Look Up Values In A Data Connection.
    3. Select Vehicles - Flat Data Source from the Data Connection drop-down list.
    4. Click the Select XPath button to the right of the Entries text box, and then select Vehicles/Vehicle/model.

    Filter the Model drop-down list based on the selected Year:

    1. Click Filter Data, and then click Add.
    2. In the Specify Filter Conditions dialog box, select Select A Field Or Group from the first drop-down list.
    3. In the Select A Field Or Group dialog box, select Vehicles/Vehicle/year, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Select A Field Or Group.
    6. In the Select A Field Or Group dialog box, select Main from the Data Source drop-down list, select myFields/Vehicle/Year, and then click OK.

    Filter the Model drop-down list based on the selected Make:

    1. Click And to create a second filter condition.
    2. In the first drop-down list of the second filter condition, select Select A Field Or Group.
    3. In the Select A Field Or Group dialog box, select Vehicles/Vehicle/make, and then click OK.
    4. In the second drop-down list, select Is Equal To.
    5. In the third drop-down list box, select Select A Field Or Group.
    6. In the Select A Field Or Group dialog box, select Main from the Data Source drop-down list, select myFields/Vehicle/Make, and then click OK (refer to Figure 3).


    Figure 3. Filtering the third level of a cascading list.

    1. Click OK four times to close all open dialog boxes.

    You have now created a three-level cascade. Preview the form and test the functionality of the drop-down list boxes. You may discover two issues: first, the list options are not unique, and second, you can create invalid selection combinations. These two issues will be resolved in the next two sections.


    FILTERING LISTS FOR UNIQUE VALUES

    Values in flat data sources are usually repeated. Although this is important given the XML structure, it can lead to option bloat in your list box. It can only serve to confuse and frustrate the user to present them with numerous identical options. The answer is to filter the list to display only unique values. This can be done using XPath.

    It should be mentioned that just as the complexity of the cascading filters compounded with each additional cascading level, so does the complexity of the uniqueness filters. You will see this in the expression used to filter the Model drop-down list for unique values.

    Add a uniqueness filter to the Year drop-down list:

    1. Double-click the Year drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click the Select XPath button to the right of the Entries text box.
    3. In the Select A Field Or Group dialog box, click Filter Data, and then click Add.
    4. In the Specify Filter Conditions dialog box, select The Expression from the first drop-down list, and then type the following expression (as shown in Figure 4):

    not(. = ../preceding-sibling::Vehicle/@year)


    Figure 4. Filtering list options to display only unique values.

    1. Click OK four times to close all open dialog boxes.

    Add a uniqueness filter to the Make drop-down list:

    At each cascade level beyond the initial list box, your uniqueness filter must take into consideration the selection from each of the previous levels. Due to the nature of this filter, if you do not take the previous selections into consideration, you may inadvertently completely filter out all valid options.

    For example, in our sample secondary data source, vehicle years 1987 and 1999 both include the Honda make. If we did not account for the selected year, the Honda make would not appear as an option when year 1999 was selected. This is because the filter would identify that the Honda make appeared earlier in the secondary data source. The Dodge make in years 2003 and 2004 would also be completely filtered out because Dodge appears earlier in year 1987.  There are a few other makes and models in the sample secondary data source that would encounter this issue.

    1. Double-click the Make drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click the Select XPath button to the right of the Entries text box.
    3. In the Select A Field Or Group dialog box, click Filter Data, and then click Add.
    4. In the Specify Filter Conditions dialog box, select The Expression from the first drop-down list, and then type the following expression:

    not(. = ../preceding-sibling::Vehicle[@year = current()/my:Vehicle/my:Year]/@make)

    Note that compared with the uniqueness filter we placed on the Year drop-down list box, there is an additional subfilter specified on the Vehicle node. The subfilter [@year = current()/my:Vehicle/my:Year] constrains the main filter to verify that we display unique values for each make within the selected year.

    1. Click OK four times to close all open dialog boxes.

    Add a uniqueness filter to the Model drop-down list:

    1. Double-click the Model drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click the Select XPath button to the right of the Entries text box.
    3. In the Select A Field Or Group dialog box, click Filter Data, and then click Add.
    4. In the Specify Filter Conditions dialog box, select The Expression from the first drop-down list, and then type the following expression:

    not(. = ../preceding-sibling::Vehicle[@year = current()/my:Vehicle/my:Year and @make = current()/my:Vehicle/my:Make]/@model)

    Just as we did with the uniqueness filter for the Make drop-down list above, here we have added an additional subfilter to guarantee that we are only eliminating repeated options from the list of models within the selected year and selected make.

    1. Click OK four times to close all open dialog boxes.

    If you can guarantee that the values, at any level of cascade, will always and forever be unique then you do not need to add the uniqueness filter. If, however, there is any doubt, it is always safer to add it. For more information on filtering lists for unique values, refer to Display Only Unique Options in a List.


    CLEARING SELECTIONS AFTER CHANGES

    One issue with cascading lists that needs to be addressed is that when a selection is changed in an earlier level the selections following that change are likely to be invalid. For example, if you select year 1963 and model Chevrolet, and then select year 1973, Chevrolet remains the selected model, even though our data source does not list it as a model for 1973. The old value needs to be cleared so that invalid selection combinations cannot exist. This can be easily corrected with Rules.

    With some extra work, you can probably determine whether the following selected values are still valid and clear only invalid ones, but there are advantages to just clearing each following selected value. One advantage is that rules can cascade as well—like a Domino effect. As one value is changed, the next value is cleared; clearing that value triggers the next value to clear, and so on.

    The rules we create will have no condition so that they will be processed every time the selected value changes. To clear the selected value of a field, we leave the Value text box of the rule blank.

    Clear the selected Make when the selected Year changes:

    1. Double-click the Year drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click Rules, and then click Add.
    3. Name the rule Clear Make, and then click Add Action.
    4. In the Action dialog box, select Set A Field's Value from the Action drop-down list.
    5. Click the Select XPath button to the right of the Field text box, and then select myFields/Vehicle/Make in the Main data source.
    6. Click OK five times to close all open dialog boxes.

    Clear the selected Model when the selected Make changes:

    1. Double-click the Make drop-down list box.
    2. In the Drop-Down List Box Properties dialog box, click Rules, and then click Add.
    3. Name the rule Clear Model, and then click Add Action.
    4. In the Action dialog box, select Set A Field's Value from the Action drop-down list.
    5. Click the Select XPath button to the right of the Field text box, and then select myFields/Vehicle/Model in the Main data source.
    6. Click OK five times to close all open dialog boxes.

    Try it:

    You have now created a three-level cascading list that filters for unique values and prevents invalid selection combinations. Preview the form and try various selection combinations.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Switch Views During the OnLoad Event

    InfoPath provides the SwitchView method to allow you to programmatically switch views from within your code. But SwitchView is a method of the View object, which does not exist until after the OnLoad event has completed. Any attempt, therefore, to use the SwitchView method in the OnLoad event handler will fail.

    The appropriate method to switch views during the OnLoad event is to set the default view. The default view is the view that will be displayed when the form first loads. Add the following code to the OnLoad event handler to set the default view:

    BLOCKED SCRIPT
    XDocument.ViewInfos("My View Name").IsDefault = true;

    C#:
    thisXDocument.ViewInfos["My View Name"].IsDefault = true;

    This code only works in the OnLoad event handler. Attempts to set the default view elsewhere will not accomplish anything—not even result in a failure.

    An alternative to setting the default view in the OnLoad event handler is to switch views using the open rules. This performs the same function, yet requires no code.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Lock the Format Painter for Repeated Usage

    The Format Painter, located on the Standard toolbar, is a very useful tool for applying established formatting from one item to another. It avoids the potentially lengthy process of applying a complex combination of formatting styles by use of the menus, task panes, etc. It does, however, have its limitations: It does not apply formatting such as borders, padding and margins, and it can be very tedious to use as it only applies the source formatting to a single destination before you need to reselect the source formatting.

    Although there is nothing that can be done about the borders, padding and margins, there are two rather obscure approaches that allow you to continue to apply the source formatting without the need to reselect it after each application.

    Before addressing each approach it should be noted that switching views will cause the format painter to reset, or lose it settings. It is therefore impossible to paint a format across views. To work around this, you can copy the formatted text from the source view and paste it into the destination view, use the format painter, and then delete the copied source text.


    APPROACH 1 – LOCK THE FORMAT PAINTER ON

    The first approach is to lock the Format Painter on. You do this by first clicking on or selecting the source of the formatting, and then double-clicking the toolbar button. The Format Painter will remain in this locked position until you unlock it. This allows you to continue to apply the source formatting to multiple destinations without needing to reselect it. To unlock the Format Painter press Escape, click the toolbar button again, activate another toolbar button or menu item, or start typing.


    APPROACH 2 – USE KEYBOARD SHORTCUTS

    The second approach is to use the keyboard shortcuts. The source formatting you select using either the Format Painter toolbar button or the keyboard shortcut is stored until you change it. To use the keyboard shortcuts, first click on or select the source of the formatting, and then press Ctrl+Shift+C to copy it. You can continue applying the source formatting by clicking on or selecting the destination, and then pressing Ctrl+Shift+V.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Change the Checked and Cleared Values of a Check Box

    Changing the checked and cleared values of a check box bound to a field in the main data source is easily accomplished using the built-in UI on the Data tab of the Check Box Properties dialog box. Changing the checked and cleared values of a check box bound to a field in a secondary data source requires manually modifying the view .xsl file.

    When you add a data connection to an .xml file, InfoPath makes no attempt to decipher data types for each field and attribute but simply assigns everything the string data type. Although this can be inconvenient, it can be fixed.

    When you insert a Check Box into the view for a field with the string data type, whether from the main data source or a secondary data source, InfoPath will always use yes for the checked value and no for the cleared value (as shown in Figure 1).


    Figure 1. For string data type fields, InfoPath uses yes for the checked value and no for the cleared value.

    When you insert a Check Box into the view for a field with the Boolean data type, whether from the main data source or a secondary data source, InfoPath will always use true for the checked value and false for the cleared value (as shown in Figure 2).


    Figure 2. For Boolean data type fields, InfoPath uses true for the checked value and false for the cleared value.

    Figures 1 and 2 illustrate that a check box bound to a field in a secondary data source does not provide the ability to change the checked and cleared values, as these options are grayed out. If your form is expecting these values to be something other than yes/no or true/false, you will need to modify the view .xsl file to change these values.

    In this task we will create a form that includes a secondary data source with two fields intended to hold Boolean values, for which InfoPath will create a schema using the string data type. We will modify the view .xsl file to use 1 and 0 as the checked and cleared values of the first check box, and use Present and Absent as the checked and cleared values of the second check box. Let's start by creating the secondary data source.

    Create the secondary data source:

    Copy the following code into a text editor, and then save the file as Booleans.xml. This file will be used as a secondary data source in our form.

    <?xml version="1.0" encoding="UTF-8"?>
    <Booleans>
        <ItemAvailable/>
        <StudentAttendance/>
    </Booleans>

    Add the secondary data source to a form:

    1. Design a new blank form.
    2. Choose Data Connections from the Tools menu, and then click Add.
    3. In the Data Connection Wizard, select Receive Data, and then click Next.
    4. Select XML Document, and then click Next.
    5. Click Browse, locate and select the Booleans.xml file, click Open, and then click Next.
    6. Click Finish, click Yes, and then click Close.

    Insert the two check boxes into the view:

    1. Open the Data Source task pane.
    2. Select the Booleans secondary data source.
    3. Right-click ItemsAvailable, click Check Box, and then press Enter.
    4. Right-click StudentAttendance, and then click Check Box.

    Modify the view .xsl file:

    1. Choose Extract Form Files from the File menu.
    2. Select a location to save your extracted form files to, and then click OK.
    3. Close InfoPath to release the lock it places on your form files.
    4. Using a text editor, open your view .xsl file.

    Change the checked and cleared values for the first check box:

    1. Search for the text xd:offValue="no" to locate the input element that represents your first Check Box control.
    2. Make the following changes to the first input element:

    xd:offValue="no" xd:onValue="yes"

    to:

    xd:offValue="0" xd:onValue="1"

    1. Search for the text &quot;yes, and then make the following change:

    ItemAvailable=&quot;yes&quot;

    to:

    ItemAvailable=&quot;1&quot;

    Change the checked and cleared values for the second check box:

    1. Search for the text xd:offValue="no" to locate the input element that represents your second Check Box control.
    2. Make the following changes to the second input element:

    xd:offValue="no" xd:onValue="yes"

    to:

    xd:offValue="Absent" xd:onValue="Present"

    1. Search for the text &quot;yes, and then make the following change:

    StudentAttendance=&quot;yes&quot;

    to:

    StudentAttendance=&quot;Present&quot;

    Review your changes:

    1. Save the view .xsl file, and then close the text editor.
    2. Reopen your form template by right-clicking the manifest.xsf file and choosing Design.

    Now when examine the Check Box Properties dialog boxes for the two check boxes, you will find your altered checked and cleared values, as shown in Figure 3. Provided that you do not delete the modified check box and insert a new one, the updated values will be persisted even through a rebinding.


    Figure 3. The checked and cleared values have been manually modified.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Remove a Form Template From the Cache

    The first time a form template is launched, InfoPath places it into its form template cache. On each subsequently launch, InfoPath will first check to see whether the template is already in the cache. This is very beneficial for forms that are only available online. If you are working with an online form, and you go offline, the cached form template is still available.

    While you are still designing your form template you will be testing the work you do. If you preview your form template from the designer, all of the latest changes will be made available. But previewing is not always an appropriate method to test your form. If you save the form template and then launch it from another method, the latest changes might not be made available if the form template is already in the cache. To remedy this you will need to remove the form template from the cache.

    Removing a form template from the cache is accomplished differently based on whether it was installed from a .msi file. You are not allowed to remove an installed form template in the same way you can a normal form template. Installed form templates must be uninstalled.

    In this task, we will learn how to remove a normal, and an installed form template from the InfoPath cache. This will force InfoPath to reload the form template from the source the next time it is launched, thus making available any recent changes.

    Remove a normal form template from the InfoPath cache:

    1. Close any open instance of the form template you want to remove.
    2. Launch InfoPath, or if InfoPath is already open choose Fill Out A Form from the File menu.
    3. In the Fill Out A Form dialog box, select the form that you want to have removed from the cache.

    If you do not find the form listed, select the All Forms category, and then look again.

    1. Click Remove This Form in the Form Tasks.

    Remove an installed form template from the InfoPath cache:

    1. Shut down InfoPath.
    2. Open the Windows Control Panel.
    3. Launch Add Or Remove Programs.
    4. Locate and select the installed form template, and then click Remove.
    5. Click Yes if asked whether you are sure you want to remove the form template from your computer.

    That's it. You have successfully removed a form from the cache. For a normal form template, you only need to launch it again and it will be added back to the cache with the latest changes. An installed form must be reinstalled from an updated .msi file.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Make Hyperlinks Visually Interactive

    The InfoPath designer only allows you to change the color of a hyperlink. It does not allow you to remove the underline text decoration, nor does it allow you to create a separate color for when the mouse pointer is hovering over the hyperlink or for when the user tabs to the hyperlink. These designer limitations can be overcome by manually modifying the view .xsl file.

    In this task we will make hyperlinks visually interactive by adding a custom internal style sheet to your view .xsl file. Let's start by designing a new blank form.

    Add a Hyperlink control to the view:

    1. Open the Controls task pane.
    2. Insert a Hyperlink into the view.
    3. In the Insert Hyperlink dialog box, type http://www.InfoPathDev.com into the Link To Address text box, and then click OK.

    Try it:

    1. Preview your form.
    2. Hover over the hyperlink, tab to it, and click on it to see how it responds.
    3. Close the preview.

    As you can see, InfoPath does not display hyperlinks differently for any of the mouse and keyboard activity we tried. Now let's enhance the behavior.

    Manually add a custom internal style sheet to the view:

    1. Choose Extract Form Files from the File menu.
    2. Select a location to save your extracted form files to, and then click OK.
    3. Close InfoPath to release the lock it places on your form files.
    4. Using a text editor, open the view .xsl file.
    5. Add the following code just below the last style element:

    <style title="myCustomHyperlinks" type="text/css">
        A { COLOR: orange; TEXT-DECORATION: none }
        A:visited { COLOR: red; } <!-- This pseudo class has no effect in the editor -->
        A:active { COLOR: blue; TEXT-DECORATION: underline }
        A:hover { COLOR: green; TEXT-DECORATION: underline }
    </style>

    If you have already made any color changes to the hyperlinks in the designer, you will need to manually remove the font elements immediately around your hyperlink text to allow your new styles to take effect.

    1. Save your view .xsl file, and then close the text editor.

    Try it:

    1. Reopen your form template by right-clicking the manifest.xsf file and choosing Design.
    2. Preview your form.
    3. Hover over the hyperlink, tab to it, and click on it to see the changes.

    The styles specified in the active pseudo class appear when the user tabs to the hyperlink, while the style specified in the hover pseudo class appear when the user holds the mouse pointer over the hyperlink. The ordering of the pseudo classes is important. If active is listed after hover, the user will not have any mouseover effects for the active hyperlink. If this is the effect you desire, make the appropriate change in order.

    The visited pseudo class appears to work in the designer, but the InfoPath editor does not keep track of which links were visited; therefore the user will never see this style applied.

    For more information about custom style sheets, refer to Add a Custom Style Sheet to a View.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

  • Continue a Numbered List

    When creating numbered lists in InfoPath, you might need to have the numbers of a second list continue where the first list left off. In Microsoft Word you can right-click the numbers of the second list and choose Continue Numbering. You cannot do this in InfoPath. Though not as convenient, InfoPath does provide a couple ways to do this.

    In this task we will examine two approaches to continuing a numbered list: start numbering at a specific number and use line breaks. Each approach has an advantages and disadvantages. Let's start with a new blank form.


    APPROACH 1 – START NUMBERING AT A SPECIFIC NUMBER

    InfoPath provides an obscure feature at the bottom of the Bullets And Numbering task pane that allows you to specify a starting number for a numbered list. The advantages of this approach are that the content placed between the two lists can appear as a normal paragraph—meaning that it will not be indented, the content is not actually part of the list, and there are no restrictions to the content that can be used. The disadvantage is that the number chosen to start the second list is fixed and must be updated when items are added to or removed from the first list.

    Create a ten item numbered list:

    1. Click Numbering on the Formatting Toolbar to create a numbered list.
    2. Add ten random items to the numbered list.

    Specify the starting number for a list:

    1. Click on the end of list item five to set the insertion point.
    2. Press Enter, and then press Backspace to separate the lists.
    3. Add some random non-list content.
    4. Click on the start of the second list to set the insertion point.
    5. Choose Bullets and Numbering from the Format menu.
    6. In the Start Numbering At spin box at the bottom of the Bullets and Numbering task pane, specify the number 6.

    One interesting thing to note is that although you can choose between Arabic, Roman, or Alphabetic number formatting, the Start Numbering At spin box always displays Arabic numbers.


    APPROACH 2 – USE LINE BREAKS

    Another obscure feature—part of rich text editing—is that you can press Shift+Enter on a list item to create a line break rather pressing Enter, which will create a new list item. The advantage of this approach is that the list is never actually broken. There is, therefore, no issue with continuing numbers becoming out of sync. The disadvantages are that line breaks are indented to left-align with the list item, the non-list content is actually part of the list item, and layout tables are forced onto a new list item. There are also certain formatting features that may not work as expected (or at all) in this approach.

    Create a ten item numbered list:

    1. Click Numbering on the Formatting Toolbar to create a numbered list.
    2. Add ten random items to the numbered list.

    Insert line breaks:

    1. Click on the end of list item five to set the insertion point.
    2. Press Shift+Enter to create a line break.
    3. Add some random non-list content, making sure to use Shift+Enter instead of Enter to start each new line.

    ©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

More Posts Next page »
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.