-
Notifications
You must be signed in to change notification settings - Fork 17
WSubordinateControl
WSubordinateControl was a means to provide some simple client-level state control in a Java API. It is a weak mechanism which is an artefact of a past time with flawed framework design paradigms.
- Using WSubordinateControl
- The Java API
- WSubordinateControl actions
- Trigger components
- Target components
- Further information
The WSubordinateControl provides a way to improve the perceived application performance by shifting some basic conditional operations to the client. The WSubordinateControl enables screen logic to be abstracted in such a way that the logic can be executed by both the client-side theme and the server-side WComponent framework.
A word of warning: Use of this control is likely to cause maintenance issues. It is recommended that you use it only for simple situations as overly complex rules become difficult to maintain.
WSubordinateControl does not itself have a UI artefact.
The subordinate logic can be expressed in pseudo-code as:
if
some condition is met
then
perform some action (if set)
else
perform some other action (if set)
Conditions are specified using equality tests on input field values and the "And" and "Or" logical operators. Consider the condition expressed in pseudo-code:
if myCheckbox is checked
AND (
myDropdown's selection = "abc"
OR
myTextField's text = "def"
)
Conditions in the subordinate API are built starting from the innermost expression, which in this case are the equality tests in the "Or" condition. The equality checks are built first and placed in an "Or" condition. The "Or" condition is then itself placed in an "And" condition with the remaining equality check:
Equal dropCheck = new Equal(myDropdown, "abc");
Equal textCheck = new Equal(myTextField, "def");
Or or = new Or(dropCheck, textCheck);
boxCheck = new Equal(myCheckBox, true);
And and = new And(boxCheck, or);
The actions can be performed on a single component or a group of components and include:
- hiding or showing components;
- enabling or disabling components; and
- marking components mandatory or optional.
The WSubordinateControl itself does not have a visual representation but it must still be added to a visible section of the WComponents somewhere within the application. To use the WSubordinateControl supply it with the Function objects that implement the screen logic. The snippet below toggles the visibility of a text field depending on whether a check-box is checked.
WCheckBox extraInfoRequired = new WCheckBox();
WTextField extraField = new WTextField();
add(extraInfoRequired);
add(extraField);
Rule rule = new Rule("Extra text required");
rule.setCondition(new Equal(extraInfoRequired, true));
rule.addActionOnTrue(new Show(extraField));
rule.addActionOnFalse(new Hide(extraField));
WSubordinateControl control = new WSubordinateControl();
control.addRule(rule);
add(control);
The SubordinateBuilder
class provides an easier to read syntax for constructing WSubordinateControls. The previous example can also be implemented as:
WCheckBox extraInfoRequired = new WCheckBox();
WTextField extraField = new WTextField();
add(extraInfoRequired);
add(extraField);
SubordinateBuilder builder = new SubordinateBuilder();
builder.condition().equals(extraInfoRequired, "true"));
builder.whenTrue().show(extraField));
builder.whenFalse().hide(extraField));
WSubordinateControl control = builder.build();
add(control);
Consider a more complex example where the user interface contains two "yes"/"no" radio button groups and two text inputs. A rule which makes the text inputs mandatory if either "yes" option has been selected can be implemented as follows:
SubordinateBuilder builder = new SubordinateBuilder();
builder.condition().equals(radioButtonGroup1, "Yes").or()
.equals(radioButtonGroup2, "Yes");
builder.whenTrue().setMandatory(textInput1, textInput2);
builder.whenFalse().setOptional(textInput1, textInput2);
add(builder.build());
The following actions are available:
- show;
- hide;
- enable;
- disable;
- make mandatory;
- make optional;
- show 1 ... n of a group of n controls (and hide the others);
- hide 1 ... n of a group of n controls (and show the others);
- enable 1 ... n of a group of n controls (and disable the others); and
- disable 1 ... n of a group of n controls (and enable the others).
WComponents which may be WSubordinateControl triggers implement the SubordinateTrigger interface. The best source of information for a complete list of such components is the JavaDoc for com.github.bordertech.wcomponents.SubordinateTrigger.
WComponents which may be the target of a WSubordinateControl implement the SubordinateTarget interface. The best source of information for a complete list of such components is the JavaDoc for com.github.bordertech.wcomponents.SubordinateTarget.
Note that not all target components support all types of subordinate control action. For example a WPanel may be hidden (or shown) but not disabled or made mandatory. This is the weakest aspect of WSubordinateControl and the implications of this design have never really been investigated.
An action which is applied to a SubordinateTarget which does not implement it is ignored except for disable
and enable
which are treated as follows.
When a WSubordinateControl action is to disable or enable a target and the target component does not implement the Disableable interface then the behaviour is agreed by convention. The children of the component will be tested recursively until a component that does implement Disableable is found and that component will be actioned. This leads to a problem if the target component is a WDataTable
as it implements Disableable but the client code does not allow tables to be disabled as it is not informed if a table is the output of WTable or WDataTable
. This is one of the minor reasons why WDataTable
was removed.
- JavaDoc;
- SubordinateTrigger interface;
- SubordinateTarget interface;
- List of WComponents.