2

I am using Omnifaces <o:validateBean /> to use JSR303 bean validation with a class level constraint.

The whole thing works quite good. The validation message is displayed in a Primefaces <p:messages /> component. Now I wanted to know whether it is possible to narrow the error message to a more precise component (i. e. a <p:message /> tag on a specific element)? In the example below I want to direct the error message to the <p:message /> component with id="id_msg_anniversary" (or if that is possible, to both id="id_msg_anniversary" and id="id_msg_wedding").

One of my intention is to validate everything with bean validation and not to use <o:validateOrder /> or <o:validateMultiple />.

@DayIsBeforeAnniversary
@Entity
public class Person implements Serializable
{
    @Temporal(TemporalType.DATE)
    private Date weddingDay;

    @Temporal(TemporalType.DATE)
    private Date silverWeddingAnniversary;
    ...
}
<p:messages id="id_messages" />

<h:outputLabel value="Wedding Day" />
<p:message id="id_msg_wedding" display="icon" for="id_wedding" />
<p:calendar 
    id="id_wedding" 
    value="#{personController.person.weddingDay}"> <br />

<h:outputLabel value="Silver Wedding Anniversary" />
<p:message id="id_msg_anniversary" display="icon" for="id_anniversary" />
<p:calendar 
    id="id_anniversary" 
    value="#{personController.person.silverWeddingAnniversary}" /> <br/>

<p:commandButton 
    value="test" 
    action="#{personController.navigate()}" 
    update="@all"/>

<o:validateBean value="#{personController.person}" />
public class DayIsBeforeAnniversaryValidator implements ConstraintValidator<DayIsBeforeAnniversary, Person>
{
    @Override
    public boolean isValid(Person person, ConstraintValidatorContext context)
    {
        return person == null
            || person.getWeddingDay() == null
            || person.getSilverWeddingAnniversary() == null
            || person.getWeddingDay().before(person.getSilverWeddingAnniversary());
    }
    ...
}
public @interface DayIsBeforeAnniversary { ... }

For clarification I could attach more code.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Filou
  • 490
  • 4
  • 17
  • Please have a look on this http://stackoverflow.com/questions/5288267/how-to-add-a-message-to-a-specific-component-from-java – Subodh Joshi Mar 14 '16 at 09:37
  • Thanks for the quick response. I basically know that I can create a message for a specific component. But in my case the message is not generated by myself but by the Omnifaces library. – Filou Mar 14 '16 at 12:18

1 Answers1

2

The <o:validateBean> associates its message with the <h:form>. So, all you need to do is to make sure you have a <p:message for="formId"> at the desired place. Do note that you can have multiple of them. Below is a kickoff example.

<h:form id="formId">
    <p:inputText id="foo" ... />
    <p:message for="foo" />
    <p:message for="formId" />
    ...
    <p:inputText id="bar" ... />
    <p:message for="bar" />
    <p:message for="formId" />
    ...
    <o:validateBean ... />
</h:form>

I however do agree this is not the most elegant solution, surely not when compared with members of ValidateMultipleFields family which has an useful showMessageFor attribute for the purpose. It's only unfortunately technically pretty convoluted to implement it on <o:validateBean> too as there's technically no direct relationship between BV constraint violation errors and JSF input fields, so it has to be manually inspected based on bean properties and JSF component tree, which is not exactly an oneliner work.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Big thanks! That'll work for me for now. I am afraid I have another Entity where I want to create more than one class level constraint. In that case I'll have a problem with this approach I guess... Anyway do you have by chance any idea if there will be a sophisticated solution in upcoming JSF 2.3 [as you once said that it is based on o:validateBean](http://stackoverflow.com/a/27786669)? – Filou Mar 14 '16 at 14:48
  • About two years later I am still struggling with bean validation. But with Omnifaces 2.6 my whole question has a final solution. There is a `showMessageFor` attribute like in the other members of the ValidateMultipleFields family. Thanks for adding this! Anyway I still have some problems using it but thats a differen story ... ([Omnifaces validateBean: can not get showMessageFor attirbute to work](https://stackoverflow.com/q/49409845/5176800)) – Filou Mar 21 '18 at 15:09