«

»

Jun
26

Validate different validation groups depending on clicked button

One of the new features intruduced with JSF 2 is JSR-303 aka. Bean Validation. With bean validation the input’s are validated against built-in or user defined annotations, placed on the fields, methods or classes.

I’m often in the situation, where I have to validate different values in the same form, depending on what action should be executed. After a lot google’ing and researching, I’ve found the following, pretty easy solution.

Imagine, you have the following managed bean, with the two fields firstname and lastname and a bunch of actions for doing some usefull stuff. But for some obvious reasons one of the actions needs only firstname to be validated, but another action needs firstname and lastname to be validated.

For doing this, we first need the placeholder interfaces for building the two validation groups. I use validate.Both and validate.FirstnameOnly here.

1
2
3
4
5
6
7
8
9
10
11
@ManagedBean
@ViewScoped
public class TestBean implements Serializable {

  @NotNull(groups = {Both.class, FirstnameOnly.class},
           message = "First name must not be empy")
  private String firstname;

  @NotNull(groups = {Both.class},
           message = "Last name must not be empy")
  private String lastname;

Now lets see how to trigger the different validation groups using different commandButtons (or commandLinks, …).
For getting things work, we just add a f:param tag to the commandButtons and assign the full qualified class name of the validation group placeholder interface (If you want more than one, just separate it by comma) to a request parameter (GROUPS in my case).

Now you simply have to attach this value to the validationGroups attribute of the f:validateBean tag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<h:form>
  <h:messages/>
  <h:panelGrid columns="2">
    <h:outputText value="First name"/>
    <h:inputText value="#{testBean.firstname}">
      <f:validateBean validationGroups="#{param['GROUPS']}"/>
    </h:inputText>

    <h:outputText value="Last name"/>
    <h:inputText value="#{testBean.lastname}">
      <f:validateBean validationGroups="#{param['GROUPS']}"/>
    </h:inputText>
  </h:panelGrid>

  <h:commandButton value="First and last name"
                  action="#{testBean.someAction}">
    <f:param name="GROUPS" value="validate.Both"/>
  </h:commandButton>

  <h:commandButton value="First name only"
                  action="#{testBean.someAction}">
    <f:param name="GROUPS" value="validate.FirstnameOnly"/>
  </h:commandButton>
</h:form>

If you press the first commandLink now, both fields are validated, and if you press the second, only the first name gets validated.

In simpler cases (also if the current case is really simple), where you just want to exclude some fields from validation, just use the same method for disabling the appropriate validators. This can be done by setting the disabled attribute of the f:validateBean tag using the f:param tag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<h:form>
  <h:messages/>
  <h:panelGrid columns="2">
    <h:outputText value="First name"/>
    <h:inputText value="#{testBean.firstname}">
      <f:validateBean />
    </h:inputText>

    <h:outputText value="Last name"/>
    <h:inputText value="#{testBean.lastname}">
      <f:validateBean disabled="#{param['FIRSTNAME_ONLY']}"/>
    </h:inputText>
  </h:panelGrid>

  <h:commandButton value="First and last name"
                  action="#{testBean.someAction}">
    <f:param name="FIRSTNAME_ONLY" value="false"/>
  </h:commandButton>

  <h:commandButton value="First name only"
                  action="#{testBean.someAction}">
    <f:param name="FIRSTNAME_ONLY" value="true"/>
  </h:commandButton>
</h:form>

6 comments

1 ping

  1. Ugo says:

    Hello,

    Nice article !
    However I tried the first method with the GROUPS param in the validationGroups attribute, but it didn’t work.

    I think that this is because your param is set first when you click the command button, but not before. So when you’re action is performed, the validationGroups attribute isn’t set yet.

    Am I wrong ?

  2. Feliciano says:

    Hey Dirk,
    thanks for your advice :-) . For me the first method worked perfectly. In fact the f:param tag is set before the validation begins and not as Ugo assumes afterwards.

    Cheers,

    Feliciano

  3. Ugo says:

    That’s right, your f:param is set before the validation begins, but not before the request is sent, unless you re-render the page with the parameters set.

    I’ve tried exactly your code, but still it’s not working. I’m interested in this solution, but I can’t find out how to make it work. Isn’t there some special configuration behind this ?

  4. Dirk Reske says:

    Hello Ugo,

    I’ve created a minimal demo project to show the described behavior: Just download the zip from http://dl.dropbox.com/u/654527/validation-test.zip

    Sources and packaged war included.

    Greets from germany
    Dirk

  5. Ugo says:

    Hello Dirk,

    My friend tested your code yesterday, and we noted that it work just fine. So I came back to my computer and tried to find out what’s wrong with my environment. It just came out that a web.xml configuration was making go your code wrong:

    javax.faces.PARTIAL_STATE_SAVING
    false

    With some deeper research I also learnt that the f:param is actually set into the JSF component tree during the Apply Request Value lifecycle phase, so it is reported into the f:validateBean BEFORE the Validation phase, and I was wrong on that point.

    Thank you for your help !

  6. Dirk Reske says:

    No Problem,

    but good to know it’s not working with partial state saving enabled.

  1. Les groupes de validation dynamiques avec JSF 2 et Hibernate Validator > Patate-chaude says:

    [...] originale est tirée de ce blog. Publié le janvier 27, 2012 par mathieu. Cet article a été publié dans Hibernate, Java, JSF, [...]

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>