2011-12-29 105 views
2

我正在使用表单来搜索数据库中的客户端。这种形式实际上分开在两个形式:比方说简单搜索高级搜索验证不同的验证组JSF 2.0

我可以选择通过点击相应的单选按钮来进行高级搜索。当我单击单选按钮时,支持bean的状态从SimpleSearchState更改为AdvancedSearchState(State Pattern)。

这里是我的形式支持bean:

public class SearchContextBean { 

    /** 
    * Injected beans 
    */ 
    @ManagedProperty(value = "#{simpleSearchStateBean}") 
    private SimpleSearchStateBean simpleSearchStateBean; 

    @ManagedProperty(value = "#{advancedSearchStateBean}") 
    private AdvancedSearchStateBean advancedSearchStateBean; 
    /** 
    * State 
    */ 
    private SearchState searchState = simpleSearchStateBean; 

    /** 
    * Properties, validations. 
    */ 
    @NotEmpty(groups={SimpleSearchValidationGroup.class}) 
    private String   name; 
    @Size(max=18, groups={AdvancedSearchValidationGroup.class}) 
    private String   firstName; 

    ... 

    } 

所以我有一个在财产我想成为强制性的简单搜索。另一方面,我希望名字属性仅在高级搜索时才按其大小进行验证。

这里是我的一块.xhtml页面:

<h:inputText name="name" id="name" 
value="#{cc.attrs.searchContextBean.name}"> 
    <f:validateBean 
     validationGroups="package.to.my.SimpleSearchValidationGroup" /> 
</h:inputText> 
<h:inputText name="firstName" id="firstName" 
value="#{cc.attrs.searchContextBean.firstName}"> 
    <f:validateBean 
     validationGroups="package.to.my.AdvancedSearchValidationGroup" /> 
</h:inputText> 

我试图实现Hibernate's GroupSequenceProvider没有成功:在覆盖方法getValidationGroups总是收到空,而不是我的bean对象的。然后,即使我通过返回验证组类的不同列表来更改组序列,它在验证我的网页时也不会改变任何内容。

的问题是,我不能把禁用属性在我F:validateBean其设置为根据我SearchContextBean的状态,因为我不能重新呈现形式因为某些原因(我需要隐藏/显示错误消息容器根据EL#{name.valid}在处保留为真,如果发生错误,即使在重新渲染之后)。

我希望有一个更清晰的解决方案来验证一个或另一个组。

提前感谢您的帮助。

回答

2

我从未使用过组验证。但是,对我来说,代码会更清楚,如果我的简单搜索&高级搜索分成2名不同的形式是这样的:

<h:selectBooleanCheckbox id="isSimple" value="#{searchBean.simple}"> 
    <f:ajax render="searchPanel" /> 
</h:selectBooleanCheckbox> 

<h:panelGroup id="searchPanel"> 
    <h:form rendered="#{searchBean.simple}" id="simpleSearch> 
     <h:inputText id="name" value="#{simpleSearchBean.name}" /> 
     <h:inputText id="age" value="#{simpleSearchBean.age}" /> 

     <h:commandButton id="simpleButton" action="#{simpleSearchBean.search}" value="Search" /> 
    </h:form> 

    <h:form rendered="#{not searchBean.simple}" id="advancedSearch> 
     <h:inputText id="firstname" value="#{advancedSearchBean.firstName}" /> 
     <h:inputText id="age"  value="#{advancedSearchBean.age}" /> 

     <h:commandButton id="advancedButton" action="#{advancedSearchBean.search}" value="Search" /> 
    </h:form> 
</h:panelGroup> 

@ManagedBean 
@ViewScoped 
public class SearchBean { 
    private boolean simple; 
} 

然后你就可以分别执行验证。只是我的2美分!希望它可以帮助你:)。

+0

谢谢J4mes先生。这显然是解决我的问题的方法,除了我必须保留单选按钮(这不是我的决定)之外,这是我将要使用的方法。 无论如何,为了使它工作,我仍然需要将隐藏的命令按钮放到这些窗体中的每一个中,并为我的搜索按钮创建一个'onclick',以触发其中一个或另一个。 但是我仍然对JSF2跨域验证感到不满意,我很乐意在这个框架中使用更多简单的Hibernate验证。 – Ugo 2011-12-30 09:03:18

+0

@Ugo:我刚刚编辑了我的答案。你可以这样放2个commandButton。一次只显示其中一个。 – 2011-12-30 09:06:46

+0

是的,但我必须坚持我的'onclick'技巧,因为我有一个完整的按钮栏,我不能重复维护。 – Ugo 2011-12-30 09:15:07