Validation Framework |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Developer’s Guide Home
Installation and Configuration Common Concepts Components Index Border Layout Panel Calendar Chart Command Button Command Link Composite Filter Confirmation Data Table Date Chooser Day Table Drop Down Field Dynamic Image Folding Panel For Each Graphic Text Hint Label Input Text Input Textarea Layered Pane Level Indicator Popup Layer Popup Menu Select Boolean Checkbox Select Many Checkbox Select One Radio Spinner Suggestion Field Tabbed Pane Tab Set Tree Table Two List Selection Window Focus Load Bundle Scroll Position Ajax Framework Validation Framework Tag Reference API Reference |
IntroductionThe OpenFaces validation framework is designed to compensate for lack of explicit and full support for client-side validation in JSF. In essence, it shifts the server-side validation logic of standard JSF validators to the client side. Key Features
BenefitsIn the standard JSF validation routine, user-entered data is validated on the server side by the validators and converters assigned to an input field. If either fails, the page is re-rendered back to the client to display validation errors to the user. The OpenFaces validation framework allows you to validate data on the client side before a page with invalid data is submitted, thus, minimizing server round-trips and enhancing user experience. With almost zero configuration, you can shift the standard JSF validation to the client side, preserving both logic and visual presentation of validation errors. The OpenFaces validation framework allows you to customize presentation of validation errors. Instead of using simple labels as standard HTMLMessage(s) do, with OpenFaces, you can change a CSS of the input component with an invalid value or show a special "error" icon over the component. There is no need to track all the validation checks and ensure there is an appropriate component to display the error. The OpenFaces validation framework provides default validation presentation for both client-side and server-side validation. If validation fails, you can be sure this will be displayed on the page. To cover various validation scenarios, the OpenFaces validation framework allows you to choose which components to validate and when to validate them. Getting Started with Client-Side ValidationAn existing JSF application can be configured to perform all input data validation on the client side in these simple steps: 1. Attach the OpenFaces library to your project by following the instructions in the Installation section. 2. Set the application-scope context parameter org.openfaces.validation.clientValidation to "onSubmit" in web.xml. This instructs the OpenFaces validation framework to use client-side validation for the whole application. <web-app> ... <context-param> <param-name>org.openfaces.validation.clientValidation</param-name> <param-value>onSubmit</param-value> </context-param> ... </web-app> As a result, client-side validation will be triggered before any form submission. In case of a validation error, a corresponding message will be displayed just like it is for server-side validation, but without any round-trips to the server. Furthermore, you can configure client-side validation in a fine-grained way on a form and component level, use alternative ways of error presentation for failed validation, add OpenFaces validators, and customize validation messages. How the Validation Framework WorksWhen client-side validation is turned on for a specific set of components, the components become ready to be validated on the client side. The validation process can be initiated in two ways: "automatic" - when all the components are validated before page submission, and "on demand" - when validation is invoked manually by the developer, from JavaScript code. The set of components to be validated, the logic for automatic validation triggering, and error messages can be additionally configured to suit the logic of the most sophisticated pages. The basics of the OpenFaces validation framework can be summarized as follows:
Configuring Components for Client-Side ValidationThere are three levels on which server-to-client validator porting can be configured: application-wide, form-wide, and per-component. Note that lower-level configuration settings take precedence. If validation is not configured on some level, it defaults to the higher-level configuration. Application-wideConfigured by the org.openfaces.validation.clientValidation application-scope context parameter in web.xml. For more information, see the section Application Settings . These settings affect all the components on all pages within the application. You may want to fine-tune validation settings for specific pages by using form-wide and per-component settings. Note Form-wideConfigured by adding the ClientValidationSupport component to the form. For more information, see the section ClientValidationSupport Component. Affected are the components within the form to which the ClientValidationSupport component is added. This allows you to specify form-specific client-side validation configuration. Per-componentConfigured by specifying the component attributes. See the section Component Attributes. Only the component is affected. Can be used to exclude the component from validation. Supported Validators and ConvertersOn the client side, the OpenFaces validation framework supports all the OpenFaces Validators as well as the following standard JSF validators:
The following standard JSF converters are supported:
Note
Configuring Validation Error PresentationThe OpenFaces validation framework provides an alternative way to present validation messages to the user: by using the FloatingIconMessage component. It displays an image over an invalid component and applies a CSS style to it . See FloatingIconMessage for details. This kind of error messaging does not affect the page layout and, therefore, can be used as default validation error presentation. That is, when no standard HTML messages are found to display a client-client validation message, the FloatingIconMessage is automatically added to the component. If there are no components to present validation messages to the user, all validation messages are displayed with the FloatingIconMessage component. This feature is turned on even if there is no client-side validation. You can specify whether to use default validation presentation or not by using the org.openfaces.validation.useDefaultServerPresentation and org.openfaces.validation.useDefaultClientPresentation application context parameters. These parameters should be specified in web.xml and by default are set to "true" (for more details, see the Application Settings section). These parameters also can be used for a certain form. To define whether or not to use default validation presentation for the form, you should specify the useDefaultServerValidationPresentation and useDefaultClientValidationPresentation attributes for the ClientValidationSupport component (for more details, see the ClientValidationSupport Component section). By default, validation messages in the entire application are displayed with the FloatingIconMessage component. You can specify a different component for default validation presentation with the org.openfaces.validation.defaultPresentationClass application context parameter. In this parameter, you should define a fully-qualified class name of the component that will be used for default validation presentation and that extends the UIMessage class. For more details, see the Application Settings section. You can also specify a component for default validation presentation for a particular form. In this case, you should define the component which is used for default presentation as a child tag for the ClientValidationSupport component (for more details, see the ClientValidationSupport Component section). Customizing Validation MessagesValidation messages used by client-side validators and converters are the same as for the corresponding server-side validators. The messages used by OpenFaces validators can be configured either by message resource bundles , just like for standard JSF validators or as attributes of the validator tags. See the section Configuring Validator Messages for more details. For the OpenFaces validators, you can define the summary and detail messages in place, as the corresponding validator attributes. For example: <o:validateCustom clientFunction="return value.length>0;" detail="field with id = \{0\} is required" summary="validation error" /> Default validator messages of the OpenFaces validators are listed below:
Validation TriggeringWhen client-side validation is triggered for a specific set of components, all validators attached to these components are evaluated. If any validator fails, the failed validation results are shown using the available messages component. Client-side validation can be triggered in one of the following ways:
Validated Components SetThe client-side validators are assigned to a component, if all of the following conditions are true:
See the section Client-Side Component Value for the description of how the validated value is retrieved for the component. OpenFaces Validation Framework APIApplication Settings
The application-wide settings can be overridden on the form-wide and per-component levels. <web-app> ... <context-param> <param-name>org.openfaces.validation.clientValidation</param-name> <param-value>onSubmit</param-value> </context-param> ... </web-app>
Type: boolean Values:
Default value: "true" The application-wide settings can be overridden at the form-wide and per-component levels. <context-param>
<param-name>org.openfaces.validation.useDefaultClientPresentation</param-name>
<param-value>true</param-value>
</context-param>
Type: boolean Values:
Default value: "true" The application-wide settings can be overridden at the form and component levels. <context-param>
<param-name>org.openfaces.validation.useDefaultServerPresentation</param-name>
<param-value>true</param-value>
</context-param>
<!-- DEFAULT VALIDATION PRESENTATION CLASS PARAMETER --> <context-param> <param-name>org.openfaces.validation.defaultPresentationClass</param-name> <param-value>org.openfaces.component.validation.FloatingIconMessage</param-value> </context-param> <!-- DEFAULT VALIDATION PRESENTATION COMPONENT ATTRIBUTES CONFIGURATION --> <context-param> <param-name>FloatingIconMessage.style</param-name> <param-value>background: red;</param-value> </context-param> ClientValidationSupport ComponentThe ClientValidationSupport component provides configuration of client-side validation for the enclosing form. Tag: <o:clientValidationSupport> Example : <form id="form1> ... <o:clientValidationSupport clientValidation="onSubmit" useDefaultClientValidationPresentation="true" useDefaultServerValidationPresentation="true"> <o:floatingIconMessage showDetail="true" showSummary="true" style="background: red;"/> </o:clientValidationSupport> ... </form> The ClientValidationSupport component can contain the default validation presentation component as a child defined inside. In this case, the defined presentation component will override the application's defaultValidationPresentationClass component and will be used for the enclosing form to display validation or conversion errors. Attributes:
Component AttributesTo manually enable client-side validation for an individual component, you can use the clientValidation attribute by adding it to the component with the standard <f:attribute> nested tag. This attribute is of org.openfaces.renderkit.validation.validator.ClientValidationEnum type and accepts the following values:
<h:inputText id="testInput" required="true" value="#{Bean.value}"> <f:attribute name="clientValidation" value="onDemand"/> </h:inputText> Validation Error Message ComponentThe OpenFaces validation framework provides an alternative way to present validation messages by using the FloatingIconMessage component. FloatingIconMessageTag: <o:floatingIconMessage> The FloatingIconMessage component allows you to display a validation error of a validated component by changing its appearance and adding a floating icon over the component. A FloatingIconMessage does not change the page layout, so it can be added safely without raising any problems with the layout change. The validation error description will be shown through a standard HTML title attribute for the invalid component and floating icon . FloatingIconMessage is the default presentation component for failed validation if no application-wide defaultValidationPresentationClass parameter is specified or the ClientValidationSupport component doesn't have the default presentation component declaration. This means that if no messages are configured for a component and no application- or form-wide validation presentation component is defined, the FloatingIconMessage will be automatically added for every component with client-side validators. Example: <form id="form1"> ... <h:inputText id="requiredInput" required="true"/> <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/> ... </form> Specific attributes:
Client-Side Component ValueThe value of the component to validate during client-side validation is retrieved during validation triggering by following these rules:
You can specify the value to be validated by client-side validation by providing a custom JavaScript function that will be called each time the framework needs to get the component value. You should provide a JavaScript code snippet returning the value of the component by using a standard <f:attribute> nested tag with the name clientValueFunction. In the example below, the value of the component 'test1' will be returned as the value of the component 'test2' during the client-side validation. . <form id="testForm"> ... <h:inputText id="test1"/> <h:inputText id="test2" > <f:attribute name="clientValueFunction" value="return document.getElementById('testForm:test1').value;" /> </h:inputText> ... </form> Client-Side APIThe OpenFaces validation framework provides the following client-side functions that can be called from JavaScript. validateFunction: O$.validate(component) Triggers all present client-side validators for the component represented by the DOM node which is specified in the component parameter. The value of the component is determined as described in the section Client-Side Component Value. Client-side validators corresponding to the server-side converters will be processed before other validators. If a converter-corresponding validator considers the value invalid, the following validators will not be processed, and only the conversion error message will be shown. Parameters Return value - boolean, "true" if the component value is valid, "false" - otherwise. <form id="testForm"> ... <h:inputText id="requiredInput" required="true" onchange="O$.validate(this);"/> <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/> ... </form> validateByIdFunction: O$.validateById(component_id) Triggers all present client-side validators for the component with the id specified in the component_id parameter. It is equivalent to finding the component by id and then invoking the O$.validate(component) function. Parameters Return value - boolean. "true" if the component value is valid, "false" - otherwise. <form id="testForm"> ... <h:inputText id="requiredInput" required="true" /> <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/> <h:commandButton action="#{Bean.action}" onclick="O$.validateById('testForm:requiredInput');"/> ... </form> validateFormFunction: O$.validateForm(form) Triggers all present client-side validators for all the components within the form specified in the form parameter. It is equivalent to invoking the O$.validate(component) function for all the components within a form. In the current version, validation is triggered for all the components rendered on the server side and included into the response. If on the client side, the visible property is set to "false", the validation will be triggered anyway. Parameters Return value - boolean. "true" if all components within a specified form are valid, "false" - if there is even one invalid component within a form. <form id="testForm"> ... <h:inputText id="requiredInput" required="true" /> <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/> <h:commandButton action="#{Bean.action}" onclick="O$.validateForm(document.getElementById('testForm'));"/> ... </form> validateFormByIdFunction: O$.validateFormById(form_id) Triggers all present client-side validators for all the components within the form whose id is specified in the form_id parameter. It is equivalent to invoking the O$.validate(component) function for all the components within the form. Parameters Return value - boolean. "true" if all components within a specified form are valid, "false" - if there is even one invalid component within a form. <form id="testForm"> ... <h:inputText id="requiredInput" required="true" /> <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/> <h:commandButton action="#{Bean.action}" onclick="O$.validateFormById('testForm');"/> ... </form> validateEnclosingFormFunction: O$.validateEnclosingForm(component) Triggers all present client-side validators for all the components within the form containing the component specified in the component parameter. It is equivalent to invoking the O$.validate(component) function for all the components within the form. Parameters Return value - boolean. "true" if all components within the form to which the specified component belongs are valid, "false" - if there is even one invalid component within the form. <form id="testForm"> ... <h:inputText id="requiredInput" required="true" /> <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/> <h:commandButton action="#{Bean.action}" onclick="O$.validateEnclosingForm(this);"/> ... </form> submitWithoutValidationFunction: O$.submitWithoutValidation(component) Submits the form containing the component specified in the component parameter by skipping client-side validation triggering. Parameters <form id="testForm"> ... <h:inputText id="requiredInput" required="true" /> <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/> <h:commandButton action="#{Bean.action}" onclick="O$.submitWithoutValidation(this);"/> ... </form> resetFormValidationFunction: O$.resetFormValidation(form) Resets all client-side validators and clears validation messages for all the input components within the form specified in the form parameter. Parameters <form id="testForm"> ... <h:inputText id="requiredInput" required="true" /> <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/> <h:commandButton value="Cancel" action="back" onclick="O$.resetFormValidation(document.getElementById('testForm'));"/> ... </form> resetFormValidationByIdFunction: O$.resetFormValidationById(formId) Resets all client-side validators and clears validation messages for all the input components within the form whose id is specified in the form_id parameter. Parameters <form id="testForm"> ... <h:inputText id="requiredInput" required="true" /> <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/> <h:commandButton action="back" value="Cancel" onclick="O$.resetFormValidationById('testForm');"/> ... </form> resetEnclosingFormValidationFunction: O$.resetEnclosingFormValidation(element) Resets all client-side validators and clears validation messages for all the input components within the form containing the component specified in the component parameter. Parameters <form id="testForm"> ... <h:inputText id="requiredInput" required="true" /> <o:floatingIconMessage for="requiredInput" style="border: 2px solid red;"/> <h:commandButton action="back" value="Cancel" onclick="O$.validateEnclosingForm(this);"/> ... </form> OpenFaces ValidatorsThe OpenFaces validation framework provides several validators to complement a set of standard JSF validators. All the OpenFaces validators are supported both on the server and client side. In addition, they come with the attributes that allow you to specify validation messages for each validator. org.openfaces.CustomAllows you to write custom code to validate a value. This validator has two attributes to specify the code to validate a value: clientFunction and serverFunction. The clientFunction attribute should contain a JavaScript function that returns a boolean value. The serverFunction attribute should be specified as a method-binding expression that references a method that should validate a value. Please note that the serverFunction attribute is only effective for the server-side validation and the clientFunction attribute -- for the client side validation. So, to make <o:validateCustom> work both on the server and client side, you should write the validation logic twice: in the JavaScript function and in the Java method. Tag: <o:validateCustom> Attributes:
The validation checks on the client and server sides are completely independent and do not interact. If both functions, clientFunction and serverFunction, are omitted, this validator will have no sense, but this situation is not checked by the framework because it will not cause any trouble. Note Suppose there's a page with a text field for entering card code information. If a card with this code exists in the database, the user can see detailed information from this card. The code starts with "IC" and should not exceed the length of 10 characters. We could check these validation rules on the client side, but we need to check whether there is a card with certain code in the database. <h:form> Please, enter a card code: <h:inputText id="cardCodeField"> <o:validateCustom clientFunction="return (value.length>0 && value.indexOf('IC')==0);" detail="Card code should start with 'IC' and should be 10 characters long." summary="Card code validation error."/> <o:validateCustom serverFunction="#{Bean.testCardCode}" detail="Please check the card code. There is no card with code provided." summary="Card code validation error."/> </h:inputText> <h:commandButton id="viewCardButton" action="viewCard" value="view card"/> </h:form> Backing bean: public class Bean(){ ... public boolean testCardCode(FacesContext context, UIComponent component, Object value){ Card card = CardCode.findCardByCode(value); return card!=null; } ... } The example above uses two validators, but it is possible to use clientFunction and serverFunction at the same time in one validator, provided they have the same error description. org.openfaces.RegularExpressionEnsures that a value matches the pattern described as a regular expression in the pattern attribute. Tag: <o:validateRegex> Attributes:
<h:inputText id="regexValidatorField" style="width: 120px;"> <o:validateRegex pattern="\+\d\d [(]\d\d\d[)] \d\d\d \d\d \d\d" summary="Wrong number" detail="Please provide phone number in the following format: +xx (xxx) xxx xx xx"/> </h:inputText> org.openfaces.EMailEnsures that the component has a well-formed e-mail address as a value. It is based on one of the regular expressions. Tag: <o:validateEmail> Attributes:
<h:inputText id="emailValidatorField" style="width: 120px;"> <o:validateEmail summary="Incorrect email" detail="Please provide correct email address"/> </h:inputText> org.openfaces.URLEnsures that the component has a valid URL as a value. Based on the regular expression. Tag: <o:validateUrl> Attributes:
<h:inputText id="urlValidatorField" style="width: 120px;"> <o:validateUrl summary="Incorrect URL" detail="Please provide valid URL address"/> </h:inputText> org.openfaces.EqualChecks that the values of two input components are the same. In the for attribute, you should specify the component whose value must be equal to the value of the component the validator is assigned to. A common example is a double password or double e-mail address. Tag: <o:validateEqual> Attributes:
Note <h:inputText id="equalValidatorField1" style="width: 120px;"> <o:validateCustom clientFunction="return value.length > 0" detail="Value should not be empty"/> </h:inputText> <h:inputText id="equalValidatorField2" style="width: 120px;"> <o:validateEqual for="equalValidatorField1"/> </h:inputText> Configuring Validator MessagesThe messages generated by the validators and converters are handled by JSF normal application message queue and can be displayed with the standard HtmlMessage and HtmlMessages components and OpenFaces FloatingIconMessage component (for more details, see the section Validation Error Message Component ). Messages have the summary and detailed description of a validation error. The messages of OpenFaces validators and converters have severity level information like those of standard JSF validators and converters. These messages are configured using a normal Java resource bundle called a message bundle with one extra rule for handling the detailed error description. The OpenFaces validation framework supports this way of specifying messages of validators and converters and provides OpenFaces Message Bundle that contains default messages for the OpenFaces validators. The client-side validation errors for the standard validators and converters which are ported to the client side are the same as for server-side validation. In JSF standard, the parameters in the messages are filled by the framework, and there is a limited number of the parameters. For instance, if there is a parameter {0} in the message, during the rendering phase it will be replaced with the client-side id of the component for which this message will be shown. The OpenFaces validation framework supports all standard parameters for the specified messages. Also, you can use additional parameters for the OpenFaces validators. Their values should be embedded into the component with a nested MessageParam tag. There is one more way to specify the summary and detailed error description for the OpenFaces validators. You can use the summary and detail attributes. <h:inputText id="i1"> <o:validateEmail detail="Please enter a valid first user's email"/> </h:inputText> <h:inputText id="i2"> <o:validateEmail detail="Please enter a valid second user's email"/> </h:inputText> MessageParamThe MessageParam component allows you to specify parameters for validation messages within any OpenFaces validator. Attributes:
For example, if you have several input components with e-mail addresses, you can use a clearer message than the standard ones. org.openfaces.EMailValidatorMessage = E-mail Validator Error org.openfaces.EMailValidatorMessage_detail = Please enter a valid \{1\} e-mail Page: <h:inputText id="i1"> <o:validateEmail> <o:messageParam value="first user's" /> </o:validateEmail> </h:inputText> <h:inputText id="i2"> <o:validateEmail> <o:messageParam value="second user's" /> </o:validateEmail> </h:inputText> In this case, two parameters will be accessible during formatting of the messages. Standard {0} with the client-side id of the component (it will not be used in the particular example so there is no {0} in the message body) and the next parameter {1} whose value will be first user for the first field and second user for the next one. So the message detailed description will be Please enter a valid first user's email and Please enter a valid second user's email respectively. OpenFaces Message BundleFollowing the JavaServer Faces technology standard to access default messages via message bundles, the OpenFaces validation framework provides a message bundle (standard message.properties file ) with the following messages: org.openfaces.CustomValidatorMessage = Validation Error org.openfaces.CustomValidatorMessage_detail = validation error in input ''{0}'' org.openfaces.RegexValidatorMessage = Regex Validator Error org.openfaces.RegexValidatorMessage_detail = ''{0}'': does not match regex org.openfaces.URLValidatorMessage = URL Validator Error org.openfaces.URLValidatorMessage_detail = ''{0}'': not a valid URL org.openfaces.EMailValidatorMessage = E-mail Validator Error org.openfaces.EMailValidatorMessage_detail = ''{0}'': not a valid e-mail org.openfaces.EqualValidatorMessage = Equal Validator Error org.openfaces.EqualValidatorMessage_detail = ''{0}'' must be equal to the ''{1}'' Parameter values: Each message can reference the predefined parameter storing the client-side id of the component for which the message will be displayed by "{0}". (Equal validator has also a second parameter ("{1}") referencing the second component. You can change the messages by adding a new message bundle and registering it within the application settings section in web.xml. Annotation-based ValidationThe OpenFaces validation framework provides an alternative way to configure validation - using annotations. To enable annotation-based validation you have to enclose components to be validated within <o:validateAll> tag. This tag will add server-side validators for child input components and client-side validators for supported annotations if client-side validation is enabled. See details below. Server-side Annotation-based ValidationServer-side Annotation-based Validation supports all hibernate validator annotations and allows to define custom validator annotations by providing implementation of org.hibernate.validator.Validator interface. Please refer Hibernate Validator documentation for a list of supported annotations and on how to define your own validator. Client-side Annotation-based ValidationThis type of validation can be enabled by application-wide or form-wide client-side validation configuration. Per-component configuration is not supported yet. Please refer section Configuring Components for Client-Side Validation for details. List of supported annotations for client-side validation: @NotNull, @NotEmpty, @Email, @Length, @Pattern, @Range, @Max, @Min. ValidateAll ComponentThe ValidateAll component is a container that automatically adds annotation-based validators to all child input components. Currently it is almost the same to JBossSeam's <s:validateAll> component but also provides client-side validation. It requires Hibernate annotations library to be available in classpath. Tag: <o:validateAll> Example: ... <o:validateAll> <h:inputText id="email" value="#{ValidateAllBean.email}"/> <h:message id="emailMessage" for="email" showSummary="true" showDetail="false"/><br/> <o:dateChooser id="registrationDate" value="#{ValidateAllBean.registrationDate}" pattern="dd/MM/yyyy"/> <h:message id="registrationDateMessage" for="registrationDate" showDetail="false" showSummary="true"/><br/> <o:validateAll> <h:commandButton value="Submit" id="submit"/> ... Here is an example of how the EditUserBean backing bean can be implemented: public class EditUserBean{ private Date registrationDate; private String email; @Email public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Past public Date getRegistrationDate() { return registrationDate; } public void setRegistrationDate(Date registrationDate) { this.registrationDate = registrationDate; } } |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
© 2010 TeamDev Ltd. | ![]() |