<p:commandButton> not working when disable="true" initially - jsf

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

hiding and showing commandButton in jsf

I am new to JSF(PrimeFaces).
I have two commandButtons Do and Undo. I want only one button to be visible at one time.
like, When I click Do button, onclicking Do button should hide(performing its action simultaneously) and Undo button should be visible
and when i click Undo button onclicking it should hide and Do button should come back to active
I tried using
enable() and disable() methods but were of no use.
Can I get some help in achieving this. any predefined methods available?
Heard rendered attribute will help but couldnt understand what exactly will the attribute do .
Can someone explain pls
JSF rendered attribute will define if the component should be rendered/visible or not.
If
<h:commandButton value="Undo" rendered="#{false}" />
Then your above Undo button will be hidden.
rendered attribute can be bound to a ManagedBean property. In case if you want this dynamic, you have to update the component to see the result.
Here is a Small Example:
XHTML:
<h:panelGroup id="doBtnPG">
<h:commandButton value="Do" rendered="#{myBean.showDo}" action="#{myBean.doAction}">
<f:ajax render="unDoBtnPG"/>
</h:commandButton>
</h:panelGroup>
<h:panelGroup id="unDoBtnPG">
<h:commandButton value="Un Do" rendered="#{myBean.showUndo}" action="#{myBean.undoAction}">
<f:ajax render="doBtnPG"/>
</h:commandButton>
</h:panelGroup>
ManagedBean:
#ManagedBean
#ViewScoped
public class MyBean{
private boolean showDo=true;
private boolean showUndo=true;
public void doAction(){
showUndo=false;
}
public void undoAction(){
showDo=false;
}
//SETTER and GETTERS
}
In the above example, on clicking on one button the corresponding action method makes the property on which other button is being rendered as false, f:ajax will re render/update the other button's panelGroup to reflect the changes.
Since you marked this question as Primefaces, here is the XHTML code for Primefaces:
<h:panelGroup id="doBtnPG">
<p:commandButton value="Do" rendered="#{myBean.showDo}"
action="#{myBean.doAction}" update="unDoBtnPG"/>
</h:panelGroup>
<h:panelGroup id="unDoBtnPG">
<p:commandButton value="Un Do" rendered="#{myBean.showUndo}"
action="#{myBean.undoAction}" update="doBtnPG"/>
</h:panelGroup>
Notice that on Primefaces commandButtons you dont need to use f:ajax or p:ajax explicitly because they are Ajax by default.
Please note that the functions enable() and disable() provided by Primefaces are only client side. When disabled attribute is false and if you enable the button using enable(), it will not fire your action method.

Primefaces commandButton not updating datatable. Is update attribute required

I changed my <h:commandButton> tag to a PrimeFaces <p:commandButton> tag on a search page and my datatable stopped displaying the results. After adding an update attribute things worked again. I'm just trying to understand whether it is how I implemented the overall functionality (viewscope, action vs actionListener, etc) or is the update attribute really required?
<h:form id="search_form">
<p:inputText id="search" value="#{searchBean.searchString}" />
<p:commandButton update="search_form" value="Search" action="#{searchBean.searchByString}" >
</p:commandButton>
<p:dataTable id="output" var="res" value="#{searchBean.results}" emptyMessage="No results found with given criteria">
etc...
#ViewScoped
#ManagedBean
public class SearchBean {
#Inject
private SearchRepository searchRepository;
private List<Results> res;
private String searchString;
public SearchBean() {
}
public String searchByString()
{
this.setRes(searchRepository.searchBySingleString(searchString));
}
One of the differences between h:commandButton and p:commandButton is that the second one performs an ajax request by default, while the first executes a plain POST request.
In an ajax request, you must specify what you want to process when form is sent and what to update when response happens. The p:commandButton updates nothing by default, that's why your table is not being properly filled.
See also:
Prime Faces Command Button vs. Default Command Button
Primefaces commandButton

How can I change a bean property with a button

I'm trying to create a button that once clicked will change a property in a bean.
<h:commandButton type="button" action="#{loginBean.withdraw}" id="thousand" class="buttons" style="top:180px;left:570px;">
<f:setPropertyActionListener target="#{loginBean.withdrawAmount}" value="1000" />
</h:commandButton>
public class LoginBean {
int withdrawAmount;
This method only works when I omit the type="button" from the commandButton, but with the type="button" it doesn't work and I'm not sure why.
I need the type="button" to be there , is there any way to keep it and still make it work ?
There is an error in your facelet snippet:
There is no such attribute as class for <h:commandButton>. Possibly you meant styleClass.
As for the problem you have, you have to:
Either provide a setter method for the withdrawAmount property
public void setWithdrawAmount(int withdrawAmount) {
this.withdrawAmount = withdrawAmount;
}
and your facelet should look like:
<h:commandButton type="submit"
action="#{loginBean.withdraw}"
id="thousand"
styleClass="buttons"
style="top:180px;left:570px;">
<f:setPropertyActionListener target="#{loginBean.withdrawAmount}"
value="1000" />
</h:commandButton>
Or, you can get rid of the <f:setPropertyActionListener> and add a statement the changes the value of the withdrawAmount as a first line of the #{loginBean.withdraw} method.
In this case your facelet snippet should look like:
<h:commandButton type="submit"
action="#{loginBean.withdraw}"
id="thousand"
styleClass="buttons"
style="top:180px;left:570px;" />
and your LoginBean#withdraw() method should start with the statement, that changes the withdrawAmount value:
public String withdraw() {
this.withdrawAmount = 1000;
//the remaining logic.
}
Personally, I would prefer the first option.
More info:
< h:commandButton > tag reference
JSF Core Tag :setPropertyActionListener vs attribute vs param
The type is the entire reason why you're having this issue. I'm posting this answer because the accepted answer doesn't explain why you're experiencing the issue.
<h:commandButton/> is designed to work in 3 modes:
submit: This is the default mode that the button is set to. This mode sends an HTTP POST request to the server that triggers the JSF request processing lifecycle. It's only this mode that enables you to trigger backing bean methods(using the action or actionListener attributes).
button: This mode triggers a GET request in the application. As GET requests go, this mode is mostly suited for navigation, i.e. requesting another view or page. In this mode, there's no easy/straightforward way to execute backing bean code, or trigger the JSF request processing lifecycle. This is your current issue
reset: This mode simply resets the value of all input components within its enclosing <h:form/>
Reference:
JSF2 Command Button VDL
JSF redirect via commandButton
Difference between h:button and h:commandButton

java ee - JSF 2.0 ViewScoped Bean after redirect to new window NPE

I use tip from this post https://stackoverflow.com/a/13838907 to open new tab, however when I go back to old one I get nullPointerException and my ViewScoped bean data are lost.
<h:form target="_blank">
<p:commandButton value="open new tab" action="#{otherBean.newTab}" ajax="false" />
</h:form>
<h:form>
<p:commandButton value="this wll cause NPE" action="#{pageBean.action}"/>
</h:form>
Click first button, go back to previous tab, click second button. PageBean is created once again and all data are lost. Both beans are ViewScoped.
Indeed, the view scoped bean in the initial tab/window get killed by returning a String navigation case outcome. You would like to return null or void to keep it alive. Based on the newTab() code as shown in your other question, you need to replace the navigation case by a Faces#redirect() call (assuming that it's indeed OmniFaces which you're using there for Faces#setFlashAttribute()). You only need to set Flash#setRedirect() to true beforehand to instruct the flash scope that a redirect will occur.
public void newTab() throws IOException {
Faces.setFlashAttribute("foo", bar);
Faces.getFlash().setRedirect(true);
Faces.redirect("otherView.xhtml");
}
ViewScope beans only live as long as you post back to same view.
If you post back to other views in your action data will be lost since the ViewScope bean will be recreated.

Re-enabled p:commandButton not firing ajax

If I initiate a commandButton disabled the AJAX event does not fire even after re-enabling the button.
<p:commandButton id="btnAJAX" value="AJAX" widgetVar="btnAJAX" disabled="true" action="#{bean.neverReached()}"/>
<p:commandButton id="btnEnabler" value="Enable" oncomplete="btnAJAX.enable()"/>
Similar problem identitifed here : http://forum.primefaces.org/viewtopic.php?f=3&t=7817
I am using primefaces 3.0.1 and JDK 1.7
Is there any solution to this?
You need to enable the button by JSF, not by JavaScript/HTML DOM. During processing of the form submit, JSF will verify in the server side view state as well if the button is enabled or not, as part of safeguard against tampered requests.
E.g.
<p:commandButton id="btnAJAX" value="AJAX" action="#{bean.someAction}" disabled="#{!bean.enabled}" />
<p:commandButton id="btnEnabler" value="Enable" action="#{bean.enableButton}" process="#this" update="btnAJAX" />
with
private boolean enabled;
public void enableButton() {
enabled = true;
}
public boolean isEnabled() {
return enabled;
}
Make sure that the bean is at least #ViewScoped and not #RequestScoped, otherwise the action of button will still fail because the bean is recreated during the form submit request and thus the enabled property will become the default value, which is false.
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated

Resources