How to handle errors on interdependent fields

This ‘How-to’ provides information on how to handle errors on two or more interdependent fields, for example a ‘Start’ and ‘End’ date range.

When in the ‘context’ of a particular field, the Supervisor will handle the ‘clean up’ of errors assigned to that field.
For example, in the context of Start date the following code checks that Start date is not greater than End date (if End date is not blank):

    $PROPERTIES
       Case CURPRO
          When “STARTDATE” : Gosub STARTDATE
       Endcase
    Return

    $STARTDATE
       Case ACTION
          When “PROPAGATE”
             Gosub VALIDATE_STARTDATE
       Endcase
    Return

    $VALIDATE_STARTDATE
       If this.ENDDATE <> AVOID.ADATE & this.STARTDATE > this.ENDDATE
          ASTATUS = fmet this.ASETERROR(“STARTDATE”, “Start date cannot be after End date”, [V]CST_AERROR)
       Endif
    Return

If an invalid Start date is entered, the error “Start date cannot be after End date” is displayed, attached to the Start date field.

If, subsequently, a valid Start date is entered, the error is cleared by the Supervisor.

Note: Implementing the validation on the Start date’s PROPAGATE event means that the validation will not be executed again when 'Save' is clicked.

Similar validation can also be applied to the End date:

    $PROPERTIES
       Case CURPRO
          When “STARTDATE” : Gosub STARTDATE
          When “ENDDATE” : Gosub ENDDATE
       Endcase
    Return

    $STARTDATE
       Case ACTION
          When “PROPAGATE”
             Gosub VALIDATE_STARTDATE
       Endcase
    Return

    $ENDDATE
       Case ACTION
          When “PROPAGATE”
             Gosub VALIDATE_ENDDATE
       Endcase
    Return

    $VALIDATE_STARTDATE
       If this.ENDDATE <> AVOID.ADATE & this.STARTDATE > this.ENDDATE`
          ASTATUS = fmet this.ASETERROR(“STARTDATE”, “Start date cannot be after End date”, [V]CST_AERROR)
       Endif
    Return

    $VALIDATE_ENDDATE
       If this.ENDDATE <> AVOID.ADATE & this.ENDDATE < this.STARTDATE
          ASTATUS = fmet this.ASETERROR(“ENDDATE”, “End date cannot be before Start date”, [V]CST_AERROR)
       Endif
    Return

If an invalid End date is entered, the error “End date cannot be before Start date” is displayed, attached to the End date field.

If, subsequently, a valid End date is entered, the error is cleared by the Supervisor.

However, instead of correcting the last error by re-entering a valid End date, what if the date range error was corrected by adjusting the Start date?

Although the date range is now valid, and no new error is displayed, the previous error (assigned to End date) is not cleared by the Supervisor because the process is now in the context of Start date.

To clear the previous error in this scenario, the method "ADELETEERROR" must be manually called to clear any errors on the alternate field (see the following code):

    $VALIDATE_DATES

       If CURPRO = “STARTDATE”
          ASTATUS = fmet this.ADELETEERROR(“ENDDATE”)
       Else
          ASTATUS = fmet this.ADELETEERROR(“STARTDATE”)
       Endif

       If this.ENDDATE <> AVOID.ADATE & this.STARTDATE > this.ENDDATE
          If CURPRO = “STARTDATE”
             ASTATUS = fmet this.ASETERROR(“STARTDATE”, “Start date cannot be after End date”, [V]CST_AERROR)
          Else
             ASTATUS = fmet this.ASETERROR(“ENDDATE”, “End date cannot be before Start date”, [V]CST_AERROR)
          Endif
       Endif
    Return

    $VALIDATE_STARTDATE
       ASTATUS = fmet this.ADELETEERROR(“ENDDATE”)
       If this.ENDDATE <> AVOID.ADATE & this.STARTDATE > this.ENDDATE
          ASTATUS = fmet this.ASETERROR(“STARTDATE”, “Start date cannot be after End date”, [V]CST_AERROR)
       Endif
    Return

    $VALIDATE_ENDDATE
       ASTATUS = fmet this.ADELETEERROR(“STARTDATE”)
       If this.ENDDATE <> AVOID.ADATE & this.ENDDATE < this.STARTDATE
          ASTATUS = fmet this.ASETERROR(“ENDDATE”, “End date cannot be before Start date”, [V]CST_AERROR)
       Endif
    Return

Note: Hard-coded message strings should be replaced with mess( ) calls.