This question already has an answer here:
How to call JSF backing bean method only when onclick/oncomplete/on... event occurs and not on page load
(1 answer)
Closed 5 years ago.
<h:outputLink value="/4JVA-157292-war/supinfo/auth/mycar.xhtml">Car</h:outputLink>
<h:outputLink value="Log Out" onclick="${loginController.logout()}" />
As you see, If i click the Car link. I will excute the ${loginController.logout()}, but if i delete the Log out. I will go into the car page.
<h:ouputLink> component is used to render plain a anchor element with its href attribute evaluated as value attribute of <h:outputLink> with the query parameters attached in case the component has <f:param> tags as its children.
<h:ouputLink> is not used to execute server-side actions as you wrongly seemed to expect. You may have confused it with a <h:commandLink> component that is used to trigger a server-side action via a JavaScript call.
If you want to call the action method you must switch to a command comnponent (or its derivative) like <h:commandLink>. Its action attribute should point to the desired action method, like so:
<h:commandLink value="Log out" action="#{loginController.logout}" />
In this way you will be able to execute the bean action method.
Also it is worth noting that since JSF 2.0 there has been an <h:link> component that is useful for handling application-wide navigation. It takes a navigation case outcome in its outcome attribute thus leaving <h:outputLink> component useful for links to external resources.
For more information on the subject read the following answer: When should I use h:outputLink instead of h:commandLink?.
As to the cause of the problem you faced, onclick attribute is rendered as onclick event handler of the generated a element that responds to a click event on the HTML element it is attached to. In case the event is fired a client-side JavaScript code is called (by function call onclick points to or by executing inline code that is contained therein). Do note that onclick runs on the client (in JavaScript context within web browser) while action runs on the server (executes Java code depending on the submit button pressed within web server).
Usage of onclick may be fruitful at least in the following circumstances:
in case it is used in conjunction with a command component it may stop form submission to the server if some client-side requirements are not met (i.e. confirm dialog was shown and cancel button was pressed, or client-side validation failed) as soon as the event will be fired before any consecutive events associated with the element (like form submission):
<h:commandLink value="Delete item" action="#{bean.delete(item)}" onclick="return confirm("Are you sure you want to delete this item?");" ... />
or
<h:commandLink value="Submit data" action="#{bean.action}" onclick="return inputValid();" ... />
with
<script type="text/javascript">
function inputValid() {
var isInputValid = ...;
//decide what's valid or not and set variable to true/false accordingly
return isInputValid;
}
</script>
it may be used to trigger some GUI changes, especially when used in conjunction with non-command components, like in:
<h:button value="Show dialog" onclick="showDialog(); return false;" ... />
Related
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.
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!
In JSF 2, what is the difference between h:button and h:commandButton ?
<h:button>
The <h:button> generates a HTML <input type="button">. The generated element uses JavaScript to navigate to the page given by the attribute outcome, using a HTTP GET request.
E.g.
<h:button value="GET button" outcome="otherpage" />
will generate
<input type="button" onclick="window.location.href='/contextpath/otherpage.xhtml'; return false;" value="GET button" />
Even though this ends up in a (bookmarkable) URL change in the browser address bar, this is not SEO-friendly. Searchbots won't follow the URL in the onclick. You'd better use a <h:outputLink> or <h:link> if SEO is important on the given URL. You could if necessary throw in some CSS on the generated HTML <a> element to make it to look like a button.
Do note that while you can put an EL expression referring a method in outcome attribute as below,
<h:button value="GET button" outcome="#{bean.getOutcome()}" />
it will not be invoked when you click the button. Instead, it is already invoked when the page containing the button is rendered for the sole purpose to obtain the navigation outcome to be embedded in the generated onclick code. If you ever attempted to use the action method syntax as in outcome="#{bean.action}", you would already be hinted by this mistake/misconception by facing a javax.el.ELException: Could not find property actionMethod in class com.example.Bean.
If you intend to invoke a method as result of a POST request, use <h:commandButton> instead, see below. Or if you intend to invoke a method as result of a GET request, head to Invoke JSF managed bean action on page load or if you also have GET request parameters via <f:param>, How do I process GET query string URL parameters in backing bean on page load?
<h:commandButton>
The <h:commandButton> generates a HTML <input type="submit"> button which submits by default the parent <h:form> using HTTP POST method and invokes the actions attached to action, actionListener and/or <f:ajax listener>, if any. The <h:form> is required.
E.g.
<h:form id="form">
<h:commandButton id="button" value="POST button" action="otherpage" />
</h:form>
will generate
<form id="form" name="form" method="post" action="/contextpath/currentpage.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="form" value="form" />
<input type="submit" name="form:button" value="POST button" />
<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="...." autocomplete="off" />
</form>
Note that it thus submits to the current page (the form action URL will show up in the browser address bar). It will afterwards forward to the target page, without any change in the URL in the browser address bar. You could add ?faces-redirect=true parameter to the outcome value to trigger a redirect after POST (as per the Post-Redirect-Get pattern) so that the target URL becomes bookmarkable.
The <h:commandButton> is usually exclusively used to submit a POST form, not to perform page-to-page navigation. Normally, the action points to some business action, such as saving the form data in DB, which returns a String outcome.
<h:commandButton ... action="#{bean.save}" />
with
public String save() {
// ...
return "otherpage";
}
Returning null or void will bring you back to the same view. Returning an empty string also, but it would recreate any view scoped bean. These days, with modern JSF2 and <f:ajax>, more than often actions just return to the same view (thus, null or void) wherein the results are conditionally rendered by ajax.
public void save() {
// ...
}
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
When should I use h:outputLink instead of h:commandLink?
Differences between action and actionListener
h:button - clicking on a h:button issues a bookmarkable GET request.
h:commandbutton - Instead of a get request, h:commandbutton issues a POST request which sends the form data back to the server.
h:commandButton must be enclosed in a h:form and has the two ways of navigation i.e. static by setting the action attribute and dynamic by setting the actionListener attribute hence it is more advanced as follows:
<h:form>
<h:commandButton action="page.xhtml" value="cmdButton"/>
</h:form>
this code generates the follwing html:
<form id="j_idt7" name="j_idt7" method="post" action="/jsf/faces/index.xhtml" enctype="application/x-www-form-urlencoded">
whereas the h:button is simpler and just used for static or rule based navigation as follows
<h:button outcome="page.xhtml" value="button"/>
the generated html is
<title>Facelet Title</title></head><body><input type="button" onclick="window.location.href='/jsf/faces/page.xhtml'; return false;" value="button" />
This is taken from the book - The Complete Reference by Ed Burns & Chris Schalk
h:commandButton vs h:button
What’s the difference between h:commandButton|h:commandLink and
h:button|h:link ?
The latter two components were introduced in 2.0 to enable bookmarkable
JSF pages, when used in concert with the View Parameters feature.
There are 3 main differences between h:button|h:link and
h:commandButton|h:commandLink.
First, h:button|h:link causes the browser to issue an HTTP GET
request, while h:commandButton|h:commandLink does a form POST. This
means that any components in the page that have values entered by the
user, such as text fields, checkboxes, etc., will not automatically
be submitted to the server when using h:button|h:link. To cause
values to be submitted with h:button|h:link, extra action has to be
taken, using the “View Parameters” feature.
The second main difference between the two kinds of components is that
h:button|h:link has an outcome attribute to describe where to go next
while h:commandButton|h:commandLink uses an action attribute for this
purpose. This is because the former does not result in an ActionEvent
in the event system, while the latter does.
Finally, and most important to the complete understanding of this
feature, the h:button|h:link components cause the navigation system to
be asked to derive the outcome during the rendering of the page, and
the answer to this question is encoded in the markup of the page. In
contrast, the h:commandButton|h:commandLink components cause the
navigation system to be asked to derive the outcome on the POSTBACK
from the page. This is a difference in timing. Rendering always
happens before POSTBACK.
Here is what the JSF javadocs have to say about the commandButton action attribute:
MethodExpression representing the application action to invoke when
this component is activated by the user. The expression must evaluate
to a public method that takes no parameters, and returns an Object
(the toString() of which is called to derive the logical outcome)
which is passed to the NavigationHandler for this application.
It would be illuminating to me if anyone can explain what that has to do with any of the answers on this page. It seems pretty clear that action refers to some page's filename and not a method.
I have a button that is supposed to close a modal panel and render several elements.
Is there an easy way to check if an element was rendered after the button was pressed?
example button:
<a4j:commandButton onclick="#{rich:component('modal')}.hide();"
style="background-repeat:no-repeat;width:18px;height:18px;"
image="includes/images/close.gif"
render=":id1 :id2">
<f:setPropertyActionListener target="#{Controller.attribute}" value="false" />
</a4j:commandButton>
I have another button that does not "work" on the un-rendered div.
The conditon of the rendered attribute of all of the button's parent components must be preserved when you're submitting the form. So it should not only evaluate true during the request of presenting the form with the button, but it should also evaluate true during the request of processing the form submit. Easiest is to put the backing bean in the view scope by #ViewScoped.
Also, if you're re-rendering a component which in turn contains a <h:form>, you need to explicitly add the client ID of that <h:form> to the render attribute. E.g. when component with client ID id1 has in turn a <h:form id="formOfId1">.
render=":id1 :id2 :formOfId1"
You can debug this all by just exploring the HTTP traffic in the webbrowser's developer toolset (press F12 in Chrome/IE9/Firebug and check the "Network" section).
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated - Points 5 and 7.
I have hit the same problem. My solution was to display the current time inside the element that i want to be rendered.
If, for instance, you want to render a panel, just paste inside that panel the following snippet:
<h:outputText value="#{session.lastAccessedTime}">
<f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss.SSS" type="date" />
</h:outputText>
If the time is updated after button click, then obviously the component was rendered. But is the opposite also true? If the time is not updated, does this mean the component was not rendered? What if the component got rendered properly, but the time displayed is frozen to the moment the page was first accessed? I had small doubts about that, so i refreshed the page, and the time changed. So the time displayed is not frozen to the initial moment.
Also note that there are multiple ways to get the time; if you don't like to use session time, you could set a property in the backing bean, and initialize it to new Date()
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