See: Description
Interface | Description |
---|---|
FieldValidator<D> |
Interface for an additional external validator that can be added to a Field.
|
Form |
Interface for building and querying Forms.
|
FormValidator |
Interface for objects that can perform a global consistency check on a Form
If it is more convenient to perform validation as part of the
FormAction
then you can throw a TransitionValidationException there instead. |
Identified | |
ModifyingFormValidator |
a
FormValidator that applies additional changes to the Form itself
for example adding a 2FA token input |
Class | Description |
---|---|
BaseForm |
superclass for all Forms.
|
Field<I> |
Field represents a single field in the form consisting of a label and and Input.
|
MapForm |
Form that can take its inputs as a Map
|
SetParamVisitor |
An
InputVisitor that adds the inputs contents to a map
equivalent to the form post parameters |
The initial implementation is aimed at HTML forms but it is also possible to generate GUI forms using the same basic structure.
A standard form consists of an ordered list of named fields. For each field the form consists of a text label (defaulting to the name of the field) and a Input. Inputs can be text-boxes, pull-downs, radio-buttons etc. A form also has a set of action/submit buttons.
Note that Inputs may be composite. For example we may want to build a Date Input out of separate pull-down menus for year, month and day.
When a form is submitted each of the inputs is parsed and the overall submission validated. If there are any errors in the form input the form is re-presented marked up with errors. Errors can be presented in the following ways:
Non optional fields can be marked as missing
Fields can be annotated with field specific error messages
A general error message can be presented.
Each field in a validated form has a corresponding value (Object).
The Form can return a Map of values for use by the program logic
after the form has been verified. Alternatively if a form has action
buttons defined then these buttons are tied to a FormAction
class that acts like a method call on the form.
The Form superclass is independent of how the form is edited. This allows us to use generic code to build Forms of different types. The Form validation code is also the same for all form types.
There are 2 levels of validation. Each field/Input can validate
its own inputs independently and generate field specific errors. Every Input class has its own
built in validation code and this can be augmented by adding a FieldValidator
to the corresponding field of the form.
The overall form can also be validated and generate a generic error. This
is done by adding a FormValidator
object to the form. These can be used to validate constraints that affect multiple fields for example if
one value should be less than another.
The activation pattern for HTML and GUI forms are significantly different. In a GUI there is a single Form instance each field can be validated as it is edited. Each edit invokes an appropriate call-back. In HTML form generation and parsing are separated into two separate phases on different instances and progress in batch mode. The Form editing methods are therefore specific to the subclass or handled using a visitor pattern. The flow of control is as follows:
The enclosing Servlet/GUI environment code creates a form of the correct sub-class.
This blank form is passed to a method on some model class to build the form
The enclosing environment code calls the form edit methods on the Form.
The validated form is passed to an action method to perform the necessary action. This may be a method on a model class
but it is more usual to embed a FormAction
class within the form itself that contains references
to the model classes that need to be modified.
To improve the user interface inputs that correspond to HTML5 input types can implement
HTML5Input
to take advantage of browser level field validation.
In general we prefer to rely on html5 features rather than introducing additional javascript. In principal we could allow inputs and validators
to add additional javascript though this would require each validation rule to be implemented and maintained in two different languages.
I
The Input classes are kept generic to all different types of Form. The Form class has to implement the different types of edit operation depending on the kind of selector. This allows us to use inheritance between different types of Input. If we sub-classed Inputs by Form type each new Input type would need to be sub-classed for every Form type. Where we subclass an Input by type there is a reasonable chance that the inherited edit code will be sufficient and not need re-implementing For example most Inputs can share text-box edit code from a common superclass but can be quite different when it comes to parse and validation.
There is a very powerful framework for implementing application logic based on the
interfaces Transition
and
TransitionFactory
. These define general form-based methods that can be called on an object.
A Transition
defines the operation and associated form and the TransitionFactory
provides the logic for
identifying the target and access control. This allows large amounts of functionality to be implemented independently of the jsp/servlet framework.