2
votes

I have a Primefaces (version 3.4.1) selectOneMenu which fires a ajax event when it's changed to update another selectOneMenu.

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

The listener method is below:

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

When I change the orgao selectOneMenu to a not null value, everything occurs as expected: The converter and the listener are called and the collection listaImportacaoFinanceira is filled. However, when I select the empty option, neither listener nor converter are called.

Therefore, I would like to know what is missing here. In the Primefaces valueChangeListener or <p:ajax listener not firing for p:selectOneMenu page it is showed how to use selectOneMenu ajax event. However apparently doesnot apply to null values are chosen.

Thanks,

Rafael Afonso

EDIT 1

I tried an alternative: When filling the listaOrgaos collection, I added a empty Orgao with out ID:

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

In the converter, the getAsString method will return the Orgao´s ID to put in the value attribute. getAsObject will return the Orgao correspondent to ID, or null if there is no Orgao correspondent to ID or it is not a valid number (such as literal 'null').

If orgaoNulo ID is null, the converter is not called. Otherwise, if it is '0' ou a literal 'null', the converter is called. Anyway, the listener is never called. It is like the listener is called only for non-null values. Is it right?

EDIT 2

I did a wokaround here. In Ajax event tag I added a call to a JS function which will enable a second select depending if the first has a valid value selected.

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

The Javascript function:

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

Both validator and listener continue to be not called. The suggestions which people gave me did not work. Therefore, I had to implement this workaround.

3
Because of required="true".Tiny
@Tiny: It did not make any difference changing the required attribute in both selects.Rafael Afonso
Have you tried to remove that noSelectionOption="true" ?Pellizon
@Pellizon: It did not work. Even if in empty option I put itemValue="#{null}"or use value attribute instead itemValue, it continues to have the incorrect behavior.Rafael Afonso
i did the same work but used primefaces 3.4.2vinod

3 Answers

1
votes

I was stuck with a similar issue. I tried the solution in EDIT 2 of the original question. I got stuck because I could not get it to work because this selOrgao.getSelectedValue() was throwing error. So I did the following and got it to work:

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

In the script file, I did the following:

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

And made the select field unclickable using CSS.

0
votes

Removing required="true" corrects the issue in PrimeFaces 4.0.24.

0
votes

if first combo is required, you could use immediate="true" and try to get your values as getSubmittedValue in your listener