javaee / javaserverfaces-spec

JavaServer(TM) Faces Specification web site
https://javaee.github.io/javaserverfaces-spec/
Other
43 stars 19 forks source link

multi-component validation #1

Closed glassfishrobot closed 8 years ago

glassfishrobot commented 20 years ago

Next spec should support multi-component validation.

Environment

Operating System: All Platform: All URL: http://weblogs.java.net/pub/wlg/1625

Affected Versions

[2.0]

glassfishrobot commented 20 years ago

Reported by @edburns

glassfishrobot commented 19 years ago

@edburns said: move to 2.0

glassfishrobot commented 16 years ago

rdelaplante said: I will attach a screenshot to go with this comment:

I have a form where the validators for some fields depend on the submitted values of other fields. For example, "re-enter e-mail address" needs to be compared to the submitted value of "e-mail address". Both of these fields should only be validated if "Send an email" radio button is selected. In my validator code I use other components' getSubmittedValue() method which works perfectly. getSubmittedValue has been deprecated, and the javadoc warns that it should not be used. Why? If you take it out, I'll need to move the logic into my action, and won't be able to "light up" the component's associated label to indicate an error. One developer told me that this is an example of business logic that belongs in an action. I disagree, this is validation logic that belongs in the validator.

glassfishrobot commented 16 years ago

rdelaplante said: Created an attachment (id=121) Form with multi field validators

glassfishrobot commented 16 years ago

rogerk said:

glassfishrobot commented 16 years ago

@edburns said: EGTop5

glassfishrobot commented 15 years ago

@edburns said: effort_hard

glassfishrobot commented 15 years ago

@edburns said:

glassfishrobot commented 15 years ago

mojavelinux said: I don't think that cross-field validation is a difficult problem to solve from the specification level. The reason cross-field validation is difficult today is because each field is converted individually, just prior to being validated. Therefore, when the validate() method is called on a UIInput component, there is no guarantee that any other component in the form will have been converted at that time. It depends on the relative placement of the components in the form, a fact which should not be relied on in a validator.

The current strategy puts the onus of having to convert the related field(s) on the validator that is attempting to perform a cross-field check. Naive developers will simply ignore the converters on that field. The developers that do use the proper converter logic may still get sloppy with exception handling. Refer to either the EqualityValidator in Seam or Tomahawk to witness the ridiculous amount of code that must be used to handle all of these concerns properly.

A better way to implement validation is to first convert all of the components in the form. Once all the conversions are complete, then the validators run. An extra walk of the component tree can be avoided by putting the input components that were converted into an ordered collection (or map) and then iterating over that collection (or map) to apply the validators. Using this suggested strategy, implementing a multi-component validator is no more difficult than implementing a validator on a single component. The validator tag would need to provide some way to declaratively refer to the related components, such as by ID or value expression.

Frankly, I don't feel it is the responsibility of the specification to create a multi-component validator solution. What the specification should do is make it easy to create such a solution. With that said, I do believe it would be a good idea to implement a couple of basic multi-component validators to demonstrate 1) how it's done and 2) the ease in which it can be done with conversion and validation happening in distinct steps. Reference validators would include an equality validator (one or more components), a greater and less than validator, and perhaps a switch validator (a boolean component toggles the required flag on another component).

glassfishrobot commented 15 years ago

rdelaplante said:

Frankly, I don't feel it is the responsibility of the specification to create a multi-component validator solution. What the specification should do is make it easy to create such a solution.

IMO JSF should come complete out of the box and not require additional frameworks to make it usable unless it is some other JSR built into Java EE 6 application servers.

glassfishrobot commented 15 years ago

rdelaplante said: The following comment was added to Ed Burns' blog about this ticket:

Hello, we're looking to JSR-303 BeanValidation to help with this. In fact, Emmanuel Bernard, has been doing an excellent job and we're fully ready to include it in JSF 2.0 when the Java EE 6 platform group approves it for inclusion.

Ed

Posted by: edburns on January 21, 2009 at 09:27 AM http://weblogs.java.net/blog/edburns/archive/2009/01/jsf_20_public_r.html

glassfishrobot commented 15 years ago

rdelaplante said: John Reynolds wrote about an interesting idea [1] where JSF's h:form tag can have validator(s) attached to it, like any other input component. The form could validate the submitted values of any combination of components using business rules, and throw a ValidatorException when there is a problem. That is how Wicket does "business form"/multi component validation [2] and it seems that this would be a simple addition to JSF 2.0 or 2.1. JSR-303 BeanValidation is definitely welcome, but I think this idea is just as important for JSF.

[1] http://weblogs.java.net/blog/johnreynolds/archive/2004/07/improve_jsf_by_1.html [2] http://cwiki.apache.org/WICKET/validating-related-fields.html

glassfishrobot commented 15 years ago

@edburns said: Created an attachment (id=197) Fix for this bug, first iteration.

glassfishrobot commented 15 years ago

@edburns said: Created an attachment (id=198) Zip of changed files, in lieu of checkin.

glassfishrobot commented 15 years ago

@edburns said: I have attached a fix for this bug, based on the new event system in JSF 2.0

glassfishrobot commented 15 years ago

@edburns said: Fixed enough for 2.0

glassfishrobot commented 13 years ago

@edburns said: Marked fixed, but I am not convinced it's actually committed.

glassfishrobot commented 13 years ago

kito75 said: Ed, correct me if I'm wrong, but isn't this patch just a specific use case rather than a generic solution?

I would expect something like this:

<f:validatorGroup name="insidePanel" validator="#

{myBean.validatePanel}

"/> <h:inputText id="input1" validator="#

{myBean.validateInput1}

" validatorGroup="insidePanel"/>

In this scenario, myBean.validatePanel() would be called, but sent in a Map<String, Object> of values, where String is the component id. validatePanel() wouldn't be called, however, unless myBean.validateInput1() executed successfully.

glassfishrobot commented 13 years ago

@arjantijms said: Such a validator group does sound like a nice idea. Optionally, you could loose the name if the components are nested:

<f:validatorGroup validator="#{myBean.validatePanel}">
   <h:inputText id="input1" validator="#{myBean.validateInput1}" />
   <h:inputText id="input2" />
</f:validatorGroup>

For general purpose multi-component validation, requiring the components to use a hard coded ID might be problematic. These IDs may already be needed for other purposes. So in that case perhaps f:validatorGroup can take f:param children to indicate this, or the proposed validatorGroup attribute could include some kind of designator, e.g.:

<f:validatorGroup name="insidePanel" validator="#{myBean.validatePanel}"/>
<h:inputText validator="#{myBean.validateInput1}" validatorGroup="insidePanel:input1"/>
<h:inputText validatorGroup="insidePanel:input2"/>
glassfishrobot commented 12 years ago

struberg said: Just a side note from the spectator seats:

glassfishrobot commented 12 years ago

kito75 said: Depending on JSR-303 seems naive to me. A lot of people simply don't use it, and if you have an existing application it's prohibitively expensive to convert it (if not impossible, perhaps do to political constraints or time constraints).

So we need a solution that works within the JSF validation mechanism, and action methods don't cut it. I've seen a people use the postValidate event for this, which does work, but it's not very elegant. Something like what Seam-Faces has would work out fine: http://docs.jboss.org/seam/3/faces/reference/snapshot/en-US/html_single/#validateForm. I would want it to work without CDI, though.

This is a major whole in the JSF spec – I've seen people use different solutions on almost every project.

glassfishrobot commented 12 years ago

john_waterwood said: I hope its still posible to do this for JSF 2.2. Everyone now does this in their own way and it's such a basic thing. Anyone noticed this is issue nr 1? Would be great if it finally can be closed.

glassfishrobot commented 11 years ago

@edburns said: Still on the radar for 2.3.

glassfishrobot commented 10 years ago

rdelaplante said: OmniFaces has support for this feature:

http://showcase.omnifaces.org/validators/validateMultiple

I also like their other helpful validators such as , , , , , , or

glassfishrobot commented 10 years ago

@edburns said: Set priority to baseline ahead of JSF 2.3 triage. Priorities will be assigned accurately after this exercise.

glassfishrobot commented 10 years ago

@manfredriem said: Setting priority to Critical. Lets get this one done!

glassfishrobot commented 8 years ago

muellermi said:

I don't think that cross-field validation is a difficult problem to solve from the specification level. The reason cross-field validation is difficult today is because each field is converted individually, just prior to being validated. Therefore, when the validate() method is called on a UIInput component, there is no guarantee that any other component in the form will have been converted at that time. It depends on the relative placement of the components in the form, a fact which should not be relied on in a validator.

Thus, IMHO we need conversion, (individual) validation for each component ant then group validation.

<f:validatorGroup name="insidePanel" validator="#

{myBean.validatePanel}"/>

The example from Arjan might take us into the right direction. But why is there an additional qualifier after the group name? And, in this example the group declares a validation method. Usually in JSF, we can declare a method using the validator attribute, or use a predefined validator (to be declared) by the validator tag.

<f:validatorGroup name="insidePanel" validator="#{myBean.validatePanel}

">

</f:validatorGroup> <h:inputText id="text1" validator="#

{myBean.validateInput1}

" validatorGroup="insidePanel"/>

This might offer a second approach beside bean validation.

glassfishrobot commented 8 years ago

@edburns said: Thanks for the input, Michael. In the name of platform integration, I want to adopt a solution that depends on JSR-303 Bean Validation, and this is what my proposal that I sent to the EG today does. I've committed the work to the JAVASERVERFACES-1 branch.

glassfishrobot commented 8 years ago

@edburns said: Nice to close our oldest issue.

glassfishrobot commented 8 years ago

kito75 said: Where can I find an example of how this works?

glassfishrobot commented 8 years ago

@edburns said: https://java.net/projects/mojarra/sources/git/show/test/javaee7/multiFieldValidation

glassfishrobot commented 8 years ago

jonleyo said: Does the "<f:validateWholeBean" run in the "validation" phase?

From what I understand, a bean is passed through the validator.

How can you validate a bean if the "update model values" phase has not run.

glassfishrobot commented 8 years ago

@edburns said:

Does the "<f:validateWholeBean" run in the "validation" phase?

From what I understand, a bean is passed through the validator.

How can you validate a bean if the "update model values" phase has not run.

See: <https://maven.java.net/service/local/repositories/snapshots/archive/org/glassfish/javax.faces/2.3.0-m04-SNAPSHOT/javax.faces-2.3.0-m04-20151005.070345-179-documentation.jar/!/vdldoc/f/validateWholeBean.html>.

Support multi-field validation by enabling class-level bean validation on CDI based backing beans. This feature causes a temporary copy of the bean referenced by the value attribute, for the sole purpose of populating the bean with field values already validated by and then performing class-level validation on the copy.

glassfishrobot commented 15 years ago

File: 1.zip Attached By: @edburns

glassfishrobot commented 15 years ago

File: changebundle.txt Attached By: @edburns

glassfishrobot commented 16 years ago

File: [radio buttons.png](https://java.net/jira/secure/attachment/13449/radio buttons.png) Attached By: rdelaplante

glassfishrobot commented 20 years ago

Issue-Links: depends on JAVASERVERFACES_SPEC_PUBLIC-626 JAVASERVERFACES_SPEC_PUBLIC-1062 is related to JAVASERVERFACES-4068

glassfishrobot commented 7 years ago

This issue was imported from java.net JIRA JAVASERVERFACES_SPEC_PUBLIC-1

glassfishrobot commented 8 years ago

Marked as fixed on Friday, October 2nd 2015, 9:11:03 am