InfoPath Forms "Dropdown of Repeating Self" Bug Stomp


I was fooling around with InfoPath this weekend, trying to create a generic form and data definition for a flexible ad hoc workflow.

One thing I wanted in this form was the ability to specify dynamic routing between workflow steps. So, I created a repeating table for the steps and I also bound a repeating section to the same repeating group in the data. This let me summarize the steps in the table and then let the user specify the properties for each step in the details section below.

In the details section, I have dropdowns for Approve To, Reject To, and Overdue To that are meant to tell the workflow which step it should switch to when these events take place. Each of these dropdowns is meant to be populated by the list of steps.

Here is a shot of the designer:

Screenshot of the Designer View in InfoPath

So, in the data the XML looks like this:

Workflow Data Source Schema

Basically, I have the dropdowns bound to RouteTo in each case, and I want them to let the user pick from ID and TItle for the entire list of WorkflowTask items.

This is where InfoPath barfed, showing a glaring weakness. When you bind the dropdown list's items to the form data, and specify the repeating group as //WorkflowTasks/WorkflowTask it *should* encode that as relative to the parent element, giving you the full list, but instead it encodes it relative to the current element (which turns out to be just '.') giving you only the current WorkflowTask node.

I should also note that if you point the list to a repeating node that is outside the parent oath of the node of your dropdown list, then it will behave itself normally and give you all the nodes under that group.

Though it may be okay in some cases, for a dropdown list this behavior is less than useless. The field browser should give you enough control to let you specify a differnt xpath query at least, which it does not, leaving you stuck with what the wizard lets you pick. I will completely ignore the obvious usefulness of an xpath expression complete with functions, etc. that could've easily allowed for dynamic filtering of the list items.

So, my workaround was to save the IP template as source files, and then go into the source for view1.xsl and find the specific xsl that does the transform for the list. In my case, this looks like this.

I search for "Route To", which is my display name for the dropdown. Below, look for code like:

<xsl:for-each select="."><-- This is the offending xpath
<option>
<xsl:attribute name="value">
<xsl:value-of select="@my:ID"/>
</xsl:attribute>
<xsl:if test="$val=@my:ID">
<xsl:attribute name="selected">selected</xsl:attribute>
</xsl:if>
<xsl:value-of select="@my:DisplayName"/>
</option>
</xsl:for-each>

So, to get the complete list of nodes when you are already inside of it, just swing up to the parent node and select all the desired sub-nodes, like so:

<xsl:for-each select="../my:WorkflowTask">

Once I am done, I open my manifest.xsf and save as back to the original xsn form template. It isn't clear to me how long this hack will hold, but I was able to preview the modified template, and even make some changes to other parts of the form without reverting to the undesirable '.'.

Here's the preview of the form:

Screenshot of InfoPath Form in Preview Mode

It's not the most elegant solution in terms of maintainability, but it was a lot easier than writing custom code behind (and in some cases that isn't necessarily an option anyway), so I am glad to have found it.

Come to think of it, though I haven't tried it yet, you could hack the select with an xpath expression to filter the dropdown. If anyone gives that a shot, shoot me an email or comment and let me know. (Send it to anything at thomascarpe.com until I get my blog comments working.)

Update:
I did eventually see some weird looking XSL in the dropdowns after a couple of successive load-saves. This caused the value that was selected to be displayed as a choice within the list, and was completely undesirable behavior. I simply used the same hack as above to rid myself of the annoying extra option tag. :-)