ti-enxame.com

keyup do primefaces ou outro atraso do evento ajax

Eu tenho algo como:

<p:inputText...>
    <p:ajax event="keyup" update="somefield" listener="#{someBean.doSomething}"/>
</p:inputText>

Mas não quero fazer uma solicitação do Ajax a cada pressionamento de tecla. Gostaria de fazer a solicitação meio segundo depois que o usuário parar de escrever.

Eu já vi esse problema resolvido no jQuery em outra pergunta: Como atrasar o manipulador .keyup () até o usuário parar de digitar?

Gostaria de saber se é possível fazer isso em primefaces ou como adaptar a solução da pergunta do jQuery.
Estou usando o PrimeFaces 3.0.M4.
Agradeço antecipadamente.

22
Roteke

Por que você não usa o componente RemoteCommand do PrimeFaces?

Ele fornece uma função Javascript global, que você pode chamar de onde e quando quiser. E permite chamar o método de bean gerenciado e possui o atributo update para atualização parcial.

<p:inputText id="input" />

<h:form>
    <p:remoteCommand name="sendAjaxical" update="somefield" action="#{someBean.doSomething}"/>
</h:form>

Registre o manipulador de eventos, peguei emprestado o seguinte de a mesma resposta que você posto :

var delay = (function() {
    var timer = 0;
    return function(callback, ms) {
        clearTimeout (timer);
        timer = setTimeout(callback, ms);
    };
})();


jQuery("#input").keyup(function() {
    delay(function() { sendAjaxical(); }, 2000); //sendAjaxical is the name of remote-command
});
18
Bhesh Gurung

Se você estiver usando o Primefaces 5.x, há um atributo delay no p:ajax tag para esse fim. Então é feito assim:

<p:inputText...>
    <p:ajax event="keyup" delay="1000" listener="#{someBean.doSomething}"
        update="somefield" process="@this" />
</p:inputText>

Caso contrário, você pode conseguir usando f:ajax ao invés de p:ajax (sim, funciona com p:inputText, também). f:ajax adicionou suporte para controle de fila a partir do JSF 2.2. Portanto, o código se parece com:

<p:inputText...>
    <f:ajax event="keyup" delay="1000" listener="#{someBean.doSomething}"
        render="somefield" execute="@this" />
</p:inputText>

Veja também:

21
Xtreme Biker

Você não pode usar o Componente Primefaces Ajax se tiver escolhido a solução jquery/javascript. Você precisaria implementar sua própria função javascript (com ajax/xmlHttpRequest suporte) e dispara essa função após meio segundo.

Mas há outra solução, uma solução alternativa: você pode usar um componente de preenchimento automático e usar 3 atributos úteis: valueChangeListener (A method expression that refers to a method for handling a valuchangeevent - você usa isso em vez de completeMethod porque não precisa das sugestões retornadas), queryDelay (Delay to wait in milliseconds before sending each query to the server) e minQueryLength (Number of characters to be typed before starting to query - se você não deseja iniciar a solicitação ajax após apenas um caractere digitado).

Espero que você ache esta solução interessante e interessante ... Consulte o componente de preenchimento automático em ação aqui ( http://www.primefaces.org/showcase-labs/ui/autocompleteHome.jsf ) e você pode descobrir mais lendo o Guia do usuário do Primefaces para 3.0.M4.

1
spauny

Um hack rápido adicionaria um atraso em onstart do p:ajax. Defina a seguinte função em algum lugar do seu javascript:

function keyupDelay(request, cfg, delay) {
    delay = delay || 2000;// if no delay supplied, two seconds are the default seconds between ajax requests
    setTimeout(function() {
        cfg.onstart = null;
        request.send(cfg)
    }, delay);
    return false;
}

Basicamente, essa função aciona a solicitação ajax em um determinado tempo limite, retornando false para a imediata e esvaziando o início nessa solicitação de tempo limite para não ficar preso em um loop desagradável.

Então no p:ajax:

<p:ajax event="keyup" onstart="return keyupDelay(this, cfg)" />

O parâmetro delay é opcional aqui, por padrão é de 2 segundos.

1
Hatem Alimam