JSF2 ignores Action attribut [duplicate] - jsf

This question already has answers here:
commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated
(12 answers)
Closed 2 years ago.
my xhtml code:
<h:commandLink action="#{detailController.updateProject}" class="positive" >
<h:graphicImage library="img" name="tick.png" alt=""/>
<h:outputText value="Save" />
</h:commandLink>
This action (updateProject()) is not being called from JSF framework! Even if I delete it in the managedBean there is no exception thrown.
Does anybodyelse has had problems like that? I can't even explain that -.- I mean this action ethod is there!
ADD: Yes it is in a h:form tag! But I have two forms in that view! May that be the problem?
ADD2: I should also mention that if I hit the button it throws me back to the previous view! So my action method is being ignored and instead it opens another view ?!?!
To provide more information, my page is built like that:
panelGroup name=show rendered=!controller.edit
form
buttons
outputtext
/form
/panelGroup
panelGroup name=edit rendered=controller.edit
form
buttons
inputText
/form
/panelGroup
So I have both, edit and show of one entity at one file! But only the buttons in the bottom form show that strange behaviour (see above).
Answering BalusC:
1. I use two forms (they aren't nested!)
2. In the bottom form I had already placed a h:messages
I'm gonna try putting my controller into viewScop for checking 3 and 4
I don't know how to check 5.
Thank you for that..

This can have a lot of possible causes. #romaintaz has mentioned only the most obvious one (the most common beginner's mistake): UICommand components must be placed inside an UIForm component.
There are however more causes:
You have multiple nested forms. This is illegal in HTML. The behaviour is dependent on the webbrowser used, but usually the button won't do anything. You may not nest forms, but you can use them in parallel.
A validation or conversion error has occurred which is not been catched by a h:message. Normally this is logged to stdout, but you can also use h:messages to get them all.
The UICommand component is been placed inside an UIData component (e.g. h:dataTable) whose value is not been preserved the right way during the subsequent request. If JSF cannot find the associated data row, the action won't be invoked. Putting bean in view scope should help a lot.
The component or one of its parents has a rendered or disabled attribute which evaluated false during apply request values phase. JSF won't invoke the action then. Putting bean in view scope should help a lot.
Some PhaseListener, EventListener, Filter or Servlet in the request-response chain has changed the JSF lifecycle to skip the invoke action phase or altered the request parameters so that JSF can't invoke the action.

Just a quick question: is your <h:commandLink> nested inside a <h:form>?
If this is not the case, you must include your command link inside a form element, otherwise it will not work.
Just for code simplification, you can use the value attribute instead of adding a <h:outputText> component:
<h:commandLink action="#{detailController.updateProject}" class="positive" value="Save">
<h:graphicImage library="img" name="tick.png" alt=""/>
</h:commandLink>

Unfortunately, I don't know where the mistae was. I guess it was about wrong my JSF code.
I solved this problem by simplifying my code. From that xhtml page and that one controller I made 3 xhtml-pages and 3 Controller. After refactoring all that my code looks much easier and it works now :-)
Thank you for your helpful suggestions

Related

primefaces update attribute not working on modal dialog opened from modal dialog [duplicate]

I have a question about the idea behind the fact, that only UIForm got the attribute prependId. Why is the attribute not specified in the NamingContainer interface? You will now probably say that's because of backward compability but I would preferre breaking the compability and let users which implement that interface, also implement methods for the prependId thing.
The main problem from my perspective about the prependId in the UIForm component is, that it will break findComponent()
I would expect that if I use prependId, then the NamingContainer behaviour would change, not only related to rendering but also when wanting to search for components in the component tree.
Here a simple example:
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
Now when i want to get the panelGroup component I would expect to pass the string "group" to the method findComponent(), but it won't find anything, I have to use "test:group" instead.
The concrete problem with that is, when using ajax with prependId="false". The ajax tag expects in the attributes update and process, that the values care of naming containers. It's a bit strange that when I use prependId="false" that I have to specify the full id or path, but okay.
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
<h:form id="test1" prependId="false">
<h:commandButton value="go">
<f:ajax render="test:group"/>
</h:commandButton>
</h:form>
Well this code will render without problems but it won't update the panelGroup because it cannot find it. The PartialViewContext will contain only the id "group" as element of the renderIds. I don't know if this is expected, probably it is but I don't know the code. Now we come to the point where the method findComponent() can not find the component because the expression passed as parameter is "group" where the method would expect "test:group" to find the component.
One solution is to write your own findComponent() which is the way I chose to deal with this problem. In this method i handle a component which is a NamingContainer and has the property prependId set to false like a normal UIComponent. I will have to do that for every UIComponent which offers a prependId attribute and that is bad. Reflection will help to get around the static definition of types but it's still not a really clean solution.
The other way would be introducing the prependId attribute in the NamingContainer interface and change the behaviour of findComponent() to work like described above.
The last proposed solution would be changing the behaviour of the ajax tag to pass the whole id, but this would only solve the ajax issue and not the programmatic issues behind the findComponent() implementation.
What do you think about that and why the hell is it implemented like that? I can't be the first having this problem, but I wasn't able to find related topics?!
Indeed, UIComponent#findComponent() as done by <f:ajax render> fails when using <h:form prependId="false">. This problem is known and is a "Won't fix": JSF spec issue 573.
In my humble opinion, they should never have added the prependId attribute to the UIForm during the JSF 1.2 ages. It was merely done to keep j_security_check users happy who would like to use a JSF form with JSF input components for that (j_security_check requires exact input field names j_username and j_password which couldn't be modified by configuration). But they didn't exactly realize that during JSF 1.2 another improvement was introduced which enables you to just keep using <form> for that instead of sticking to <h:form>. And then CSS/jQuery purists start abusing prependId="false" to avoid escaping the separator character : in their poorly chosen CSS selectors.
Just don't use prependId="false", ever.
For j_security_check, just use <form> or the new Servlet 3.0 HttpServletRequest#login(). See also Performing user authentication in Java EE / JSF using j_security_check.
For CSS selectors, in case you absolutely need an ID selector (and thus not a more reusable class selector), simply wrap the component of interest in a plain HTML <div> or <span>.
See also:
How to select JSF components using jQuery?
How to use JSF generated HTML element ID with colon ":" in CSS selectors?
By default, JSF generates unusable ids, which are incompatible with css part of web standards

Commandlink with ajax works only on second click [duplicate]

This question already has answers here:
h:commandButton/h:commandLink does not work on first click, works only on second click
(2 answers)
Closed 6 years ago.
What I'm trying to do is just a simple logout function. The main page will call a template page; consist of header and content. The header contains the logout button. There will be 2 forms in the page, one in the header (logout button), one in the content (few buttons,links, etc).
My problem is the page refresh when first click on the logout link and only proceed after second click. The problem starts to appear when I include primefaces or ajax code inside the content form. When I remove that particular code, the logout works as intended.
The logout form in main template templateUser.xhtml:
<h:form id="logout">
<h:commandLink action="#{tenantController.customLogout(e)}"
id="logoutBtn" immediate="true" value="Logout" />
</h:form>
The backing bean:
public String customLogout(ActionEvent e) {
return "login.xhtml";
}
FYI: the customLogout method also consist of session destroy, but I just put page redirect here.
In template client, the template is specified as:
<ui:composition template="/templateUser.xhtml">
As for the JSF library, currently use jsf 2.0
Solutions I've tried:
immediate="true"
put id for both form and commandLink (template form & content form)
use primefaces (<p:commandLink> with ajax false ==> this returb to the previous page; the method in backed bean is not running.
Below are few links I tried here:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated
How can I prevent page refresh on click of <h:commandLInk>
JSF PrimeFaces p:commandLink won't redirect to new page?
The problem starts to appear when I include primefaces or ajax code inside the content form. When I remove that particular code, the logout works as intended.
Your problem is caused by point 7 as described in commandButton/commandLink/ajax action/listener method not invoked or input value not updated. When you fire an ajax request using <f:ajax> and performs an update which also covers all other forms, then all those other forms will lose their view state. This causes that the 1st submit will always "do nothing", but the next submits will work, which matches exactly your problem symptoms.
You can solve this problem in one of the following ways:
Explicitly specify the client ID of all other forms in the <f:ajax render>. You can specify multiple client IDs space separated. E.g.
<f:ajax ... render="someComponent otherComponent :loginForm" />
Use the JavaScript based fix as proposed in this answer: h:commandButton/h:commandLink does not work on first click, works only on second click.

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.

Modify dynamically JSF snippets by h:commandlink

I have a h:commandlink control in page1. the control uses f:ajax to call to the following h:panelgroup :
I have a h:panelgroup control in page2 (a snippet), which has a ui:include within it.
I have a h:panelgroup control in page3 (a snippet), which has a ui:include within it.
Now according to the choices made on page1, I would like to switch the snippets by clicking on the h:commandlink control.
I have a BIG problem there: it seems that only if I click twice on the commandlink, only then the snippet changes - and not on one click.
I have tried to remove the f:ajax to render the panelgroup, and still it does not work...
There are two potential causes of this problem.
The <f:ajax> is fully re-rendering another <h:form> than where it is sitting in. This way the view state of the other form will get lost which would require invoking the action on the other form twice before it really get executed.
The solution is to not re-render the other <h:form>, but only some container component in that form. E.g.
<h:form id="otherForm">
<h:panelGroup id="content">
...
<h:panelGroup>
</h:form>
with
<f:ajax render=":otherForm:content" />
When there's a rendered attribute on the <h:commandLink> or any of its parent components, then it must evaluate true during the apply request values phase of the postback request in order to get JSF to invoke the bean action associated with the <h:commandLink> during the invoke action phase of that request. Perhaps the bean is request scoped and/or some odd/illogical flow inside the bean caused that the rendered attribute is not properly been preserved.
Best is to maintain those rendered conditions in a #ViewScoped bean and let its action methods return void or null so that the bean lives as long as you're interacting with the same view. Change the rendered conditions during action methods only and not inside setters/getters or something.

JSF: Unwanted page refresh on action call

Sometimes, if I click a commandButton that calls an action method, it will just do a page refresh without actually calling the method!
I set a breakpoint in that method and if this behavior takes place, the method is not called. What is also strange about it: It also does that if I didn't fill values in input components that have "required=true". I would expect that a valdiation error appears. The error appears only if the action method would be called fine. But not if it will just issue that strange page refresh.
The call looks pretty normal and works in most cases:
<h:commandButton value="Do something"
action="#{bean.doSomething(someBean.value)}" />
I can't exactly figure out when this behavior appears (and when not), but it should have something to do with the values chosen in some of the other components. But... how?
(I have two forms in a xhtml file. I just mention that because I don't know if it is important or not. However, there are no nested forms and h:messages displays nothing after page refresh.)
I'm using JSF 2 (MyFaces) + Tomahawk.
there are no nested forms and h:messages displays nothing after page refresh
You've likely a rendered attribute on the component or one of its parents which evaluated false during the processing of the form submit request. You need to ensure that it evaluates the same as it did during displaying the page. You can do this by putting the bean responsible for this in the view scope instead of the request scope.
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated

Resources