views:

229

answers:

2

Hello,

I am having problem with required=true validation which is applied on disabled fields.

I have an a4j:commandButton and two dropdowns containing list of states and list of countries inside a form. Both the dropdowns have required="true" validation applied. state dropdown is enabled and country dropdown is disabled by default by using the tag attribute disabled="true" as shown below:

<h:selectOneMenu value="#{states}" required="true">
  <f:selectItems>
</h:selectOneMenu>

and

<h:selectOneMenu value="#{countries}" disabled="true" required="true">
  <f:selectItems>
</h:selectOneMenu>

Scenario# 1: click on the a4j:commandButton without selecting anything in the state dropdown. result: required field validation error for state dropdown which is expected

Now on clicking a radio button (outside the form), state dropdown is disabled and country dropdown is enabled using jquery/javascript as shown below:

$j('#stateDropdown').attr('disabled', 'disabled');
$j('#countryDropdown').removeAttr('disabled');

Scenario# 2: click on the a4j:commandButton without selecting anything in the country dropdown. result: required field validation error for both state and country dropdowns. However, only validation error for country dropdown was expected.

the html code generated by for <h:selectOneMenu> tag on runtime:

for dropdown disabled using jsf tag attibute: <select disabled="disabled">...</select>

for dropdown disabled using jquery: <select disabled="">...</select>

Does anyone have any idea why jsf is validating the fields disabled by jquery?

A: 

It should obviously. as you have mentioned required="true" it will check for it any how

I would suggest handle it with fully JQuery or Fully JSF validation.

org.life.java
A: 

JSF does the validation based on the JSF UIComponent tree in the server side, not on the HTML DOM tree in the client side as you seem to expect. With jQuery you're only changing the HTML DOM tree in the client side without notifying JSF about the state change so that it could reflect it in its component tree.

You have to disable/enable it using JSF instead of jQuery. As you're using Ajax4jsf, you can use a4j:support for this.

<h:selectOneMenu value="#{bean.state}" required="true">
    <f:selectItems value="#{bean.states}" />
    <a4j:support event="change" reRender="country" />
</h:selectOneMenu>
<h:selectOneMenu id="country" value="#{bean.country}" required="true" disabled="#{bean.countryDisabled}">
    <f:selectItems value="#{bean.countries}" />
</h:selectOneMenu>

In this example, the <a4j:support> will re-render the country dropdown on every change of the state dropdown. The country dropdown in turn has a its disabled attribute attached to a boolean bean property. You have to make sure that it returns the desired outcome based on the currently selected state. You could do that in the getter method or in the valueChangeListener of the state dropdown.

BalusC
Hi, we thought of this approach but whats bothering us is: what if I press the submit button before the ajax request re-renders the dropdown? In this case I will get two validation errors. I am not sure how realistic is this on real production servers? basically it would depend on the server's response time.Is this a good practice to follow i.e firing ajax resquests to change the state of the ui components
Aarti Grover
Either overlay the page or disable the submit button while Ajax request is running.
BalusC