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

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top