function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
DCSDCS 

Disable apex command button

I have an apex command button as below calling a custom controller method

 

<apex:commandButton value="Save" id="Save" action="{!save}" onclick="this.disabled=true;"/>

 

The method saves the item and navigate to another page. It is not a partial page update call.

 

I would like to disable button after the first click. I tried using onclick and calling a javascript to set the disabled status as true. When I use onclick even to make the javascript call, the button becomes disabled, but the save method on the controller is not being called.

 

I changed the button onclick event  to just alert 'hi' as below and it works. It alerts and then also makes the method call

 

<apex:commandButton value="Save" id="Save" action="{!save}" onclick="alert('hi');"/> 

 

But when I added the code to disable the button too as shown below, it stops calling the controller method.

 

<apex:commandButton value="Add Item(s)" id="addItem" action="{!addItems}" onclick="alert('hi');this.disabled=true;"/>

 

Is there a different way to solve this?

Message Edited by DCS on 05-07-2009 02:03 PM
Best Answer chosen by Admin (Salesforce Developers) 
edgarMedgarM

Hello everyone this is a solution!!, a few days ago I presented a requirement where I needed to disable the button was pressed once, the easiest way to do this is by using the tag <apex:actionStatus> and then I leave <apex:facet> a small example of implementation. Greetings.

 

 

<apex:actionStatus id="mySaveStatus1">

<apex:facet name="stop">

<apex:commandButton action="{!youmethod}" status="mySaveStatus1" value="Save" disabled="false" rerender="mySaveStatus"/>

</apex:facet>

<apex:facet name="start">

<apex:commandButton action="{!youmethod}" status="mySaveStatus1" value="Processing..." disabled="true"/> </apex:facet>

</apex:actionStatus>

 

 

 

Message Edited by edgarM on 03-03-2010 02:37 PM

All Answers

jeffdonthemicjeffdonthemic

Could you set the value of the commandButton's disabled attribute based upon a Boolean in the controller? This would toggle the button on and off for you.

 

Jeff Douglas

Informa Plc

http://blog.jeffdouglas.com

DCSDCS
But then how it can be used to disable button on first click? Can you please explain?
prageethprageeth
In the above case, the action method does not work because the "onClick" is excecuted first. In the "onClick" event the button is disabled and then the action is not excecuted.
As jeffdonthemic said you can set the disabled value using the controller. 
 
Controller :
global class MyClass{
Boolean isDisabled = false;
global void Save(){
//Your codes here
this.isDisabled = true;
}

global Boolean getIsDisabled(){
return this.isDisabled;
}
}
 
Page: 
<apex:page Controller="MyClass">

<apex:form>

<apex:commandButton value="Click" action="{!save}" disabled="{!isDisabled}" onclick="alert('hi');"/>

</apex:form>

</apex:page> 

TLFTLF
prageeth, I'm not sure what DCS was trying to accomplish, but I'm trying to disable the "submit" button on a page on first click because I'm invoking a possibly long running action in my controller (10 seconds or more), and I wish to prevent the user from clicking the button again, and double submitting. Using the approach you suggest does not work for me, because the button is not disabled until the action completes and the page is re-rendered with the "isDisabled" flag set to true. This is why I was trying to accomplish this in javascript, so that the disabling of the button is immediate. Unfortunately, I ran into the same issue as DCS, in that once I disable the button in javascript, the action method doesn't get invoked in my controller. Any other suggestions?
prageethprageeth

Hello TLF;

It's difficult to answere your question without seeing your javascript. But note that, if your javascript returns a "false" (Boolean) value, the action method is not invoked. 

TLFTLF

I've tried adding a javascript onclick function directly to the commandButton that looks like this:

 

 

. . . <apex:commandButton id="myButton" action="{!complete}" value="Complete" onclick="return buttonClicked(this);" /> </apex:form> <script> function buttonClicked(myButton) { myButton.disabled=true; return true; } </script> . . .

 

 

I've also tried adding a similar function to the form's onsubmit event that uses the $Component global to get the button by ID and disable it. In both cases, the javascript function disables the button, and returns true. I've verified with a javascript debugger that the functions are called and behave as expected. I've also observed that the form is posted when the button is clicked, however, the post does not contain the value of the command button as a parameter. If I remove my code that disables the button, the post does contain the button value as a parameter. My action function is not invoked when the button is disabled.

edgarMedgarM

Hello everyone this is a solution!!, a few days ago I presented a requirement where I needed to disable the button was pressed once, the easiest way to do this is by using the tag <apex:actionStatus> and then I leave <apex:facet> a small example of implementation. Greetings.

 

 

<apex:actionStatus id="mySaveStatus1">

<apex:facet name="stop">

<apex:commandButton action="{!youmethod}" status="mySaveStatus1" value="Save" disabled="false" rerender="mySaveStatus"/>

</apex:facet>

<apex:facet name="start">

<apex:commandButton action="{!youmethod}" status="mySaveStatus1" value="Processing..." disabled="true"/> </apex:facet>

</apex:actionStatus>

 

 

 

Message Edited by edgarM on 03-03-2010 02:37 PM
This was selected as the best answer
DCSDCS

Yes, I ended up doing excatly the same.

 <apex:actionStatus id="mySaveStatus">

<apex:facet name="stop">

<apex:commandButton value="Add Item(s)" id="addItem" action="{!addItems}" status="mySaveStatus" rerender="LitList"/>

 </apex:facet>

<apex:facet name="start">

<apex:commandButton value="Adding Item(s)" disabled="true"/>

</apex:facet>

</apex:actionStatus>

SankkyySankkyy

Hi ,

     As we do in javascript in html like id some javascript validation is false we return false to button and click

event is not fired. but here i am not able to do that. even if i return false it is executed what to do.

Collect-Pro UserCollect-Pro User

Thanks for posting this solution.

That really solved my problem :)

SRKSRK

Just do this :-

<apex:commandButton action="{!submitform}" value="Submit" onclick="return checkform()"/>

 

make it onclick="return checkform()" // add return in end the it work fine

SoloSolo

Hello All,

 

Just want to share my approach to solve the isue.

 

Approach to disable the button using call from controller does not
work, because the button is not disabled until the action completes -
this take time. We can not also disable the button by JavaScript
(disabled = true). "onClick" event is executed first. If the "onClick"
event will disable the button, the AJAX action will not executed.

 

So the best solution in this case is to not try to "disable" buttons, but call
custom modal window which will prevent user from multiple clicks and
multiple form submission.

 

Here is a code example:


VF page components

*** CSS ***
<style>
#modalWindow {display: none; position: fixed; width: 100%; height: 100%; top: 0px; left: 0px; }
</style

<script>
function revealModal(divID) {
    window.onscroll = function () { document.getElementById(divID).style.top = document.body.scrollTop; };
    document.getElementById(divID).style.display = "block";
    document.getElementById(divID).style.position = "relative";
    document.getElementById(divID).style.top = document.body.scrollTop;
}
</script>

*** Command Button ***

<apex:commandButton  value="Save  As  Draft"   action="{!saveAsDraft}" onclick="revealModal('modalWindow');" />

*** Modal Window ***
<apex:outputPanel>
             <!-- Modal Window to Prevent Users from Submitting a Form Twice  -->
            <div id="modalPage0">
                <div class="modalBackground"></div>
                <div  style=" position: fixed; z-index: 750; left: 45%; top: 40%; width: 200px; padding: 20px; border: solid 2px #ccc; background-color: white;">
                    <img src="{!$Resource.LoadingSm}"  style=" float: left; padding-right: 5px;"/><b>Processing. Please wait...</b>
                </div>
            </div>
</apex:outputPanel>


P.S.

As a $Resource.LoadingSm you can use any .gif animated "in progress" image


Regards,
Evgeny

 

 

 

 

 

 

 

docbilldocbill

I tried most of the techiniques described in this thread, and a few of my own.  All of them have problems.  First it seems if you overload the onclick event, and the action returns in error, then the visual force page will never show the error message.   If you don't set the onclick the the refresh works as expected and you'll see the error message.   The other method of using actionStatus is more successful, and seems to acheive the goal of blocking multiple clicks but the one downside to that is the user can actually see the one button removed and the disabled button added, rather than just a smooth change of display class like you get with the onclick method.

 

 

SoloSolo
Please refer to the blog post "Disable and animate APEX command button after click to avoid double submission (http://salesforce.websolo.ca/2016/03/disable-and-animate-apex-command-button.html" target="_blank)". There are few possible approaches along with visual demos to show how to achieve required result. Hope this will help.
Matt Cooper 7Matt Cooper 7
Edgar's solution works great.  However, when I get my button status changed, it only appears to change the button I click (either top or bottom). If I click the top button, the bottom button still allows me to click it. Am I missing a step?