[RESOLVIDO] Como disparar Ajax para carregar Dropdowns aninhados após carregar um formulário?

Oi pessoal.

Ao clicar num botão é exibido um dialog para edição de dados, onde contém um selectOneMenu que mostra prefixos e, após selecionar um desses prefixos, três selectCheckboxMenus são carregados com dados de funcionários.

<p:outputLabel value="prefix" for="prefixo" />
<h:panelGroup>
    <p:selectOneMenu id="prefixo" value="#{demandasController.selected.prefixo}" converter="prefixosConverter" filter="true" filterMatchMode="contains">
        <f:selectItem itemLabel="#{adeBundle.SelectOneMessage}" itemValue="#{null}" />
        <f:selectItems value="#{prefixosController.items}"
                       var="prefixoItem"
                       itemValue="#{prefixoItem}"
                       itemLabel="#{prefixoItem.prefixo} - #{prefixoItem.nomePrefixo}"
                       />
        <p:ajax event="valueChange" update="uorPosCollection uorPosCollection1 uorPosCollection2" listener="#{demandasController.changePrefixo}"/>
    </p:selectOneMenu>
</h:panelGroup>

<p:outputLabel value="Executivo(s)" for="uorPosCollection" />
<p:selectCheckboxMenu id="uorPosCollection" value="#{demandasController.selected.uorPosCollection}" label="Executivo(s)" multiple="true" converter="uorPosConverter" filter="true" filterMatchMode="contains" >
    <f:selectItems value="#{demandasController.availableExecutivos}"
                   var="uorPosCollectionItem"
                   itemValue="#{uorPosCollectionItem}"
                   itemLabel="#{uorPosCollectionItem.matricula} - #{uorPosCollectionItem.nome} (#{uorPosCollectionItem.prefixo.prefixo})" />
</p:selectCheckboxMenu>
<!-- código análogo omitido-->

O Listener:

public void changePrefixo(AjaxBehaviorEvent event) {
availableExecutivos = LoadExecutivosListCombo(super.getSelected().getPrefixo());
//código análogo omitido
}

Os métodos para carregar as listas de funcionários:

private List<UorPos> LoadExecutivosListCombo(Prefixos prefixos) {
    List<SelectItem> listExecutivosCombo = new ArrayList<>();
    List<UorPos> listExecutivos = uorPosFacade.findUorPosExecutivosByPrefixo(prefixos);
    for (int i = 0; i < listExecutivos.size(); i++) {
        listExecutivosCombo.add(new SelectItem(listExecutivos.get(i)));
    }
    return listExecutivos;
}
//código análogo omitido

Native queries para recuperar no banco de dados:

public List<UorPos> findUorPosExecutivosByPrefixo(Prefixos prefixo) {
return (List<UorPos>) getEntityManager().createNativeQuery("SELECT * FROM UorPos WHERE prefixo=9951", UorPos.class).setParameter(1, prefixo.getPrefixo()).getResultList();
}
//código análogo omitido

Tudo funciona ok, porém, ao abrir o form para editar um registro previamente salvo, eles estão aparecendo o id junto com o nome da classe (o que eu não quero) e as listas dentro dos combobox não são carregadas:

Exemplo: na figura acima, o prefixo 9882 é exibido como esperado e os três comboboxes estão vazios e são exibidos o id com o nome da classe. Se eu selecionar um valor diferente de 9882, o ajax é ativado e os comboboxes são carregados, mas os ids com o nome das classes continuam sendo exibidos. Mas se eu selecionar 9882 novamente, os ids são exibidos como deveriam, ou seja, sem os nomes das classes e as listas nos comboboxes são carregadas:

Estou tentando resolver isso ativando o ajax ao carregar o dialog, mas não sei como chamar o Listener na função:

<p:dialog onShow="CallAjaxFunction()" modal="true" >

    <script>
    function CallAjaxFunction() {
    <!-- como ativar o ajax /Listener aqui ?-->
        alert("exibido após carregar o dialog.")        
    }
    </script>
...
</p:dialog>

Alguém sabe como fazer para acionar o ajax ao carregar um formulário?

Ou, se alguém tiver outra solução para exibir os valores nos labels (sem o nome da classe) e carregar automaticamente as listas nos comboboxes seria ótimo.

Desde já, obrigado.

Ola Marcel,

Em uma imagem vc disse que selecionou 9882 depois de ter selecionado outro valor para poder executar o ajax, isso é normal porque você declarou o evento como valueChange. Se a opção de 9882 já vier selecionada e você clicar nela novamente, o valor não mudará, concorda? Se você quer disparar ajax quando selecionar, não importante se selecionar o mesmo item, troque o evento para itemSelect

Quando você acessar essa página, você ja deve deixar previamente selecionado a primeiro opção do selectOneMenu (selected.prefixo = suaLista.get(0)), ai os outros selects (executivo, gerente, assessor) ja trarão os dados.

Aqui você esta passando um parametro, mas tem um valor fixo(9951) na query

Eu só tinha visto sobre aparecer o pacote quando eu ia printar uma classe e n tinha implementado toString

Pode ser quando o dialog abrir?

<p:dialog ...>
    <p:ajax event="open" listener="" update=""/>
</p:dialog>

Talvez ja tenha tentado, mas se o dialog é aberto através de um click do botão e você precisa atualizar um valor, você pode fazer algo assim também:

<p:commandButton value="Abrir dialog" actionListener="#{bean.atualizarValores}" oncomplete="PF('dialog').show()">

Importante lembrar que métodos que vão ser chamado através de listeners, devem obrigatoriamente serem void

1 curtida

Oi Mike !

Sobre o evento ajax, concordo, era isso mesmo! Mudei para o evento para itemSelect e agora quando clico no mesmo valor que vem selecionado os outros combos são carregados.:smiley:

Desculpe não ter ficado muito claro o funcionamento do meu app, pois esqueci de informar como o dialog em questão é exibido, primeiro eu seleciono alguma linha de uma datatable e depois clico no botão abaixo:

<p:commandButton id="editButton" value="Editar" update=":DemandasEditForm" oncomplete="PF('DemandasEditDialog').show()" disabled="#{empty demandasController.selected}" resetValues="true" />

Ou seja, quando eu seleciono a linha da datatable, os valores já vem selecionados nos campos.

A verdadeira query eu omiti por ser comprida, porém ela tem um parâmetro sim:

SELECT d FROM DIAGE.ade.Demandas WHERE situacao=3 AND status NOT IN (2,5,6,7) AND prefixo IN (SELECT prefixoJurisdicionada FROM DIAGE.ade.Jurisdicionadas WHERE prefixo = (SELECT prefixo FROM DIAGE.ade.Jurisdicionadas WHERE prefixoJurisdicionada = ?)

Sim, os combos podem (e é exatamente isso o que eu pretendo fazer) ser carregados quando o dialog abrir. Mudei o evento para itemSelect como você mostrou e, como o valor já vem selecionado, eu tentei executar o comando para clicar na opção que vem selecionada com o seguinte código:

<p:dialog onShow="PF('prefixowv').selectValue(':selected').click();" ... >

Usnado o evento itemSelect que você mostrou e clicando na opção que vem selecionada, já resolve o problema. Mas o código acima não deu certo.:confused:

Tentei o código abaixo como você indicou, mas não funcionou também:

<p:dialog ...>
    <p:ajax event="open" listener="#{demandasController.changePrefixo}" />

Com o itemSelect no evento, já resolvi metade do problema e a primeira opção já vem selecionada. Nesse caso, como carregar a lista para os outros selects ?

Mas esse método é executado, não? Talvez falte um update

Eu vejo duas formas a se fazer
1- Colocar um selectItem informando para selecionar

<f:selectItem itemLabel="Selecione..." noSelectionOption="true"/>

2- No actionListener do botão chamar um método para selecionar o primeiro item da lista, testar trocar de oncomplete para onsucess e no update colocar os componentes a serem atualizados. Eu digo testar pq eu não lembro se o update no dialog funciona, mesmo ele não estando visivel. Por exemplo: se você tem um componente que não foi renderizado de inicio e a sua condição do rendered acabou de ser true, para o componente aparecer na tela, será necessário atualizar o componente pai ao invés dele mesmo.

DemandasEditForm é o form do dialog dos selects?

Lembrete => A ordem de execução das ações é a seguinte:
onclick, actionListener, action, process, onsucess, update e oncomplete

Normalmente só um update ja basta, mas se não tiver indo, tenta abrir o dialog pelo onsucess

1 curtida

Era isso apenas que faltava Mike, o update!!

<p:dialog onShow="PF('prefixowv').selectValue(':selected').click();" update= DemandasEditForm:uorPosCollection DemandasEditForm:uorPosCollection1 DemandasEditForm:uorPosCollection2 />

Mike, mais uma vez você me ajudou muito!
Agradeço imensamente!!
Um abraço!!

1 curtida