3

I have a checkbox group (h:selectManyCheckbox) with an AJAX event to fire when boxes are checked or unchecked. This is straightforward with f:ajax, e.g., f:ajax execute="@form" event="click".

I'd like to enhance this to not re-execute after every click. Instead, I'd like an idle delay such that if the user clicks three boxes in quick succession, there's only one round trip instead of three.

Is there a way to have a JSF AJAX listener (f:ajax) fire after a delay like this?

wrschneider
  • 17,913
  • 16
  • 96
  • 176
  • Why do you want to call an ajax function when you click on a checkbox? If you need to update or render some part of your page by doing this, use plain JavaScript, don't add extra calls to your server. – Luiggi Mendoza Oct 01 '12 at 16:59
  • @LuiggiMendoza: re-applying business rules server-side before re-rendering. Of course if I were just toggling visibility, I'd be doing straight jQuery. – wrschneider Oct 01 '12 at 17:25

1 Answers1

6

If you're not on JSF 2.2 yet, you could use JS setTimeout()/clearTimeout() to timeout the onclick and clear any previously set ones when clicked again.

E.g.

<h:selectManyCheckbox ... styleClass="delayClick">
    <f:selectItems ... />
    <f:ajax ... />
</h:selectManyCheckbox>

with basically (also with a little help of jQuery)

$(".delayClick input").each(function(index, input) {
    var onclick = input.onclick;
    input.onclick = null;

    $(input).on("click", function(event) {
        delay(function() { onclick.call(input, event); }, 1000);
    });
});

var delay = (function() {
    var timer = 0;

    return function(callback, timeout) {
        clearTimeout(timer);
        timer = setTimeout(callback, timeout);
    };
})();

If you're already on JSF 2.2, set the delay attribute of <f:ajax>.

<h:selectManyCheckbox ...>
    <f:selectItems ... />
    <f:ajax ... delay="1000" />
</h:selectManyCheckbox>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555