Search code examples
javajspjsfjsf-2

How can I disable an h:commandButton without preventing the action and actionListener from being called?


I have a simple script tag with a function that I include at the bottom of the html body. This script simply disables a submit button. I then have a onclick event that calls the function.

I have this code in 5 different pages and it works on 3 of the five.

Here is the code:

<!-- more non-important html -->

<h:commandButton id="buttonToDisable" 
    value="some text"
    action="#{myBean.myBeansAction}" 
    actionListener="#{myBean.myBeansActionListener}" 
    onclick="disableButton()">

    <!-- I also have an f:param in some of these pages but I didn't 
    think that would matter -->

</h:commandButton>

<!--  more non-important html -->

<script>
    function disabledButton() {
        document.getElementById("myForm:buttonToDisable").disabled = 'true';
    }
</script>

Any help would be greatly appreciated. The only differences between the pages that do and don't work is that the action and actionListeners are different types of beans and some have f:params and others don't.


Solution

  • You should be setting the enabled status of the commandButton component from the server side actionListener after the click event.

    <h:commandButton disabled="#{managedBean.someBooleanPropertyThatWasToggledInTheEvent}" />
    

    You can simply set the managed property after invoking your server side event and it will be disabled on the page refresh.

    UPDATE:

    I just realized that the OP has a completely different issue. Users are impatient and clicking the button and not waiting for the postback. Disabling the command button however will sometimes prevent the server side actions from being invoked.

    The correct way to resolve this is to put an absolute position div overlay across the page with a higher z-index than any other element on the page. This will prevent further clicks from occurring on anything but the overlay div. Here is an example:

    CSS style

    .div-overlay {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: #000;
        filter:alpha(opacity=50);
        -moz-opacity:0.5;
        -khtml-opacity: 0.5;
        opacity: 0.5;
        z-index: 10000;
    }
    

    Javascript toggle function utilizing jQuery fadeToggle functionality

    function toggleLoadingOverlay() {
      var div = jQuery('.div-overlay');
      div.fadeToggle(150);
    }
    

    ** JSF commandButton onclick event that will occur once the button is clicked (and assuming that event propogation has not been interrupted)**

    <h:commandButton onclick="toggleLoadingOverlay();" action="..." />