ActionListener phases in JSF - jsf

HI,
I have a doubt on calling the ActionListener method in the JSF beans. For example every request or submission of JSF form is gone through the life cycle of six phases. But, when we are triggering the particular event like action listener or value change listener, is there any lifecycle associated with that request?
Please clarify me.

Any action listener is invoked during invoke action phase, before the real action method. Which action listener methods are to be invoked are determined based on the actionListener attribute of the UICommand component which is associated with the submit.
Any value change listener is invoked during validations phase (or apply request values phase when immediate="true" for the particular UIInput component) after a succesful conversion/validation of the submitted value and only when the submitted value differs from the initial value. Which value change listener methods are to be invoked are determined based on the valueChangeListener attribute of the UIInput components which are associated with the submit.
And no, they do not have their own lifecycle. When they finish executing and return, it's still inside the same phase of the lifecycle. After invoking the valueChangeListener, JSF will continue with conversion/validation of the next UIInput component, or if there are none, then proceed to the next phase. After invoking the actionListener, JSF will continue with the next actionListener or if there are none, invoke the real action method.
Update: after reading your comments again, I think that I now see your doubt about particularly the value change listener. You seem to think that it by default immediately fires a brand new request to the server side during the client side change event. It does that not by default. You can only achieve this by adding a little piece of JavaScript code which submits the entire HTML form during the change event of the HTML input field.
onchange="this.form.submit()"
This part has nothing to do with JSF. It's a simple HTML attribute. Open the page in webbrowser, rightclick and choose View Source. You'll see that it's there. Disable JavaScript in your browser or remove it in JSF code and you'll see that it won't work anymore. You would need to press the submit button yourself to get it all to run.

Related

Show dialog after successful operation in jsf?

I am adding some value to database in jsf. I have a manage bean for this purpose. Now when insertion is successful then I want to show a success alert dialog. please tell me how to do it?
I would suggest to add a dialog component in your page (the same page that calls your bean to insert a value into the DB for instance)
p:dialog id="dialog" widgetVar="widgetVarOfDialog"
Then let assume that you have either a commandButton or a commandLink (you don't provide enough information in your first post) that triggers the insert action in your bean. Just add an oncomplete callback:
p:commandButton action="#{bean.insertValue}" oncomplete="PF('widgetVarOfDialog').show()"
You could also display a p:dialog right from your bean method by using:
RequestContext context = RequestContext.getCurrentInstance();
context.execute("PF('widgetVarOfDialog').show()");

Execution order of events when pressing PrimeFaces p:commandButton

I am trying to execute a JSF2 bean method and show a dialog box after completion of the method on click of PrimeFaces <p:commandButton>.
<p:commandButton id="viewButton" value="View"
actionlistener="#{userBean.setResultsForSelectedRow}" ajax="false"
update=":selectedRowValues"
oncomplete="PF('selectedRowValuesDlg').show()">
</p:commandButton>
<p:dialog id="selectedRowValues" widgetVar="selectedRowValuesDlg" dynamic="true">
<h:outputText value="#{userBean.selectedGroupName}" />
</p:dialog>
When I click on the command button, the bean action listener method setResultsForSelectedRow executes properly, but it does not show the dialog box when the method completes. If I remove actionlistener, it shows the dialog box. I do not know what is going wrong.
What is the execution order of events? Is it possible to execute actionlistener and oncomplete simultaneously?
It failed because you used ajax="false". This fires a full synchronous request which in turn causes a full page reload, causing the oncomplete to be never fired (note that all other ajax-related attributes like process, onstart, onsuccess, onerror and update are also never fired).
That it worked when you removed actionListener is also impossible. It should have failed the same way. Perhaps you also removed ajax="false" along it without actually understanding what you were doing. Removing ajax="false" should indeed achieve the desired requirement.
Also is it possible to execute actionlistener and oncomplete simultaneously?
No. The script can only be fired before or after the action listener. You can use onclick to fire the script at the moment of the click. You can use onstart to fire the script at the moment the ajax request is about to be sent. But they will never exactly simultaneously be fired. The sequence is as follows:
User clicks button in client
onclick JavaScript code is executed
JavaScript prepares ajax request based on process and current HTML DOM tree
onstart JavaScript code is executed
JavaScript sends ajax request from client to server
JSF retrieves ajax request
JSF processes the request lifecycle on JSF component tree based on process
actionListener JSF backing bean method is executed
action JSF backing bean method is executed
JSF prepares ajax response based on update and current JSF component tree
JSF sends ajax response from server to client
JavaScript retrieves ajax response
if HTTP response status is 200, onsuccess JavaScript code is executed
else if HTTP response status is 500, onerror JavaScript code is executed
JavaScript performs update based on ajax response and current HTML DOM tree
oncomplete JavaScript code is executed
Note that the update is performed after actionListener, so if you were using onclick or onstart to show the dialog, then it may still show old content instead of updated content, which is poor for user experience. You'd then better use oncomplete instead to show the dialog. Also note that you'd better use action instead of actionListener when you intend to execute a business action.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
Differences between action and actionListener
I just love getting information like BalusC gives here - and he is kind enough to help SO many people with such GOOD information that I regard his words as gospel, but I was not able to use that order of events to solve this same kind of timing issue in my project. Since BalusC put a great general reference here that I even bookmarked, I thought I would donate my solution for some advanced timing issues in the same place since it does solve the original poster's timing issues as well. I hope this code helps someone:
<p:pickList id="formPickList"
value="#{mediaDetail.availableMedia}"
converter="MediaPicklistConverter"
widgetVar="formsPicklistWidget"
var="mediaFiles"
itemLabel="#{mediaFiles.mediaTitle}"
itemValue="#{mediaFiles}" >
<f:facet name="sourceCaption">Available Media</f:facet>
<f:facet name="targetCaption">Chosen Media</f:facet>
</p:pickList>
<p:commandButton id="viewStream_btn"
value="Stream chosen media"
icon="fa fa-download"
ajax="true"
action="#{mediaDetail.prepareStreams}"
update=":streamDialogPanel"
oncomplete="PF('streamingDialog').show()"
styleClass="ui-priority-primary"
style="margin-top:5px" >
<p:ajax process="formPickList" />
</p:commandButton>
The dialog is at the top of the XHTML outside this form and it has a form of its own embedded in the dialog along with a datatable which holds additional commands for streaming the media that all needed to be primed and ready to go when the dialog is presented. You can use this same technique to do things like download customized documents that need to be prepared before they are streamed to the user's computer via fileDownload buttons in the dialog box as well.
As I said, this is a more complicated example, but it hits all the high points of your problem and mine. When the command button is clicked, the result is to first insure the backing bean is updated with the results of the pickList, then tell the backing bean to prepare streams for the user based on their selections in the pick list, then update the controls in the dynamic dialog with an update, then show the dialog box ready for the user to start streaming their content.
The trick to it was to use BalusC's order of events for the main commandButton and then to add the <p:ajax process="formPickList" /> bit to ensure it was executed first - because nothing happens correctly unless the pickList updated the backing bean first (something that was not happening for me before I added it). So, yea, that commandButton rocks because you can affect previous, pending and current components as well as the backing beans - but the timing to interrelate all of them is not easy to get a handle on sometimes.
Happy coding!

f:ajax listener not executed because of rendered="false"?

I have a commandLink which has a "rendered" which is calculated based on values in a #RequestScoped bean. The commandLink uses f:ajax to call a listener but it appears that the method is never executed.
It turns out if I set rendered="#{true}" or no rendered attribute at all, the listener is executed properly. Is it possible that because the rendered is based on request scoped values which no longer exist at the time of the ajax postback (and hence result in a 'false'), that the listener is being skipped? Note that the f:ajax also performs a few execute actions which are performed successfully.
You should never use a request scoped bean to define the value of a rendered attribute of any UI component. Unless you take special care, the original bean is destroyed losing its values, a new one is created instead with each request. Thus the component will be hidden as the rendered attribute value is most probably not evaluated to true for the next request.
You should use the view scope instead for your bean. See an example here, but you should easily find other examples searching for something like 'jsf rendered attribute request scope bean'.

JSF: Unwanted page refresh on action call

Sometimes, if I click a commandButton that calls an action method, it will just do a page refresh without actually calling the method!
I set a breakpoint in that method and if this behavior takes place, the method is not called. What is also strange about it: It also does that if I didn't fill values in input components that have "required=true". I would expect that a valdiation error appears. The error appears only if the action method would be called fine. But not if it will just issue that strange page refresh.
The call looks pretty normal and works in most cases:
<h:commandButton value="Do something"
action="#{bean.doSomething(someBean.value)}" />
I can't exactly figure out when this behavior appears (and when not), but it should have something to do with the values chosen in some of the other components. But... how?
(I have two forms in a xhtml file. I just mention that because I don't know if it is important or not. However, there are no nested forms and h:messages displays nothing after page refresh.)
I'm using JSF 2 (MyFaces) + Tomahawk.
there are no nested forms and h:messages displays nothing after page refresh
You've likely a rendered attribute on the component or one of its parents which evaluated false during the processing of the form submit request. You need to ensure that it evaluates the same as it did during displaying the page. You can do this by putting the bean responsible for this in the view scope instead of the request scope.
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated

Doubt on immediate attribute for command button

HI,
I have a doubt on setting the immediate attribute for the command button. I would like to know what will be the changes in the life cycle?
I have read that setting immediate attribute will call the action listener or action methods in the apply request values phase. My doubts is it only the difference of preponding the phase. Also it will execute the all the business logic in the action methods regardless of setting the immediate attribute.
Please clarify my doubts.
If immediate="true" is set in an UICommand component, then the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s) in the same UIForm. Use this to skip the entire processing of the form. E.g. "Cancel" or "Back" button.
If immediate="true" is set in both UIInput and UICommand components in the same UIForm, then the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s) in the same form which does not have this attribute set. Use this to skip the processing of the entire form expect for certain fields (with immediate). E.g. "Password forgotten" button in a login form with a required but non-immediate password field.
See also
Debug JSF lifecycle

Resources