myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gerald Turner <gtur...@unzane.com>
Subject Re: ExtVal BV question
Date Thu, 08 Mar 2012 19:47:27 GMT
Gerhard Petracek <gerhard.petracek@gmail.com> writes:
> please also describe the use-case for this feature.

I guess my Widget with option1 and option2 fields wasn't a very good
example.

I could conjure up a typical password + passwordVerify validation combo,
but that wouldn't be realistic for JPA (persistent Registration
entity?).

I'll give another example of a table I'm working with that functions
like a generic Map of name-value pairs.

There is an enum called Feature:

  enum Feature { Recording, MediaPreTransfer, MediaNoTransfer, ... }

There is a table called FeatureConfig that maps Features to String
values:

  @Entity
  @FeatureConfigValid
  class FeatureConfig {

    @Column
    @Enumerated
    @NotNull
    Feature feature;

    @Column
    @NotEmpty
    String value;

  }

There is a JSF for creating or modifying FeatureConfig, the page
contains two components, a h:selectOneMenu for the 'feature' property
and a h:inputText for the 'value' property.  Both components have a
h:message, and the entire form has a h:messages with globalOnly="true".

  <h:form>
    <h:messages globalOnly="true"/>

    <h:selectOneMenu id="feature" value="#{edit.config.feature}">
      <f:selectItems value="#{constants.features}"/>
    </h:selectOneMenu>
    <h:message for="feature"/>

    <h:inputText id="value" value="#{edit.config.value}"/>
    <h:message for="value"/>

    <h:commandButton value="Submit" actionListener="#{edit.save}"/>
  </h:form>

The behavior should be that the message component for feature should
trigger if feature is not selected (@NotNull), and message should
trigger for value if value is empty (@NotEmpty), and furthermore message
for value should trigger for the following conditions:

  • Selected Feature is Recording, and Value is not an integer between 0
    and 100.

  • Selected Feature is one of the Media* types, and Value is not a URL.

I would like a JSR303 multi-field ConstraintValidator called
FeatureConfigValid that has something like the following isValid
implementation:

  public boolean isValid(FeatureConfig config,
                         ConstraintValidatorContext ctx) {
    boolean valid = true;
    String value = config.getConfig();
    switch (config.getFeature()) {
      case Recording:
        if (!isNumeric(value, 0, 100)) {
          ctx.disableDefaultConstraintViolation();
          ctx.buildConstraintViolationWithTemplate("{must_be_numeric}")
             .setNode("value")
             .addConstraintViolation();
          valid = false;
        }
        break;

      case MediaPreTransfer:
      case MediaNoTransfer:
        if (!isURL(value)) {
          ctx.disableDefaultConstraintViolation();
          ctx.buildConstraintViolationWithTemplate("{must_be_url}")
             .setNode("value")
             .addConstraintViolation();
          valid = false;
        }
        break;
    }
    return valid;
  }

The behavior is that instead h:message for 'value' being triggered (via
ConstraintViolation propertPath linkage), the global h:messages is being
triggered.  Not too bad for this small example, but image a page full of
dozens of fields and more cross-field validations, it would put more
strain on the user to decipher the global messages and hunt down the
related fields (that aren't decorated as being invalid whatsoever).

-- 
Gerald Turner   Email: gturner@unzane.com   JID: gturner@unzane.com
GPG: 0xFA8CD6D5  21D9 B2E8 7FE7 F19E 5F7D  4D0C 3FA0 810F FA8C D6D5

Mime
View raw message