Tuesday 10 August 2010

Conditional Default Values in InfoPath

Sometimes you want the default value of a field to be dependent upon a condition. However, there isn't any direct functionality to support IF statements in the default values of fields. Substituting a rule for a default value only gets you so far, as the rule is only applied when that field that changes, not the fields that the rule depends on. Updating the field whenever any dependent field is changed would require you to copy the rule to each field. This is not very maintainable, so below I will describe two approaches to avoiding this.

The first approach is simple, but it has some limitations and caveats. The second approach is more complicated, but should work in all cases.

Method 1: Using the union and array indexer operators

The first approach is to use the union operator '|' along with an array indexer '[]' to select the proper value:

(TrueResult | ElseResult) [(BoolCondition) + 1]

There are two caveats to using this approach:

  1. The node set will always be returned in document order. It does not matter what the order is in the parenthesis, as (field1 | field2) == (field2 | field1). Since you cannot change the node set ordering, you may have to modify your BoolCondition to be NOT-ed. For more information on document order, you can visit the w3.org page on XPaths.
  2. Inside of the parenthesis, you must only have nodes; you cannot have strings or any other type. So (field1 | "hello world") will not work.

Method 2: Using concat, substring and string-length

To overcome these caveats, you can use the second approach here.  That is to use concat, substring and string-length.  For example, the same generic if statement from the previous approach converts to

concat(

substring(TrueResult, 1, (BoolCondition) * string-length(TrueResult)),

substring(ElseResult, 1, (not(BoolCondition)) * string-length(ElseResult)))

No comments:

Post a Comment