Wednesday, November 12, 2008

Poor Man's Encapsulation in InfoPath Conditional Formatting

Clay Fox (Infopath MVP) answered one of my recent posts on the InfoPath newsgroup in a way that led me to the realization that the encapsulation I had been missing while using the same conditions repeatedly throughout my large InfoPath form is actually available in a sort of poor-man's encapsulation way.

Say you want to disable or hide a lot of your form controls if the form has already been submitted according to a field called "Project Status" which is on the "General" view of your multi-view form. This could affect dozens of fields across multiple views that require essentially the same conditional formatting conditions to be true in order to be disalbed, hidden, or rendered read-only.

You might normally enter the conditions in this manner:

But if you have to work all those dropdowns again and again for every control on your form, you have a few problems, including a lot of time required to step through all that tedious stuff, the possibility you'll commit errors while entering the conditions, or that you'll omit certains parts of the conditions from one or more fields.
What you really want is an easy way to make sure any number of fields have these same conditions. That's what programmers would use encapsulation for, but since InfoPath doesn't really offer encapsulation to people configuring forms, we have to use a poor man's version.

To do this, assume you've set up your conditions as shown in the previous image. Next, you want to change the leftmost dropdownon on each line to "The expression." When you do this, you'll notice that the textbox just to the right gets automatically updated to reflect the XPath expression equivalent to what you had previously selected in dropdown lists.

Copy each row after the first row into the first row's text box, separating each clause by the word " and " so you get one long expression in the first row. Delete the other rows, leaving only the first row, with the long expression showing in the textbox. (Make sure you haven't forgotten to separate each clause by " and " !)

If you haven't already done so, copy the long expression out of the textbox into your clipboard, and/or drop it into a notepad file or something similar, to keep it handy.

Click"OK" to close this dialog box, and return to your form in design mode.

Just to understand what all that did, right-click your form control again, and click "Conditional Formatting." You should see the following, which is equivalent to the conditions you established in the first place:

If this is seeming like a long way to go to get the same result, remember that our goal is to achieve some sort of reuse here that saves us time and reduces errors when we're setting up other, identical conditional formatting rules elsewhere on our large form. Well, now you just need to go to those controls, right click and choose "Conditional Formatting" and just select "The expression" and paste in the long expression, and you're all set.
By the way, since I originally posted this blog entry, I've observed that this method does not always work when dealing with controls embedded within repeating tables, and that there may also be some problems when working with radio buttons, so keep your eyes out for those gotchas when testing your form. Fortunately, the old-fashioned way works as a fallback solution for these flaws in the approach.
In the case of a multi-view form, you may need to use the old-fashioned method for the first control on each view, and then recapture the expression before pasting it elsewhere, because each successive view is further removed in the schema, and additional information may therefore be required when identifying your particular field. The telltale sign of this problem is that InfoPath does not automatically convert your expression to a form that looks just as if the old-fashioned method had been used in the first place.
Try it out and let me know what you think!
Again, I have to thank Clay Fox for mentioning to me that you could do this kind of thing.
Clay Fox regularly contributes to:


  1. The experession doesn't work for more than 10 fields, why?

  2. So far I have not been able to figure out how to get around the 5 field limit in any obvious way. Generally speaking when you have more than five fields involved, you are likely to have some exclusive ORs going on. If that's the case, keep in mind that you can have two separate rules that fire in sequence. The first rule can be everything before the OR and the second rule can be everything after the OR. The effect should be the same as one long multi-clause rule with an OR in between.

    If you do indeed have an AND situation that exceeds five fields, you may have to either find some way to simplify your schema, or look at a custom code approach.

    If you do find a workaround for that problem, please be sure to come back and share it.


  3. This solution works but only for a certain limit of conditions. In my case, I needed to apply around 80 condition checks on submit button, I used the above solution but the form started throwing error while publishing the form. In the design checker it said - Xpath requires complicated processing something something, I spent so much time debugging the problem and finally found out that its not accepting so many conditions in the expression so I broke my expression into 2 parts (with 40 conditions in each) and then create two rules in my submit button. This worked for one the condition checks where i was using "or" but I am not sure how to fix this problem where I need to "and" all the 80 fields.
    Any inputs would be helpful.

  4. Wow, if you are trying to do 80 condition checks, you may need to look at programming, as opposed to configuration. I haven't tackled one on that scale (yet), so I can't advise. Anyone?

  5. This seems to work:

  6. Thank you so much for posting this, it's what I needed to figure out how to evaluate 18 different choices for setting a field's value. I'm using infoPath 2010 and it limited me to only 5 "or" choices in the expression per line - basically I had to break my expression up into 4 conditions in order to cover all 18. But it works. Much appreciated.


What do you think?