0

I have written a bit of code, that will disable a button in VF page once it is clicked with the help of JQuery. Unfortunately, although the button gets grayed out once clicked, my action method from the button does not get executed. Could anyone help me understand why?

<script src="http://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
        $('input[id$=submitButton]').on('click', function(){ 
            console.log( "jQuery loaded1" );
            $('input[id$=submitButton]').attr('disabled','disabled');
            console.log( "jQuery loaded2" );
         });
    });
</script>
    <apex:commandButton id="submitButton" action="{!saveConsent}" value="{!$Label.Disaster_Submit}"  styleClass="btn btn-fill btn-danger btn-wd btn-sm">     </apex:commandButton>
1
  • why not use a spinner to prevent further page input and use a controller variable to disable the commandButton once the action method completes
    – cropredy
    Mar 21, 2019 at 18:17

1 Answer 1

1

That is because, client side code i.e. Javascript or JQuery executes before your controller code i.e. actionMethod.

  • JQuery/Javacript on onclick event executes, which disables the button
  • It checks for the actionMethod on the commandButton and tries to execute it.
  • But as the button is disabled because of the first step, it skips calling the controller i.e. it prevents the postback from occurring.

The code which you have written is same as below, which disables the button on click using javascript. Both the approaches would prevent the post back from happening due to the reasons mentioned above.

<apex:commandButton id="submitButton" value="{!$Label.Disaster_Submit}" action="{!saveConsent}" styleClass="btn btn-fill btn-danger btn-wd btn-sm" onclick="this.disabled=true;"/>

There are two approaches that can be used to prevent such kind of scenarios i.e. to prevent the same action being calling multiple times due to multiple clicks

  1. Using actionStatus : Using this approach, the button can be disabled on click and user can be shown with the disabled button saying that processing is going on. Once the action is complete, the button will be enabled once again. Note that you need to use dummy (or any component you want to reRender) reRender attribute on commandButton for this to work properly. Also, if you are making any redirection from your actionMethod, then make sure that development mode of user is switched OFF, as this does not redirect to the page when development mode is ON for the user.
  2. Using actionFunction : Using this approach, actionMethod can be called using actionFunction and then button can be disabled. Note the sequence of the code in Javascript method, it first calls the actionFuction and then disables the button. (The reason for this is explained above)

Using actionStatus

<apex:actionStatus id="buttonStatus">
   <apex:facet name="stop">
      <apex:commandButton id="submitButton" value="{!$Label.Disaster_Submit}" action="{!saveConsent}" styleClass="btn btn-fill btn-danger btn-wd btn-sm" status="buttonStatus" reRender="dummy"/>
   </apex:facet>
   <apex:facet name="start">
     <apex:commandButton disabled="true" value="Processing..." styleClass="btn btn-fill btn-danger btn-wd btn-sm" status="buttonStatus"/>
   </apex:facet>
 </apex:actionStatus>

Using actionFunction

<script type="text/javascript">
    function disableAndCallActionMethod(elementId){
        saveConsentJS();
        var submitButton = document.getElementById(elementId);
        submitButton.disabled = true;
    }
</script>
<apex:actionFunction name="saveConsentJS" action="{!saveConsent}" />
<apex:commandButton id="submitButton" value="{!$Label.Disaster_Submit}" onclick="return disableAndCallActionMethod('{!$component.submitButton');" styleClass="btn btn-fill btn-danger btn-wd btn-sm"  > 
</apex:commandButton>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .