Não é possível definir um evento e vincular um neste evento ao mesmo tempo
Pergunta
Vamos considerar este código simples:
<h:form id="myForm">
<h:inputText id="myInput">
<a4j:support event="onchange" actionListener="#{myBean.doSomething}"/>
</h:inputText>
</h:form>
Isso gerará o seguinte código HTML:
<input id="myForm:myInput" type="text" name="myForm:myInput" onchange="A4J.AJAX.Submit(...)" />
Agora, acabei de adicionar algo no onchange
evento do meu <h:inputText>
:
<h:form id="myForm">
<h:inputText id="myInput" onchange="alert('foobar');">
<a4j:support event="onchange" actionListener="#{myBean.doSomething}"/>
</h:inputText>
</h:form>
Isso gerará o seguinte código HTML:
<input id="myForm:myInput" type="text" name="myForm:myInput" onchange="alert('foobar');" />
Como você pode ver, o código Ajax é não adicionado não mais. Este é um comportamento realmente estranho no que me diz respeito. Porque o <a4j:support>
Não anexe a chamada AJAX se o evento já estiver definido no campo de entrada?
Então minha pergunta é como fazer o <a4j:support>
trabalhando em um event
que já está definido no input
? Obviamente, a solução deve executar o código JavaScript definido em onchange
e A chamada Ajax.
Em outras palavras, eu gostaria de ter o seguinte HTML:
<input id="myForm:myInput" type="text" name="myForm:myInput" onchange="alert('foobar'); A4J.AJAX.Submit(...)" />
Estou usando Richfaces 3.3.2 e JSF 1.2
EDITAR
Claro, eu posso mover o onchange
Código JavaScript no onsubmit
atributo do <a4j:support>
, fazendo algo assim:
<h:inputText id="myInput">
<a4j:support onsubmit="alert('foobar');" event="onchange" actionListener="#{myBean.doSomething}"/>
</h:inputText>
Mas é a única maneira ??
Solução 3
Mais sobre o contexto
Na verdade, eu realmente não posso modificar o event
valor do <a4j:support>
, como sugestão por Abel Morelos, porque o que estou tentando fazer é adicionar um componente personalizado que execute alguma validação do lado do cliente. Essa validação chama uma função JavaScript, então meu componente personalizado modifica o onchange
valor de seus pais.
Meu código JSF se parecerá:
<h:inputText id="myInput">
<my:validation .../>
<a4j:support event="onchange" actionListener="#{myBean.doSomething}"/>
</h:inputText>
Este código é bastante equivalente ao código a seguir, exceto que o onchange
do <h:inputText>
é adicionado automaticamente pelo meu componente:
<h:inputText id="myInput" onchange="if (!checkSomeValidation()) { return false; }">
<a4j:support event="onchange" actionListener="#{myBean.doSomething}"/>
</h:inputText>
Então, como você pode entender, meu componente personalizado modifica diretamente o onchange
evento do <h:inputText>
, e devido ao problema com <a4j:support>
, a chamada do Ajax é não Binded para o componente de entrada no final.
A solução
Quando vinculado a um componente JSF, o <a4j:support>
"se transformará" para uma faceta, cujo nome é org.ajax4jsf.ajax.SUPPORTxxx
, Onde xxx
é o event
nome. Então, no meu caso, o <h:inputText>
terá uma faceta chamada org.ajax4jsf.ajax.SUPPORTonchange
.
Então, o que eu faço no meu código Java do meu componente personalizado é verificar se o pai (o <h:inputText>
aqui), tem essa faceta.
Se não, isso significa que o pai não tem <a4j:support event="onchange"/>
ligado a ele. Então, neste caso, eu modifico o onchange
atributo do meu <h:inputText/>
Se sim, isso significa que existe um <a4j:support event="onchange"/>
ligado ao pai. Então, eu modifico a própria faceta usando o seguinte código:
HtmlAjaxSupport facet = (HtmlAjaxSupport) getParent().getFacet("org.ajax4jsf.ajax.SUPPORTonchange");
if (facet != null) {
facet.setOnsubmit("my Javascript code goes here");
} else {
getParent().setOnchange("my Javascript goes here");
}
Outras dicas
Se esse comportamento não estiver explicitamente documentado, eu consideraria isso um bug no Ajax4jsf. Relate -o a Ajax4jsf/richfaces caras lá em jboss.org. Eu tenho visto Problemas como esse antes com <a4j:commandButton onclick="someFunction()">
Eu já tive esse problema antes e descobri que o Richfaces 3.3.x executará apenas o código do evento OnChange definido com A4J: Suporte e ignorará o código OnChange definido com o componente JSF.
No meu caso, a solução alternativa era simples, para o meu caso, era válido usar outro evento em vez de "OnChange" (não tenho certeza se era OnClick ou OneSelect), então anexei meu código a esse outro evento e meu código funcionou, mas eu Não tenho certeza se isso poderia funcionar para você. Se você realmente precisa do evento OnChange para ambos os elementos, terá que fazer exatamente como Balusc disse e denunciá -lo ao pessoal da Richfaces.