selectOneButton无法在splitButton中提交

时间:2015-03-13 14:51:25

标签: ajax jsf primefaces

我使用JSF 2和primefaces 5.1,我有一个selectOneButton,它有2个值, EN / FR,我想在每次更改语言时收到通知,然后更改页面的区域设置。 现在问题是这个selectOneButton在splitButton中,并且出于某种原因, ajax提交"更改"对于selectOneButton,事件始终返回null,并且它永远不会传递所选的值。

<h:form prependId="false" id="headerForm">
    <p:splitButton>
        <p:menuitem>
        <p:selectOneButton id="langs" value="#{bean.lang}" >
            <f:selectItem itemLabel="English" itemValue="en"/>
            <f:selectItem itemLabel="Françcais" itemValue="fr"/>
            <f:ajax event="change"/>
        </p:selectOneButton>
        </p:menuitem>
    </p:splitButton>

这只是为了测试:

public void setLang(String lang) {
        System.out.println("Changed: " + lang);
        this.lang = lang;
}

当我将selectOneButton放在p:菜单中作为示例时,它可以正常工作。

1 个答案:

答案 0 :(得分:2)

这个问题是双重的。

首先,大多数PrimeFaces组件,特别是那些生成隐藏的HTML输入元素的组件,并通过一堆带有点击监听器的div /列表呈现给最终用户,而不是&#34;纯HTML&#34;输入,要求在ajax提交期间正确处理<p:ajax>而不是<f:ajax>

<p:selectOneButton id="lang" value="#{bean.lang}" >
    <f:selectItem itemLabel="English" itemValue="en"/>
    <f:selectItem itemLabel="Français" itemValue="fr"/>
    <p:ajax />
</p:selectOneButton>

请注意,我省略了event属性,因为它已经具有正确的默认值,如果是输入则为valueChange,如果是命令则为actionchange的值不一定是正确的默认值,因为某些组件需要click,尤其是具有固定值的单选按钮和复选框。

在任何情况下,一般建议是,如果您使用PrimeFaces,只需坚持<p:ajax>。它将使用特定于PrimeFaces的基于jQuery的Ajax API来处理ajax请求而不是JSF本机Ajax API,并且它能够处理PrimeFaces组件。

其次,与<p:splitButton>关联的JavaScript代码将菜单的HTML表示移动到正文的末尾(为了确保与z-index的最佳交叉浏览器兼容性)。然而,这会导致菜单不再处于某种形式。您可以通过右键单击 Inspect Element (不是查看源!)来查看webbrowser中的HTML DOM树来确认它。您可以通过两种方式解决这个问题:

  1. 将表单移动到菜单项内。无论如何,为这个特定要求提交所有其他菜单项是没有意义的。

    <p:splitButton>
        <p:menuitem>
            <h:form id="languageForm">
                <p:selectOneButton id="lang" value="#{bean.lang}" >
                    <f:selectItem itemLabel="English" itemValue="en"/>
                    <f:selectItem itemLabel="Français" itemValue="fr"/>
                    <p:ajax />
                </p:selectOneButton>
            </h:form>
        </p:menuitem>
    </p:splitButton>
    
  2. 使用<p:ajax partialSubmit="true">让PrimeFaces Ajax API收集invidivual输入值,而不是搜索<form>serializing它(因为有&#39; s会失败)没有形式)。

    <h:form id="headerForm">
        <p:splitButton>
            <p:menuitem>
                <p:selectOneButton id="lang" value="#{bean.lang}" >
                    <f:selectItem itemLabel="English" itemValue="en"/>
                    <f:selectItem itemLabel="Français" itemValue="fr"/>
                    <p:ajax partialSubmit="true" />
                </p:selectOneButton>
            </p:menuitem>
        </p:splitButton>
    </h:form>