Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Ouvir evento executado pelo servidor

Coloquei o evento de Change em um select, para executar determinada função. Está funcionando ok, o usuário muda os itens, e o JS executa normalmente a função. Entretanto, é um formulário que o Usuário pode recuperar algumas informações em consultas ao DB. Desta forma, quando ele consulta, esse select é automaticamente selecionado e o JS não escuta esse evento. O que posso fazer????

7 respostas

Vitor, acho que entendi o problema, mas sem o codigo é meio dificil de te ajudar, poderias posta o codigo aqui?

Se for um projeto aberto pode ser o link do gitHub.

Vamos lá, Henrique.. Javascript

function verificaMarca() {

    var marca = $("#marcaVeiculo");
    $("body").on("change","#marcaVeiculo",function() {
        if (marca.val() == 75) {
            $("#outraMarca").removeClass("hidden");
            $("#inputOutraMarca").attr("required",true);
        } else {
            $("#outraMarca").addClass("hidden");
            $("#inputOutraMarca").removeAttr('required');
        }
    });

}

Tive que colocar esse body on pq estava perdendo o javascript sempre que renderizava o ajax no #marcaVeiculo...

A função acima é chamada ao carregar a pagina:

$(function(){
//outras chamadas
verificaMarca();
});

E meu select:

<h:selectOneMenu id="marcaVeiculo" class="form-control input-sm" value="#formularioBean.formulario.veiculo.marca}"     
converter="#{marcaConverter}" required="true" requiredMessage="Selecione uma marca">
    <f:selectItem itemLabel="--- Selecione ---" itemValue="#{null}" noSelectionOption="true"/>
    <f:selectItems var="m" value="#{formularioBean.todasMarcas}" itemLabel="#{m.descricao}" itemValue="#{m}" converter="#{marcaConverter}"/>
</h:selectOneMenu>

Dessa forma, se o usuário seleciona a opção por si só, ele ouve o evento. Entretanto, se fizer buscando no bd, com esse command button:

<h:commandButton id="placaButton" action="#{formularioBean.buscaPorPlaca}">
<f:ajax execute="placaVeiculo" render="marcaVeiculo modeloVeiculo corVeiculo" />        
</h:commandButton>

Qualquer evento nesses inputs e selects renderizados não são ouvidos pelo JS.

Bom nao sou um programador Java experiente (estou do outro lado da força no momento), mas minha ideia para resolver.

Dentro do ajax :

placaVeiculo

Deve existir um CallBack que preenche seus dados, correto?

Bom minha ideia. Isolar a função que altera os campo no Change.

function removeOutraMarca() {
        if (marca.val() == 75) {
            $("#outraMarca").removeClass("hidden");
            $("#inputOutraMarca").attr("required",true);
        } else {
            $("#outraMarca").addClass("hidden");
            $("#inputOutraMarca").removeAttr('required');
        }
    }

No evento agora vai ficar assim

function verificaMarca() {
    var marca = $("#marcaVeiculo");
    $("body").on("change","#marcaVeiculo", removeOutraMarca);
}

Dai agora no Callback do

placaVeiculo

Voce chama no final a função:

removeOutraMarca()

É uma ideia, porém, pode ser que o Callback do placaVeiculo não seja acessivel (detalhe do Java que nao sei), então se ele nao tiver vamos ter que esperar um programador Java para resolver o problema.

Henrique, entendi.. só não sei se conseguirei executar. Os valores dos meus campos correspondem a atributos do meu Bean. Portanto, ao executar o action do meu commandButton, meu Bean faz a pesquisa no DB e seta seus respectivos valores, que são automaticamente carregados pelo View.

Então, não me ligo sobre o Callback direito... ://

solução!

Tive outra ideia, podes tentar chamar essa mesma função no init da pagina, considerando que não estas utilizando uma SPA, deve funcionar.

Coloca esse codigo no mesmo local que chamas o registro do evento Change

$(function(){
//outras chamadas
verificaMarca();
removeOutraMarca();
});

Opa, Henrique. Acho que só não funcionou porque, ao consultar, não chama a página toda, apenas os campos que eu mando renderizar:

<f:ajax execute="placaVeiculo" render="marcaVeiculo modeloVeiculo corVeiculo" />

E eu nem posso tirar, pq senão esculhamba tudo...

Consegui resolver, mas não sei se é a melhor prática (com certeza não), mas deu certo...

Criei um panelgroup e dentro dele coloquei

<h:panelGroup id="scripts">
    <script>
        removeOutraMarca();
    </script>
</h:panelGroup>

aí quando renderizo, na buscaplaca, mando renderizar tbm o #scripts...

Bom, funcionou assim, pelo menos.. :D

Muito obrigado pela ajuda, Henrique.