如何根据selectOneMenu的当前选择验证selectManyCheckbox的最大检查值? [英] How to validate the maximum amount of checked values of a selectManyCheckbox based on the current selection of a selectOneMenu?

查看:80
本文介绍了如何根据selectOneMenu的当前选择验证selectManyCheckbox的最大检查值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using JSF 2.0 and PrimeFaces. I have a selectOneMenu and a selectManyCheckbox. I want to achieve this scenario:

当用户选择:


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

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

这是我到目前为止的尝试,视图:

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>

(注意:我不确定< p :ajax事件> 是正确的)

(note: I am not sure if the <p:ajax event> is correct)

豆子:

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的解决方案,发生了这个错误:

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)

更新

谢谢问题解决了: )

推荐答案

你需要一个自定义 Validator 抛出 ValidatorException 当复选框包含太多选中的项目时。此 Validator 需要附加到复选框组件,并且应该有< h:message> < h:messages> 组件中的某个组件可以显示验证错误。

You need a custom Validator which throws a ValidatorException when the checkbox contains too many checked items. This Validator 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.

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

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 on click event instead. Both which are already the default when you leave the event 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.

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

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.

总结一下,下面的启动示例应该有效(注意我使用了< f:ajax> as < p:ajax> 在这个特殊情况下没有额外的优势而且我无法从如何,如果这将工作):

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):

<h:selectOneMenu id="chartType" binding="#{chartType}" value="#{bean.chartType}">
    <f:selectItem itemValue="PieChart" itemLabel="PieChart" />
    <f:selectItem itemValue="BarChart" itemLabel="BarChart" />
    <f:ajax execute="chartType checkbox" render="checkboxmessage" />
</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" />
    <f:validator validatorId="myCheckboxValidator" />
    <f:attribute name="chartType" value="#{chartType}" />
    <f:ajax execute="chartType checkbox" render="checkboxmessage" />
</h:selectManyCheckbox>
<h:message id="checkboxmessage" for="checkbox" />

使用

@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<String> selectedItemscheckbox = (List<String>) 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> 。如果它实际上一个 String [] ,那么你需要相应地改变验证器代码。

Note that I assume the #{bean.selectedItemscheckbox} to be a List<String>. If it's actually a String[], then you need to alter the validator code accordingly.

这篇关于如何根据selectOneMenu的当前选择验证selectManyCheckbox的最大检查值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆