client validation framework
ilya_shaikovsky Jun 2, 2010 10:07 AMThis thread is for discussion of implementation questions for RichFaces Client Validation mechanism.
Base document for discussion - http://community.jboss.org/wiki/ClientSideValidation
In order to start I will make write-up based on Pavel prototyping work and our local discussion of some problems with it.
First point we discussed - way to provide form validation. It should be done in order to handle form submits properly. Consider next case -
<form> //set of inputs with validators attached <input/> <input/> <input/> ... //store button <button> </form>
inputs itself could be validated on blur or keyup or some other event.. But after clicking the button - we should be able to invoke the same validation and to cancel submit if any errors occured. So we coming with proposal (already written in comments of base document) to the usage of clientValidator tag not only for EditableValueHolders but also for form or even view like:
<form> <rich:clientValidator [event="onsubmit"]/> ....set of inputs there
So inputs in form could even omit clientValidator definition, if UI requirements do not consist of highlighting wrong inputs immediatelly but only after store button pressed. Using such declaration - validators should be attached by tag handler to all the inputs in form but called only by the script handler of form onsubmit. And form submit will be canceled by stopping the event in validators if some problems reported.
Second point is - implementation of clientValidator as a behavior looks not really convinient for us. Instead we propose to register validators by using some CV api like there:
<input> <clientValidator /> </input>
should generate input and some js code to bind validators to it:
addValidator(id, options)
where options is some array of objects like
{event, validator:function, validatorOptions, validationMessages:['statusId':message, ...], msgComponents:[...]} //all that stuff generated according to Bean validation annotations
instead of encoding like onchange = "validators calling JS".
Main advantages of such approach:
1) if we adding validation to whole form - we could just call that registered validators easilly from the handler attached to the form. And if this will be a behavior - code duplication will appears in form component onsubmit in order to register all the same validation methods.
2) possibility to register validator without event specifying (not possible with behavior but also required for form validation case(no validation untill submit pressed) described in first point)
Example of registration form validator using not behavior but handler registration:
addFormValidator(formId) // the form validator validate method - will lookup for registered validators inside all the nested inputs
Third point although the lookup mechanism for validators JS implementation looks really good and allows to avoid any registry creation and having mappings for Bean validator - > client validator - it has one problem. We definitelly need to aggregate validators implementations required for concrete view. As Alex written in initial document there could be too much resources requests in other case and even the problems with browser restrictions of count of such inclusions could appear.
so this point looks required to be implemented:
Define JavaScript resource and function name in the faces-config.xml as extension element. Allows to use one .js file for many converters/validators and define short names for functions. Disadvantage: complicated configuration.
Open question - do we able to add some runtime aggregation in order custom validators implementations also be included as bundled into single resourse? Does it sounds reasonable from performance point of view for example?
Fourth point Ajax call for validation if no JS implementation exist or no problems found during JS validation(also seems reasonable). In our opinion this should became at least configurable at tag level as Emmanuel mentioned.
Example: If most of the form inputs has simple js Validators attached and the single input needs to be additionally validated at server side(e.g. checking email or nickname duplication during registration requires server side validator) - it's not looks reasonable to flood server with many validation requests but perform them only where them really required for that concrete fields.
So could look like:
<input> <clientValidator useAjaxValidation="true"/> </input>
Fifth Point We propose to add the handling of <rich:messages/> also in next way: If the rich:messages with globalOnly="false" exist - it should be also registered and used by some RichFaces.validators.addMessage() api during addition of validation message to target messages components. We just need to use clientId's of inputs which causes validation message in order to identify the messages added there and perform proper clean-up, update after further changes in form and next validations.