Introduction
Most websites where we need the user to enter details to place an order not only require validation of fields but also these validations
are based on values of other fields. For example, if a user selects product of type A then he is also supposed to enter
the number of products
(which has to be an integer, etc.). There can be complex conditions as well. You may require to enable/disable or show/hide
a few controls based on these conditions.
All these have to be implemented at four places:
- After page load (the controls should be rendered in a particular state).
- When the user alters the page.
- On the server side in the UI layer.
- In the BL layer.
The same logic has to be implemented on all the layers and the JavaScript has to
be consistent with the Java code. Also the JavaScript for
validating controls is somewhat similar but has to be written repeatedly. Whenever the requirement changes, the change has to be done at all places.
Most validations framework provide just basic validation but not depending on the value/state of other entities/controls.
Prerequisites
- The name of the HTML control has to be the same as the corresponding member "
name
" in the server object. - Each HTML control should have a valid "id".
- Label associated with the control should have a "
for
" attribute. - Page should have jQuery's following libraries:
- jquery-1.7.1.min.js
- jquery-ui-1.7.2.min.js (in case date is used)
- jquery-ui-timepicker-addon.js (in case date is used)
- Page should have the following CSS classes in the HTML defined:
.enabled { ...
.disabled { ...
.mandatory { ...
.nonmandatory { ...
- Member data type corresponding to control type
- Checkbox - boolean
- Multiple select - List (All String, Long, Float and Integer generic type supported)
- Single select - String
- Textbox - String, Integer, int, Long, long, Float, float and Date (framework adds calender control by itself)
Validation XML Format
Action related nodes
- RequiredField - Validates that a field is non empty, optionally of a particular format only when given conditions are satisfied. If no conditions are given, it has to have a value. In case
of a multi select list, at least one value should be selected.
Attributes
- name (required) - Name of the control.
- regex (optional) - Regex to be validated against at both server and client side. This is only valid if
the server side data type
is
string
. This is predefined in case the data type on the server is anything from
the above mentioned types except string
. - expression (optional) - JavaScript expression to be validated in addition to regex, e.g.,
parseInt(val, 10) > 25
. - message (optional) - This message will be displayed to the user if the control is not valid.
- showHide (optional) - Hide control (and its label) if conditions are not satisfied.
- enableDisable (optional) - Disable (and its label) if conditions are not satisfied.
- ShowHide (affects only UI) - Hide HTML element if conditions are not satisfied.
Attributes
- id (required) - ID of the element.
- EnableDisable (affects only UI) - Disable HTML element if conditions are not satisfied.
Attributes
- id (required) - ID of the element.
Condition related nodes
- And - And logical operator.
- Or - Or logical operator.
- Not - Not logical operator.
- Condition - Condition to be satisfied.
Attributes:
- name (required) - Name of the control whose value has to be checked.
- value (optional) - Value to be satisfied. In case of a multi select box, use ~##~ as delimiter.
- expression (optional) - JavaScript expression to be validated on both client
and server side. Either value attribute or expression
attribute can be given. But at least one needs to be specified.
Sample XML
<RequiredField name="itemName" regex="^\w+$"
message="Item name can only be alpha numeric." />
<RequiredField name="count" />
<RequiredField name="cost" expression="parseInt(val, 10) > 0"
message="Cost cannot be zero." />
<RequiredField name="type" enableDisable="true">
<And>
<Condition name="buy" expression="val==true" />
</And>
</RequiredField>
<RequiredField name="woodValue">
<And>
<Condition name="buy" value="true" />
<Condition name="type" value="Wood" />
</And>
</RequiredField>
<ShowHide id="transferDiv">
<And>
<Condition name="transfer" value="true" />
<Not>
<Condition name="userType" value="" />
</Not>
<Condition name="transfer" value="Transfer Date" custom="myCustomFunction"/>
</And>
</ShowHide>
The condition can be as complex as required. Each RequiredField
,
ShowHide
, and EnableDisable
can have almost one And
child element and only And
as direct child element.
How to use
- To get JavaScript (for client side) use:
String generatedScript = OperationUtil.getClientScript(obj, validationXML);
- For server side validation:
InvalidField invalidField = OperationUtil.getInvalidField(obj,validationXML);
List<InvalidField> invalidFields = OperationUtil.getInvalidFields(obj,validationXML);
validationXML
is just the name of the XML (or relative path) included in class path.
The assumption is HTML has elements for all the name
s given in
the required field and condition nodes. obj
has the respective getters for all the
name
s given in the required field and condition nodes.
You can submit the form without validation if you want, by calling:
submitForm(true)
Creating your own actions
- Extend the
ui.operation.Operation
class and implement getClientScript
. - Also implement the
IValidate
interface if you require server side validation as well.
The getInvalidFields
function will return the instance
of your implementation as well if the Validate
method returns false. - Enter tagName=fully qualified name of the extended class in
uioperation.properties
.
Update
- Improved performance by using Javassist bytecode manipulation library instead of reflection.
- Support for Enum and Double data types. On client side, handling of input file type.
- Bug fixes and enhancements.