Tuesday, October 15, 2013

InfoPath Conditional Logic

InfoPath is a great tool for designing simple or complex electronic forms and provides facilities for adding both code and declarative rules that execute against data fields in the form's schema.  Although this article is not intended to provide detailed instructions on InfoPath rule creation, there are a few concepts that help to understand:
  1. InfoPath forms have data fields that are defined in a schema.
  2. Data fields can have rules associated with them (validation, action, etc).
  3. Rules have conditions and actions (i.e., set a field's value).
One challenging aspect of InfoPath rules is conditional logic - basically, there is no easy way to create 'if-then' type conditional logic in a rule action.

In most languages, conditional logic is achieved with something like:

 if(num > 100) {
    result = 100;
 }
 else {
    result = num;
 }


What if you need to set an arbitrary ceiling on a numeric InfoPath field's value without custom code?  One relatively simple (albeit somewhat ugly) solution is to use the string-length() function and basic arithmetic.  The following is a screenshot of this scenario from a form I recently designed and developed.



How does it work?
The string-length() function returns the length of TRUE or FALSE (4 or 5) based on a logical comparison (>, <=, etc).  The conditional branches (e.g., the 'if', 'else' blocks) are achieved by subtracting 4 and 5 respectively and multiplying the results.

Example 1:

 /* Typical Code Conditional
  *******************************************************************************/
  num = 15;

  if(num > 100) {
     result = 100;
  }
  else {
     result = num;
  }

 /* InfoPath Rule Formula
  *******************************************************************************/
    (5 - string-length(num > 100)) * 100 + (5 - string-length(num <= 100)) * num
  = (5 - string-length(15 > 100)) * 100 + (5 - string-length(15 <= 100)) * 15
  = (5 - string-length(FALSE)) * 100 + (5 - string-length(TRUE)) * 15
  = (5 - 5) * 100 + (5 - 4) * 15
  = (0) * 100 + (1) * 15
  = 0 + 15
  = 15

Example 2:

 /* Typical Code Conditional
  ********************************************************************************/
 num = 150;

 if(num > 100) {
    result = 100;
 }
 else {
    result = num;
 }

 /* InfoPath Rule Formula
  ********************************************************************************/
    (5 - string-length(num > 100)) * 100 + (5 - string-length(num <= 100)) * num
  = (5 - string-length(150 > 100)) * 100 + (5 - string-length(150 <= 100)) * 150
  = (5 - string-length(TRUE)) * 100 + (5 - string-length(FALSE)) * 15
  = (5 - 4) * 100 + (5 - 5) * 15
  = (1) * 100 + (0) * 15
  = 100 + 0
  = 100

A complete and functional example of this technique is demonstrated in the article InfoPath 2013 - QB Passer Rating Form and this MSDN Sample.  The InfoPath form can be downloaded directly at QBRatingForm.xsn (16K).

2 comments: