How to prevent ajax request from firing when updating some similar components several times?

958 views Asked by At

Given a RichFaces datatable, with each row bound to an "onclick" event firing an ajax request to render a frame on the same page, is it possible to prevent the sending of similar requests ?

By similar, I mean that the user is clicking fast on every row of the table. This induces several (possibly costly) requests to be sent to the backend while only the last one is sufficient to render what I want correctly.

I thought that Richfaces Queues were providing that feature but I can't make it work. The ajax request is sent using a a4j:jsFunction-generated request.

Here is the JSF code from my attempt:

<h:form>
  <a4j:queue ignoreDupResponses="true" name="selectRow" />
  <rich:datatable ...>
    [...]
    <rich:column ... />
  </rich:datatable>

  <a4j:jsFunction name="jsSelectRow" actionListener="yyy" render="xxx">
    <a4j:attachQueue name="selectRow"/>
  </a4j:jsFunction>
  <script toAddOnClickEventFiringJsSelectRowOnTR />  
</h:form>

I found these links interesting:

The second one explains what I want but for an older version and I can't reproduce the expected result from "Combining controls into the same group" paragraph.

I am using RichFaces 4.3.3.Final.

Edit: More precision on the use-case. I'd like the row to appear immediately in the general case (there should be no/little delay): as long as the client/network/server can handle it fast enough, it's alright to make a lot of requests.

Now, the real use case is when the connection is very slow. The ajax response takes time to come back and I'd like that no new ajax request is sent until the first response is received. That is, the queue should not wait for a delay to expire but should discard queued requests that have been made obsolete by the most recent one.

Actually, as I read my second link again, I think this is exactly what <a4j:queue size="2" sizeExceededBehavior="dropNext" /> would do but those attributes are seemingly not available in my (more recent) version of Richfaces...

1

There are 1 answers

1
Andrey On

It seems here is explained exactly what you are trying to achieve: http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=queue&skin=blueSky

requestDelay is the number of milliseconds to wait before sending a request in order to combine similar requests. The greater the value the fewer requests will be sent when fast typing. Similar requests in the queue are combined while waiting for the request delay

If ignoreDupResponse is true then RichFaces will not waste time updating the client side DOM if it knows another request for the same thing is pending. The best way to see that in this demo is set requestDelay to a very small value and type quickly. You will see the number of DOM updates be smaller than requests sent.

So in your case it could be something like this:

<a4j:queue requestDelay="300" ignoreDupResponses="true" name="selectRow" />

Then you need to tweak requestDelay parameter according to how fast a user could click and how fast a single request is processed on the server side.

Related link: What is the shortest perceivable application response delay?