JSF – You Can’t Submit a Disabled Form Element

by Michael Scepaniak on November 12, 2010 in software development

I previously discussed the JSF truism that you can’t re-render something you never rendered in the first place. Here’s another one:
You can’t submit a disabled form element.

Here’s the situation. We’ve got a form with a text input element that, by default, we want to be disabled unless the user changes something else, client-side, on the page. The obvious, intuitive way to do this is with the disabled attribute:

<h:inputText id="newId" value="#{thePage.newId}" disabled="true" />

Then, once the user initiates whatever action to enable the text input element, we use some JavaScript to twiddle the disabled attribute, thereby making it editable. However, if the user then fills out that text input element and submits the form, the backing bean won’t receive the user-supplied value. Why? I can only surmise that, according to the JSF viewState, the text input element in question is still disabled. Therefore, JSF sees no point in processing text input element.

One efficient (but hacky and verbose) way around this is to always keep the text input element enabled from JSF’s standpoint and, instead, do it all using JavaScript. The first step is to remove the disabled attribute from the text input element:

<h:inputText id="newId" value="#{thePage.newId}" />

Instead, we use jQuery to disable the text input element at page-load time:

jQuery(document).ready(function(){
    var newIdInput = jQuery("#theForm\:newId");
    newIdInput.attr({ disabled:true });
});

Some CSS styling completes the job, making the text input element actually “look” disabled in all browsers:

input#theForm3A newId
{
    background-color: #D6D6D6;
}
span#theForm3A newIdInputLabel
{
    color: #9C9C9C;
}

Finally, we add a JavaScript event handler function to twiddle the attribute value:

var handleSomeChange = function()
{
    var labelColor = "#9C9C9C";
    var inputColor = "#D6D6D6";
    var disabledSwitch = true;
    if ([test to see if newId should be enabled returns true])
    {
        labelColor = "#000000";
        inputColor = "#FFFFFF";
        disabledSwitch = false;
    }

    var newIdInputLabel =
        jQuery("#theForm\:newIdInputLabel");
    newIdInputLabel.css("color", labelColor);
    var newIdInput = jQuery("#theForm\:newId");
    newIdInput.attr({ disabled:disabledSwitch });
    newIdInput.css("backgroundColor", inputColor);
}

The more pure JSF way to get this done (using RichFaces) is to have the event handler function call the server, which would determine the proper disabled/enabled state and then reRender the text input element or containing form. In this way, the server-side viewState and client-side state remain in sync. But, in some instances, this introduces too much latency and negatively impacts usability. The option is available, though.

If you are, for example, disabling/enabling a text input element in a compact form in response to a checkbox being checked in that same form, I’d go with the client-side approach. However, if you are disabling/enabling lots of form elements in response to a button being clicked, going the server-side route might be more appropriate (from both a technical complexity and usability perspective).

I hope this helps.

Mike
Want to be notified when new articles are posted?
Enter your email address:

{ 5 comments… read them below or add one }

Tung December 18, 2013 at 8:35 am

very useful information.
Thanks

Reply

Tung December 18, 2013 at 8:39 am

But do you know how to deal with checkbox?

Reply

Michael Scepaniak December 19, 2013 at 8:08 pm

Tung,

You should be able to apply this same strategy to checkboxes, as well. Although, you may not need to go to any additional lengths to make a checkbox “look” disabled. I can’t recall if I’ve ever done it myself, though.

Mike….

Reply

Tung December 20, 2013 at 10:24 pm

Ok, Thanks Mike

Let me describe my problem, hope you can help me out

In previous version of JSF (JSF 1.2 for example), I can submit the value of h:selectBoooleanCheckbox even though it is being disabled
but in new version of JSF2, i can not do that.
Do you know the reason for this change?

Cheers
Tung

Reply

Michael Scepaniak December 21, 2013 at 9:03 am

I have no idea. Sorry.

Mike….

Reply

Leave a Comment

Previous post:

Next post:

Member of The Internet Defense League