OmniFaces validators

34
OmniFaces Validators Anghel Leonard

Transcript of OmniFaces validators

OmniFaces ValidatorsAnghel Leonard

What we will cover ?

• JSF Validators – short overview• OmniFaces Validators – short overview• ValidateBean• RequiredCheckboxValidator• ValueChangeValidator• ValidateUniqueColumn• JsfLabelMessageInterpolator• OmniFaces Validator family

JSF Validators – short overview (I)

• JSF developers are familiar with JSF built-in validators (which are tag handlers) and JSF custom validators (implementations of javax.faces.validator.Validator interface).

• Commonly, JSF validators are attached to inputs (e.g. <h:inputText>) via validator attribute or <f:validator>/<f:validateXxx> tags.

JSF Validators – short overview (II)

• JSF validators are by default processed in the Process Validations phase. Converters are invoked in this phase (e.g. getAsObject()), but in Render Response phase also (e.g. getAsString()).

• If the validation fails then JSF marks this via validationFailed flag, at context level, and via valid flag, at input level.

• Moreover, the JSF lifecycle “jumps” to the Render Response phase, instead of continue with the Update Model Values phase.

OmniFaces Validators – short overview (I)

• Some OmniFaces validators fixes a suite of gaps of the JSF standard validators, while others are totally new.

• Depending on their goal, OmniFaces validators are implementations of javax.faces.validator.Validator interface, are tag handlers (extends TagHandler) or even UIComponent instances.

OmniFaces Validators – short overview (II)

• While JSF doesn’t support cross-field validation (not even for <f:validateBean>), OmniFaces provides several validators that implements different validation constrains for cross-field validation.

• OmniFaces validators are easy to use and the OmniFaces Showcase provides complete and dedicated examples.

OmniFaces ValidateBean (I)

• The built-in <f:validateBean> allows validation control only on a per- form or a per-request basis, and only applies to individual properties of a bean

• The OmniFaces <o:validateBean> allows the developer to control bean validation on a per-UICommand or UIInput component basis, as well as validating a bean at the class level

OmniFaces ValidateBean (II)

• At class level, validation can be of two types: validate copy and validate actual bean.

• Validate copy (default) - make a copy of the object to validate at the end of Process Validations phase, set the values retrieved from the input components on it, and performs class level validation on the copy. Does not update the model if validation errors occur.

• Validate actual bean - the validation takes places after the Update Model Values, so the original bean is first updated with the values retrieved from the input components, afterwards validated.

OmniFaces ValidateBean (III)

• Sample of using <o:validateBean> - screenshots from Showcase

Validating at the class level that number 1 is smaller than number 2 - default (validate copy)

OmniFaces RequiredCheckboxValidator (I)

• If you need to report the un-ticked checkboxes as invalid inputs then use the OmniFaces RequiredCheckboxValidator validator.

• The RequiredCheckboxValidator solves the problem with required="true" attribute of UISelectBoolean components (<h:selectBooleanCheckbox>). In case of UISelectBoolean the validation will pass for both, ticked/un-ticked checkboxes.

OmniFaces RequiredCheckboxValidator (II)

• This validator is used by indicating the validator ID (validatorId attribute) omnifaces.RequiredCheckboxValidator in <f:validator> of the boolean selection component.

• The validator will use the message as specified in requiredMessage attribute, or the default required message as specified in custom <message-bundle> in faces-config.xml, or it will default to: {0}: a tick is required.

OmniFaces RequiredCheckboxValidator(III)

• Sample of using RequiredCheckboxValidator - screenshots from Showcase

Form with RequiredCheckboxValidator

OmniFaces ValueChangeValidator (I)

• At each postback request, the validation process validates the corresponding submitted values, regardless of whether the submitted values has changed or not.

• Most likely, we don’t want to re-validate unchanged data.

• In terms of performance, these unnecessarily validations my becomes too “expensive”. When that happens, is time for ValueChangeValidator.

• The ValueChangeValidator can be used via a transparent template. Mainly, just replace implements Validator by extends ValueChangeValidator and rename the method from validate to validateChangedObject.

OmniFaces ValueChangeValidator(II)

A JSF common custom validator modified to use ValueChangeValidator

• Sample of using ValueChangeValidator - screenshots from Showcase

A JSF common custom validator

OmniFaces ValidateUniqueColumn (I)

• The <o:validateUniqueColumn> validates if the given UIInput component in an UIData component has an unique value throughout all rows. Those not visible by pagination are also validated.

• This validator works directly on the data model and may therefore not work as expected if the data model does not represent all available rows of the UIData component (e.g. when there's means of lazy loading).

OmniFaces ValidateUniqueColumn (II)

• In an invalidating case, only the first row on which the value is actually changed will be marked invalid and a faces message will be added on the client ID of the input component in the particular row.

• The default message is: {0}: Please fill out an unique value for the entire column. Duplicate found in row {1}

OmniFaces ValidateUniqueColumn (III)

• Sample of using ValidateUniqueColumn- screenshots from Showcase

DataTable with ValidateUniqueColumn

OmniFaces JsfLabelMessageInterpolator(I)

• In Bean Validation, if a component causes a validation failure, then the label associated with this component can appear only in the front or behind the error message. This is possible thanks to javax.faces.validator.BeanValidator.MESSAGE bundle key.

• OmniFaces comes with a custom message interpolator that allows developers to place the label associated with the invalid component anywhere in the error message.

OmniFaces JsfLabelMessageInterpolator(II)

• In order to use the JsfLabelMessageInterpolator, the developer must register it in /META-INF/validation.xml via <message-interpolator> , and use the special placeholder {jsf.label} in bean validation messages.

• Message example: javax.validation.constraints.Size.message = The size of {jsf.label} must be between {min} and {max} characters

OmniFaces JsfLabelMessageInterpolator(III)

• Sample of using JsfLabelMessageInterpolator - screenshots from Showcase

Demo for JsfLabelMessageInterpolator

OmniFaces Validator family

The OmniFaces Validator family represents a collection of cross-field

validators implemented as JSF custom components. Below you can see

the Validator family API.

OmniFaces ValidateOne

• The <o:validateOne> validates if ONLY ONE of the given UIInput components have been filled out.

• The default message is: {0}: Please fill out only one of those fields

Screenshots Showcase

OmniFaces ValidateOneOrMore

• The <o:validateOneOrMore> validates if at least ONE of the given UIInput components has been filled out.

• The default message is: {0}: Please fill out at least one of those fields

Screenshots Showcase

OmniFaces ValidateAllOrNone

• The <o:validateAllOrNone> validates if at least ALL of the given UIInput components have been filled out or that NONE of the given UIInput components have been filled out.

• The default message is: {0}: Please fill out all or none of those fields

Screenshots Showcase

You can also show message on all invalid fields, invalidate only the empty fields or invalidate only the empty fields and show message only on invalid fields

OmniFaces ValidateOneOrNone

• The <o:validateOneOrNone> validates if ONLY ONE of the given UIInput components has been filled out or that NONE of the given UIInput components have been filled out.

• The default message is: {0}: Please fill out only one or none of those fields

Screenshots Showcase

OmniFaces ValidateAll

• The <o:validateAll> validates if ALL of the given UIInput components have been filled out. One could of course also just put required="true" on all of those UIInput components, but this is not always the case (e.g. having a single message for all invalid UIInput).

• The default message is: {0}: Please fill out all of those fields

Screenshots Showcase

OmniFaces ValidateEqual

• The <o:validateEqual> validates if ALL of the given UIInput components have the same value.

• The default message is: {0}: Please fill out the same value for all of those fields

Screenshots Showcase

OmniFaces ValidateUnique

• The <o:validateUnique> validates if ALL of the given UIInput components have an unique value.

• The default message is: {0}: Please fill out an unique value for all of those fields

Screenshots Showcase

OmniFaces ValidateOrder (I)

• The <o:validateOrder> validates if the values of the given UIInput components as specified in the required components attribute are in the order as specified by the optional type attribute which accepts the following values:

• lt (default) - from least to greatest, without duplicates.

• lte - from least to greatest, allowing duplicates (equal values next to each other).

• gt - from greatest to least, without duplicates.

• gte - from greatest to least, allowing duplicates (equal values next to each other).

OmniFaces ValidateOrder (II)

• The to-be-validated values must implement Comparable.

• This validator throws an IllegalArgumentException when one or more of the values do not implement it.

• Note that when this validator is placed before all of the components, then it will only compare the raw unconverted submitted string values, not the converted object values.

• If you need to compare by the converted object values, then you need to place this validator after all of the components.

OmniFaces ValidateOrder (III)

• The <o:validateOrder> validates if the values of the given UIInput respects a certain order.

• The default message is: {0}: Please fill out the values of all those fields in order

Screenshots Showcase

OmniFaces ValidateMultiple (I)

• The <o:validateMultiple> allows the developer to validate multiple fields by a custom validator method:

<!-- source code: OmniFaces Showcase --> <o:validateMultiple id="myId" components="foo bar baz" validator="#{bean.someMethod}" /> <h:message for="myId" /> <h:inputText id="foo" /> <h:inputText id="bar" /> <h:inputText id="baz" />

Method has the following signature (method name is free to your choice):

OmniFaces ValidateMultiple (II)

• The <o:validateMultiple> also allows to validate multiple fields by a managed bean that implements the MultiFieldValidator interface:

<!-- source code: OmniFaces Showcase --> <o:validateMultiple id="myId" components="foo bar baz" validator="#{validateValuesBean}" /> <h:message for="myId" /> <h:inputText id="foo" /> <h:inputText id="bar" /> <h:inputText id="baz" />

Managed bean signature (bean name is free to your choice):

References

• Bauke Scholtz - http://balusc.blogspot.com/• Arjan Tijms - http://arjan-tijms.omnifaces.org/• JSF ZEEF page  - https://jsf.zeef.com/bauke.scholtz• OmniFaces ZEEF page - https://omnifaces.zeef.com/bauke.scholtz• OmniFaces Wikipedia - http://en.wikipedia.org/wiki/OmniFaces