Update JSF components in sequence from bean - jsf

I have the need to execute three actions one another from my backing bean but the second and third ones seems to be fired before the first one finish executing.
The result is that the second/third action is called but not executed.
How do I manage to execute the first action, wait until if finishes and than start the second/third action?
Actions are
Close a modal dialog window. This take up to a second to execute the rendering.
RequestContext.getCurrentInstance().execute("PF('dlgConfirmApplicationDelete').hide();");
Update a panel h:panelGroup component
RequestContext.getCurrentInstance().update("j_idt3:panelGroupHolder");
Update a second panel h:panelGroup component
RequestContext.getCurrentInstance().update("j_idt3:center_westBody");

I need to perform an action in the database and depending on the
result I need to close the window and right after update the other two
panelGroups with the updated information
You could do this without calling actions from java code.
Without knowing your exact layout, the task you are asking for would usually look like this:
<p:commandLink
process="#form"
actionListener="#{bean1.updateDatabase}"
update="j_idt3:panelGroupHolde;j_idt3:center_westBody"
oncomplete="if (args.updateSuccessfull) PF('dlgConfirmApplicationDelete').hide();">
and inside your bean1.updateDatabase method, you specify args.updateSuccessfull depending on the actual result of the query.
Boolean updateSuccessfull = false;
RequestContext.getCurrentInstance().addCallbackParam("updateSuccessfull", updateSuccessfull);
In the example you mentioned the order is not important, as each action will have it's predetermined outcome and is dedicated to a certain phase in the life-cycle (update always comes before oncomplete):
If the update-query fails, data does not change, so the update= has no impact and the dialog stays visible due to the CallBack-Param.
If the update-query works, data does change, both ui-elements are updated (where order must not matter) and the dialog is hidden due to the CallBack-Param.
If this is not the case, then you have code inside the RenderResponse-Phase, which should rather be executed in the InvokeApplication-Phase (or earlier).
A common misstake causing the later is to call "methods containing heavy code" from the xhtml (while other listings ("second update") depend on that values as well), like
<ui:repeat values="#{bean1.queryDatabaseForXY()}" ...>
Obviously now the SECOND update needs to come after the first update, cause it also requires some data from bean1.queryDatabaseForXY().
Rather than that you should perform data loading and/or calculations in the proper phase and simply refer to a getter returning an already known collection when generating the response:
<ui:repeat values="#{bean1.getUsers()}" ...>
or more precicesly
<ui:repeat values="#{bean1.users}" ...>
(The actual loading would be either #PostConstruct, an <f:viewAction> or just the already existing list inside a view- or session-scoped bean)

Related

dealing with popups in JSF

is there a one-size-fits-all way to deal with popups in JSF2 (I use richfaces)?
I put together a list of requirements, I came across.
I tried a lot to overcome some of the addressed flaws, but there may exist a more complete and sophisticated example or best-practice to implement a popup in JSF.
the requirement list:
(I) the popups shall be attachted to for example a commandButton inside a dynamic list of items (a datatable or rich:tree); the item must be later be identifiable inside popup logic
(II) some logic (initialization) must be executed when popup opens
(IIIa) some logic when popup is dismissed (using a commandButton inside the popup). (IIIb) a callback action (of the calling backing bean) shall be called. (IIIc) result value should be passed to caller.
(IV) parameters need to be passed from caller to popup
(V) Can I have a (reusable) managed bean that encapsulates the popup logic? How to reference this bean from other beans? Which scope should I use?
(VI) can i avoid, that popup exists physically in DOM tree before it is shown - preventing it from being rendered/evaluated all the time
I am looking forward to your input/ideas.
regards

SelectManyCheckbox onHide with remoteCommand

I ran into a very interesting issue. Here is my scenario:
My Goal
Use a SelectManyCheckbox with a nested tooltip.
Use SelectManyCheckbox onHide event to fire an Ajax (ActionListener) call
and update the
SelectManyCheckbox label and nested tooltip text.
My Approach
Use a remoteCommand and tie it to the SelectManyCheckbox onHide event
XHTML
<p:selectCheckboxMenu id="sourceFilter"
onHide="sourceFilterCommand();"
value="#{viewRevenueBean.sourceSelectManyMenu.selectedValues}"
label="#{viewRevenueBean.sourceSelectManyMenu.label}"
filter="true" filterMatchMode="contains"
validator="#{viewRevenueBean.sourceSelectManyMenu.validate}"
widgetVar="srcFilterDropDown">
<f:selectItems id="sourceItems"
value="#{viewRevenueBean.sourceSelectManyMenu.availableItems}"
var="source" itemLabel="#{source.label}" itemValue="#{source.value}" />
<f:convertNumber type="number" />
<p:tooltip id="srcToolTip"
for="sourceFilter"
value="#{viewRevenueBean.sourceSelectManyMenu.tooltipText}"
showEffect="fade"
hideEffect="fade"/>
<p:remoteCommand name="sourceFilterCommand" update="sourceFilter"
actionListener=#{viewRevenueBean.sourceSelectManyMenu.defaultEventHandler}"/>
</p:selectCheckboxMenu>
My Results
Ajax (Action Listener) gets fired and SelectManyCheckbox label and nested tooltip are updated (expected behavior).
In Firebug, I noticed that each onHide event Ajax call is multiplying the preceding number of server side requests by two (unexpected behavior).
e.g
1st onHide event = 1 Request
2nd onHide event = 2 Requests
3rd onHide event = 4 Requests
4th onHide event = 8 Requests
5th onHide event = 16 Requests
etc.....
This is obviously not desired and leads to a big slow down after just
a couple onHide events.
Experiments I tried
I created a p:command button which accomplished the desired Ajax call and correct element updates (without the multiplied request
issue) . I then proceeded to steal it's Ajax JavaScript call via
Firebug and placed it in my own JavaScript function, which I then
used as my onHide callback. Again, I experience the same unwanted
result, the label and tooltip are updated, but the requests start to
multiply.
I tried placing the remoteCommand in different locations
(outside the menu, inside it's own form etc). It doesn't make a
difference. The problem is still encountered.
I tried simplifying the SelectManyCheckbox scenario (remove
tooltip, coverter, tweak various attributes etc) to eliminate other
possibilities. No difference.
I tried a p:ajax instead of p:remoteCommand using onchange.
The Ajax requests work fine but obviously it's not what I am after.
I need to trigger it onHide.
Instead of a SelectCheckboxMenu , i tried using a
SelectManyCheckbox (no label) with onchange and keeping everything
else the same. The remoteCommand works fine, the Ajax call gets
called once and everything is nice and dandy. [/list] [list] * I
tried the PrimeFaces 3.5-SNAPSHOT as well. No difference. Issue is
still manifested.
Haven't found any clues on the forum or the net thus far in regards
to this issue. Does this sound like a bug or programmer clumsiness
:roll: ? Of course any insight and/or suggestions are highly
appreciated.
I have run into similar problems when using p:remoteCommand. I can't say for sure that the root cause is the same in your case, but maybe this can help somewhat.
In my case the problem was caused by multiplied registering of jquery bindings; the p:remoteCommand seem not to use $(somesource).off("some_event").on("some_event", some_function). That means - as far as I have understood - that if you update the component containing the p:remoteCommand, it's action will be registered over and over again, each time it's being updated. That in turn will mean that if you call on the name of the p:remoteCommand, it will fire the same amount of times as it's been registered.
You said you'd tried to move it outside and still got the same problem, so maybe it's not this problem after all. In my case I tested this assumption using a p:commandLink instead and had that call the backing bean. The goal for me was to make sure that any previous registration of a binding was removed, so through registering the binding like mentioned above:
$(somesource).off("some_event").on("some_event", some_function), and let some_function click the link, you can at least check if it solves the problem.

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.

JSF page navigation failing with NullPointerException

I wrote two pages...one a form where data submitted and second just to confirm the transaction actually carried out some calculation.
I have a managed bean i.e. FormDataBean and a class Reservation.java from which i instantiate for each booking made. Now I have at the end of a form a submit button:
<h:commandButton value="Submit" action="confirmation"/>
in the bean I have setters and getters as usual. in a method i defined I create an instance of Reservation, then set the beans variables to the instance variabels, like
reservation.startDate = startDate;
reservation.endDate = endDate;
reservation.checkRange();
The last method, i.e. checkRange() will use the assigned values to instance variables to carry calculation. it should return a string successful or failure.
Now when I enter data in the form, and press submit, it just refreshes the page but nothing is submitted. because it doesn't go to next page :(
Any idea what is happening? I don't need to define a navigation rule, because in other project, I carry out simple calculation and display result in next page and it worsks! Please advice
Thanks,
Your are missing to tell us some of the more important details so the answer is a kind of guesswork.
As you don't use navigation rules I assume you are using JSF 2, aren't you?
With JSF 2 you can directly set the new navigation target, without navigation rules. A forward to "confirmation" should work if your outcome file is named confirmation.xhtml. Check that. With a navigation rule you could forward it do a different file.
This part should work regardless of the rest.
For the bean not getting any values make sure that you are using the correct scope either through annotation or entry in your faces-config.xml. As you have a quite unusal validation mechanism you probably have to use the session scope.
The correct way would be using an actionlistener that does your checks and then sets the navigation depending on your checks. The bean scope could be more restrictive then.
Did you try action="confirmation?faces-redirect=true"?

JSF Problem with selectInputDate overriding a set value

I have a problem with selectInputDate:
I have a backing bean which I am binding to the selectInputDate. I have a menu which, when the menu changes, I set the date to now to the same property the selectInputDate is bound to.
For some reason, the date changes correctly, but the selectInputDate then calls a set and overrides the value with the old value...
Any idea why selectInputDate would call the setter?
<ice:selectInputDate popupDateFormat="dd-MMM-yyyy" renderAsPopup="true" value="#{dateContoller.date}"/>
<ice:selectOneMenu value="#{dateContoller.dateRange}" valueChangeListener="#{dateRangeDateContoller.dateRangeChanged}" >
....
</ice:selectOneMenu>
(dateRangeChanged sets the current date to now)
The valueChangeListener is intend to run some code logic whenever the newly submitted value differs from the original value. But you're apparently actually not interested in the change of the value, you're actually interested in resetting the submitted value.
Just get rid of the valueChangeListener and do your thing in the bean's action method.
If that is not an option for some reason, then you need to elaborate more about the problem for which you thought that using a valueChangeListener is the right solution. There may be workarounds to keep the valueChangeListener anyway, such as calling FacesContext#renderResponse(), so that JSF won't run the update model values (and invoke action!) phases anymore, or using ValueChangeEvent#queue() to let it re-execute itself during invoke action phase.
To learn a bit more about the JSF lifecycle and when/why/how the one and other get called/invoked, you may find this practical article useful.

Resources