I have an apex:commandButton on a visualforce page that invokes a method on the controller. There is currently no rerender value set for the button. Instead the controller method returns a PageReference to redirect the user as required.
E.g.
Visualforce:
<apex:commandButton value="Save" action="{!save}"/>
Controller:
public PageReference save() {
// save body ...
// return the user the a parent opportunity
return new PageReference('/' + opp.Id);
}
Users are currently able to click on the resulting save button multiple times before the controller completes and returns the PageReference to redirect the browser to an opportunity.
How can I disable the commandButton after the first click?
I tried wrapping the commandButton in an actionStatus and facet, but the need to define the rerender property prevented the resulting PageReference redirect.
E.g.
This will render nicely in the browser and prevent multiple clicks, but doesn't redirect to the Opportunity on completion.
<apex:actionStatus id="saveStatus">
<apex:facet name="stop">
<apex:commandButton value="Save" action="{!save}" status="saveStatus" rerender="saveParentBlock" />
</apex:facet>
<apex:facet name="start">
<apex:commandButton value="Saving..." disabled="true" status="saveStatus"/>
</apex:facet>
</apex:actionStatus>
There is a similar question Using jQuery to disable VF page button onclick. I need to support an existing PageReference redirect, which slightly alters the requirements.
Force.com Discussion Boards: Disabling a commandButton to prevent double submission
Ideas: Disable command buttons on click in visualforce as standard
Best Answer
The mechanism I have found to be most maintainable uses a JavaScript function called by an element's
click
event, which internally calls anactionFunction
to post the form, disables the buttons on the page and then returns false on the commandlink/button. This is used in conjunction with anoncomplete
on theactionFunction
to re-enable the buttons when the form has been (ajax) posted and returns a result to the page.Without the
rerender
attribute the form performs a full postback along with the disabling of the buttons.Note: You can't disable the button(s) before the form is posted or the data sent to the controller will not include which button/link within the form was clicked and thus which action to execute.