Learn how to disable command buttons in Visualforce page during processing. Enhance UX by preventing multiple clicks and showing a loading overlay.

Disabling the command buttons and gray out a Visualforce page during an action, you can follow these steps. This approach provides a smooth user experience by hiding or disabling buttons and overlaying a semi-transparent background on the page, indicating that processing is happening.

Step-by-Step Guide : apex:commandButton

  1. Disable Command Buttons: We’ll use JavaScript to hide or disable the buttons when a specific action (like saving) occurs.
  2. Overlay the Page with a Gray Background: We’ll create a semi-transparent div that covers the entire page, making it appear “grayed out.”
  3. Show a Loading Indicator: To enhance the user experience, you can add a loading message or icon within the overlay to inform users that the action is processing.

Example Visualforce Code

<apex:page>
    <apex:form id="mainForm">
        <!-- Command Buttons -->
        <apex:commandButton action="{!doSave}" id="saveButton" value="Save" onclick="disablePage()" />
        <apex:commandButton action="{!doCancel}" id="cancelButton" value="Cancel" onclick="disablePage()" />

        <!-- Gray Overlay and Loading Indicator -->
        <div id="overlay" style="display:none;">
            <div id="loadingMessage">Processing...</div>
        </div>

        <script>
            function disablePage() {
                // Hide or disable the command buttons
                document.getElementById("saveButton").disabled = true;
                document.getElementById("cancelButton").disabled = true;

                // Show the overlay to gray out the page
                document.getElementById("overlay").style.display = "block";
            }
        </script>

        <!-- CSS for Overlay and Loading Message -->
        <style>
            /* Overlay that covers the entire page */
            #overlay {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent gray */
                z-index: 1000; /* High z-index to overlay everything */
                text-align: center;
                color: white;
            }

            /* Centered loading message */
            #loadingMessage {
                position: relative;
                top: 50%;
                transform: translateY(-50%);
                font-size: 24px;
                font-weight: bold;
            }
        </style>
    </apex:form>
</apex:page>

Explanation of the Code

  • Command Buttons (<apex:commandButton>): The onclick="disablePage()" attribute on each button calls the disablePage() function, which runs when the button is clicked.
  • disablePage() JavaScript Function:
  • Disables both saveButton and cancelButton to prevent multiple submissions.
  • Displays the overlay div, which grays out the entire page.
  • Overlay and Loading Indicator:
  • The overlay div, styled with position: fixed, width: 100%, and height: 100%, covers the entire viewport.
  • The background-color: rgba(0, 0, 0, 0.5); makes it semi-transparent gray.
  • The loadingMessage div is centered in the overlay to display a “Processing…” message.

Summary

  • The overlay div and loading message will only appear during the action triggered by the button click.
  • This approach effectively disables page actions and informs the user with a visual cue, improving the overall experience during processing.

How to disable the command buttons and Grey out the total vf page on any action?

Usually we multiple records creates whenever multiple click on save button on custom save button on VF page. So to overcome this issue we can hide the all buttons once user click on buttons.

<apex:page>
    <apex:form>
        <apex:commandButton action="{!doSave}" id="saveButton" value="Save" onclick="disableAllButtons()" />
        <apex:commandButton action="{!doCancel}" id="cancelButton" value="Cancel" onclick="disableAllButtons()" />

        <script>
            function disableAllButtons() {
                var j$ = jQuery.noConflict();
                j$("[id$=saveButton], [id$=cancelButton]").hide();
            }

            function showButtons() {
                j$("[id$=cancelButton], [id$=saveButton]").show();
            }
        </script>
    </apex:form>
</apex:page>
  • showButtons function is to show the button once the action.
  • If we can use the same code for the input fields as well which have the action function. So that we can restrict the user to change the field and click the buttons immediately.
  • Some times we have to restrict the user to modify the fields on that page after click on button or change on any fields of having action function.

So, here we have to grey out the total VF page to restrict the user to change the fields if any action is In-progress.

The below code is to grey out the page. Greying out the backgrouond,status box and all tex boxes in the page.

<apex:page>
    <apex:form id="formId">
        <apex:commandButton action="{!doSave}" id="saveButton" value="Save" onclick="disableAllButtons()"/>
        <apex:commandButton action="{!doCancel}" id="cancelButton" value="Cancel" onclick="disableAllButtons()"/>

        <div id="processingSimbol" style="display:none;">
            Processing…….
        </div>

        <script>
            var j$ = jQuery.noConflict();

            function disableAllButtons() {
                j$("[id$=saveButton], [id$=cancelButton]").hide();
                j$("#processingSimbol").show();
                
                j$("[id$=formId]").append(
                    j$("<div>", {"id": "blurybackground"}),
                    j$("<div>", {"id": "statusBox"}).append(
                        j$("<img>", {"src": "/img/loading32.gif"}),
                        j$("<div>", {"id": "textBox"}).text("{!$Label.MDF_Status_Processing}")
                    )
                );
            }

            function showButtons() {
                j$("[id$=cancelButton], [id$=saveButton]").show();
                j$("#blurybackground, #statusBox").remove();

                if (globalFocus != null) {
                    globalFocus.focus();
                    if (globalFocus.attr('class').indexOf('amountInput') != -1) {
                        var focusId = globalFocus.attr('id').split(':').join('\\\\:');
                        setTimeout(function() {
                            j$("#" + focusId).focus();
                        }, 300);
                    }
                }
            }
        </script>

        <style>
            #blurybackground {
                z-index: 1000;
                position: absolute;
                left: 0px;
                top: 0px;
                width: 100%;
                height: 100%;
                text-align: center;
                vertical-align: middle;
                background-color: #222;
                opacity: 0.6;
                filter: alpha(opacity=60);
            }

            #statusBox {
                /* for Mozilla */
                -moz-border-radius-bottomleft: 5px;
                -moz-border-radius-bottomright: 5px;
                -moz-border-radius-topleft: 5px;
                -moz-border-radius-topright: 5px;
                -moz-box-shadow: 1px 6px 5px #888888;
                /* for Webkit */
                -webkit-border-bottom-left-radius: 5px;
                -webkit-border-bottom-right-radius: 5px;
                -webkit-border-top-left-radius: 5px;
                -webkit-border-top-right-radius: 5px;
                -webkit-box-shadow: 1px 6px 5px #888888;
                /* General */
                box-shadow: 1px 6px 5px #888888;
                z-index: 1000;
                background: #FFFFFF;
                height: 42px;
                width: 150px;
                left: 45%;
                top: 35%;
                padding-left: 15px;
                padding-top: 11px;
                position: absolute;
                vertical-align: middle;
            }

            #textBox {
                margin-left: 40px;
                margin-top: -20px;
                font-weight: bold;
                font-size: 14px;
            }
        </style>
    </apex:form>
</apex:page>