在动态填充的JSF OneMenu上禁用验证

时间:2014-11-10 13:11:31

标签: jquery jsf jsf-2 primefaces xhtml

首先,我使用的是Primefaces 5.1和JSF 2.2.2。

问题

我正在创建一个拥有200多个OneMenus的网站(这不是我的决定......)。有一个包含选项的列表,每个OneMenu都在使用它。

使用"静态"方式导致所有探险者挂起甚至崩溃。

<h:selectOneMenu value="#{day.movieEvaluatorName}" styleClass="comboboxMitarbeiter">
<f:selectItems value="#{comboListsBean.staffMembers}" var="member" itemValue="#{member.name}" itemLabel="#{member.fullName}" />
<p:ajax listener="#{...save()}" />
</h:selectOneMenu>

现在因为选项列表总是一样的我认为&#34;让我们使用一些jQuery并在有人点击一个时填写选项。

<h:selectOneMenu value="#{day.movieTechnicanName}" styleClass="comboboxMitarbeiter">
<f:selectItem itemValue="#{day.movieTechnicanName}" itemLabel="#{day.movieTechnican}" />
<p:ajax listener="#{...save()}" />
</h:selectOneMenu>

JS

var comboboxOption = {
        <c:forEach items="#{comboListsBean.staffMembers}" var="member">
        '#{member.name}' : '#{member.fullName}',
        </c:forEach>
        };

var _select = $('<select>');
$.each(comboboxOption, function(val, text) {
    _select.append($('<option></option>').val(val).html(text));
});

$(document).ready(function() {  
    $( ".comboboxMitarbeiter" ).focus(function() {
            $(this).append(_select.html());
        });
});

现在&#34;填充&#34;工作得非常好但是当我尝试更改其中一个OneMenus JSF的值时,会对OneMenu进行一些验证,告诉我该值无效且&#34; ... save()&#34;函数永远不会被调用。

问题

如何在OneMenu上禁用验证?我已经尝试过&#34; required = false&#34;但这没有用。或者还有其他方法可以提高性能吗?

顺便说一句,我已经在primefaces论坛上发布了这个,但因为这是一个JSF问题,我不想在那里得到答案。 http://forum.primefaces.org/viewtopic.php?f=3&t=40288&e=0

1 个答案:

答案 0 :(得分:2)

问题是,这不适用于JSF的设计方式。在Apply request values阶段,JSF将恢复组件树以更新每个组件的值。到目前为止,SelectOneMenu listSource 为空。因此,JSF无法将您的(生成javascript)值绑定到组件,因为它不在listSource中,这是SelectOneMenu的要求。

这不是您可以禁用的典型验证。 SelectOneMenu 的合同,每个有效选择都需要在其元素集合中。

如果您想使用Javascript填充SelectOneMenu,则应使用jsf&#39; ish方法来实现此目的。只有这样,后端上的相应组件才会知道您的选择选项,然后只有SelectOneMenu的值才有效。

使用空列表和SelectOneMenu选项呈现noSelectionOption个。每当用户悬停selectOneMenu时,添加一个在您的辅助bean上调用方法的ajax侦听器。此方法应将所需元素添加到listsource,最后update selectOneMenu,以显示填充值。

一个简单的例子如下:

@Named
@ViewScoped
public class TestController implements Serializable {

    private List<String> options = new LinkedList<String>();
    private String selectedOption;

    public void populateList(AjaxBehaviorEvent event) {
        this.options.add("foo");
        this.options.add("bar");
        this.options.add("baz");
    }

    public void save() {
        System.out.println(this.selectedOption);
    }

    //+getter and setter
}

在ui部分,你只需要注意不要一遍又一遍地召唤听众。 当用户悬停select时,以下示例将加载元素,因此ajax事件将被禁用。现在可以使用SelectOneMenu,就像它从头开始填充一样。

<h:form>
    <h:selectOneMenu value="#{testController.selectedOption}" id="myList">
        <f:selectItem itemValue="" noSelectionOption="true" itemLabel="Please select something."/>
        <f:selectItems value="#{testController.options}" var="item" itemLabel="#{item}" />
        <p:ajax event="mouseover" listener="#{testController.populateList}" update="@this" disabled="#{not empty testController.options}" />        
    </h:selectOneMenu>

    <p:commandButton action="#{testController.save()}"></p:commandButton>
</h:form>