Custom Validation Rules
Overview
In addition to the regular-expression-based validation rules for fields, the Enterprise Forms add-on includes support for custom Java-based validation rules for fields, groups and pages. Custom rules can be added by implementing a simple Java interface, and adding a configuration node in the repository. Custom rules can be selected by the form author using the validation rules dropdown in the form field properties panel.
Rule Development
A custom validation rule class should be on the classpath of the site application, and must implement the interface com.onehippo.cms7.eforms.hst.validation.rules.ValidationRule:
public interface ValidationRule { boolean validate(Map<String, String[]> fieldValuesMap); RuleType getType(); ErrorMessage getMessage(final String name, final String label, final String value); ErrorMessage getMessage(String name, String label, String value, Locale locale); String getRuleLabel(); }
For convenience, custom validation rule classes can extend the abstract base class com.onehippo.cms7.eforms.hst.validation.rules.BaseRule. This leaves the following methods to be implemented by the custom rule class:
boolean validate(Map<String, String[]> fieldValuesMap)
Validates the form input. The fieldValuesMap parameter contains the form field names and values within the rule's scope, i.e. for a field validation rule it contains only one field value, and for a page or group it contains all the field values in the page or group.
RuleType getType();
Returns one of the validation rule types enumerated in com.onehippo.cms7.eforms.hst.validation.rules.RuleType. Custom rules should return one of the following three:
- RuleType.CUSTOM_FIELD_VALIDATION_RULE
- RuleType.CUSTOM_GROUP_VALIDATION_RULE
- RuleType.CUSTOM_PAGE_VALIDATION_RULE
protected String getResourceBundleBaseName()
Typically, a custom rule should provide its own resource bundle for localized messages, so this method should return the validation rule's fully qualified class name. The recommended approach is to provide these through Java resource bundles. From Enterprise Forms 3.0.1 onwards, these resource bundles can also be provided as Repository resource bundles. The Repository resource bundles are loaded first, in case no bundles are found, a fallback is done to the Java resource bundles.
public ErrorMessage getMessage(String name, String label, String value)
Returns a com.onehippo.cms7.eforms.hst.model.ErrorMessage.
The Enterprise Forms add-on includes an example custom field validation rule com.onehippo.cms7.eforms.hst.validation.rules.LuhnRule which implement the Luhn Algorithm, commonly used for shallow credit card number validity checks:
public class LuhnRule extends BaseRule { public static final String MESSAGE_KEY = "validation.message.luhn"; @Override public boolean validate(Map<String, String[]> fieldValuesMap) { if (fieldValuesMap.isEmpty()) { return true; } // assuming one item String[] values = fieldValuesMap.values().iterator().next(); if (ArrayUtils.isEmpty(values)) { return true; } for (String value : values) { if (StringUtils.isBlank(value)) { continue; } int sum = 0; boolean alternate = false; for (int i = value.length() - 1; i >= 0; i--) { try { int n = Integer.parseInt(value.substring(i, i + 1)); if (alternate) { n *= 2; if (n > 9) { n = (n % 10) + 1; } } sum += n; alternate = !alternate; } catch (NumberFormatException e) { return false; } } if (!(sum % 10 == 0)) { return false; } } return true; } @Override public RuleType getType() { return RuleType.CUSTOM_FIELD_VALIDATION_RULE; } @Override protected String getResourceBundleBaseName() { return getClass().getCanonicalName(); } @Override public ErrorMessage getMessage(String name, String label, String value) { return new ErrorMessage(MESSAGE_KEY, name, label, "Field " + label + " is invalid"); } }
The Enterprise Forms demo also includes an example page validation rule ( com.onehippo.cms7.eforms.demo.validationrules.NoEmptyFieldsOnPageRule) and an example group validation rule ( com.onehippo.cms7.eforms.demo.validationrules.NoEmptyFieldsInGroupRule).
Rule Configuration
Custom validation rules are configured in the repository under /hippo:configuration/hippo:modules/eforms/hippo:moduleconfig/eforms:validationrules (this is the same place where regular-expression-based rules are configured).
For each custom validation rule, a uniquely named node of type hipposys:moduleconfig must be created and have the following properties:
-
eforms:validationruleclass: The fully qualified class name of the validation rule class.
-
eforms:validationrulelabel: A human-readable identifier for the rule.
-
eforms:validationruleforpage (boolean): for page validation rules (i.e. method # getType() returning RuleType.CUSTOM_PAGE_VALIDATION_RULE) it is required and must be true. For field and group validation rules it is optional and must be false .
-
eforms:validationruleforgroup (boolean): for group validation rules (i.e. method # getType() returning RuleType.CUSTOM_GROUP_VALIDATION_RULE) it is required and must be true . Otherwise it is optional and must be false for field and page validation rules.
The Enterprise Forms demo includes configuration for all three provided example rules.
The "Luhn Algorithm" example field validation rule:
/luhn: jcr:primaryType: hipposys:moduleconfig eforms:validationruleclass: com.onehippo.cms7.eforms.hst.validation.rules.LuhnRule eforms:validationrulelabel: Luhn Algorithm
The "No empty field in group" example group validation rule:
/noemptyfieldsingroup: jcr:primaryType: hipposys:moduleconfig eforms:validationruleclass: com.onehippo.cms7.eforms.demo.validationrules.NoEmptyFieldsInGroupRule eforms:validationruleforgroup: true eforms:validationrulelabel: No empty fields in group
The "No empty field in page" example page validation rule:
/noemptyfieldsonpage: jcr:primaryType: hipposys:moduleconfig eforms:validationruleclass: com.onehippo.cms7.eforms.demo.validationrules.NoEmptyFieldsOnPageRule eforms:validationruleforpage: true eforms:validationrulelabel: No empty fields in page
Rule Selection
To configure a form item (field, group or page) to use a custom validation rule, simply select the item and in its properties box, select the rule from the "Validation Rule" dropdown:
Save and publish the form. In the site application, verify that the validation rule is active in the site application by submitting the form with invalid values: