What is the difference between partialSubmit and autoSubmit in JSF? - 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

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?

.NoSuchElementException on click of the submit button, working with SelctOneMenu in JSF1.2

I have a jsf page with few input components and two h:selectOneMenu components.
On selection of a value in the first drop down I'm calling a valuechange listener and submitting the form. Then I populate the value into the other drop down depending on the value selected from the first drop down. Now I enter other fields and click on the submit button.
It throws me the below mentioned exception.
My Backing bean is in Request scope. I hope it will work fine for me if I change it to session bean which is not right to do in my application. I'm populating the data to SelectItem variable from the "ValuechangeListener" method.
JSF version is 1.2, I can't upgrade it to 2.0 at this point.
RequestScope in this case is not enough. You need at least ViewScope.
This is because the Bean will get reset with every request. The listeners of your Bean will be called for another instance of that bean and will change that. After that you do some changes in the browser and the next time you send a request, your bean has already been destroyed. Thus everything you did in your listeners got lost and that's why you run into problems.
If you work with ajax, or stay on the same page and keep manipulating it, then you should switch to a higher scope.

JSF component value not properly updated to model upon submit

I have facelets page with a control that usually is disabled by default, i. e. when the page is first rendered to the client. This is determined by an EL expression:
disabled="#{referenceValue != requestbean.dependentControlValue}" id="notWorking"
After the page is rendered, the user can set the requestbean.dependentControlValue to referenceValue and via some Javascript for the dependent control, the component "notWorking" is enabled.
However, upon submitting the form the value for notWorking does not get updated as found out by adding a debug log message in the setter for the value. I can see, that the value for notWorking is set in the request when inspecting it with firefox.
Question:
What am I doing wrong?
By the way:
I know that according to HTML specification, disabled controls cannot be successful thanks to the research here on StackOverflow.
Moreover, I know from this post, that the disabled and rendered expressions are considered before updating the model values, but I think the disabled expression should evaluate to false upon submitting the form.
What am I doing wrong?
Using JavaScript instead of JSF to re-enable the input.
As part of JSF's builtin safeguard against tampered/hacked HTTP requests, the disabled attribute is (like rendered and readonly attributes) re-evaluated during processing the form submit. If they evaluate in such way that the value shouldn't be processed at all (i.e. disabled/readonly=true and rendered=false, then the submitted value won't be applied, converted, validated and the model won't be updated.
The solution would be to use JSF instead of JavaScript to re-enable the input, or to rewrite the condition in disabled attribute in such way so that the disabled attribute evaluates false during processing the form submit.

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?

Refreshing a component bind to request-scoped bean

Does anyone have a solution for such a problem:
In my app I'm using a complex, programmatically build dashboard based on the primefaces dashboard. To overcome problems with nonunique id's of the panels building the dashboard, I'm binding this component to a request-scoped bean. I'd also like to rebuild the dashboard based on some changable parameters after clicking a commandButton.
The problem is, that the getter for the dashboard is fired in the Apply Request Values phase, way before the actionListener of the commandButton is fired (in the Invoke Application phase). So, although the dashboard is rebuild eventually, it's not beeing refreshed in the rendered response.
On the other hand, if I try to set immediate attribute of the button to true, the actionListener is fired in the Apply Request Values phase, but still after the getter. Than the lifecycle goes directly to the Render Response phase, and the outcome is the same.
Anyone?
Thank you for the answer. Let me add a bit detail to my problem.
I store a model of a sports tournament as a property of a session scoped bean. It goes like this: the bean has a property "tournament". This class has a list of groups, each with it's table of matches. The idea was to use three different programmatically built components as renderers of this tournament model.
The dashboard would be used for drag-and-drop edition of contestant placement in groups. For viewing match tables and editing their matches I use a tab panel, with panel grid for every table. Finally, I use a panel grid to show a tournament tree. Every of those three components render some part of the model for the user to edit.
Since the model (and therefore those rendering components) are dynamically build depanding on chosable parameters like number of groups for example, i had a problem with id uniqnes when binding them to a session-scoped bean. So I bound them to a request scoped bean. With every request changing the model (mostly ajax) I wanted to rerender those components depending on the parameters set by the user (also stored in the session scoped bean).
The problem is, that when I rebuild the model in the invoke application phase (in a action listener fired by the "rebuild-my-model" button), the components bound to a request-scoped bean have already been "get-ed" from the bean (or so it seems), and they do not refresh on the page.
I would be very gratefull for a clue to what i'm doing wrong, and perhaps a suggestion, if the approach mentioned above is completelly stupid :)
The problem is, that the getter for the dashboard is fired in the Apply Request Values phase, way before the actionListener of the commandButton is fired
I'm not sure why exactly that forms a problem for you. Perhaps you're incorrectly doing business logic in the getter method instead of in the action listener method? Or perhaps you're manually creating the component instead of referencing the JSF-created one and thus always overridding the one in the JSF view?
A proper JSF getter method basically look like this:
public UIComponent getDashboard() {
return dashboard;
}
It should not contain any other line of code. The same applies to the setter method by the way. Any actions wherein you need to manipulate the component's children needs to be done in an action(listener) method, not in a getter/setter method.

Resources