Omnifaces validateBean: attach message to specific component

浪尽此生 提交于 2019-12-10 22:34:49

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/35982491/omnifaces-validatebean-attach-message-to-specific-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!