[RESOLVIDO] Problemas com valueChangeListener

Bom dia a todos!

Já estou há alguns dias com este problema; depois de muita pesquisa e muitas tentativas estou aqui pra compartilhar com vocês.

Tenho uma página onde habilito ou desabilito certos campos avaliando os valores selecionados em alguns selectOneListbox.

Basicamente funciona assim: quando o primeiro selectOneListbox está preenchido eu habilito um grupo de campos e dentre eles um segundo selectOneListbox. Quando o segundo selectOneListbox é preenchido eu habilito um outro grupo de campos.

Pra isso eu usei a propriedade “disabled” do selectOneListBox e de outros componentes amarrada a um atributo no backing bean.

Pra ilustrar melhor, aqui é o código do primeiro selectOneListBox:

                                        <h:selectOneListbox id="cbo_logico_1" size="1" styleClass="e_ou"
                                                            value="#{BeanConsulta.cbo_logico_1}" valueChangeListener="#{BeanConsulta.processValueChangeCboLogico1}"
                                                            onchange="submit()">
                                        ...
                                        </h:selectOneListbox>

Aqui o segundo:

                                        <h:selectOneListbox id="cbo_logico_2" size="1" styleClass="e_ou"
                                                            value="#{BeanConsulta.cbo_logico_2}" valueChangeListener="#{BeanConsulta.processValueChangeCboLogico2}"
                                                            onchange="submit()" disabled="#{BeanConsulta.disabledCriterio2}">
                                        ...
                                        </h:selectOneListbox>

Eu criei um ouvinte para cada um dos selectOneListbox; segue o código do primeiro:

    public void processValueChangeCboLogico1(ValueChangeEvent event) throws AbortProcessingException {
        PhaseId phaseId = event.getPhaseId();

        if (phaseId.equals(PhaseId.ANY_PHASE))
        {
            event.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
            event.queue();
        }

        if ( phaseId.equals(PhaseId.UPDATE_MODEL_VALUES)) {
            this.setDisabledCriterio2(this.getCbo_logico_1().equals("0"));
        }
    }

O segundo é praticamente igual, só troco os nomes dos atributos e métodos.

        if ( phaseId.equals(PhaseId.UPDATE_MODEL_VALUES)) {
            this.setDisabledCriterio3(this.getCbo_logico_2().equals("0"));
        }

Agora, o que para mim, é um mistério: quando eu seleciono algo no primeiro componente tudo funciona corretamente, habilitando o segundo. Quando eu seleciono algo no segundo é disparado o listener do primeiro novamente! O listener do segundo é ignorado! Resumindo, independente do componente (primeiro ou segundo selectOneListbox) sempre é executado o primeiro listener (processValueChangeCboLogico1).

Alguém tem alguma ideia do por quê??

Já tentei várias coisas e agradeço qualquer sugestão.

Emerson,

O seu Managed Bean “BeanConsulta” está em que escopo?

Se ele tiver em escopo de requisição, as propriedade estarão sendo reiniciadas a cada nova requisição. O que pode estar acontecendo é que o valor de “cbo_logico_1” pode estar avaliando para nulo e o componente selectOneListbox pode estar fazendo o seguinte na Process Validations:

  1. O valor selecionado é “0”.
  2. Qual o valor da propridade “cbo_logico_1” no BeanConsulta?
    2.1 Se BeanConsulta for de Request, ele vai ser criado naquele momento
    2.2 “0” é diferente de nulo (que é o valor da propriedade “cbo_logico_1”).
    2.3 Dispara ValueChangeEvent -> old = null, new = “0”

Na Update Model, o valor “0” vai ser atribuído ao seu BeanConsulta.

Enfim, só um palpite, mas se for isso, use t:saveState ou outro mecanismo para ampliar o escopo do seu bean. Nas próximas requisições, o teste do item 2.2 provavelmente vai ser false e o evento não vai ser disparado.

Outra pergunta: porque você está reempilhando o evento?

[]'s

Tarso, tudo bem??

Cara, o seu palpite foi muito bom! O problema era mesmo com o escopo do Managed Bean.

Sobre reempilhar o evento, foi mais um ato de “desespero” mesmo. Achei o código assim na net e copiei pro projeto.

Mas agora já está tudo ajustado.

Obrigado pela ajuda.

[]'s

[quote=tarsobessa]Emerson,

O seu Managed Bean “BeanConsulta” está em que escopo?

Se ele tiver em escopo de requisição, as propriedade estarão sendo reiniciadas a cada nova requisição. O que pode estar acontecendo é que o valor de “cbo_logico_1” pode estar avaliando para nulo e o componente selectOneListbox pode estar fazendo o seguinte na Process Validations:

  1. O valor selecionado é “0”.
  2. Qual o valor da propridade “cbo_logico_1” no BeanConsulta?
    2.1 Se BeanConsulta for de Request, ele vai ser criado naquele momento
    2.2 “0” é diferente de nulo (que é o valor da propriedade “cbo_logico_1”).
    2.3 Dispara ValueChangeEvent -> old = null, new = “0”

Na Update Model, o valor “0” vai ser atribuído ao seu BeanConsulta.

Enfim, só um palpite, mas se for isso, use t:saveState ou outro mecanismo para ampliar o escopo do seu bean. Nas próximas requisições, o teste do item 2.2 provavelmente vai ser false e o evento não vai ser disparado.

Outra pergunta: porque você está reempilhando o evento?

[]'s
[/quote]