I have an f:ajax
tag inside an h:inputText
tag, making ajax calls on keyup events :
<h:inputText id="searchinput" value="#{tvShowForm.name}">
<f:ajax event="keyup" render="results" listener="#{tvShowForm.search}" />
</h:inputText>
Each call takes enough time that the user has typed several characters before the first call is finished.
Is there a way to cancel the current ajax call (and the queued up ones), so that the last keyup event executes an ajax call immediately?
It sounds like you want to coalesce the events, for example this will wait half a second before firing an ajax request, and any input typed at that point will be included. But you won't fire an ajax request for each character typed.
<h:inputText onkeyup="keyupHandler();"/>
...
<script>
var keystrokeTimeout;
keyupHandler = function(event) {
var minChars = 4;
var len = $(this).val().length;
if((len != 0) && (len < minChars)) {
return;
}
var ajaxRequest = function() {
jsf.ajax.request('results', null, {
execute: 'results',
render: 'results'
});
}
clearTimeout(keystrokeTimeout);
keystrokeTimeout = setTimeout(ajaxRequest, 500); // millisecs
}
</script>
Is this remotely like what you want to do?
EDIT: Another suggestion is that you check out the Richfaces 4 a4j:queue functionality. This allows for combining events, for example in the keyup scenario if you've been leaning on your keyboard, when the current ajax request completes only one further request will be sent. It's also possible to specify a request delay and ignore stale responses. The big mistake Richfaces doesn't make (that primefaces does make) is that RF uses the same underlying queue as the JSF implementation, so you don't have the risk of out-of-order processing.
I appreciate that if you're not already using this library it's not a small step to take.