SelectManyCheckbox onHide with remoteCommand - jsf

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.

Related

Update JSF components in sequence from bean

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)

How to make Bootsfaces datatable display a dialog box on row selection

Currently working on a project which uses Bootsfaces. I have a bootsfaces datatable in which i need to open a dialog box upon row selection. Please advice how to proceed.
Below is the code
<b:dataTable onclick="$('viewBKDDialog').show()"
update=":ViewBKDForm"
value="#{bookingAdminController.itemsBookDet}"
var="car" ajax="true" select="true" responsive="true" >
</b:dataTable>
and i m using
<ui:include src="ViewBookingDetails_all.xhtml"/>
as the dialog box.
Currently, I don't have the complete solution, but let's analyze your code. That's interesting enough.
First of all, you want to open a modal dialog based on the selected row. (Actually, the "modal dialog" bit is an educated guess). However, you added the onclick handler to the entire table. JSF doesn't make the rows explicit, so you have to add the onclick handler to the cells of the table. For the sake of simplicity, let's assume you've assigned the onclick handler to a button within the table.
Second, there's a bug in every BootsFaces version <= 0.9.1 that prevents you from detecting which row has been selected. So you have to use a version >= 0.9.2. At the time of writing, that's the developer snapshot BootsFaces-0.9.2-SNAPSHOT. See issue 369 on how to get it and issue 486 on the row-select bug I've recently solved.
Third, you should take in mind that the JavaScript code of the onclick handler is executed before the AJAX request. I can only guess, but I assume that you want to update the content of the modal dialog based on the row selection. I also assume that the content is defined by an AJAX request. If both assumptions are true, you've got a problem. The onclick handler is executed before the AJAX call. So I suggest you use the oncomplete JavaScript callback handler that's offered by some BootsFaces components, such as b:commandButton.
Like I've said before, that's not a complete solution, but I hope it helps nonetheless.

Unable to paste the context in Primefaces Extension pe:inputNumber using mouse

We've been using Primefaces (v 3.5) and Primefaces Extensions (v 0.7.0) in our project and it's been great, cheers for the developers and community!
The inputNumber component takes care of pretty much all of our needs when dealing with decimal fields.
The one thing that isn't working is when the user paste a value into the field using the mouse right button then paste option.
When that happens, it seems these values aren't processed, since when I submit the form they are cleared, no matter it's a valid or unvalid value.
The user can even paste a text into the pe:inputNumber. The control c + control v works as expected, no problem at all.
The code we are using is like this:
<pe:inputNumber id="AmtInTxt" value="#{myController.amtField}" symbol="$ "/>
Any ideas of how can we make the context menu paste works like the control c + control v?
Community Post
Was this ever solved? For future viewers - this looks like an issue with not posting the data to the bean when using the mouse. Try putting an ajax event handler in your input field.
<pe:inputNumber ...>
<p:ajax event="blur"/>
</pe:inputNumber>
I've encountered same problem. At first I thought it happens only when using browser's autocomplete feature. From this post I've learned that it is strictly connected with just changing value via mouse. I am using <p:ajax event="blur" process="#this" /> and it doesn't change anything. More specifically, the value is empty within the InputNumberRenderer.getConvertedValue method and since then it passes null value to setter/listener.
EDIT: Also tried putting onstart="$(event.target).keypress()" within the ajax to simulate user's keypress. Sadly doesn't work.

Using binding attribute causes javax.faces.FacesException: Cannot find component with identifier

I have a problem I can't quite get a handle on.
First the context: I am developing a web application using Primefaces 3.5 (yes, unfortunately I am stuck with this old version for now), running on JBoss 7.
There is a form with id "form" encompassing all following xhtml code.
I have a component in my view which is provided by usage of the binding attribute:
<p:dashboard id="dashboard" binding="#{myBackingBean.dashboard}" />
Then sometimes I would like to perform an ajax update on this component, this is done by using the RemoteCommand component of primefaces:
<p:remoteCommand
actionListener="#{myBackingBean.someActionListener()}"
process="#this" id="myRmtCmd" oncomplete="myJsFunction();"
update=":form:dashboard" name="myRemoteCommand" />
The RemoteCommand is triggered by a clicking on a Link:
Some Text
This works pretty well so far. However after deploying this code to production I sometimes get a FacesException:
javax.faces.FacesException: Cannot find component with identifier ":form:dashboard"
referenced from "form:myRmtCmd".
This is where my problem lies because I cannot reliably reproduce this exception. My question is this: What could lead to this exception being thrown? It seems to work 95 % of the time but being the perfectionist I am (and many of you reading this are as well, I'm sure ;) ) I would like this code to work 100 % of the time. What am I missing?
Before answering please consider these constraints:
yes, i have to use the binding attribute for providing the dashboard as I need a great deal of control over what gets added to the component
to avoid using IDs I also tried updating the dashboard by its css class via one of primefaces' advanced selectors: #(.ui-dashboard) - this also does not work!
yes, it would be possible to use a commandbutton/link instead of wiring up the remotecommand component to a simple html link but in this case the link is rendered by a JSF renderer component and I made some bad experiences with dynamically adding buttons etc (due to JSF Spec Issue 790)
Cheers,
p.s.
I also had this weird behavior.
There are probably more than one component bindded to #{myBackingBean.dashboard}, so the first one sets the id and there will be no one called "dashboard".

Request update of component with ajax from LazyDataModel.load?

I'm using PrimeFaces version 3.5.
I want to implement the message informing that the filter in the DataTable have return too many rows and only first 50 will be displayed.
I've tried to do it with both Messages and outputText. I set the text to display and request update:
RequestContext context = RequestContext.getCurrentInstance();
context.update("form:message");
context.update("form:text");
message = "Too many rows";
The components:
<p:message id="message" for="message"/>
<h:outputText id="text" value="#{userPicker.model.message}"/>
However, I don's see the proper update sections in partial-request response. Is it possible to request the update of components from within the LazyDataModel.load function (and if, what I'm doing wrong here)? If it is not possible (why?) how else can I force refresh of element from DataTable filtering?
The load method of LazyDataModel is invoked in render phase, when it's too late to add additional components to update.
However, it is possible to add JavaScript execution command:
context.execute("show_message()");
Where function show_message will display the message on client side, which enables to accomplish the task with single request.

Resources