onclick for p:outputLabel works on loading/refreshing page but doesn't work when clicking - jsf

I have some problems with calling a bean method when clicking on Label.
When page is loading or refreshing click handler function pokus() is called, but when the label is clicked it isn't.
Part of my web page:
<h:form id="pokus">
<p:outputLabel id="pokus2" value="klikni" onclick="#pozadavkyBean.pokus(5)}"/>
</h:form>
and a method in bean:
public void pokus(int i){
System.out.printf("kliknuto sloupec:%d",i);
}
I've also tried it with:
<p:ajax event="click" listener="....
with the same result - method called on loading/refreshing but not when clicking
also tried others events: mousedown, mouseup, .... with same result
using PrimeFaces 5.0

If you will check official document of Primeface regarding Tag outputLabel.You can easily get attribute onclick used for
Client side callback to execute when component is clicked.
But here you are trying to run Managed bean method directly from onclick attribute while onclick used to call JavaScript functions.
As #Mahendran Ayyarsamy Kandiar mentioned and its simple thing outputLabel is not used to call any bean method. Its Just Simply used to show something in the page.In mean time for your requirement you can use CommandButton,CommandLink or some other component but its all depend upon your requirment etc.

Related

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!

commandLink is not fired in a page with a param in its URI

When I call a method in a page with a param in its URI, the method is not invoked unless I pass the parameters of the uri again. For example if I have:
http://maywebsite/myapp/mypage.xhtml?mykey=myvalue
This method results in error (obviously because it renders the page again without params, but the method foo is never invoked):
<h:commandLink value="Do Action" actionListener="#{mybean.foo}"/>
So I added an ajax to only update the component, but the button is not getting fired:
<h:commandLink value="Do Action" actionListener="#{mybean.foo}">
<f:ajax render="somecomponent"/>
</h:commandLink>
When I passed the param values again, the button invokes the method just fine:
<h:commandLink value="Do Action" actionListener="#{mybean.foo}">
<f:param name="mykey" value="myvalue"/>
<f:ajax render="somecomponent"/>
</h:commandLink>
However, this button is included (ui:include) in many pages with different param keys and values. How can I invoke the method without passing the param values?
Im using glassfish 3.1.2, jsf 2.0
Apparently the bean is request scoped and the parameter plays a role in the way how the command link is rendered (e.g. by the rendered attribute on one of its parent components, or by a dynamic include of the template containing the command link).
All those conditions are namely re-evaluated during apply request values phase of the form submit. The developer has to make sure that all those conditions are exactly the same as when the form was presented to the enduser. So, when the bean is request scoped and the parameter is absent, then the command link appears as non-rendered in the component tree and this way its action won't be invoked.
Putting the bean in the view scope is the easiest way to fix this (unless you're using a dynamic <ui:include>, this is then more complicated, you'd need to turn off partial state saving for the particular view).
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated - point 5

have to press command button twice

I'm working on building a web page and notice now that I have to press the command button twice. Any command button has the same problem, so I figured I would add and action listener on one of them to see if I could see something.
<h:form id="formP">
<p:commandButton id="temp" value="photos" actionListener="#{viewBacking.debugBreakpoint()}" action="userPhoto" />
</h:form>
The backing bean has
public void debugBreakpoint() {
int i = 0;
i++;
}
Unfortunately, this does help. It hits my breakpoint only after the second press. I suspect that some field somewhere isn't passing validation but I would like some method of detecting what exactly is going wrong - why do I need the second push? Is there some option I can turn on in Glassfish, or something else where I can look at a dump of debug information? I can ignore the dump until everything is stable and then see what exactly is happening when I press the button for the first time.
Is there any such tool which I can use?
That can happen when a parent component of the given <h:form> has been rendered/updated by another command button/link with <f:ajax>. The given form will then lose its view state which it would only get back after submitting the form for the first time. Any subsequent submits will then work the usual way. This is caused by a bug in JSF JS API as descibred in JSF issue 790 which is fixed in the upcoming JSF 2.2.
You need to fix the another command button/link with <f:ajax> to explicitly include the client ID of the given <h:form> in the render.
<f:ajax render=":somePanel :formP" />
Another way is to replace this <f:ajax> by a PrimeFaces <p:commandLink> or <p:commandButton> so that you don't need to explicitly include the client ID of all the forms. PrimeFaces's own JS API has namely already incorporated this fix.
add event="onclick" in your p:commandbutton
I guess that will sort it out.
or you can add this ajax="false" property in your commandButton
<p:commandButton ajax="false" action="#{userController.create}" value="#{bundle.CreateUserSaveLink}"></p:commandButton>
I ran into the same issue. The solution was simple, instead of having both an actionListener and an action, just convert the actionListener method to return a string to where you want to navigate to and use it as the method for the action (and don't have an actionListener).
In simple terms: only use an action (do not use an actionListener on a commandButton that is submitting a form).
Please check your binding with bean.
bean fields should be String or non primitive.

p:commandButton does not fire action

Here is the problem: actionlistener does not want to be fired
#ManagedBean(name="hotelsController")
#SessionScoped
public class HotelsController implements Serializable {
public void requestHotelAvail(ActionEvent event) {
request = new Request(df.format(arrivalDate), df.format(departureDate));
}
}
and xhtml
<h:panelgroup id="rooms"/>
<h:form id="hotelSearch">
<p:commandButton actionListener="#{hotelsController.requestHotelAvail}" value="submit" update="rooms" />
</h:form>
I have tried everything I could search of changed #managedbean to #component set import to import javax.faces.event.ActionEvent;
But it still does not fire anything.
Form is in a p:accordion and when used with h:commandbutton it works fine
EDIT: sorry for mislead. rooms updates after click but actionListener is not fired. so rooms will not get any new data. Important code in requestHotelAvail needs to be fired before updating rooms and its not.
EDIT2: PrimeFaces 2.2.1 - I've read whole manual to primefaces but theres no explanation to this as I've done all that it states
I've tried using action instead of actionListener without ActionEvent but it never do anything. using <h:commandbutton action="#{hotelscontroller.requestHotelAvail}"/> works great but I want that ajax engine to refresh only that rooms panelgroup
UPDATE: Now it works. Form couldn't be in <p:accordion> but why and how to enable it there? Form now I'll work without it.
I suspect the different behavior from h:commandLink comes from ajax/non-ajax processing.
By default - if you don't use f:ajax - h:commandLink is non-ajax and entire page is rerendered. Primefaces p:commandLink is using ajax and you indicate rooms as component to be updated. In your case rooms is outside form so it should rather be addressed as :rooms (mind the colon) instead of just rooms.
update: have you tried ajax with h:commandLink? It would be:
<h:commandButton action="#{hotelscontroller.requestHotelAvail}" value="submit">
<f:ajax render=":rooms"/>
</h:commandButton>
Also I'm not that familiar with primefaces but maybe you can try to explicitly indicate the component to process with additional process="#this" - although I would assume this to be default as in basic library.
You try to inspect the response:
Open Chrome or Firefox -> Inspect Element -> Network and follow the ajax call.

Problem With JSF 1.1 and PopUp

I am trying to popup a window when someone clicks a button on the data table.
<h:commandButton
action="#{cacheController.popupDetails}"
immediate="false"
onclick="popup()"
value="View Details"
styleClass="submit">
</h:commandButton>
The associated popup function is
function popup() {
window.open('RDDetails.jsf','popupWindow', 'dependent=yes, menubar=no, toolbar=no, height=500, width=400');
}
Now in the new 'RDDetails.jsf" file, I am trying to access the same managedBean cacheController. But the problem is, the pop-up window and JSF lifecycle is not in sync. As a result, the popup first displays blank and when I refresh, it pulls out the proper data.
Is there anyway I can click on a button which will do some processing in the managed bean and then opens a pop up which rerieves the processed data from the managed bean.
I am using JSF 1.1.
You're here basically firing two independent requests: one associated with the form submit and other which opens the RDDetails.jsf in a popup. You'll need to combine this in one request. You can achieve this in basically two ways:
Get rid of the onclick and just add target="_blank" to the <h:form> so that it get submitted into a new window/tab.
Block the default action by adding return false; to the onclick and do the business logic in the constructor of the bean associated with RDDetails.jsf. The only (major) caveat is here that the model won't be updated with the form fields. Thus, you'll need to pass the form fields as request parameters of the popup URL manually with help of JavaScript. You can then make use of managed property entries in the faces-config.xml to inject the GET request parameters into the model.
First way is obviously the easiest, but this doesn't give you a "fullworthy" popup/modal dialog. The second way is a bit harder (unless you've already a good grasp on both JavaScript and JSF). I would then consider to look for a component library which provides a ready-to-use popup component.
See my example:
<h:commandLink action="#{controller.myAction}" onmousedown="document.forms['idform'].target='_blank';">
I'm using jsf 1.1

Resources