Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi-component validation #1

Closed
eclipse-faces-bot opened this issue Jul 16, 2004 · 31 comments
Closed

multi-component validation #1

eclipse-faces-bot opened this issue Jul 16, 2004 · 31 comments

Comments

@eclipse-faces-bot
Copy link

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]

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
Reported by @edburns

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
@edburns said:
move to 2.0

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
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.

@eclipse-faces-bot
Copy link
Author

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

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
rogerk said:

      • Issue 60 has been marked as a duplicate of this issue. ***

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
@edburns said:
EGTop5

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
@edburns said:
effort_hard

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
@edburns said:

      • Issue 52 has been marked as a duplicate of this issue. ***

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
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).

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
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.

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
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

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
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

@eclipse-faces-bot
Copy link
Author

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

@eclipse-faces-bot
Copy link
Author

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

@eclipse-faces-bot
Copy link
Author

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

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
@edburns said:
Fixed enough for 2.0

@eclipse-faces-bot
Copy link
Author

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

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
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"/>
<h:inputText id="input2" 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.

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
@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"/>

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
struberg said:
Just a side note from the spectator seats:

  • doing 'easy' multi-field validations should be done via JSR-303
  • doing more complex multi-field validations are more likely part of the business logic and can be implemented in a JSF action method much more easily (and without any side-effects).

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
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.

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
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.

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
@edburns said:
Still on the radar for 2.3.

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
rdelaplante said:
OmniFaces has support for this feature:

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

I also like their other helpful validators such as <o:validateAll>, <o:validateAllOrNone>, <o:validateEqual>, <o:validateOne>, <o:validateOneOrMore>, <o:validateOneOrNone>, <o:validateOrder> or <o:validateUnique>

@eclipse-faces-bot
Copy link
Author

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

@eclipse-faces-bot
Copy link
Author

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

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
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}"/>

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

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:requiredValidator requiredOr="text1, text2" />
</f:validatorGroup>
<h:inputText id="text1" validator="#

{myBean.validateInput1}

" validatorGroup="insidePanel"/>
<h:inputText id="text2" validatorGroup="insidePanel"/>

This might offer a second approach beside bean validation.

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
@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.

@eclipse-faces-bot
Copy link
Author

@glassfishrobot Commented
@edburns said:
Nice to close our oldest issue.

@eclipse-faces-bot
Copy link
Author

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

@eclipse-faces-bot
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant