You need to sign in to do that
Don't have an account?

Hide or Disable a Button After Click
On a standard Salesforce edit page, when the save button is clicked, the button immediately grays out and prevents the user from clicking the button multiple times. I'm trying to get the same effect on a VFP but I am having no luck. Has anybody already done this? I don't know if it's pertinent, but my save button is calling a method called Save in a custom controller.
<apex:pageBlockButtons > <apex:commandButton action="{!Save}" value="Save" id="saveBtn" /> </apex:pageBlockButtons>
I should have posted this forever ago - but this is what my final solution ended up looking like. Works wonderfully.
The Javascript on the page:
<script type="text/javascript">
function KillSaveButton(){
var obj= document.getElementById('cmdSave')
var obj2= document.getElementById('cmdSave2')
obj.style.visibility = 'hidden';
obj2.style.visibility = 'hidden';
}
function KillRetryButton(){
var obj= document.getElementById('cmdRetry')
var obj2= document.getElementById('cmdRetry2')
obj.style.visibility = 'hidden';
obj2.style.visibility = 'hidden';
}
function KillLostOppButton(){
var obj= document.getElementById('cmdLost')
var obj2= document.getElementById('cmdLost2')
obj.style.visibility = 'hidden';
obj2.style.visibility = 'hidden';
}
</script>
The actionFunctions:
<apex:actionFunction name="RunSave" action="{!mySave}" reRender="ErrMsgs, RedirectTO, Buttons, Buttons2" oncomplete="RedirectOnSuccess('Save');" status="otherSaveStatus" />
<apex:actionFunction name="RunRetry" action="{!Retry}" reRender="ErrMsgs, RedirectTO, Buttons, Buttons2" oncomplete="RedirectOnSuccess('Retry');" status="RetryStatus" />
The buttons:
<!-- Buttons at the top of the page -->
<apex:outputPanel id="Buttons">
<center>
<input type="button" value="Save" id="cmdSave" onclick="KillSaveButton();RunSave();" class="btn" style="{!ShowSaveButton}" />
<input type="button" value="Retry" id="cmdRetry" onclick="KillRetryButton();RunRetry();" class="btn" style="{!ShowRetryButton}" />
<apex:commandButton action="{!SaveLostOppty}" value="Lost Opportunity" rendered="{!ShowLostOpptyButton}" />
</center>
</apex:outputPanel>
<!-- Buttons at the bottom of the page -->
<apex:outputPanel id="Buttons2">
<hr />
<center>
<input type="button" value="Save" id="cmdSave2" onclick="KillSaveButton();RunSave();" class="btn" style="{!ShowSaveButton}" />
<input type="button" value="Retry" id="cmdRetry2" onclick="KillRetryButton();RunRetry();" class="btn" style="{!ShowRetryButton}" />
<apex:commandButton action="{!SaveLostOppty}" value="Lost Opportunity" rendered="{!ShowLostOpptyButton}" />
</center>
</apex:outputPanel>
I believe that is all the pertinent code. Let me know if any clarification is needed.
All Answers
You can get this effect easily. You already know about ActionStatus, which gives the user feedback on the status of an AJAX call. Usually, we put a spinner image or some other sort of progress indicator in there.
Why not put your button as well?
Try this:
<apex:actionStatus id="mySaveStatus"> <apex:facet name="stop"> <apex:commandButton value="Save" action="{!doSave}" status="mySaveStatus" rerender="currentSiteDisplay"> </apex:commandButton> </apex:facet> <apex:facet name="start"> <apex:commandButton value="Saving..." disabled="true" action="{!doSave}" status="mySaveStatus" rerender="currentSiteDisplay"> </apex:commandButton> </apex:facet>
1) When the page renders, the actionStatus mySaveStatus has not started, so the components in the "stop" facet are rendered. This means your "Save" button appears.
2) When the user clicks the "Save" button, the status of "mySaveStatus" is set to "start" until the ajax call is finished. This means the "Save" button is hidden, and the disabled "Saving..." button is shown.
3) When the call finishes, then the greyed-out "Saving..." button disappears again, replaced by the "Save" button.
This is visually identical to the way some of the salesforce-native buttons appear, so it can be a good way to have your custom code keep the same styling and behavior when clicked.
(Note: you'll see that the disabled "Saving..." button has action and status and re-render. Why, if it's never going to be clicked? Because I'm lazy. I just copy/pasted the "Save" button, changed it's name to "Saving..." and added the disabled flag.)
<apex:pageMessages/>
can be useful to show any error messages, no matter where they come from... Just remember to refresh the component that contains this tag, so any Ajax errors appear. Basically, if parts of your page need to be updated after the data returns (or the error does), don't forget to list them in the "rerender" tag of this button, so they get updated.
Hmmm...I thought I was already doing that. Maybe I'm missing something dumb...wouldn't be the first time. Here's what the code looks like:
<apex:pageBlock title="Opportunity Detail" mode="edit" id="MainPageBlock"> <apex:pageMessages id="myMessages" /> <apex:pageBlockButtons > <apex:actionStatus id="mySaveStatus"> <apex:facet name="stop"> <apex:commandButton value="Save" action="{!Save}" status="mySaveStatus" rerender="myMessages"> </apex:commandButton> </apex:facet> <apex:facet name="start"> <apex:commandButton value="Saving..." disabled="true" action="{!Save}" status="mySaveStatus" rerender="myMessages"> </apex:commandButton> </apex:facet> </apex:actionStatus> </apex:pageBlockButtons>// the rest of my page</apex:pageBlock>
Hi,
First of all I want to thank you for your post.
It helped me alot.
But I have one issue using this code.
Im using pageblockbuttons which displays the 'Save' button on the top and bottom of the page.
Using this code it is graying out the top button, not the bottom one.
Im I missing something.
Can you please help me resolve this.
Thanks in advance
Swapna
XRADM,
Hmm... try a simple page, where the apex:messages component is refreshed successfully. Then move your button into the wrapper as suggested here, and see if that is what breaks it. If so, then you have a great "before" and "after" pair of code blocks to submit to support as a case. It's not immediately apparent to me what the problem could be there. Sorry.
sap,
I never thought of doing this to pageBlockButtons. Cool idea! As you see, with pageBlockButtons you define them once but they appear twice. I think it's a bug that the code you write is applied to the first, but not to the next. You can submit this to support. Maybe it will motivate them to have the pageBlockButtons in apex pages get the same styling as pageBlockButtons in salesforce pages, so we won't have to do this extra work to get the greyed-out button style when they are clicked! ;-)
You can do this by using javascript. Put an onlclick javascript function and create an action function for the controller method. This is what OnClick function looks like...
}
}
In your action function add oncomplete event ... this will refresh the entire page after the process ends.
Hi Kirk,
thank you very much
I should have posted this forever ago - but this is what my final solution ended up looking like. Works wonderfully.
The Javascript on the page:
<script type="text/javascript">
function KillSaveButton(){
var obj= document.getElementById('cmdSave')
var obj2= document.getElementById('cmdSave2')
obj.style.visibility = 'hidden';
obj2.style.visibility = 'hidden';
}
function KillRetryButton(){
var obj= document.getElementById('cmdRetry')
var obj2= document.getElementById('cmdRetry2')
obj.style.visibility = 'hidden';
obj2.style.visibility = 'hidden';
}
function KillLostOppButton(){
var obj= document.getElementById('cmdLost')
var obj2= document.getElementById('cmdLost2')
obj.style.visibility = 'hidden';
obj2.style.visibility = 'hidden';
}
</script>
The actionFunctions:
<apex:actionFunction name="RunSave" action="{!mySave}" reRender="ErrMsgs, RedirectTO, Buttons, Buttons2" oncomplete="RedirectOnSuccess('Save');" status="otherSaveStatus" />
<apex:actionFunction name="RunRetry" action="{!Retry}" reRender="ErrMsgs, RedirectTO, Buttons, Buttons2" oncomplete="RedirectOnSuccess('Retry');" status="RetryStatus" />
The buttons:
<!-- Buttons at the top of the page -->
<apex:outputPanel id="Buttons">
<center>
<input type="button" value="Save" id="cmdSave" onclick="KillSaveButton();RunSave();" class="btn" style="{!ShowSaveButton}" />
<input type="button" value="Retry" id="cmdRetry" onclick="KillRetryButton();RunRetry();" class="btn" style="{!ShowRetryButton}" />
<apex:commandButton action="{!SaveLostOppty}" value="Lost Opportunity" rendered="{!ShowLostOpptyButton}" />
</center>
</apex:outputPanel>
<!-- Buttons at the bottom of the page -->
<apex:outputPanel id="Buttons2">
<hr />
<center>
<input type="button" value="Save" id="cmdSave2" onclick="KillSaveButton();RunSave();" class="btn" style="{!ShowSaveButton}" />
<input type="button" value="Retry" id="cmdRetry2" onclick="KillRetryButton();RunRetry();" class="btn" style="{!ShowRetryButton}" />
<apex:commandButton action="{!SaveLostOppty}" value="Lost Opportunity" rendered="{!ShowLostOpptyButton}" />
</center>
</apex:outputPanel>
I believe that is all the pertinent code. Let me know if any clarification is needed.
I have requirement that when i will click on button Create dispute at that time value of that button must be changed and it will be disable and after called action function it will call apexmessage and one ok button. when we click on that button page will be redirected to the transaction.
I have written code for disabled button but it is not working in mozzilla and in IE it will be disabled but not redirected.any suggestion would be appreciated.
function afterSubmit(){
document.getElementById("pg:frm:pb:pbb:btnexe").value = "Executing...";
document.getElementById('{!$Component.frm.pb.pbb.btnexe}').disabled = true;
}
cn anybody help me on my application requirement? i need to hide a custom button named "Submit" if the status is already Submitted...note that the status field is also a custom one.
thanks a lot
Hi all,
i have designed VF page with Save and Cancel buttons.On Clicking Save button, Cancel button also need to go into Saving mode, similar to Salesforce standard page.
My Requirement is :
On clicking Save button ,we need to disable save a& cancel buttons and need show Saving text for both the buttons .
Thanks,
Ramana
<apex:page controller="hidebuttons">
<apex:form id="od">
<apex:pageBlock >
<apex:pageBlockSection >
<apex:commandButton value="Button1" action="{!A1}" rendered="{!b1}" reRender="od"/>
<apex:commandButton value="Button2" action="{!A2}" rendered="{!b2}" reRender="od"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
Controller Code
public with sharing class hidebuttons {
public Boolean b1 {get; set; }
public Boolean b2 {get; set; }
public hidebuttons(){
b1 = true;
b2 = true;
}
public PageReference A1() {
b1 = false;
b2 = true;
return null;
}
public PageReference A2() {
b1 = true;
b2 = false;
return null;
}
}