如何根据 selectOneMenu 的当前选择验证 selectManyCheckbox 的最大选中值数量?
我正在使用 JSF 2.0 和 PrimeFaces。我有一个 selectOneMenu 和一个 selectManyCheckbox。我想实现这种情况:
当用户选择:
- option1(PieChart),则允许用户检查最多一个复选框
- option2(BarChart),然后允许用户检查最多两个复选框
这是迄今为止我的尝试, view:
<h:selectOneMenu value="#{bean.chartType}">
<f:selectItem itemValue="PieChart" itemLabel="PieChart" />
<f:selectItem itemValue="BarChart" itemLabel="BarChart" />
<p:ajax event="keyup" update="checkbox" listener="#{bean.checkboxHandler}" />
</h:selectOneMenu>
<h:selectManyCheckbox id="checkbox" value="#{bean.selectedItemscheckbox}">
<f:selectItem itemValue="priority" itemLabel="By priority" />
<f:selectItem itemValue="project" itemLabel="By project" />
<f:selectItem itemValue="issuetype" itemLabel="By IssueType" />
<f:selectItem itemValue="group" itemLabel="By group" />
</h:selectManyCheckbox>
(注:我不确定
是否正确)
the bean:
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)
更新
谢谢,问题已解决:)
I am using JSF 2.0 and PrimeFaces. I have a selectOneMenu and a selectManyCheckbox. I want to achieve this scenario:
When an user chooses:
- option1(PieChart), then the user is allowed to check max one checkbox
- option2(BarChart), then the user is allowed to check max two checkboxes
Here is my attempt so far, the view:
<h:selectOneMenu value="#{bean.chartType}">
<f:selectItem itemValue="PieChart" itemLabel="PieChart" />
<f:selectItem itemValue="BarChart" itemLabel="BarChart" />
<p:ajax event="keyup" update="checkbox" listener="#{bean.checkboxHandler}" />
</h:selectOneMenu>
<h:selectManyCheckbox id="checkbox" value="#{bean.selectedItemscheckbox}">
<f:selectItem itemValue="priority" itemLabel="By priority" />
<f:selectItem itemValue="project" itemLabel="By project" />
<f:selectItem itemValue="issuetype" itemLabel="By IssueType" />
<f:selectItem itemValue="group" itemLabel="By group" />
</h:selectManyCheckbox>
(note: I am not sure if the <p:ajax event>
is correct)
The bean:
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.
}
}
}
}
After tring BalusC's solution,this error occured :
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)
Update
Thank you problem solved :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要一个自定义
Validator
< /a> 当复选框包含太多选中项时,它会抛出ValidatorException
。此Validator
需要附加到复选框组件,并且应该有一个
或
视图中某处可以显示验证错误的组件。ajax事件是错误的。在下拉列表中,您希望挂钩
change
事件。在复选框或单选按钮内,您希望挂钩click
事件。当您将event
属性保留为默认值时,这两者都已是默认值。每个组件应该依次使用 ajax 提交自己和另一个组件,最后重新渲染消息组件以反映验证错误。为了计算自定义验证器中选定的下拉值,最简洁的方法是将整个下拉组件设置为复选框组件的自定义属性。这可以通过通过
binding
属性将下拉列表绑定到视图并将其指定为复选框内
的值来实现。然后可以在自定义验证器内获取下拉组件及其值。总而言之,下面的启动示例应该可以工作(请注意,我使用
因为
在这种特殊情况下没有增加额外的优势,并且我诚然,无法从头顶看出这将如何工作以及是否有效):请
注意,我假设
#{bean.selectedItemscheckbox}
是列表<字符串>
。如果它实际上是一个String[]
,那么您需要相应地更改验证器代码。You need a custom
Validator
which throws aValidatorException
when the checkbox contains too many checked items. ThisValidator
needs to be attached to the checkbox component and there should be a<h:message>
or a<h:messages>
component somewhere in the view which can display the validation error.The ajax event is wrong. Inside a dropdown, you would like to hook on the
change
event instead. Inside a checkbox or radio button you would like to hook onclick
event instead. Both which are already the default when you leave theevent
attribute to default. Each component should in turn ajax-submit themselves and the other one and finally re-render the message component to reflect the validation error.In order to figure the selected dropdown value inside the custom validator, the cleanest way would be to set the whole dropdown component as a custom attribute of the checkbox component. This can be achieved by binding the dropdown to the view by
binding
attribute and specify that as value of<f:attribute>
inside the checkbox. The dropdown component and thus also its value can then be obtained inside the custom validator.Summarized, the below kickoff example should work (note that I used
<f:ajax>
as<p:ajax>
adds no extra advantages in this particular case and I admittedly can't tell from top of head how and if that would work):With
Note that I assume the
#{bean.selectedItemscheckbox}
to be aList<String>
. If it's actually aString[]
, then you need to alter the validator code accordingly.