[SalesForce] Using jQuery to disable VF page button onclick

Quick background: I've already tried disabling onclick via apex, but my disable does not execute fast enough in the UI.

I'm trying to incorporate jQuery in my VF page code so that a button is disabled upon the first click. How can I incorporate this code I found online: https://stackoverflow.com/questions/5445431/jquery-disable-submit-button-on-form-submission

to my current VF code:

    <apex:pageBlock mode="edit" rendered="{!passesCheck}" id="mainBlock">
        <apex:pageBlockButtons >
            <apex:actionStatus id="saving">
                <apex:facet name="start" ><apex:image url="{!$Resource.loading}" /></apex:facet>
                <apex:facet name="stop" >
                    <apex:commandButton action="{!save}" status="saving" disabled="{!stopSave}" 
                                        value="{!IF(OR(isAddOn, currencyUpdate), 'Update', 'Create')} Renewal" />
                </apex:facet>
            </apex:actionStatus>
            <apex:commandButton value="Cancel" action="{!cancel}" />
        </apex:pageBlockButtons> 

Best Answer

Just for clarification, the reason that this is happening in your page is not that it doesn't execute 'fast enough' but instead the intended behaviors are occurring in the wrong order.

The manner in which I normally accomplish this behavior is like this... a button on the page calls a function (of my own) which first calls the actionFunction to post the data, then disables the buttons. The actionFunction is defined with an oncomplete="" script to call another function in the page to re-enable the buttons in the page when the ajax post is finished.

In this example 'addNewRow' starts the process via the button click and 'addNewRowComplete' is called when the actionFunction is finished.

Simply adding the css class 'btnDisabled' will make the button(s) appear to the user as disabled, but will in fact still be clickable causing the form to post again.

This code should be a functional example as written though you should change the function names to fit your needs.

<apex:page>
    <script>
    // function to control the native css style 
    // and the addition and removal of the disabled attribute on the buttons
    function buttonsEnabled(enable) {
        var $buttons = jQuery('.btn'); // find all buttons in the page
        if (enable === false) {
            $buttons.toggleClass('btnDisabled', true).attr('disabled', 'disabled');
        } else {
            $buttons.toggleClass('btnDisabled', false).attr('disabled', null);
        } 
    }

    // function called by the commandButton
    function addNewRow() {
        // make the ajax post via the actionFunction definition by calling the AF
        // this is case sensitive, match the name of the actionFunction
        doTheSave(); 

        // _then_ disable the buttons on the page
        buttonsEnabled(false);

        // return false to prevent the form from performing the button's click
        // behavior in addition to this function call. note that the onclick 
        // statement of the button returns this false value to the browser.
        return false;
    }

    function addNewRowComplete() {  
        // re-enable the buttons on the page after the actionFunction is finished
        buttonsEnabled(true);   
    }

    </script>


    <apex:form>
    <!-- somewhere in your form -->
    <apex:actionFunction name="doTheSave" action="{!save}" status="saving" rerender="messages" oncomplete="addNewRowComplete();"></apex:actionFunction>

    <!-- your normal button definition with the addition of the onclick script -->
    <apex:commandButton action="{!save}" status="saving" disabled="{!stopSave}" 
        value="{!IF(OR(isAddOn, currencyUpdate), 'Update', 'Create')} Renewal" 
        onclick="return addNewRow();" />
    </apex:form>
</apex:page>

Hope this helps get you going in the right direction!

Related Topic