tags:

views:

60

answers:

2

I have a highly dynamic single page interface where various user events trigger new fields to display on the screen. I am using jsf 1.1 and basic ajax without the ability to use partial submit. Because of these limitations I have marked all of my fields required false and immediate false. The idea is to validate ONLY when the user attempts to transition to the next page in an action method NOT when they tab off and execute an ajax event. I set immediate false because I need input to make it to the modal so I can conditionally render certain fields based on business logic.

PROBLEM: I know ahead of time a list of "possible" UIInput ids which may or may not be displayed on the screen at any given time. My goal is to iterate through all these UIInputs, check to see if they are rendered, not null, and not empty otherwise mark the UIInput in error.

This works except for fields which are not displayed on the screen. For example, I have a field "amountInput" which has an XHTML rendered property set to false so it does not show up on the screen. From a display perspective, this works, but upon invoking my action, this field is still showing its rendered property as true so I have no way to know whether I should validate it or not.

What are my options here?

    public boolean validate() {
    boolean hasValidMinimumData = true;

    final List<UIInput> componentList = getComponentList();
    if (CollectionUtils.isNotEmpty(componentList)) {
        for (UIInput curComponent : componentList) {
            final Object curComponentValue = curComponent.getValue();
            if (curComponent.isRendered() && (curComponentValue == null || isNoValue(curComponent))) {
                setError(curComponent); // applies the error
                hasValidMinimumData = false;
            }
        }
    }

    return hasValidMinimumData;
}
A: 

You need to take care that exactly the same condition responsible for the outcome of the rendered attribute is preserved during the request of the form submit as it was during the initial display.

Easiest way is to put the bean responsible for the conditions in the session scope. If you prefer to have it in the request scope (which is a very reasonable decision), then I'd suggest to grab Tomahawk's t:saveState for this.

<t:saveState value="#{bean}" />

That said, have you ever considered Ajax4jsf? It's compatible with JSF 1.1 and offers transparent integration of Ajax with JSF.

BalusC
Thanks BalusC. Your name proceeds you -- I've learned quite a bit from your site. Unfortunately putting the viewbean in session scope did not work. I put a breakpoint in my conditional and it rendered exactly how it should before my action took place. It is as if the rendered attribute tied to the backing bean is different than setting the rendered attribute in XHTML.
gevaudan
I'd love to use Ajax4jsf but that is not an option at my place of work. Given my requirements I see two solutions, each of which has its flaws:1. Implement all the required field validation in javascript2. Duplicate the business logic in the action to determine when and when not to validate a field since we can't seem to rely on the rendered attribute.
gevaudan
Is the rendered el property evaluated during render response or is it applied in the update model / invoke application phase? In my current code, I am checking the rendered attribute in the action so it is prior to render response. Perhaps this is an issue.To be honest, I was a little surprised that I could even find my component that is not displayable as I thought setting render=false would exclude it from the tree making it unfindable.
gevaudan
It's also re-evaluated during apply request values and validations phases. By the way, from your initial question I understood that you was properly testing it by [`UIComponent#isRendered()`](http://download.oracle.com/javaee/6/api/javax/faces/component/UIComponent.html#isRendered%28%29), but your last comment tells otherwise. It's not true that the whole component disappears from the component tree when its `rendered` attribute evaluates `false`.
BalusC
In my XHTML page, I have a text field which evaluates against a condition to determine render true or render false. This part seems to work as the field is conditionally displayed based on this condition. In my viewbean, I modified it to use session scope, even tried binding the text fields to the bean itself but I am not seeing the isRendered() property return anything other than true.
gevaudan
A: 

RESOLVED! Issue was that in my XHTML I had set the rendered attribute on a table component which contained my input component. I thought that this would in turn set the rendered attribute appropriately on all of its children but apparently not.

Simply setting the conditional render attribute in my XHTML on the actual input component solved the issue.

gevaudan