如何根据selectOneMenu的当前选择validationselectManyCheckbox的最大检查值?

我正在使用JSF 2.0和PrimeFaces。 我有一个selectOneMenu和一个selectManyCheckbox。 我想实现这个场景:

当用户选择:

  • option1(PieChart),然后允许用户检查最多一个复选框
  • option2(BarChart),然后允许用户检查最多两个复选框

这是我到目前为止的尝试,观点:

   

(注意:我不确定

是否正确)

豆子:

 public void checkboxHandler() { Iterator it1 = selectedItemscheckbox.iterator(); if (chartType.equals("PieChart")) { while (it1.hasNext()) { if (selectedItemscheckbox.size() > 1) { // Here should be somthing that shows a message to the user. } } } } 

在使用BalusC的解决方案后,出现此错误:

 java.lang.InstantiationException: DAOKPI.TestAjax$MyCheckboxValidator at java.lang.Class.newInstance0(Class.java:340) at java.lang.Class.newInstance(Class.java:308) at com.sun.faces.application.ApplicationImpl.newThing(ApplicationImpl.java:1699) at com.sun.faces.application.ApplicationImpl.createValidator(ApplicationImpl.java:1557) at com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.createValidator(ValidatorTag HandlerDelegateImpl.java:238) at com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.applyAttachedObject(Validato rTagHandlerDelegateImpl.java:132) at com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.applyNested(ValidatorTagHand lerDelegateImpl.java:205) at com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.apply(ValidatorTagHandlerDel egateImpl.java:87) at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120) at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98) at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandle r.java:137) at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDel egateImpl.java:188) at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120) at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98) at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137) at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:188) at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120) at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98) at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137) at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:188) at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120) at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137) at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:188) at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120) at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98) at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137) at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:188) at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120) at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98) at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93) at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98) at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:86) at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:152) at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:769) at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:100) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:410) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98) at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:326) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822) at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719) at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013) at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) at com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:662) 

更新

谢谢问题解决了:)

您需要一个自定义Validator ,当复选框包含太多选中的项时,它会抛出ValidatorException 。 需要将此Validator附加到checkbox组件,并且视图中的某处应该有组件,可以显示validation错误。

ajax事件是错误的。 在下拉列表中,您希望挂钩change事件。 在复选框或单选按钮内,您希望挂钩click事件。 将event属性保留为默认值时,这两者都是默认值。 每个组件应依次ajax-submit自己和另一个组件,最后重新呈现消息组件以反映validation错误。

为了在自定义validation器中计算选定的下拉值,最简单的方法是将整个下拉组件设置为复选框组件的自定义属性。 这可以通过binding属性将下拉列表绑定到视图来实现,并在复选框内指定为值。 然后可以在自定义validation器内获取下拉组件及其值。

总结一下,下面的启动示例应该有效(注意我使用作为在这个特殊情况下没有增加任何额外的优势,我承认无法从头顶知道如何以及是否可行) :

                

 @FacesValidator("myCheckboxValidator") public class MyCheckboxValidator implements Validator { @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { UIInput chartTypeComponent = (UIInput) component.getAttributes().get("chartType"); String chartType = (String) chartTypeComponent.getValue(); List selectedItemscheckbox = (List) value; if ("PieChart".equals(chartType) && selectedItemscheckbox.size() > 1) { throw new ValidatorException(new FacesMessage("Max 1 item allowed")); } else if ("BarChart".equals(chartType) && selectedItemscheckbox.size() > 2) { throw new ValidatorException(new FacesMessage("Max 2 items allowed")); } } } 

请注意,我假设#{bean.selectedItemscheckbox}List 。 如果它实际上String[] ,那么您需要相应地更改validation器代码。