Controlling the Flow using Conditions

Conditions can be used to control a user's flow through an IEG script. A user's progression through an IEG script will follow a linear path from page to page within the script, unless you as the script author decide to change that flow. The main reason for changing this flow is to ensure users are not faced with unnecessary or irrelevant questions. A user's answers should be used to determine which questions do or do not relate to that user. For example, you may have a page which captures detailed information about a person's third-level education. You would not want to display this page to the user if the user had already indicated that he or she never attended a third-level college. In order to achieve this, you can surround one or more pages in a condition element to indicate under what conditions that page (or pages) is to be displayed; something like this:

Figure 1. Condition Element
<condition expression="attendedThirdLevel==true">
  <question-page id="ThirdLevelDetailsPage">  
    ...
  </question-page>
</condition>

When the user clicks on the Next button on the page prior to this condition, the system will evaluate the expression 'attendedThirdLevel==true'. If it evaluates to true, the page(s) within the condition will be displayed to the user; if it evaluates false, then the system will skip the page(s) and display the page after the condition element.

In this example, attendedThirdLevel is the id of a control question asked earlier in this script. The answer given will be used in the evaluation of the expression. If you want to use the value of an attribute within the Datastore instead, then you just need to prefix it with the name of the entity in which it is contained (e.g., Person.attendedThirdLevel).

When using expressions on conditions (or anywhere else for that matter), you must ensure that any attributes used within the expression will have a real value by the time they are evaluated. By default, attributes within the Datastore are null until a value has been set for them, and will stay that way if the user does not enter or choose a value for the appropriate answer.

Generally speaking, there are two ways to ensure that attributes have values before they are used in expressions: make the questions that populate them mandatory or give them default values in your Datastore schema (you could also use the set-attribute element in some cases, see set-attribute).

Conditions can contain any combination of pages (including summary pages), loops and other conditions. For example:

Figure 2. Nested Condition
<condition expression="attendedThirdLevel==true">
  <question-page id="ThirdLevelDetailsPage">
    ...        
  </question-page>
  <condition expression="hasMasters==true">
    <question-page id="MastersDetailsPage">
      ...        
    </question-page>
  </condition>
</condition>

This means that ThirdLevelDetailsPage would only be displayed if the attendedThirdLevel answer is true, and MastersDetailsPage would only be displayed if attendedThirdLevel is true and hasMasters is also true.

It is also possible to invoke a custom function from a condition or other expression. Information is automatically provided to the function to access the Datastore, i.e. root entity ID, script execution ID and currently entity ID (if the condition is within a loop). It should be noted that custom functions that have a side-effect (for example to populate some answers in the Datastore) shouldn't be used in such expressions as they won't necessarily be evaluated before the page content is loaded.

The custom function isNotNull is provided out-of-the-box in IEG to allow expressions to handle null values as parameters. For example, to validate a person's date of birth, it might first be necessary to ensure that a value exists:

Figure 3. Using 'isNotNull' Custom Function
<validation expression="
      isNotNull(Person.dateOfBirth)
      and isNotNull(Person.today)
      and (subDates(Person.dateOfBirth, Person.today) < 0)">
    <message id="DateOfBirthValidation">
      Your date of birth must be before today
    </message>
</validation>