【问题标题】:Primefaces selectOneMenu does not call ajax when empty option is chosen选择空选项时,Primefaces selectOneMenu 不会调用 ajax
【发布时间】:2015-03-04 03:20:16
【问题描述】:

我有一个 Primefaces(版本 3.4.1)selectOneMenu,它在更改为更新另一个 selectOneMenu 时会触发一个 ajax 事件。

<p:outputLabel value="Órgão:" for="orgao" />
<p:selectOneMenu id="orgao" value="#{orcamentoAnualBean.orgao}" converter="orgaoConverter" requiredMessage="Favor escolher Órgão">
    <f:selectItem itemLabel="Selecione" itemValue="" noSelectionOption="true"/>
    <f:selectItems value="#{orcamentoAnualBean.listaOrgaos}" var="orgao" itemLabel="#{orgao.nome}" itemValue="#{orgao}" />
    <p:ajax update="revisao" listener="#{orcamentoAnualBean.mudancaDeImportacoes}" />
</p:selectOneMenu>

<p:outputLabel value="Revisão:" for="revisao" />
<p:selectOneMenu id="revisao" value="#{orcamentoAnualBean.importacaoFinanceiraSelecionada}" effect="fade" converter="importacaoConverter" required="true" requiredMessage="Favor escolher Revisão" disabled="#{empty orcamentoAnualBean.listaImportacaoFinanceira}">
    <f:selectItem itemLabel="Selecione" itemValue="" />
    <f:selectItems value="#{orcamentoAnualBean.listaImportacaoFinanceira}" var="importacao" itemLabel="#{importacao.exibicaoCombobox}" itemValue="#{importacao}" />
</p:selectOneMenu>

监听方法如下:

public void mudancaDeImportacoes(AjaxBehaviorEvent ev) {
    log.info("mudancaDeImportacoes: " + orgao);
    if (orgao != null && orgao.getId() != 0)
        listaImportacaoFinanceira = importacaoFinanceiraDAO.listar(orgao);
    else
        listaImportacaoFinanceira = new ArrayList<ImportacaoFinanceira>();
}

当我将 orgao selectOneMenu 更改为非 null 值时,一切都会按预期发生:转换器和侦听器被调用并且集合 listaImportacaoFinanceira 是填充。但是,当我选择空选项时,既不会调用侦听器也不会调用转换器。

因此,我想知道这里缺少什么。 Primefaces valueChangeListener or <p:ajax listener not firing for p:selectOneMenu 页面显示了如何使用selectOneMenu ajax 事件。但是显然不适用于null 值被选择。

谢谢,

拉斐尔·阿方索

编辑 1

我尝试了另一种方法:在填充 listaOrgaos 集合时,我添加了一个没有 ID 的空 Orgao:

        this.listaOrgaos = orgaoDAO.listarOrcamentoAnual();
        Orgao orgaoNulo = new Orgao();
        // orgaoNulo.setId(0);
        orgaoNulo.setNome("Selecione");
        this.listaOrgaos.add(0, orgaoNulo);

在转换器中,getAsString 方法将返回 Orgao 的 ID 以放入 value 属性中。 getAsObject 将返回Orgao 对应的ID,或者null 如果没有Orgao 对应的ID 或者它不是有效数字(例如文字'null')。

如果orgaoNulo ID 为null,则不调用转换器。否则,如果它是“0”或文字“null”,则调用转换器。无论如何,永远不会调用侦听器。就像只为非空值调用侦听器一样。对吗?

编辑 2

我在这里做了一个 wokaround。在 Ajax 事件标记中,我添加了对 JS 函数的调用,该函数将启用第二个选择,具体取决于第一个选择是否具有有效值。

<p:outputLabel value="Órgão:" for="selOrgao" />
<p:selectOneMenu id="selOrgao" widgetVar="selOrgao" required="true"
    value="#{orcamentoAnualBean.orgao}" effect="fade"
    converter="orgaoConverter"
    requiredMessage="Favor selecionar o Órgão">
    <f:selectItem itemLabel="Selecione" value="#{null}" />
    <f:selectItems value="#{orcamentoAnualBean.listaOrgaos}"
        var="orgao" itemLabel="#{orgao.nome}" itemValue="#{orgao}" />
    <p:ajax update="selRevisao"
        listener="#{orcamentoAnualBean.mudancaDeImportacoes}"
        oncomplete="habilitarRevisao()" />
</p:selectOneMenu>

<p:outputLabel value="Revisão:" for="selRevisao" />
<p:selectOneMenu id="selRevisao" widgetVar="selRevisao"
    ...>
    ...
</p:selectOneMenu>

Javascript函数:

function habilitarRevisao() {
    if (!!selOrgao.getSelectedValue()) {
        selRevisao.enable();
    } else {
        selRevisao.disable();
    }
}

验证器和侦听器都继续不被调用。人们给我的建议没有奏效。因此,我必须实施此解决方法。

【问题讨论】:

  • 因为required="true".
  • @Tiny:在两个选择中更改required 属性没有任何区别。
  • 您是否尝试删除该noSelectionOption="true"
  • @Pellizon:它不起作用。即使在空选项中我输入itemValue="#{null}" 或使用value 属性而不是itemValue,它仍然有不正确的行为。
  • 我做了同样的工作,但使用了 primefaces 3.4.2

标签: ajax jsf primefaces


【解决方案1】:

我遇到了类似的问题。我在原始问题的 EDIT 2 中尝试了解决方案。我被卡住了,因为我无法让它工作,因为这个selOrgao.getSelectedValue() 正在抛出错误。所以我做了以下事情并让它工作:

<p:ajax event="change" listener="#{backingBean.changeData}" oncomplete="updateFormDetails(args)"></p:ajax>

在脚本文件中,我做了以下操作:

function updateFormDetails(args) {
if(args && args.validationFailed) {
     document.getElementById("selRevisao").addClass("disable");    
 } else {
     document.getElementById("selRevisao").removeClass("disable");   
}

并使用 CSS 使选择字段不可点击。

【讨论】:

  • 所以您使用的是 PrimeFaces 3.4.1?
  • 不,我目前的版本是 6.0
  • 请在您的答案中明确添加。并尝试了 7.0 只是为了看看它是否同时修复。
【解决方案2】:

删除 required="true" 更正了 PrimeFaces 4.0.24 中的问题。

【讨论】:

    【解决方案3】:

    如果需要第一个组合,您可以使用 immediate="true" 并尝试在您的侦听器中获取您的值作为 getSubmittedValue

    【讨论】:

      猜你喜欢
      • 2014-11-13
      • 2011-09-29
      • 1970-01-01
      • 2013-11-30
      • 1970-01-01
      • 2014-07-05
      • 2013-10-24
      • 2018-04-06
      • 2012-10-03
      相关资源
      最近更新 更多