JSF 2.0 f:ajax listener is not invoked when controller is request scoped - spring

I am facing very weird issue with JSF2.0 Ajax Tag. Below are the steps that causes an issue for me
My project uses JSF2.0 and Spring 3.0. The JSF is wired to spring controller and life cycle is managed by Spring.
My Controller is Request Scoped.
Everything works fine till this point
i have a selectOne dropdown and on selection of a value on drop down it renders bottom portion of screen which has another dropdown. I use a rendered attribute on a parent panelgroup to show and hide this drop down.
However for the newly rendered drop down on selection of a value the ajax listener(F:ajax tag defined inside it) is not getting invoked. I see the following happening
The bean is reintialized as it is request scope.I see my postconstruct getting executed.
i see success message in the data object in client.
Only thing missing is that the listener method is not invoked.
Is there anyway to debug the life cycle and find what is going wrong?

If the rendered attribute of one of the parent components of <f:ajax> evaluates false during processing the ajax request, then the ajax action listener won't be invoked.
A request scoped bean is recreated on every single request, so all its properties would be resetted to default, unless initialized otherwise in the (post)constructor. If the property behind the rendered attribute isn't properly reinitialized based on some request parameters, then it would evaluate false like as on the initial request.
To fix it, you'd need to do proper initialization in bean's (post)constructor based on request parameters or just put the bean in the JSF view scope.
See also:
How to choose the right bean scope?
commandButton/commandLink/ajax action/listener method not invoked or input value not updated

Related

JSF, AJAX and the rendered attribute

If you do JSF AJAX calls and change the component tree while rerendering (or between ajax calls), you'll get exceptions from Mojarra. As I understand it, it's difficult to recreate the component tree partially when the new tree is different as the one stored in the ViewState (or the actual JSF class). That's "ok". I'm thinking about using the rendered attribute and not rendering the component.
My question: How does the rendered attribute work? Does the component get restored and is the component tree, that JSF creates during restore phase, safe? We have a very dynamic XHTML page and not rendering object's instead of disabling them with css classes would really up the speed of the page.
I tried it and it works as expected. So JSF only assumes that the component is there even if it doesn't render anything.
Please consider that the view state does get restored and it's still a performance hit (but a smaller one as nothing get's sent over the wire and the output string/html doesn't need to be rendered).

JSTL tag management on RichFaces 3 re-rendering

I read various examples on the web where an ajax call sent through a4j tags of ReachFaces 3 re-renders a jstl tag. In this example:
http://relation.to/Bloggers/UsingDynamicallyCreatedRichFacesTabPanelForSearchResults
an ajax call re-renders a c:foreach inside a rich:tabPanel (look at the code after "Add the next code just after the panel code:").
My question is: since the c:forEach tag is evaluated during view creation (like any other jstl tag), the portion of the view pointed by the reRender attribute is reconstructed from scratch on every ajax request?
Thanks a lot.
Nico
Looking at JSF lifecycle docs, more specifically the Restore View Phase and Render Response Phase parts, you can find what are you looking for:
Restore View Phase
If the request for the page is an initial request, the JavaServer Faces implementation creates an empty view during this phase and the life cycle advances to the render response phase. The empty view will be populated when the page is processed during a postback.
If the request for the page is a postback, a view corresponding to this page already exists. During this phase, the JavaServer Faces implementation restores the view by using the state information saved on the client or the server.
Render Response Phase
During this phase, the JavaServer Faces implementation delegates authority for rendering the page to the JSP container if the application is using JSP pages. If this is an initial request, the components represented on the page will be added to the component tree as the JSP container executes the page. If this is not an initial request, the components are already added to the tree so they needn't be added again. In either case, the components will render themselves as the JSP container traverses the tags in the page.
In short words, when you perform an Ajax request, you already have the view there. JSF will just search the components you want to rerender through it, just after their model have been updated, and update the view with their new values. In case of c:forEach, it's not a component, but a tag handler, so it's evaluated before that.
Related to the link you posted, have a look at this page about the difference between components and tag handlers. They just have different lifecycles, so take care when mixing them.

Is it possible to have multiple actions for the action attribute of h:commandLink?

Is it possible to have multiple actions for the action attribute of h:commandLink tag? I want to perform two actions while clicking on the link rendered by h:commandLink tag. An action needs to be performed in a Spring bean, and a pop up window displaying a certain webpage.
No, it is not possible to call two methods in action attribute. And I don't think this is major disadvantage. Encapsulate logic in one method in managed bean, and call those to actions from that method.
No, it's not possible to have multiple actions in a commandLink action. If you want to perform some logic and to display a pop up window just wrap your logic in a single method, and at the bottom add a FacesMessage to the the context. You can do an AJAX partial refresh of the h:messages component to show the message as a "pop up" without reloading the page.

jsf - a4j action firing, but after page rendering logic fires

Using richfaces 3.1.5 with myfaces/jsf and notice when I invoke an a4j action, before it executes, the entire facelet it is on is getting rerendered - I'm remote debugging and when I click the a4j link, I first see my phaseListener get invoked (which makes sense), but then I also see all the logic in my bean getters that are in the facelet containing the a4j action link firing off, then finally the action executing and then its rerenders. The logic in some of the getters is expensive and so I do not want them to be getting invoked unnecessarily - I just want action click -> invoke action -> rerender zones, rather than this cycle of action click -> rerender entire page -> invoke action -> rerender zones that is happening now.
Don't know if it matters but my a4j action is not mapped to an actionListener but just an action which calls a String method returning null. Thanks for any help.
There is no guarantee getters will only be called once in JSF. You should move the expensive calls out of getters or do a check before invoking the logic in getters. In general, it's not recommended to put expensive logic in getters (in the context of JSF).

JSF - force UIInput components to refresh

I'm currently working on a JSF 1.2 project (IBM implementation and a "company layer").
PROBLEM
Here's the situation (numbers of items are just for the example), simple CRUD
List item
I have a list of items
I click on item 2 to see detail
I click on modify, the modification page displays values of item 2
Back to the list with a button "Back" and immediate="true" (because we don't want to submit the modifications)
Detail of item 4
Modify item 4 > Values of item 2 are displayed
BUT
if I set the "immediate" attribute of the "Back" button to false, values of item 4 are OK.
if I set the "disabled" attibute of an inputText component to true, value of item 4 is OK.
if I use <h:outputText value="#{item4.myValue}/> (UIOutput) instead of <h:inputText value="#{item4.myValue}/> (UIInput)
Also, I checked in debug mode that the bean I wanted to display was "item 4" and it was.
WHAT I FOUND
After some research on Google I found that this problem comes from the lifecycle of JSF, although the documentation and solutions found are for specific implementations of JSF.
So I guess it's because the value is populated with "localValue" instead of "submittedValue" (#see EditableValueHolder interface could help understanding), and there are some solutions from these pages
Apache wiki
IceFaces forum
RESULT
It doesn't work (I wouldn't be here, I swear ^^).
The "Refresh" solution is ineffective.
The "Erase input" is scary. I can't admit that I need to reference every input field! Plus I didn't find the setSubmittedValue() method on the UIInput in my IBM JSF.
The "Clear" method is ineffective. I tried on one element, and on the complete component tree with this code
public void cleanAllChildren(List<UIComponentBase> list){
for(UIComponentBase c : list){
this.cleanAllChildren(c.getChildren());
c.getChildren().clear();
}
}
But without success. So here I am.
Did I miss something? is there a nice tricky solution I didn't see? I'm not really familiar with the JSF lifecycle.
Put the bean with request scoped data in request scope, not in session scope.
You probably have the entire list in session to "save" DB calls and all the work to retain values in the subsequent requests inside the same session. You can use a separate session scoped bean for that, e.g. DataManager. Then you should have a request scoped bean to represent the selected item, e.g. DataItem. You can familarize the both beans with help of managed property injection.

Resources