Maintaining RichFaces panelMenu state between requests - jsf

I'm attempting to use a RichFaces panelMenu as a navigation menu but have yet to figure out a way for it to maintain state between requests. Is there anyway to tell the panelMenu to render itself with certain groups expanded without using ajax?
I've attempted setting the value on the panelMenu and using selectedChild, all to no avail.

The state of the expanded sections is controlled by the rich:panelMenuGroup children, in particular their expanded attributes; these can be bound to server-side objects. You need to ensure their server-side state is updated somehow, though, either through setting the rich:panelMenu with the attribute expandMode="server" (which will cause a server-side submit) or by making it a child of whatever form is being submitted.

Related

best practice for communicating between two beans that back the same page

We are making the transition to bootstrap pages. As part of this, we are making most of our dialogs into simple include files that get rendered on demand. The include files have their own backing bean to minimize code duplication.
The typical use case is when a user enters a page a datatable shows a list of things. The user selects one or more rows in the table and then clicks a button to perform an action. The page is re-rendered using ajax. The datatable is not displayed but the former dialog is. The user then does whatever bulk operation the former dialog does and clicks execute (or cancel). The page is then re-rendered with the datatable showing and the former dialog box not.
The problem here is simple; how do you set the render flags on the datatable and former dialog box? Each of the beans needs to set the render flag of the other bean. I blithely tried injecting each bean into the other and promptly got a circular injection error at runtime. I've gone to having a callback interface that the datatable beans implement. When the former dialog bean gets injected, the datatable bean sets itself up to be called back. This works but I am not sure it's the best way to do it. Being an old swing programmer, I considered using property change listeners, which are much more robust than the simple interface, but I'm not sure what the implications of using them in a managed bean environment are. I did check out the messaging API but it clearly doesn't apply to this case.
So, what's the best way for two view beans that are backing the same page to talk to each other?

A few questions reagarding UI components state and phases

Having gone through these excellent posts:
Why JSF saves the state of UI components on server?
Why does JSF save component tree state?
and midway the JavaEE6 tutorial I still have the following questions:
When I am developing a custom UI component whose values (styleClass, value, etc) are either defined statically(in the xhtml) or set via a bean, do I need to explicitly save/restore state in the extended component as well?
Is it correct to say that the scope of the UI components is view scoped?
How is the view identified behaviour? (If I navigate away from a view, the view gets rebuild the next time around. But if I open another tab, it is restored - at least the bean!)
When I am executing an Ajax call, I would expect that 'execute' part of the UI component would be restored&processed and the 'rendered' part would be restored&updated. After running into some problems with UI:repeat, it is not clear to which extend the component tree is to be restored and if is possible to partially edit.
As an example (I am not sure that it works like this): I define a UI:repeat that iterates over some values and creates some Ajax commandlinks. Whenever I call the command, it will restore the whole ui:repeat regardless of the Ajax scope (execute/render) that I have defined. So it will re-render the whole ui:repeat. Furthermore, I don't understand how it could ever -not- restore the ui:repeat as due to being a namingcontainer it will edit the id of my newly added component.
How can I define a build-time component (vs render-time) and why would I want to do this? (It seems that build time components are troublesome when mixed with rendertime, so why have both)
Thanks
When I am developing a custom UI component whose values (styleClass, value, etc) are either defined statically(in the xhtml) or set via a bean, do I need to explicitly save/restore state in the extended component as well?
Yes. You normally use StateHelper for this.
See also:
How to save state when extending UIComponentBase
JSF custom component: support for arguments of custom types, the attribute setter is never invoked
Adding Custom Attributes to Primefaces Autocomplete Component in JSF
Is it correct to say that the scope of the UI components is view scoped?
Absolutely not. UI component instances are request scoped. Only anything which is stored via StateHelper is in essence view scoped (and restored into newly created component instances during "restore view" phase).
See also:
JSF composite component - weird behavior when trying to save state
Backing bean in composite component is recreated on every request
How is the view identified behaviour? (If I navigate away from a view, the view gets rebuild the next time around. But if I open another tab, it is restored - at least the bean!)
It's likely requested from browser cache. Try submitting a form therein. The chance is big that you get a ViewExpiredException. You need to tell the browser to not cache dynamic pages. Putting a breakpoint on bean's constructor would also confirm that it's never been invoked.
See also:
Avoid back button on JSF web application
Is JSF 2.0 View Scope back-button safe?
javax.faces.application.ViewExpiredException: View could not be restored
When I am executing an Ajax call, I would expect that 'execute' part of the UI component would be restored&processed and the 'rendered' part would be restored&updated.
This is not true as to restore part. The "whole" view state is restored. Note that the view state does since JSF 2.0 not necessarily represent the entire component tree. You've found the explanation/answer to that already in the two links mentioned in your question.
How can I define a build-time component (vs render-time) and why would I want to do this? (It seems that build time components are troublesome when mixed with rendertime, so why have both)
This is called a "tag handler". I.e. just extend from TagHandler instead of UIComponent and implement according its contract. Tag handlers are useful if the sole goal is to build the view (the JSF component tree). They do not appear in the JSF component tree. As to when to create a custom component or a custom tag handler, check the "components" and "taghandlers" sections of OmniFaces showcase, it may give some new insights as to real world use cases of those things.
See also:
Custom Facelet component in JSF
JSTL in JSF2 Facelets... makes sense?

How to handle multiple submits before response is rendered?

It has been reported from testing that it is occasionally possible to press a button more than once if the response is not rendered fast enough, causing several invocations of the back-end code, which we do not want.
Application is Java EE 6 Web Profile using JSF 2.0 inside Glassfish 3.1.1.
I was wondering how this should be properly dealt with, and have thought of a few scenarios:
Submitting should disable all buttons using javascript while response is being rendered.
A flag in the Session scope saying it is already active, so the sensitive code is skipped and just moves on to the re-rendering of the response for the previous submit.
A synchronized block delaying the processing until the previous request have finished. Then it should be detected that it has been already processed and skipped.
Using one of the "new" scopes like conversion to handle the detection?
My immediate gut feeling is that the best approach is to have sensitive code blocks atomic, but then the problem is with rendering the correct response.
How should I approach this?
Submitting should disable all buttons using javascript while response is being rendered.
This is the easiest to implement in a generic manner. If you happen to use <f:ajax> exclusively, you could use the jsf.ajax.addOnEvent() to perform the job in a generic manner. An alternative JavaScript approach is to create kind of an "Loading" overlay which blocks the UI so that the enduser won't be able to interact with the underlying page anymore. This is basically an absolutely positioned hidden <div> which spans the entire viewport with some opacity (transparency). You could show it on submit and hide it on render. The keyword for this technique is "modal dialog". UI-oriented JSF component libraries have at least such a component already in their assortiment. E.g. PrimeFaces with a <p:dialog modal="true"> inside a <p:ajaxStatus>, or the <p:blockUI>
The only disadvantage is that it won't work if the client has JS disabled or don't use it and it thus won't prevent HTTP clients from double submits.
A flag in the Session scope saying it is already active, so the sensitive code is skipped and just moves on to the re-rendering of the response for the previous submit.
This is more known as "synchronizer token pattern" and has ever been requested for JSF by spec issue 559 which is currently on the ticket targeted for 2.2, but there doesn't seem to be any activity on it. The detection and blocking part is technically easy to implement, but the synchronous response handling part is not easy to implement if you want that the enduser ultimately retrieves the response as generated by the initial request. The asynchronous response handling is easy: just don't specify any components to update, i.e. empty the collection as returned by PartialViewContext#getRenderIds(). After all, this is more robust than using JS to disable the buttons or block the UI.
As far as I know, Seam 2 was the only who offered a reuseable JSF component for this, the <s:token>. I must however admit that this is an interesting idea for a new OmniFaces component. Maybe I will personally take a look at it.
A synchronized block delaying the processing until the previous request have finished. Then it should be detected that it has been already processed and skipped.
This is not easy to implement generically, this would require a change in all action methods to check if the job is already done. It also won't work if the webapp runs on multiple servers. A synchronizer token is easier as it would be performed before the action methods are invoked. A synchronizer token is also less expensive as you don't end up with multiple requests in the queue which would only cost threads/resources.
Using one of the "new" scopes like conversion to handle the detection?
This problem cannot be solved by playing around with managed bean scopes. Managed bean scopes serve a different purpose: the lifetime of the bean instance.
As Adrian mentioned, I would also use BlockUI. There is a BlockUI component from Primefaces. When you submit your forms through ajax, you could also use an overlay during the request. See Primefaces`s Ajax Status for an example.

What is the difference between partialSubmit and autoSubmit in JSF?

I guess I knew the difference, but right now I find myself confused. :P
Both of them seem to be do the same thing, except that partialSubmit is used on submit buttons to submit the form using AJAX and autoSubmit is used on editable components, which submits only its own contents. Am I right in saying this?
The accepted answer isn't 100% correct for ADF. The partialTriggers attribute is involved in the lifecycle.
From Enabling Partial Page Rendering Declaratively
The autoSubmit attribute on an input component and the partialSubmit
attribute on a command component are not the same thing. When
partialSubmit is set to true, then only the components that have
values for their partialTriggers attribute will be processed through
the lifecycle. The autoSubmit attribute is used by input and select
components to tell the framework to automatically do a form submit
whenever the value changes. However, when a form is submitted and the
autoSubmit attribute is set to true, a valueChangeEvent event is
invoked, and the lifecycle runs only on the components marked as root
components for that event, and their children. For more information,
see Section 4.4, "Using the Optimized Lifecycle".
They are both AJAX enabled calls occurring from custom properties of custom JSF components. The autoSubmit essentially asynchronously postsback content specific to the component for keeping the server side managed bean values current with the content within the component on the client side.
A partialSubmit is another asynchronous AJAX call that will serve to immediately postback a component value on some kind of component event, like losing focus on an ICEFaces inputText component for example.
The interesting thing to note is that the entire ViewState is posted back on each type of asynchronous submit, so if the values of other components HAD changed on the page before the submit, the bound server side managed bean properties will have their values refreshed as well, even though the client side components MAY not be refreshed to reflect any server side data changes that may have occurred.
In fact, the entire JSF server side lifecycle occurs on each postback, read the following article on implementing a debug PhaseListener that allows you to see what Phases are occurring after each asynchronous submit operation occurs.
http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html

JSF Page Navigation

I want to enable or disable component based on navigation rule. For example, I want to enable a component when I traverse from a particular page otherwise it should be in disabled state.
Probably the easiest way if you're using JSF 2.0, is to put a parameter in your navigation rule. If you use an f:viewParam on the target page that you bind to some bean, you can just check whether the property to which you bound the view parameter is empty or not.
If your navigation rule does not cause a redirect, you can also put some marker in request scope. The initial rendering of the target page will happen within the same request and easily pick this up. In that case, you do have to store it in some appropriate place (e.g. view scope in JSF 2) to retain the info on postbacks.

Resources