Commandlink with ajax works only on second click [duplicate] - jsf

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.

Related

Is loading triggered from the click of a submit button generated by h:commandButton a full load?

A jsf page contains a form with a commandButton element like <h:commandButton action="#{bean.search}". This submit button will trigger a bean, which then will send more data back to this same jsf page.
Question: after the submit, is the jsf page fully loaded again? or is just the part containing the newly retrieved data reload and other parts are not loaded again?
By default JSF will fully reload the page. This can be tested by looking at the browser network developer tools while submitting the commandButton. If you intend to only render a part of the page - e.g. a label that outputs the result - you can do that by using AJAX.
For example if your commandButton is in a form, by adding
<f:ajax execute="#form" render="#form:result" />
within your commandButton tag, you can specify that only the contents of the form are processed by the server and only the label with the ID 'result' is rendered.
For further information take a look at this guide for AJAX in JSF: https://www.beyondjava.net/a-comprehensive-guide-to-jsf-ajax
You will see that the author shows the full page loading without AJAX.
Alternatively here is the official documentation for <f:ajax>:
https://jakarta.ee/specifications/faces/2.3/vdldoc/f/ajax.html

<p:commandLink> not firing actions at all

I can't make my commandLink fire a bean action.
I've tried calling my bean method with <p:commandButton>, <h:commandLink>, <h:outputLink> and <p:commandLink>.
Also, i've used onclick, onmousedown, action and actionListener and none of those worked.
My code looks like this at the moment:
base.xhtml
<div>
<h:form>
<p:commandLink id="logoutButton" action="#{loginController.logout}">
<p:graphicImage name="/images/logout.png"/>
</p:commandLink>
</h:form>
<!-- Rest of code (layout with some layoutUnits) -->
</div
Bean method (Testing purposes, not the actual method):
public void logout() {
System.out.println("logged out");
}
According to BalusC, my question is duplicated. I had already searched for similar problems before making this question, and guess what? Nothing worked. Looking at same question that has already been answered, here are my answers to the previously described problems:
1 - The commandLink is inside a form.
2 - The commandLink is not in a nested form.
3 - No UIInput value validation/conversion is showing errors.
4 - The commandLink is not inside a iterating component.
5 - As the pages load, the button is not rendered. I've set it to render only if the user log-ins with a commandLink placed in that same form. It is indeed using AJAX.
6 - The onclick attribute of the UICommand component and the onsubmit attribute of the UIForm are not throwing a JavaScript error.
7 - base.xhtml has a <h:head>
8 - The parent of my <h:form> is not being updated/rendered.
9 - Im not using enctype="multipart/form-data" in my form.
10 - I'm not using actionListener.
11 - I'm not using PhaseListener or EventListener.
12 - There is no Filter or Servlet blocking the request to the FacesServlet.
Bonus:
Debugging with Firebug, i've noticed that when i click the logout button i'm getting a code 200 response from the server, meaning it is supposed to be OK.
My form is in a Template file (base.xhtml). After that form, i am using a <p:layout> element and my website code is inside it's <p:layoutUnit>.

Issue with primefaces , Specially p:commandButton

I developed a JSF 2 application using RichFaces first and then migrated to Primefaces recently.
All things are working fine except:
When clicking on a button and calling update="id1, id2, etc", it does not update my page contents.
<p:commandButton value="Logout" action="#{profile.logout}" /> does not work, in logout method I simply clear session and return to login page, but it stays on the same page.
I am using Tomcat 6.0.32 on Windows 7 with 4GB RAM. I m using PrimeFaces 2.2, the latest Stable build.
When clicking on a button and calling update="id1, id2, etc", it does not update my page contents.
You have to provide more context before we can give an answer on that. My first guesses would be that you have to remove those commas (and only separate by spaces like in standard JSF2 and RF4). My second guess would be that those components are simply not resolveable in the current component and NamingContainer hierarchy. My third guess would be that the ajax request didn't return a valid ajax response (use Firebug to check it).
<p:commandButton value="Logout" action="#{profile.logout}" /> does not work, in logout method I simply clear session and return to login page, but it stays on the same page.
The <p:commandButton> sends by default an ajax request. If you want to navigate to a different view as response on an ajax request, then you have to send a redirect. You can do this among others by adding the faces-redirect=true parameter to the outcome:
return "login?faces-redirect=true";
Or, alternatively, just turn off ajax on the button:
<p:commandButton ... ajax="false" />
Or, use the standard <h:commandButton> instead:
<h:commandButton ... />

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

JSF2 ignores Action attribut [duplicate]

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

Resources