I have this simple facelets page:
<!DOCTYPE html>
<html xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Index</title>
</h:head>
<h:body>
<h:form>
<h:inputText id="firstname" value="#{fooBar.firstname}">
<f:ajax event="keyup" render="echo" execute="myCommandButton"/>
</h:inputText>
<h:commandButton value="Submit" action="#{fooBar.fooBarAction()}" id="myCommandButton"/>
</h:form>
<br/>
<h:outputText id="echo" value="#{fooBar.firstname}"/>
</h:body>
</html>
and the Foobar bean is as follows:
#ManagedBean
#ApplicationScoped
public class FooBar {
private String firstname;
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getFirstname() {
return firstname;
}
public void fooBarAction() {
System.out.println("Foo bar action being executed!!!");
}
}
So my expectation is to see the text Foo bar action being executed whenever I type something in the inputText field, but it is not the case. What am I missing?
Edit: Why am I expecting this behavior?
I am studying the book Core JavaServer Faces and in the book it is noted that:
JSF 2.0 splits the JSF life cycle into two parts: execute and render.
Execute consists of: Restore View -> Apply Request Values -> Process
Validations -> Update Model Values -> Invoke Application
When JSF executes a component on the server, it:
-Converts and validates the component 's value (if the component is an input).
-Pushes valid input values to the model (if the component is wired to a bean property).
-Executes actions and action listeners (if the component is an action).
So here, myCommandButton should be executed, isn 't it? And execution of a component means its action to be executed?
Edit #2
This quotation is from JavaServer Faces Complete Reference
If listener is not specified, the only action that will be invoked
during the Invoke Application phase will be the one that corresponds
to an ActionSource component listed in the execute attribute.
So as far as I understand, in my example, I have a component that implements the ActionSource interface (myCommandButton), and the action attribute of this component should be executed. But it is not?
The execute attribute of <f:ajax> basically tells JSF which components to process through the JSF lifecycle during the postback. I.e. it basically tells JSF for which components it must execute the apply request values, process validations, update model values and invoke application phases. The apply request values phase will collect (decode) submitted HTML form (input and button) values. The validations phase will run conversion/validation on submitted values. The update model values phase will set submitted/converted/validated values in backing bean. The invoke application phase will execute the submitted action. Note that the key is that JSF will do this all based on submitted HTML form values.
In other words, the execute attribute is entirely server side. It is not client side as you seemed to expect. You seemed to expect that it tells the webbrowser to submit the specified component, as if you were clicking on it. This is not true. The button value is only processed through the JSF lifecycle when it was actually being pressed/clicked/submitted.
If the button is specified in execute attribute and JSF determines during processing the lifecycle that the button value is actually not submitted (i.e. it is entirely absent in HTTP request parameter map), then JSF won't queue the action event during apply request values phase at all. And therefore nothing will be invoked during invoke application phase.
When the <f:ajax> event is triggered, it's actually the enclosing component which is the action source. You should therefore hook the desired action listeners on it. You can use listener attribute of <f:ajax> for that.
<h:form>
<h:inputText id="firstname" value="#{fooBar.firstname}">
<f:ajax event="keyup" listener="#{fooBar.keyupListener}" render="echo" />
</h:inputText>
<h:commandButton value="Submit" action="#{fooBar.fooBarAction}" id="myCommandButton"/>
</h:form>
#ManagedBean
#RequestScoped
public class FooBar {
private String firstname;
public void keyupListener() {
System.out.println("Keyup listener being executed");
}
public void fooBarAction() {
System.out.println("Foo bar action being executed");
}
// ...
}
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
How does JSF process action listener?
The action and/or actionListener you want to call on each key stroke have to be defined in the f:ajax facet. You defined your action in the h:commandButton below. JSF doesn't see any connection between the ajax facet and the button. Apart from technical reasons, there are at least two reasons making this behaviour plausible:
You can have multiple command buttons in your form. In fact, more often than not you have at least two: "save" and "cancel". Should both actions be triggered on every key stroke? In which order? There's no way to decide that automatically, so JSF decides to avoid this problem by forcing you to define the action within the AJAX facet. Mind you: Your form might contain a table consisting of 100 rows, each with a "delete", "edit", and "insert new row after this row" button. Which action should be executed?
The input field may have multiple f:ajax facets. For example, you can define different facets for the events "keyup" and "blur". If you define multiple facets, you probably want them to call different backend bean methods. You do not want them to call any other command button of the form. Remember, it might be the "cancel" button, which is a bit inconvenient if it's triggered on each key stroke.
So the statement you've quoted from the Core JSF book is correct. Every action and actionListener is executed. Your mistake is that you've mentally expanded the scope to the entire form. Instead, JSF only looks at the component surrounding the AJAX facet.
The quotation of the JavaServer Faces Complete Reference simply sounds wrong to me. When neither an action nor an actionListener is specified, the "invoke application" phase of JSF doesn't do anything. The input is sent to the server, it is validated, it is stored in the backend bean and it's used to render the page again. But no action is called because you didn't specify an action to be called.
Related
Sometimes, when using <h:commandLink>, <h:commandButton> or <f:ajax>, the action, actionListener or listener method associated with the tag are simply not being invoked. Or, the bean properties are not updated with submitted UIInput values.
What are the possible causes and solutions for this?
Introduction
Whenever an UICommand component (<h:commandXxx>, <p:commandXxx>, etc) fails to invoke the associated action method, or an UIInput component (<h:inputXxx>, <p:inputXxxx>, etc) fails to process the submitted values and/or update the model values, and you aren't seeing any googlable exceptions and/or warnings in the server log, also not when you configure an ajax exception handler as per Exception handling in JSF ajax requests, nor when you set below context parameter in web.xml,
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
and you are also not seeing any googlable errors and/or warnings in browser's JavaScript console (press F12 in Chrome/Firefox23+/IE9+ to open the web developer toolset and then open the Console tab), then work through below list of possible causes.
Possible causes
UICommand and UIInput components must be placed inside an UIForm component, e.g. <h:form> (and thus not plain HTML <form>), otherwise nothing can be sent to the server. UICommand components must also not have type="button" attribute, otherwise it will be a dead button which is only useful for JavaScript onclick. See also How to send form input values and invoke a method in JSF bean and <h:commandButton> does not initiate a postback.
You cannot nest multiple UIForm components in each other. This is illegal in HTML. The browser behavior is unspecified. Watch out with include files! You can use UIForm components in parallel, but they won't process each other during submit. You should also watch out with "God Form" antipattern; make sure that you don't unintentionally process/validate all other (invisible) inputs in the very same form (e.g. having a hidden dialog with required inputs in the very same form). See also How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?.
No UIInput value validation/conversion error should have occurred. You can use <h:messages> to show any messages which are not shown by any input-specific <h:message> components. Don't forget to include the id of <h:messages> in the <f:ajax render>, if any, so that it will be updated as well on ajax requests. See also h:messages does not display messages when p:commandButton is pressed.
If UICommand or UIInput components are placed inside an iterating component like <h:dataTable>, <ui:repeat>, etc, then you need to ensure that exactly the same value of the iterating component is been preserved during the apply request values phase of the form submit request. JSF will reiterate over it to find the clicked link/button and submitted input values. Putting the bean in the view scope and/or making sure that you load the data model in #PostConstruct of the bean (and thus not in a getter method!) should fix it. See also How and when should I load the model from database for h:dataTable.
If UICommand or UIInput components are included by a dynamic source such as <ui:include src="#{bean.include}">, then you need to ensure that exactly the same #{bean.include} value is preserved during the view build time of the form submit request. JSF will reexecute it during building the component tree. Putting the bean in the view scope and/or making sure that you load the data model in #PostConstruct of the bean (and thus not in a getter method!) should fix it. See also How to ajax-refresh dynamic include content by navigation menu? (JSF SPA).
The rendered attribute of the component and all of its parents and the test attribute of any parent <c:if>/<c:when> should not evaluate to false during the apply request values phase of the form submit request. JSF will recheck it as part of safeguard against tampered/hacked requests. Storing the variables responsible for the condition in a #ViewScoped bean or making sure that you're properly preinitializing the condition in #PostConstruct of a #RequestScoped bean should fix it. The same applies to the disabled and readonly attributes of the component, which should not evaluate to true during apply request values phase. See also JSF CommandButton action not invoked, Form submit in conditionally rendered component is not processed, h:commandButton is not working once I wrap it in a <h:panelGroup rendered> and Force JSF to process, validate and update readonly/disabled input components anyway
The onclick attribute of the UICommand component and the onsubmit attribute of the UIForm component should not return false or cause a JavaScript error. There should in case of <h:commandLink> or <f:ajax> also be no JS errors visible in the browser's JS console. Usually googling the exact error message will already give you the answer. See also Manually adding / loading jQuery with PrimeFaces results in Uncaught TypeErrors.
If you're using Ajax via JSF 2.x <f:ajax> or e.g. PrimeFaces <p:commandXxx>, make sure that you have a <h:head> in the master template instead of the <head>. Otherwise JSF won't be able to auto-include the necessary JavaScript files which contains the Ajax functions. This would result in a JavaScript error like "mojarra is not defined" or "PrimeFaces is not defined" in browser's JS console. See also h:commandLink actionlistener is not invoked when used with f:ajax and ui:repeat.
If you're using Ajax, and the submitted values end up being null, then make sure that the UIInput and UICommand components of interest are covered by the <f:ajax execute> or e.g. <p:commandXxx process>, otherwise they won't be executed/processed. See also Submitted form values not updated in model when adding <f:ajax> to <h:commandButton> and Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes.
If the submitted values still end up being null, and you're using CDI to manage beans, then make sure that you import the scope annotation from the correct package, else CDI will default to #Dependent which effectively recreates the bean on every single evaluation of the EL expression. See also #SessionScoped bean looses scope and gets recreated all the time, fields become null and What is the default Managed Bean Scope in a JSF 2 application?
If a parent of the <h:form> with the UICommand button is beforehand been rendered/updated by an ajax request coming from another form in the same page, then the first action will always fail in JSF 2.2 or older. The second and subsequent actions will work. This is caused by a bug in view state handling which is reported as JSF spec issue 790 and currently fixed in JSF 2.3. For older JSF versions, you need to explicitly specify the ID of the <h:form> in the render of the <f:ajax>. See also h:commandButton/h:commandLink does not work on first click, works only on second click.
If the <h:form> has enctype="multipart/form-data" set in order to support file uploading, then you need to make sure that you're using at least JSF 2.2, or that the servlet filter who is responsible for parsing multipart/form-data requests is properly configured, otherwise the FacesServlet will end up getting no request parameters at all and thus not be able to apply the request values. How to configure such a filter depends on the file upload component being used. For Tomahawk <t:inputFileUpload>, check this answer and for PrimeFaces <p:fileUpload>, check this answer. Or, if you're actually not uploading a file at all, then remove the attribute altogether.
Make sure that the ActionEvent argument of actionListener is an javax.faces.event.ActionEvent and thus not java.awt.event.ActionEvent, which is what most IDEs suggest as 1st autocomplete option. Having no argument is wrong as well if you use actionListener="#{bean.method}". If you don't want an argument in your method, use actionListener="#{bean.method()}". Or perhaps you actually want to use action instead of actionListener. See also Differences between action and actionListener.
Make sure that no PhaseListener or any EventListener in the request-response chain has changed the JSF lifecycle to skip the invoke action phase by for example calling FacesContext#renderResponse() or FacesContext#responseComplete().
Make sure that no Filter or Servlet in the same request-response chain has blocked the request fo the FacesServlet somehow. For example, login/security filters such as Spring Security. Particularly in ajax requests that would by default end up with no UI feedback at all. See also Spring Security 4 and PrimeFaces 5 AJAX request handling.
If you are using a PrimeFaces <p:dialog> or a <p:overlayPanel>, then make sure that they have their own <h:form>. Because, these components are by default by JavaScript relocated to end of HTML <body>. So, if they were originally sitting inside a <form>, then they would now not anymore sit in a <form>. See also p:commandbutton action doesn't work inside p:dialog
Bug in the framework. For example, RichFaces has a "conversion error" when using a rich:calendar UI element with a defaultLabel attribute (or, in some cases, a rich:placeholder sub-element). This bug prevents the bean method from being invoked when no value is set for the calendar date. Tracing framework bugs can be accomplished by starting with a simple working example and building the page back up until the bug is discovered.
Debugging hints
In case you still stucks, it's time to debug. In the client side, press F12 in webbrowser to open the web developer toolset. Click the Console tab so see the JavaScript conosle. It should be free of any JavaScript errors. Below screenshot is an example from Chrome which demonstrates the case of submitting an <f:ajax> enabled button while not having <h:head> declared (as described in point 7 above).
Click the Network tab to see the HTTP traffic monitor. Submit the form and investigate if the request headers and form data and the response body are as per expectations. Below screenshot is an example from Chrome which demonstrates a successful ajax submit of a simple form with a single <h:inputText> and a single <h:commandButton> with <f:ajax execute="#form" render="#form">.
(warning: when you post screenshots from HTTP request headers like above from a production environment, then make sure you scramble/obfuscate any session cookies in the screenshot to avoid session hijacking attacks!)
In the server side, make sure that server is started in debug mode. Put a debug breakpoint in a method of the JSF component of interest which you expect to be called during processing the form submit. E.g. in case of UICommand component, that would be UICommand#queueEvent() and in case of UIInput component, that would be UIInput#validate(). Just step through the code execution and inspect if the flow and variables are as per expectations. Below screenshot is an example from Eclipse's debugger.
If your h:commandLink is inside a h:dataTable there is another reason why the h:commandLink might not work:
The underlying data-source which is bound to the h:dataTable must also be available in the second JSF-Lifecycle that is triggered when the link is clicked.
So if the underlying data-source is request scoped, the h:commandLink does not work!
While my answer isn't 100% applicable, but most search engines find this as the first hit, I decided to post it nontheless:
If you're using PrimeFaces (or some similar API) p:commandButton or p:commandLink, chances are that you have forgotten to explicitly add process="#this" to your command components.
As the PrimeFaces User's Guide states in section 3.18, the defaults for process and update are both #form, which pretty much opposes the defaults you might expect from plain JSF f:ajax or RichFaces, which are execute="#this" and render="#none" respectively.
Just took me a looong time to find out. (... and I think it's rather unclever to use defaults that are different from JSF!)
I would mention one more thing that concerns Primefaces's p:commandButton!
When you use a p:commandButton for the action that needs to be done on the server, you can not use type="button" because that is for Push buttons which are used to execute custom javascript without causing an ajax/non-ajax request to the server.
For this purpose, you can dispense the type attribute (default value is "submit") or you can explicitly use type="submit".
Hope this will help someone!
Got stuck with this issue myself and found one more cause for this problem.
If you don't have setter methods in your backing bean for the properties used in your *.xhtml , then the action is simply not invoked.
I recently ran into a problem with a UICommand not invoking in a JSF 1.2 application using IBM Extended Faces Components.
I had a command button on a row of a datatable (the extended version, so <hx:datatable>) and the UICommand would not fire from certain rows from the table (the rows that would not fire were the rows greater than the default row display size).
I had a drop-down component for selecting number of rows to display. The value backing this field was in RequestScope. The data backing the table itself was in a sort of ViewScope (in reality, temporarily in SessionScope).
If the row display was increased via the control which value was also bound to the datatable's rows attribute, none of the rows displayed as a result of this change could fire the UICommand when clicked.
Placing this attribute in the same scope as the table data itself fixed the problem.
I think this is alluded to in BalusC #4 above, but not only did the table value need to be View or Session scoped but also the attribute controlling the number of rows to display on that table.
I had this problem as well and only really started to hone in on the root cause after opening up the browser's web console. Until that, I was unable to get any error messages (even with <p:messages>). The web console showed an HTTP 405 status code coming back from the <h:commandButton type="submit" action="#{myBean.submit}">.
In my case, I have a mix of vanilla HttpServlet's providing OAuth authentication via Auth0 and JSF facelets and beans carrying out my application views and business logic.
Once I refactored my web.xml, and removed a middle-man-servlet, it then "magically" worked.
Bottom line, the problem was that the middle-man-servlet was using RequestDispatcher.forward(...) to redirect from the HttpServlet environment to the JSF environment whereas the servlet being called prior to it was redirecting with HttpServletResponse.sendRedirect(...).
Basically, using sendRedirect() allowed the JSF "container" to take control whereas RequestDispatcher.forward() was obviously not.
What I don't know is why the facelet was able to access the bean properties but could not set them, and this clearly screams for doing away with the mix of servlets and JSF, but I hope this helps someone avoid many hours of head-to-table-banging.
I had lots of fun debugging an issue where a <h:commandLink>'s action in richfaces datatable refused to fire. The table used to work at some point but stopped for no apparent reason. I left no stone unturned, only to find out that my rich:datatable was using the wrong rowKeyConverter which returned nulls that richfaces happily used as row keys. This prevented my <h:commandLink> action from getting called.
One more possibility: if the symptom is that the first invocation works, but subsequent ones do not, you may be using PrimeFaces 3.x with JSF 2.2, as detailed here: No ViewState is sent.
I fixed my problem with placing the:
<h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>
In:
<h:form>
<h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>
</h:form>
This is the solution, which is worked for me.
<p:commandButton id="b1" value="Save" process="userGroupSetupForm"
actionListener="#{userGroupSetupController.saveData()}"
update="growl userGroupList userGroupSetupForm" />
Here, process="userGroupSetupForm" atrribute is mandatory for Ajax call. actionListener is calling a method from #ViewScope Bean. Also updating growl message, Datatable: userGroupList and Form: userGroupSetupForm.
<ui:composition>
<h:form id="form1">
<p:dialog id="dialog1">
<p:commandButton value="Save" action="#{bean.method1}" /> <!--Working-->
</p:dialog>
</h:form>
<h:form id="form2">
<p:dialog id="dialog2">
<p:commandButton value="Save" action="#{bean.method2}" /> <!--Not Working-->
</p:dialog>
</h:form>
</ui:composition>
To solve;
<ui:composition>
<h:form id="form1">
<p:dialog id="dialog1">
<p:commandButton value="Save" action="#{bean.method1}" /> <!-- Working -->
</p:dialog>
<p:dialog id="dialog2">
<p:commandButton value="Save" action="#{bean.method2}" /> <!--Working -->
</p:dialog>
</h:form>
<h:form id="form2">
<!-- .......... -->
</h:form>
</ui:composition>
Sometimes, when using <h:commandLink>, <h:commandButton> or <f:ajax>, the action, actionListener or listener method associated with the tag are simply not being invoked. Or, the bean properties are not updated with submitted UIInput values.
What are the possible causes and solutions for this?
Introduction
Whenever an UICommand component (<h:commandXxx>, <p:commandXxx>, etc) fails to invoke the associated action method, or an UIInput component (<h:inputXxx>, <p:inputXxxx>, etc) fails to process the submitted values and/or update the model values, and you aren't seeing any googlable exceptions and/or warnings in the server log, also not when you configure an ajax exception handler as per Exception handling in JSF ajax requests, nor when you set below context parameter in web.xml,
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
and you are also not seeing any googlable errors and/or warnings in browser's JavaScript console (press F12 in Chrome/Firefox23+/IE9+ to open the web developer toolset and then open the Console tab), then work through below list of possible causes.
Possible causes
UICommand and UIInput components must be placed inside an UIForm component, e.g. <h:form> (and thus not plain HTML <form>), otherwise nothing can be sent to the server. UICommand components must also not have type="button" attribute, otherwise it will be a dead button which is only useful for JavaScript onclick. See also How to send form input values and invoke a method in JSF bean and <h:commandButton> does not initiate a postback.
You cannot nest multiple UIForm components in each other. This is illegal in HTML. The browser behavior is unspecified. Watch out with include files! You can use UIForm components in parallel, but they won't process each other during submit. You should also watch out with "God Form" antipattern; make sure that you don't unintentionally process/validate all other (invisible) inputs in the very same form (e.g. having a hidden dialog with required inputs in the very same form). See also How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?.
No UIInput value validation/conversion error should have occurred. You can use <h:messages> to show any messages which are not shown by any input-specific <h:message> components. Don't forget to include the id of <h:messages> in the <f:ajax render>, if any, so that it will be updated as well on ajax requests. See also h:messages does not display messages when p:commandButton is pressed.
If UICommand or UIInput components are placed inside an iterating component like <h:dataTable>, <ui:repeat>, etc, then you need to ensure that exactly the same value of the iterating component is been preserved during the apply request values phase of the form submit request. JSF will reiterate over it to find the clicked link/button and submitted input values. Putting the bean in the view scope and/or making sure that you load the data model in #PostConstruct of the bean (and thus not in a getter method!) should fix it. See also How and when should I load the model from database for h:dataTable.
If UICommand or UIInput components are included by a dynamic source such as <ui:include src="#{bean.include}">, then you need to ensure that exactly the same #{bean.include} value is preserved during the view build time of the form submit request. JSF will reexecute it during building the component tree. Putting the bean in the view scope and/or making sure that you load the data model in #PostConstruct of the bean (and thus not in a getter method!) should fix it. See also How to ajax-refresh dynamic include content by navigation menu? (JSF SPA).
The rendered attribute of the component and all of its parents and the test attribute of any parent <c:if>/<c:when> should not evaluate to false during the apply request values phase of the form submit request. JSF will recheck it as part of safeguard against tampered/hacked requests. Storing the variables responsible for the condition in a #ViewScoped bean or making sure that you're properly preinitializing the condition in #PostConstruct of a #RequestScoped bean should fix it. The same applies to the disabled and readonly attributes of the component, which should not evaluate to true during apply request values phase. See also JSF CommandButton action not invoked, Form submit in conditionally rendered component is not processed, h:commandButton is not working once I wrap it in a <h:panelGroup rendered> and Force JSF to process, validate and update readonly/disabled input components anyway
The onclick attribute of the UICommand component and the onsubmit attribute of the UIForm component should not return false or cause a JavaScript error. There should in case of <h:commandLink> or <f:ajax> also be no JS errors visible in the browser's JS console. Usually googling the exact error message will already give you the answer. See also Manually adding / loading jQuery with PrimeFaces results in Uncaught TypeErrors.
If you're using Ajax via JSF 2.x <f:ajax> or e.g. PrimeFaces <p:commandXxx>, make sure that you have a <h:head> in the master template instead of the <head>. Otherwise JSF won't be able to auto-include the necessary JavaScript files which contains the Ajax functions. This would result in a JavaScript error like "mojarra is not defined" or "PrimeFaces is not defined" in browser's JS console. See also h:commandLink actionlistener is not invoked when used with f:ajax and ui:repeat.
If you're using Ajax, and the submitted values end up being null, then make sure that the UIInput and UICommand components of interest are covered by the <f:ajax execute> or e.g. <p:commandXxx process>, otherwise they won't be executed/processed. See also Submitted form values not updated in model when adding <f:ajax> to <h:commandButton> and Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes.
If the submitted values still end up being null, and you're using CDI to manage beans, then make sure that you import the scope annotation from the correct package, else CDI will default to #Dependent which effectively recreates the bean on every single evaluation of the EL expression. See also #SessionScoped bean looses scope and gets recreated all the time, fields become null and What is the default Managed Bean Scope in a JSF 2 application?
If a parent of the <h:form> with the UICommand button is beforehand been rendered/updated by an ajax request coming from another form in the same page, then the first action will always fail in JSF 2.2 or older. The second and subsequent actions will work. This is caused by a bug in view state handling which is reported as JSF spec issue 790 and currently fixed in JSF 2.3. For older JSF versions, you need to explicitly specify the ID of the <h:form> in the render of the <f:ajax>. See also h:commandButton/h:commandLink does not work on first click, works only on second click.
If the <h:form> has enctype="multipart/form-data" set in order to support file uploading, then you need to make sure that you're using at least JSF 2.2, or that the servlet filter who is responsible for parsing multipart/form-data requests is properly configured, otherwise the FacesServlet will end up getting no request parameters at all and thus not be able to apply the request values. How to configure such a filter depends on the file upload component being used. For Tomahawk <t:inputFileUpload>, check this answer and for PrimeFaces <p:fileUpload>, check this answer. Or, if you're actually not uploading a file at all, then remove the attribute altogether.
Make sure that the ActionEvent argument of actionListener is an javax.faces.event.ActionEvent and thus not java.awt.event.ActionEvent, which is what most IDEs suggest as 1st autocomplete option. Having no argument is wrong as well if you use actionListener="#{bean.method}". If you don't want an argument in your method, use actionListener="#{bean.method()}". Or perhaps you actually want to use action instead of actionListener. See also Differences between action and actionListener.
Make sure that no PhaseListener or any EventListener in the request-response chain has changed the JSF lifecycle to skip the invoke action phase by for example calling FacesContext#renderResponse() or FacesContext#responseComplete().
Make sure that no Filter or Servlet in the same request-response chain has blocked the request fo the FacesServlet somehow. For example, login/security filters such as Spring Security. Particularly in ajax requests that would by default end up with no UI feedback at all. See also Spring Security 4 and PrimeFaces 5 AJAX request handling.
If you are using a PrimeFaces <p:dialog> or a <p:overlayPanel>, then make sure that they have their own <h:form>. Because, these components are by default by JavaScript relocated to end of HTML <body>. So, if they were originally sitting inside a <form>, then they would now not anymore sit in a <form>. See also p:commandbutton action doesn't work inside p:dialog
Bug in the framework. For example, RichFaces has a "conversion error" when using a rich:calendar UI element with a defaultLabel attribute (or, in some cases, a rich:placeholder sub-element). This bug prevents the bean method from being invoked when no value is set for the calendar date. Tracing framework bugs can be accomplished by starting with a simple working example and building the page back up until the bug is discovered.
Debugging hints
In case you still stucks, it's time to debug. In the client side, press F12 in webbrowser to open the web developer toolset. Click the Console tab so see the JavaScript conosle. It should be free of any JavaScript errors. Below screenshot is an example from Chrome which demonstrates the case of submitting an <f:ajax> enabled button while not having <h:head> declared (as described in point 7 above).
Click the Network tab to see the HTTP traffic monitor. Submit the form and investigate if the request headers and form data and the response body are as per expectations. Below screenshot is an example from Chrome which demonstrates a successful ajax submit of a simple form with a single <h:inputText> and a single <h:commandButton> with <f:ajax execute="#form" render="#form">.
(warning: when you post screenshots from HTTP request headers like above from a production environment, then make sure you scramble/obfuscate any session cookies in the screenshot to avoid session hijacking attacks!)
In the server side, make sure that server is started in debug mode. Put a debug breakpoint in a method of the JSF component of interest which you expect to be called during processing the form submit. E.g. in case of UICommand component, that would be UICommand#queueEvent() and in case of UIInput component, that would be UIInput#validate(). Just step through the code execution and inspect if the flow and variables are as per expectations. Below screenshot is an example from Eclipse's debugger.
If your h:commandLink is inside a h:dataTable there is another reason why the h:commandLink might not work:
The underlying data-source which is bound to the h:dataTable must also be available in the second JSF-Lifecycle that is triggered when the link is clicked.
So if the underlying data-source is request scoped, the h:commandLink does not work!
While my answer isn't 100% applicable, but most search engines find this as the first hit, I decided to post it nontheless:
If you're using PrimeFaces (or some similar API) p:commandButton or p:commandLink, chances are that you have forgotten to explicitly add process="#this" to your command components.
As the PrimeFaces User's Guide states in section 3.18, the defaults for process and update are both #form, which pretty much opposes the defaults you might expect from plain JSF f:ajax or RichFaces, which are execute="#this" and render="#none" respectively.
Just took me a looong time to find out. (... and I think it's rather unclever to use defaults that are different from JSF!)
I would mention one more thing that concerns Primefaces's p:commandButton!
When you use a p:commandButton for the action that needs to be done on the server, you can not use type="button" because that is for Push buttons which are used to execute custom javascript without causing an ajax/non-ajax request to the server.
For this purpose, you can dispense the type attribute (default value is "submit") or you can explicitly use type="submit".
Hope this will help someone!
Got stuck with this issue myself and found one more cause for this problem.
If you don't have setter methods in your backing bean for the properties used in your *.xhtml , then the action is simply not invoked.
I recently ran into a problem with a UICommand not invoking in a JSF 1.2 application using IBM Extended Faces Components.
I had a command button on a row of a datatable (the extended version, so <hx:datatable>) and the UICommand would not fire from certain rows from the table (the rows that would not fire were the rows greater than the default row display size).
I had a drop-down component for selecting number of rows to display. The value backing this field was in RequestScope. The data backing the table itself was in a sort of ViewScope (in reality, temporarily in SessionScope).
If the row display was increased via the control which value was also bound to the datatable's rows attribute, none of the rows displayed as a result of this change could fire the UICommand when clicked.
Placing this attribute in the same scope as the table data itself fixed the problem.
I think this is alluded to in BalusC #4 above, but not only did the table value need to be View or Session scoped but also the attribute controlling the number of rows to display on that table.
I had this problem as well and only really started to hone in on the root cause after opening up the browser's web console. Until that, I was unable to get any error messages (even with <p:messages>). The web console showed an HTTP 405 status code coming back from the <h:commandButton type="submit" action="#{myBean.submit}">.
In my case, I have a mix of vanilla HttpServlet's providing OAuth authentication via Auth0 and JSF facelets and beans carrying out my application views and business logic.
Once I refactored my web.xml, and removed a middle-man-servlet, it then "magically" worked.
Bottom line, the problem was that the middle-man-servlet was using RequestDispatcher.forward(...) to redirect from the HttpServlet environment to the JSF environment whereas the servlet being called prior to it was redirecting with HttpServletResponse.sendRedirect(...).
Basically, using sendRedirect() allowed the JSF "container" to take control whereas RequestDispatcher.forward() was obviously not.
What I don't know is why the facelet was able to access the bean properties but could not set them, and this clearly screams for doing away with the mix of servlets and JSF, but I hope this helps someone avoid many hours of head-to-table-banging.
I had lots of fun debugging an issue where a <h:commandLink>'s action in richfaces datatable refused to fire. The table used to work at some point but stopped for no apparent reason. I left no stone unturned, only to find out that my rich:datatable was using the wrong rowKeyConverter which returned nulls that richfaces happily used as row keys. This prevented my <h:commandLink> action from getting called.
One more possibility: if the symptom is that the first invocation works, but subsequent ones do not, you may be using PrimeFaces 3.x with JSF 2.2, as detailed here: No ViewState is sent.
I fixed my problem with placing the:
<h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>
In:
<h:form>
<h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>
</h:form>
This is the solution, which is worked for me.
<p:commandButton id="b1" value="Save" process="userGroupSetupForm"
actionListener="#{userGroupSetupController.saveData()}"
update="growl userGroupList userGroupSetupForm" />
Here, process="userGroupSetupForm" atrribute is mandatory for Ajax call. actionListener is calling a method from #ViewScope Bean. Also updating growl message, Datatable: userGroupList and Form: userGroupSetupForm.
<ui:composition>
<h:form id="form1">
<p:dialog id="dialog1">
<p:commandButton value="Save" action="#{bean.method1}" /> <!--Working-->
</p:dialog>
</h:form>
<h:form id="form2">
<p:dialog id="dialog2">
<p:commandButton value="Save" action="#{bean.method2}" /> <!--Not Working-->
</p:dialog>
</h:form>
</ui:composition>
To solve;
<ui:composition>
<h:form id="form1">
<p:dialog id="dialog1">
<p:commandButton value="Save" action="#{bean.method1}" /> <!-- Working -->
</p:dialog>
<p:dialog id="dialog2">
<p:commandButton value="Save" action="#{bean.method2}" /> <!--Working -->
</p:dialog>
</h:form>
<h:form id="form2">
<!-- .......... -->
</h:form>
</ui:composition>
Our team is writing its first JSF 2.0 application since using Stripes for many years, and I have some questions on the best way to use the f:ajax tag and validate the input.
A lot of questions I've seen answered have a form with multiple inputs and then a submit button), but we would like to maintain individual input fields updated immediately upon change and persisted to the database (with no submit button. We had this working fine in Stripes using Prototype's Ajax.Request, but it was an extra step I'd like to avoid if possible.
Essentially we have a page with a bunch of inputs on it directly backed by beans, for example:
<h:inputText id="name" value="#{personController.name}" >
<f:ajax listener="#{personController.ajax}" />
</h:inputText>
As you may know, by the time the listener is invoked, the value of name has already been changed on the bean. This would be convenient, but I have a few problems with it:
the listener doesn't obviously know which value of the bean was changed
the value has already been changed, I can't perform any server side validation on it
I don't know what the old value of name is even if I could perform some sort of validation on it, I wouldn't know what to set the value back to
Right now it's looking like we'll have to implement some kind of javascript middleman to take in what property changed and the new value, send that to the Controller, and have it perform validation, updating the database, sending back something to render, etc. But like I said, this is what we used to do with Stripes and I'd really like to use something more native.
I did see that if we wanted some kind of Submit button on the page we could use something like the valueChangeListener attribute, but I'd also like to avoid massive submits.
I included the OpenFaces tag because we're already using that for datatables, so if there's something nice in there we're open to using it. But as far as I can tell their o:ajax tag isn't that much more powerful than JSF's f:ajax.
Thanks!
You're looking in the wrong direction to achieve the concrete functional requirement of validating an input field. You should use a normal JSF validator for this, not some ajax listener method which runs at the wrong moment (the INVOKE_ACTION phase instead of PROCESS_VALIDATIONS phase) and where you don't directly have a hand at the model value. The ajax listener method is merely to be used to execute some business logic based on the current model value(s).
JSF has several builtin validators behind the required attribute and several <f:validateXxx> tags. You can even create custom validators by implementing the Validator interface.
E.g. checking the requireness:
<h:inputText ... required="true">
<f:ajax />
</h:inputText>
Or checking if it matches a pattern using one of the various <f:validateXxx> tags:
<h:inputText ...>
<f:validateRegex pattern="[a-z]+" />
<f:ajax />
</h:inputText>
Or using a custom validator:
<h:inputText ...>
<f:validator validatorId="myValidator" />
<f:ajax />
</h:inputText>
with
#FacesValidator("myValidator")
public class MyValidator implements Validator {
#Override
public void validate(FacesContext context, UIComponent component, Object value) {
if (value is not valid) {
throw new ValidatorException(new FacesMessage(...));
}
}
}
The <f:ajax> is merely there to submit the current input field during the HTML DOM change event (or click event in case of checkboxes/radiobuttons). You don't necessarily need a <f:ajax listener> method in order to submit the current input field by ajax. If you want to hook on a value change event, just use valueChangeListener.
<h:inputText ... valueChangeListener="#{bean.valueChanged}">
<f:ajax />
</h:inputText>
with
public void valueChanged(ValueChangeEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getValue();
UIComponent component = event.getComponent();
// ...
}
Note that this will only be invoked when validation has passed on the particular component.
I have an JSF page backed by NewsBean.java which has <f:event type="preRenderComponent" listener="#{newsBean.init}" /> as bean initializer.
There is a button at the bottom of the page for sending comments which has:
<f:ajax event="click" execute="#form" render="#form" listener="#{newsBean.sendComment}" /> and is surrounded by an <h:form>. When button is clicked, NewsBean.init() is always called.
My bean scope is view. Is this a valid behavior (calling always init())? How can I prevent always calling init()?
A preRender listener is always invoked on pre render event, regardless of if it's an initial request or a postback request. Every single request has a render response phase, regardless of if it's a normal request or ajax request. So this behaviour is by specification. You need to check yourself in the listener method if it's a postback request or not by checking FacesContext#isPostback().
public void sendComment() {
if (!FacesContext.getCurrentInstance().isPostback()) {
// ...
}
}
The <f:event type="preRenderXxx"> (where Xxx can be View or Component) is by the way in essence a "workaround approach" for the functional requirement of being able to invoke a bean action method after the view parameters are been processed on the initial request. In the upcoming JSF 2.2 a new <f:viewAction> tag will be introduced which should do exactly the job as intented:
<f:viewAction action="#{newsBean.sendComment}" />
This tag supports an onPostback attribute which already defaults to false:
<f:viewAction action="#{newsBean.sendComment}" onPostback="false" />
JSF 2.2 will be released the first quart of 2012. Snapshot releases of JSF 2.2 are currently already available.
I guess your <f:event> tag is put inside the <h:form> tag. Hence, when you click the ajax button, it re-render the whole <h:form> component which results in the preRenderComponent event being triggered again.
I think what you should use is PreRenderViewEvent.
In the Question commandButton/commandLink/ajax action/listener method not invoked or input value not updated there are 7 issues mentioned.
Now, I have the same problem, but I don't see which of the issues mentioned are causes the problem I'm having... nor did I manage to find the solution in any articles I've read.
I have an h:commandLink inside a snippet, which is in :main:profileContentSnippet in regard to the project:
...
<h:commandLink action="#{usersController.prepareModel}" value="ViewDetails" immediate="true">
<f:param name="pageViewId" value="EditDetails"/>
<f:ajax render=":main:profileContentSnippet" />
</h:commandLink>
...
Now, it is supposed to render :main:profileContentSnippet and modify it to present another snippet (which the commandLink is not a part of...). It renders EditProfilePersonalDetails, as sent by parameter.
The commandLink action doesn't fire.
Now if I remove it from the snippet that holds it, it works, but the h:commandLink is still there - and I wish it to disappear, as the snippet it resided on did... I wonder why's that? How can a control modify its own appearance if it is inside the snippet that is about to be replaced by another snippet using AJAX?
Thanks in advance.
Additional code:
The snippetFileName should change (and it is) after clicking on the h:commandLink from above.
Now, the file that contains the h:commnandLink is replaced by:
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
</h:panelGroup>
</ui:composition>
Note: the h:commnadLink is in a ui:composition too.
The Action in the managed bean that should be fired is:
#ManagedBean (name="usersController")
#RequestScoped
public class UsersController {
public String prepareConnected() {
//need to add getting user id from session
System.out.println("in prepareConnected");
current = ejbFacade.find( (long)2);
if (current == null){
System.out.println("in prepareConnected is null");
JsfUtil.addSuccessMessage("User Deleted in other request");
return null;
}
return "viewPersonalDetails-snippet";
}
}
...
This include part holds the commandLink from above:
<h:panelGroup id="profileContentSnippet" >
<ui:include src="#{snippetsProfileLinkerBean.snippetFileName}"/>
</h:panelGroup>
basically, the snippet is modified, but the current variable stays null since the preapareConnected doesn't fire. If I remove it from the snippet to other part in the site that is not in the include part it works. The problem is that I wish the h:commandLink part will disappear as well.`
It seems that there is a web.xml definition that should have been made for this to work:
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
The problem was in the JSF 2 flow. First time the page is rendered, JSF builds a component tree, which means that only one of the snippets was in that tree at the time of the creation of the component tree. Therefore, in other requests (of the same page) only that component could have an action and an action listener registered. The other component didn't, because it was not in the component tree that was built from the start (though I could see it in the view).
Now, modifying the definition of javax.faces.PARTIAL_STATE_SAVING to false, makes JSF 2 flow create on every request the component tree. It is not the best solution, but I didn't find any documentation on how inserting dynamically a component to the compont tree after it tree has already been built, other than build it again for each request.