0

This is my first post on SO.

I am using JSF2 with Richfaces4 and I have the following problem:

Depending the value of a drop down menu I want some input fields in a panel to be disabled and not required otherwise those fields should be enabled and required.

I have the following in my xhtml

<h:selectOneMenu value="#{backingBean.field}" id="ResponseType">
    <f:selectItems value="#{backingBean.responseTypes}" />
    <f:ajax event="change" execute="@this" render="myPanel" listener="#{backingBean.responseTypeValueChange}" immediate="true"></f:ajax>
</h:selectOneMenu>
<rich:panel id="myPanel">
    <h:inputText id="input1" label="label1" value="#{backingBean.input1}" required="#{not backingBean.flagDisabled}" disabled="#{backingBean.flagDisabled}" />
    <h:inputText id="input2" label="label2" value="#{backingBean.input2}" required="#{not backingBean.flagDisabled}" disabled="#{backingBean.flagDisabled}" />
    <h:inputText id="input3" label="label3" value="#{backingBean.input3}" required="#{not backingBean.flagDisabled}" disabled="#{backingBean.flagDisabled}" />
    <h:inputText id="input4" label="label4" value="#{backingBean.input4}" required="#{not backingBean.flagDisabled}" disabled="#{backingBean.flagDisabled}" />
</rich:panel>

My backing bean is a Spring bean and the code is:

public class BackingBean {
    private boolean flagDisabled;
    private String field;

    // getters and setters

    public List<SelectItem> getResponseTypes() {
        ...
        // returns values [1: Positive], [2: Negative]
    }

    public void responseTypeValueChange(AjaxBehaviorEvent event) {
        flagDisabled = "2".equals(field);
    }
}

My problem is that when the responseTypeValueChange method is invoked the field variable holds the value from the previous request. So I always get the exact opposite behavior.

I have also tried with a4j:ajax but I get the same results.

Then i changed the method to get the submittedValue from the event argument like this:

public void responseTypeValueChange(AjaxBehaviorEvent event) {
    if (event.getSource() instanceof HtmlSelectOneMenu) {
        HtmlSelectOneMenu source = (HtmlSelectOneMenu) event.getSource();
        flagDisabled = "2".equals(source.getSubmittedValue());
    }
}

The above works but how I can update the flagDisabled value and THEN invoke the method? I feel that my solution is not the best. It is actually a hack.

Thank you.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
kpagan
  • 173
  • 1
  • 7
  • is all in side the form ? – Ravi Kavaiya Jul 27 '13 at 12:26
  • @Ravi: Yes everything is inside h:form. Besides the method is invoked. The field just has the value from the previous ajax request – kpagan Jul 27 '13 at 13:09
  • This construct requires bean in view scope. Spring has by default no such scope out the box. If you was using request scope, then essentially the bean is destroyed by end of request and newly reconstructed on every request. Perhaps you made the misobservation that the "previous value" is *actually* the bean property's default value. That'd at least explain your concrete problem. See further also http://stackoverflow.com/questions/7031885/how-to-choose-the-right-bean-scope/7031941#7031941 You'd need to implement a custom view scope for Spring yourself. There are a lot of examples on Google. – BalusC Jul 27 '13 at 20:33
  • @BalusC: Thanks, I will try the custom view scope for Spring. If I cann't solve it this way then I will make my bean a JSF managed bean with ViewScope. Btw, the Spring bean is session scoped and there is no default value for the property "flagDisabled" – kpagan Jul 28 '13 at 17:53
  • The problem is that I have the immediate="true" so the method is invoked in the Apply Request Values phase. But the problem is that i want to skip validation so the fields will be enabled/required even when have invalid values. Is there any other way to accomplish this? – kpagan Jul 31 '13 at 16:06

1 Answers1

1

After so much time and while investigating another matter concerning the JSF validation I figured out how to properly invoke the method without using something like:

if (event.getSource() instanceof HtmlSelectOneMenu) {
    HtmlSelectOneMenu source = (HtmlSelectOneMenu) event.getSource();
    flagDisabled = "2".equals(source.getSubmittedValue());
}

In the <h:selectOneMenu> I added the attribute execute="@this" in order to include only this element in the ajax request.

Strange thing is that I had it in my example here but not in the actual code. Sorry for the misleading post guys.

BTW: This has nothing to do with the scope of the managed bean. The bean is session scoped but I created even a custom View scope for Spring and even used the JSF @ViewScope without any results.

kpagan
  • 173
  • 1
  • 7