Validation Rules
Overview
Editors can choose one of the built-in standard validation rules for input fields. As shown below, if you select an input field which can be validated by a regular expression, then you can choose one of the built-in standard validation rules instead of typing a complex regular expression by yourself.
By default, the standard validation rules for a number, percentage, alphanumeric, e-mail and website address are provided as out-of-box. If you choose one of those standard validation rules, then the editor will set a validation regular expression automatically on behalf of the editor. The 'Validation RegEx' property field below will be disabled with the build-in standard validation rules.
Also, it is possible for editors to enter a custom validation regular expression by themselves by choosing 'Custom Input' instead. If you choose 'Custom Input', the the 'Validation RegEx' property field will become enabled and editors will be able to enter a custom validation regular expression.
The validation rules enforce checking the user inputs. So, for example, if a text input must be a valid e-mail address, then the runtime form template page can render a proper error information like the following example.
Built-in Standard Validation Rules
The built-in standard validation rules are configured under /hippo:configuration/hippo:modules/eforms/hippo:moduleconfig/ in the repository. The following configuration is initialized by default through hippo-addon-eforms-repository-1.xx.xx.jar for the default built-in standard validation rules.
The validation rule configurations are very intuitive. You can add any other validation rules under /hippo:configuration/hippo:modules/eforms/hippo:moduleconfig/eforms:validationrules/ node. The node name of each validation rule must be 'eforms:validationrule', and each validation rule should contain an ID (eforms:validationruleid), a default label (eforms:validationrulelabel) and a regular expression (eforms:validationruleexpr).
<?xml version="1.0" encoding="UTF-8"?><sv:node sv:name="eforms" xmlns:sv="http://www.jcp.org/jcr/sv/1.0"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>hipposys:module</sv:value> </sv:property> <sv:node sv:name="hippo:moduleconfig"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:property sv:multiple="true" sv:name="jcr:mixinTypes" sv:type="Name"> <sv:value>mix:lockable</sv:value> </sv:property> <sv:node sv:name="eforms:templatelocations"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:property sv:name="basepath" sv:type="String"> <sv:value>/content/eforms/templates</sv:value> </sv:property> <sv:property sv:name="fieldgroups" sv:type="String"> <sv:value>/fieldgroups</sv:value> </sv:property> </sv:node> <sv:node sv:name="eforms:validationrules"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:node sv:name="eforms:validationrule"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:property sv:name="eforms:validationruleexpr" sv:type="String"> <sv:value>^[-+]?\d+(\.\d+)?$</sv:value> </sv:property> <sv:property sv:name="eforms:validationruleid" sv:type="String"> <sv:value>number.general</sv:value> </sv:property> <sv:property sv:name="eforms:validationrulelabel" sv:type="String"> <sv:value>Number</sv:value> </sv:property> <sv:property sv:name="eforms:validcasesensitive" sv:type="Boolean"> <sv:value>false</sv:value> </sv:property> </sv:node> <sv:node sv:name="eforms:validationrule"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:property sv:name="eforms:validationruleexpr" sv:type="String"> <sv:value> ^-?[0-9]{0,2}(\.[0-9]{1,2})?$|^-?(100)(\.[0]{1,2})?$ </sv:value> </sv:property> <sv:property sv:name="eforms:validationruleid" sv:type="String"> <sv:value>number.percent</sv:value> </sv:property> <sv:property sv:name="eforms:validationrulelabel" sv:type="String"> <sv:value>Percent</sv:value> </sv:property> <sv:property sv:name="eforms:validcasesensitive" sv:type="Boolean"> <sv:value>false</sv:value> </sv:property> </sv:node> <sv:node sv:name="eforms:validationrule"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:property sv:name="eforms:validationruleexpr" sv:type="String"> <sv:value>^[A-Za-z\d]+$</sv:value> </sv:property> <sv:property sv:name="eforms:validationruleid" sv:type="String"> <sv:value>string.alphanumeric</sv:value> </sv:property> <sv:property sv:name="eforms:validationrulelabel" sv:type="String"> <sv:value>Alphanumeric</sv:value> </sv:property> <sv:property sv:name="eforms:validcasesensitive" sv:type="Boolean"> <sv:value>false</sv:value> </sv:property> </sv:node> <sv:node sv:name="eforms:validationrule"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:property sv:name="eforms:validationruleexpr" sv:type="String"> <sv:value> \b[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b </sv:value> </sv:property> <sv:property sv:name="eforms:validationruleid" sv:type="String"> <sv:value>email</sv:value> </sv:property> <sv:property sv:name="eforms:validationrulelabel" sv:type="String"> <sv:value>E-Mail</sv:value> </sv:property> <sv:property sv:name="eforms:validcasesensitive" sv:type="Boolean"> <sv:value>false</sv:value> </sv:property> </sv:node> <sv:node sv:name="eforms:validationrule"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:property sv:name="eforms:validationruleexpr" sv:type="String"> <sv:value> (http|https):\/\/[\w\-_]+(\.[\w\-_]+)+ ([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])? </sv:value> </sv:property> <sv:property sv:name="eforms:validationruleid" sv:type="String"> <sv:value>website</sv:value> </sv:property> <sv:property sv:name="eforms:validationrulelabel" sv:type="String"> <sv:value>Website</sv:value> </sv:property> <sv:property sv:name="eforms:validcasesensitive" sv:type="Boolean"> <sv:value>false</sv:value> </sv:property> </sv:node> <sv:node sv:name="eforms:validationrule"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:property sv:name="eforms:validationruleclass" sv:type="String"> <sv:value> com.onehippo.cms7.eforms.hst.validation.rules.LuhnRule </sv:value> </sv:property> <sv:property sv:name="eforms:validationruleid" sv:type="String"> <sv:value>luhn</sv:value> </sv:property> <sv:property sv:name="eforms:validationrulelabel" sv:type="String"> <sv:value>Luhn Algorithm</sv:value> </sv:property> </sv:node> </sv:node> <sv:node sv:name="eforms:daterules"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:node sv:name="eforms:daterule"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:property sv:name="eforms:dateruleclass" sv:type="String"> <sv:value> com.onehippo.cms7.eforms.hst.daterules.NextSaturdayDateRule </sv:value> </sv:property> <sv:property sv:name="eforms:dateruleid" sv:type="String"> <sv:value>next-saturday</sv:value> </sv:property> <sv:property sv:name="eforms:daterulelabel" sv:type="String"> <sv:value>Next Saturday</sv:value> </sv:property> </sv:node> </sv:node> </sv:node> </sv:node>
For example, if you want to add a custom built-in validation rule in your project like 'Dutch Postcode', then you may consider adding a validation rule node like the following:
<sv:node sv:name="eforms:validationrule"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>nt:unstructured</sv:value> </sv:property> <sv:property sv:name="eforms:validationruleid" sv:type="String"> <sv:value>dutch.postcode</sv:value> </sv:property> <sv:property sv:name="eforms:validationrulelabel" sv:type="String"> <sv:value>Dutch Postcode</sv:value> </sv:property> <sv:property sv:name="eforms:validationruleexpr" sv:type="String"> <sv:value>^\d{4}\s[A-Z]{2}$</sv:value> </sv:property> </sv:node>
Validation Rule Label Localization
The default labels of the validation rules are configured in the node configurations ('eforms:validationrulelabel' property). But, you can localize the labels by providing localization resources.
For the CMS Form Editor view, you can put your custom resource strings in classpath:com/onehippo/cms7/eforms/cms/properties/panels/AbstractPropertiesPanel*.properties. By default, the properties are provided as follows:
# classpath:com/onehippo/cms7/eforms/cms/properties/panels # /AbstractFieldPropertiesPanel*.properties # ... validation.rule.no.validation.label=No validationvalidation.rule.none.label=None validation.rule.number.general.label=Number validation.rule.number.percent.label=Percent validation.rule.string.alphanumeric.label=Alphanumeric validation.rule.email.label=E-mail Address validation.rule.website.label=Website Address # ...
As you may already recognize, the resource key is in the pattern, "validation.rule.${validationRuleId}.label". So, for example, if you add a new validation rule, the id of which is 'dutch.postcode', then you can add a resource string like the following example:
# ... validation.rule.dutch.postcode.label=Dutch Postcode # ...
For the HST side form rendering template page, you should add the resource strings in classpath:com/onehippo/cms7/eforms/hst/messages/eforms*.properties in the same way:
# classpath:com/onehippo/cms7/eforms/hst/messages/eforms*.properties # ... validation.rule.number.general.label=Number validation.rule.number.percent.label=Percent validation.rule.string.alphanumeric.label=Alphanumeric validation.rule.email.label=Email Address validation.rule.website.label=Website Address # ...
Specifying different Validation Messages per Field Type
The default messages of the validation rules are configured in classpath:com/onehippo/cms7/eforms/hst/messages/eforms*.properties:
# classpath:com/onehippo/cms7/eforms/hst/messages/eforms*.properties# ... validation.message.required=Field {0} is required. validation.message.maxlength=Field {0} is longer than {3} characters. validation.message.minlength=Field {0} must be longer than {3} characters. validation.message.dateformat=Field {0} is invalid date format, it must be in this format: {3}. validation.message.regexp=Field {0} is invalid, it must be in this format: {3}. # ...
These validation messages can be overridden, and there's another extension you can use. You can specify a different message per field type, in regard of the validation rule that you've configured for a field. So for example, you can have different message for the regexp validator, depending on the type of field that is being validated. To do that, you need to add the classname of the field, in lowercase, to the message key. So for example, if you need to specify different message for a date field with a regular expression validator, you would write:
# ... validation.message.regexp.datefield=Your custom error message for date fields that use the regexp validator. Date field {0} is invalid, it must be in this format: {3}. # ...
The available classnames can be found under package com.onehippo.cms7.eforms.cms.fields. For convenience, here's a complete list:
- CheckBoxesField
- DateField
- DropDownField
- FieldSetTagField
- FileUploadField
- LikertField
- RadioGroupField
- SimpleTextField
- TextAreaField
- TextField
Using Validation Rule Info in the Form Rendering Templates
You may customize the form rendering template (e.g, eforms-default.jsp and eformsrenderfield.tag in the Enterprise Forms Demo project). So, when iterating the field info beans, you can read the validation rule information of the field by using ${field.validationRuleId}, ${field.validationRuleLabel} and ${field.regExp}.
The following example shows an example handling a special validation rule for the specific use case.
<form class="form" action="<hst:actionURL/>" method="post" name="${form.name}"> <c:forEach var="field" items="${form.fields}"> <c:choose> <!-- SNIP --> <c:when test="${field.textField}"> <div class="ef-field"> <c:choose> <c:when test="${field.validationRuleId eq 'dutch.postcode'}"> MAYBE YOU CAN PUT A MASK EDIT INPUT HERE. </c:when> <c:otherwise> YOU CAN PUT A TEXT INPUT HERE. </c:otherwise> </c:choose> </div> </c:when> <!-- SNIP --> </c:choose> </c:forEach> </form>Finally, please note that you can customize the form rendering template page to use more advanced client-side validation engine such as jQuery validation plugin, for instance.