2 title clarified from question text
| link

How to conceptually consider and implement user interface rules for numerous controls and data inputs?

source | link

How to conceptually consider and implement user interface rules?

I have a user interface with numerous controls and data inputs on it. Buttons, text fields, and checkboxes, etc. Imagine the following "rules" exist for a sample UI with 2 of those controls:

  • B2 cannot be used until TF1 and TF2 both have values
  • TF2 cannot be entered until TF1 has a value
  • CB2 cannot be checked unless TF1 has a value
  • CB2 cannot be checked unless CB1 is checked

These rules are arbitrary here, but I have a variety of business rules which will ultimately govern the UI functionality.

I would like to implement logic for this in my UI code to enforce these rules. However, I am having a hard time determining a good way to do so. I can think of two primary ways but I'm not really a fan of either.

Method 1 - adding logic to each control callback

One way to do this would be to add the logical check(s) to each method callback. So for the first rule, in the code associated with B2, include hard coded checks like if TF1 == "" and if TF2 == "". I am not a fan of this idea because I'm going to scatter any sequencing/logic everywhere in my UI and it seems inevitable sometime this process will result in obscure and impossible to track down bugs. Also seems like maintenance will be impossibly complex.

Method 2 - build collection of all rules

The way I'm leaning towards is building a collection of rules. The first step would be defining a set of rules for "passing" for each type of control and its associated lookups, such as:

  • For checkboxes, "passes" check for true, "fails" if false
  • For textboxes, "passes" if not empty, "fails" if = ""

I can then create a collection of all the prerequisite pass/fail checks for each UI component and its associated components. This can be abstracted into a single check method called in each UI action like:

  • myChecker(mControlName)

where myChecker is a method which iterates through the list of all matching rules, checks them, and returns true/false based on whether the rules pass. This method could be called from each UI control before any control-specific logic takes place.

This is nice, but it seems creating the rules and not forgetting any might be even more complex than the first method. Additionally, all control types have to have a "pass/fail" criteria or the myChecker method might become ridiculously complex with lots of hard to read if statements.

Am I missing something? There has to be a more clearly defined pattern or some better strategy for incorporating these sorts of validation/rules into a UI.