1

I've been trying the solutions outlined on this page: Disable commandButton after first click to prevent double submission

However, I am still creating multiple submissions. I am unsure if this is because I am first doing some js validation or if there is another reason? Is there a way to still do the validation and still have a hard stop after a single click? Below is the related code:

<apex:actionFunction name="saveNow" action="{!saveNowITellYou}"/>
<apex:commandButton id="hideSubmitButton" onclick="validateChecked()" value="Submit Form" action="{!saveNowITellYou}"  styleClass="commandButton" style="
                        display: inline-block;
                        font-family: 'Futura WGU', Lato, arial, sans-serif;
                        text-transform: uppercase;
                        font-size: 12px;
                        font-weight: normal;
                        padding: 0 10px;
                        border-radius: 5px;
                        color: #002f51;
                        -webkit-tap-highlight-color: transparent;
                        cursor: pointer;
                        outline: none;
                        min-height: 28px;
                        line-height: 28px;
                        text-align: center;
                        background-image: none;
                        background-position: 0%;
                        margin: 0;"/>

 <script>
        //We use this to modify elements when we don't want those modifications to
        //display on the PDF (Generated from the html)
        var changeStyling = function(){
            var submitButton = document.getElementById('addButtonColor').childNodes[1];
            submitButton.style.backgroundColor = '#ffcc5b';
            submitButton.style.borderColor = '#ffcc5b';
            var formCheckbox = document.getElementById('formCheckbox');
            formCheckbox.style.display = 'inline-block';
            var fakeCheckbox = document.getElementById('fakeCheckbox');
            fakeCheckbox.style.display = 'none';
            var fakeCheckbox = document.getElementById('nameForPDF');
            fakeCheckbox.style.display = 'none';
            var formCheckbox = document.getElementById('formNameInput');
            formCheckbox.style.display = 'inline-block';
        }

        var validateChecked = function() {
            var errorTextDiv = document.getElementById('formErrorText');
            var checkboxOutline = document.getElementById('checkboxOutline');
            if(!formCheckbox.checked) {
                errorTextDiv.style.display='block';
                checkboxOutline.style.border='1px solid #be1e2d';
            } else {
                doSomeWork();
                checkboxOutline.style.border='1px solid #fff';
                //We no longer need the hideForPDF line but if it is removed
                // the form doesn't submit for some reason.
                document.getElementById('hideForPDF').style;
                errorTextDiv.style.display='none';
            }
        }
           function buttonsEnabled(enabled) {
    // retrieve all of the buttons or links on the page
    // with the css class of btn
    var $buttons = jQuery('.btn');
    if (enabled === false) {
        // add the btnDisabled class to give it the look of being disabled
        // add the disabled attribute to actually disable interactability
        $buttons.toggleClass('btnDisabled', true).attr('disabled', 'disabled');
    } else {
        // remove the css class and the disabled attribute
        $buttons.toggleClass('btnDisabled', false).attr('disabled', null);
    } 
}

function doSomeWork() {
    // first, call the action function to post the form
    saveNow();

    // second, disable the buttons
    buttonsEnabled(false);

    // third, return false to prevent the click from
    // posting the form a second time
    return false;
}
        changeStyling();
    </script

2 Answers 2

3

I am assuming that your apex:commandbutton is within an apex:form, note that an apex:commandbutton reders to:

<input id="thePage:theForm:theButton" type="submit" name="thePage:theForm:theButton" value="Save" />

as per the documentation.

Instead of using the apex:commandbutton, you could use an html input tag with an id and disable the button with javascript (i'm using jquery) as follows:

Javascript

  $('#theButton').on('click', function() {
$(this).prop('disabled', true);
});

html input

<input id="theButton" type="submit" name="thePage:theForm:theButton" value="Save" />

The apex:command button triggers a page refresh.

After inserting the above javascript with the appropriate id and clicking the button, it will be disabled.

2

You need validateChecked() to return true or false so that you can control the behavior of the onclick="" function call on the commandbutton.

onclick="validateChecked()"

should be adjusted like this below so that when the form has been checked by your script and is "invalid", the default behavior of form submission can be stopped and the javascript tacked onto the end of the onclick by the platform after your custom js is not executed. You only want to stop the default behavior when validation fails.

onclick="if(validateChecked() === false) { return false; }" 

You would then need to adjust your validateChecked function to return the boolean.

// this function is designed to make sure the form is valid
// return true when it is
// return false when it is not
var validateChecked = function() {
    var errorTextDiv = document.getElementById('formErrorText');
    var checkboxOutline = document.getElementById('checkboxOutline');
    if (!formCheckbox.checked) {
        errorTextDiv.style.display = 'block';
        checkboxOutline.style.border = '1px solid #be1e2d';

        // assuming this is the error path
        return false;

    } else {
        doSomeWork();
        checkboxOutline.style.border = '1px solid #fff';
        //We no longer need the hideForPDF line but if it is removed
        // the form doesn't submit for some reason.
        document.getElementById('hideForPDF').style;
        errorTextDiv.style.display = 'none';

        // assuming this is the success path
        return true;
    }
}
3
  • Could you just do onclick="return validateChecked()"?
    – Adrian Larson
    Commented Jul 27, 2017 at 1:19
  • No, you don't want to return control to the browser in the case of success. The return statement should only be executed when you want to bail out, so it's only needed in the negative path. On the positive path, the code SFDC appends to the end of the onclick script will be executed.
    – Mark Pond
    Commented Jul 27, 2017 at 1:26
  • onclick="return validateChecked()" has the effect of never posting the form because even in the truthy state, control immediately returns to the browser. Truthy = no error message shown; Falsy = errorTextDiv shown. In both cases, no form submission takes place because of the return.
    – Mark Pond
    Commented Jul 27, 2017 at 1:31

You must log in to answer this question.

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