In preparing for my ODTUG 2007 presentation on AJAX in ADF Faces, I decided to play a little with JDeveloper 11g Technology Preview, to have an interesting demo in order to go out with a bang. I was happily surprised with some of the functionality I accidentally stumbled into while trying out different things. In this article I will show you a little bit of those validation features that made me smile this morning.
- Plain old JSF ValidateLongRange and ValidateLength validators give us instant, field level validation
- Multiple client side validation errors are presented in a popup display with hyperlinks to the indivual fields that have the errors
- Any field with an erroneous value is marked; when that field is navigated to, the errormessage is displayed in a nice popup
- Any field with an autoSubmit and server side validator is instantaneously validated and marked upon failed validation
- When the page is redisplayed after a full form submit and validation has failed for one or more fields, all invalid fields are marked with their own personal validation error messagesL including fields in a table layout
- All of the above is either declarative or built-in, zero effort.
Note: this is 11g functionality, which is currently not even in Beta status; there will not be production release before very deep in 2007. Let's visit these features in some detail.
Client Side validation of Standard JSF Validators
The screenshot you see above is the result of having applied a validateLongRange validator to the Salary inputText element in the Employees table:
<af:column sortProperty="Salary" sortable="true" headerText="#{bindings.EmployeesView1.hints.Salary.label}"> <af:inputText value="#{row.Salary}" required="#{bindings.EmployeesView1.hints.Salary.mandatory}" columns="#{bindings.EmployeesView1.hints.Salary.displayWidth}"> <af:convertNumber groupingUsed="false" pattern="#{bindings.EmployeesView1.hints.Salary.format}"/> <f:validateLongRange minimum="1500" maximum="25000"/> </af:inputText> </af:column>
other than applying this validator – I did not have to do anything. The standard JSF validator is apparently recognized by the ADF Faces framework and used to inspire client side validation behavior. As soon as I navigate out of the Salary field, validation takes place and upon failure the field is marked with the red box and the error message pops up.
Note that when I enter a field against which a validator has been defined, a tip pops up that indicates the nature of the rule that will be enforced:
Presenting all form validation errors – even for Table Layouts
When I submit my data page, form level client side validation is performed and all client side validation errors are presented together:
This allows the user to correct all errors before attempting to resubmit the page.
When client side validation is complete without errors, all server side validations are performed. When some validations fail, all the validation errors are presented together – and all invalid fields are marked. In this example, a server side validation is performed on the hiredate, stating that no one can be hired on the 13th of the month:
Now we can click on the Component hyperlink to focus on the specific field that has the value that caused a particular validation failure to occur:
Using the 1 of 2 navigation drop down list or the navigation widgets, we can navigate to all the errors and correct them.
Implementing instantaneous validation with server side validators
The standard JSF and ADF Faces validators are applied on the client side, immediately when the user navigates out of a field. When we define our own custom validator, typically that will not be a client side validation (though that can be achieved with ADF Faces too). However, it turns out to be quite simple to turn server side validations into instantaneous validation when the user tabs out of a field.
In this example, I have set a validator on the Hire_Date inputText.
<af:column sortProperty="HireDate" filterable="true" sortable="true" headerText="#{bindings.EmployeesView1.hints.HireDate.label}"> <af:inputDate value="#{row.HireDate}" required="#{bindings.EmployeesView1.hints.HireDate.mandatory}" valueChangeListener="#{HireDateValidator.validateChangedHiredate}" validator="#{HireDateValidator.ValidatorHiredate}" > <af:convertDateTime pattern="#{bindings.EmployeesView1.hints.HireDate.format}"/> </af:inputDate> </af:column>
The backing bean validation method is implemented like this:
public void ValidatorHiredate(FacesContext facesContext, UIComponent uIComponent, Object object) { FacesContext fc = FacesContext.getCurrentInstance(); Date newDate = (Date)object; if ("13".equalsIgnoreCase(new SimpleDateFormat("dd").format(newDate.getValue()))) { FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unfortunately we cannot hire Employees on the 13th of any given month!", "Due to dark influences on the founder and chairman of our company, we have to avoid all references to the number 13, 666 and 6545142312."); fc.addMessage(uIComponent.getClientId(fc), message); ((RichInputDate)uIComponent).setValid(false); } }
Now the validation gets performed when the page is submitted, as we have seen in the previous image. To turn this page submit level server side validation into an immediate-when-I-leave-a-changed-field kind of of validation, there is just one thing I need to do: set the autoSubmit attribute on the inputDate component to true. That's it. That's all you need.
We change the date from the 17th to the 13th and then (try to) tab out of the field. The partial submit is performed, server side validation takes place and the validation error message is presented.
hi i want to validate if a date from an iput text is higer from another inputDate but i have no idea how to do this can u help me
Does anyone have an idea, how the validator in the UI input Text component can validate through a database select ….
Â
Regards,
M.Kotsovoulou
I have few buttons (for example ButtonA and ButtonB) on page and few field (some inputTexts, selectOneChoices, …) that I want validate. I want to fire validation only on inputTexts fields when ButtonA click (not for selectOneChoice components) and fire validation on click ButtonB only for selectOneChoice components.
The question is: How to create validation group for components and actions on form?
Thanks