How to do double-click prevention in JSF
You can use 'onclick' and 'oncomplete' listeners. When user click on button - disable it. When action completed - enable.
<p:commandButton id="saveBtn"
onclick="$('#saveBtn').attr('disabled',true);"
oncomplete="$('#saveBtn').attr('disabled',false);"
actionListener="#{myBean.save}" />
If you're using solely ajax requests, you could use jsf.ajax.addOnEvent
handler of the JSF JavaScript API for this. The below example will apply on all buttons of type="submit"
.
function handleDisableButton(data) {
if (data.source.type != "submit") {
return;
}
switch (data.status) {
case "begin":
data.source.disabled = true;
break;
case "complete":
data.source.disabled = false;
break;
}
}
jsf.ajax.addOnEvent(handleDisableButton);
Alternatively, if you need this on specific buttons only, use the onevent
attribute of <f:ajax>
.
<h:commandButton ...>
<f:ajax ... onevent="handleDisableButton" />
</h:commandButton>
If you also need to apply this on synchronous requests, then you need to take into account that when you disable a button during onclick
, then the button's name=value
pair won't be sent as request parameter and hence JSF won't be able to identify the action and invoke it. You should thus only disable it after the POST request has been sent by the browser. There is no DOM event handler for this, you'd need to use the setTimeout()
hack which disables the button ~50ms after click.
<h:commandButton ... onclick="setTimeout('document.getElementById(\'' + this.id + '\').disabled=true;', 50);" />
This is only rather brittle. It might be too short on slow clients. You'd need to increase the timeout or head to another solution.
That said, keep in mind that this only prevents double submits when submitting by a web page. This does not prevent double submits by programmatic HTTP clients like URLConnection
, Apache HttpClient, Jsoup, etc. If you want to enforce uniqueness in the data model, then you should not be preventing double submits, but preventing double inserts. This can in SQL easily be achieved by putting an UNIQUE
constraint on the column(s) of interest.
See also:
- Pure Java/JSF implementation for double submit prevention
- How to handle multiple submits before response is rendered?