This is my ManagedBean:
#Named(value = "mrBean")
#RequestScoped
public class MrBean {
public void laugh() {
System.out.println("HAHAHA");
}
public void prepareToLaugh() {
System.out.println("Drink water.");
}
}
And this is the working version of my commandButton:
<p:commandButton actionListener="#{mrBean.laugh}" widgetVar="laughtButton"
value="Laugh" oncomplete="laughButton.disable();" />
When I clicked the above button, I saw HAHAHA and the button is disabled. However, when I set the laughButton's disable attribute to true, the button does not work anymore:
<p:commandButton actionListener="#{mrBean.laugh}" widgetVar="laughtButton"
value="Laugh" disabled="true" oncomplete="laughButton.disable();" />
<p:commandButton actionListener="#{mrBean.prepareToLaugh}"
value="Prepare to laugh" oncomplete="laughButton.enable();" />
When I click the 2nd button, I saw Drink water and the 1st button is enabled. However, when I click on the 1st button, nothing happens.
I'd be very grateful if someone could give me an advice on how I should tackle this problem. I'm using PrimeFaces 3.0 RC2.
Like as with rendered attribute, JSF re-evaluates the disabled attribute in the server side during processing of the form submit as part of safeguard against tampered requests and like. You're however enabling/disabling it by JS without notifying the server side of the changes.
You need to ensure that the value of the disabled attribute evaluates false during the request whenever you intend the button to be enabled during processing of the form submit. For example, bind it to a boolean property of a view scoped bean which is set by the other button.
<h:commandButton disabled="#{bean.laughDisabled}" />
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated
Related
What is the best approach to disable a commandButton if the fields with required=true are not filled with values?
The button should be disabled on first page load, and only be enabled in case all required fields are fields with values.
By best approach i mean no javascript and minimum-code :-)
In addition it would be excellent if the commandButton is only enabled when all validators evaluate to true.
Using PF 3.2
EDIT
by best approach i also mean, it should only be evaluate on client-side
This is not possible for two reasons.
For client side validation, you would definitely require javascript.
The required attribute of components is stored server side ONLY, the client has no idea of which fields are required by default.
Without using required, you could achieve this in client-side as following. validateContent should contain the logic to disable the commandButton.
<h:inputText value="#{bean.text}" >
<pe:javascript event="keyup" execute="validateContent();"/>
</h:inputText>
If going to server is okay, then you could do this:
<h:inputText id="test1" value="#{bean.text}" required="true" immediate="true">
<f:ajax listener="#{bean.makeDisable()}" render="test2" />
</h:inputText>
</h:commandButton id="test2" value="commandButton1" disabled="#{bean.disable}" />
And in the bean:
private String text;
private boolean disable;
// setter & getter of text
public boolean isDisable()
{
return disable;
}
public void makeDisable(AjaxBehaviorEvent event)
{
if(text == null || text.equals(""))
this.disable=true;
else
this.disable=false;
}
This basically will load the commandButton disabled on initial load and it will only be enabled on entering any value in text field.
It is possible but I would hardly call it the "best way".
You would need to supply an ajax tag for change events on each field. Each field would have to be immediate to skip initial validation and process will need to be set to #this.
In an event listener you can check if values exist for each of the required fields and if so then set a boolean field that determines if the commandButton is disabled or not.
These ajax tags will need to render #this as well as the commandButton.
But even then there is a LOT of Javascript actually going on, just none that you would have to write directly.
Here's my scenario: I'd like to update a page via Ajax in some cases, in other cases, execute a navigation rule. My use case is a login form. I'd like them to receive an error message via ajax if their uname/password fails, but navigate to a new page if it succeeds.
Has anyone done this using JSF2.0 f:ajax apis? I'm not really interested in solutions that go outside standard facelets, jsf2.0, etc.
It's not different from when doing it without ajax. Just return the next view ID as String the usual way via <h:commandXxx action> (and thus not <f:ajax listener>).
So, just
<h:commandButton value="Login" action="#{bean.login}">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
with
public String login() {
// ...
return "nextpage";
}
will work as good as without <f:ajax>. It'll just go to nextpage.xhtml.
See also:
Differences between action and actionListener
JSF f:ajax listener vs commandButton action
I'm using PrimeFaces with JSF 2.0, I have this layout:
<h:panelGroup layout="block" id="panelGroup" binding="#{bean.boundPg}" />
<p:commandButton value="Update" action="#{bean.updateMe}" update="panelGroup" />
in which, the bean is SessionBean. By using log4j to debug I found out that the binding process called getBoundPg before executing the action updateMe. So the view is always out-of-date.
Do you know why and how to reverse that order? Thanks!
------------- Edit ---------------
I'm making a web app for a quiz game.
<h:panelGroup layout="block" id="pgContents" binding="#{bean.boundContents}" />
<p:commandButton value="Prev page" action="#{bean.prevPage}" update="pgContents" />
<p:commandButton value="Next page" action="#{bean.nextPage}" update="pgContents" />
pgContents contains many h:pannelGroups, each sub-group contains a label showing the content of a quiz, a h:inputText for the player to give their answer. Because of some reasons, I had to generate the children of pgContents programmatically.
The Prev page and Next page buttons will retrieve the prev/next group of quiz
Below is the bean (getters & setters are skipped)
#ManagedBean(name = "bean")
#SessionScoped
public class LessonHelper {
private int currentPage;
private HtmlPanelGroup boundContents;
public void prevPage() {
// decrease currentPage
// fetch contents
// add children for boundContents (label, inputText)
}
// nextPage() is similar
}
My problem is that, when I click the Prev/Next button, the getter getBoundContents is called first in binding process, and the prevPage()/nextPage() is called later, which cause the content always out-of-date.
Because this is the natural way, as you can see in this wonderful tutorial by BalusC: http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html
Tell me exactly what do you want to do, show what's inside that bean and a solution to your problem will be found!
I have the following piece of code with a simple h:outputText pointing to a int and a p:commandLink to set a value:
<h:form id="f1">
<h:outputText id="text" value="#{testBean.index}"/>
<p:commandLink actionListener="#{testBean.test}" update="text">
<f:setPropertyActionListener target="#{testBean.index}" value="5" />
<h:graphicImage url="/images.png"/>
</p:commandLink>
</h:form>
The managed bean looks like this:
#javax.faces.bean.ManagedBean #ViewScoped
public class TestBean implements Serializable{
private int index; // getter/setter
#PostConstruct public void init() {
index = 0;log.log(Level.WARNING, "#PostConstruct");}
public void test(ActionEvent ae){
log.log(Level.WARNING, "Index: "+index);}
}
The bean is constructed correctly, and after the first click on the image the h:ouputText is updated to 5. But in my log message I only see Index: 0 during the first click on the image.
It's something similar like Jsf updates model value with old value, but I have the JSF #ManagedBean annotation.
Action listeners are invoked in the order they're definied in the view. You want to use action instead of actionListener. Even more, the action should in first place have been used to invoke a business action.
<p:commandLink action="#{testBean.test}" update="text">
<f:setPropertyActionListener target="#{testBean.index}" value="5" />
<h:graphicImage url="/images.png"/>
</p:commandLink>
See also:
Differences between action and actionListener
What is happening is that the test ActionEvent is getting fired before the request values have been applied.
To get a better understanding of the JSF phase lifecycle and when lifecycle events and ActionEvents fire, implement the Debug PhaseListener as specified in the following blog article.
http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html
This should help you understand when request values are being applied, and when events are being fired.
I use a navigation tool called dock, from primefaces. I need to redirect to another page when i click on one of the items.
The problem is that i need to find an alternative to the url attribute, this is because if i use it, the page gets redirected and the action attribute don't makes a call to the method is supposed to call.
This is how my nav bar looks like:
<h:form>
<p:dock position="top">
<!--Some other menu items ...-->
<p:menuitem value="Logout" icon="unsecuredimages/logout.png" action="#{securityController.logOut}" rendered ="#{!securityController.checkLogged}"/>
</p:dock>
</h:form>
This is the backing bean that is called to do the logout. It works good the only problem is that i don't get redirected.
#ManagedBean
#RequestScoped
public class SecurityController {
#EJB
private IAuthentificationEJB authentificationEJB;
public String logOut() {
authentificationEJB.releaseUserState();
return "main.xhtml";
}
...
As you see i tried to return an String form the backing bean method, but doesn't work.
Could you help me find the way to redirect when i click on the p:menuItem?
Do you know maybe some javascript trick or something similar i can use to get redirected when i click?
Use
return "main.xhtml?faces-redirect=true";