Variable in Bean is not holding its value through Button Clicks [duplicate] - ajax

This question already has an answer here:
#SessionScoped bean looses scope and gets recreated all the time, fields become null
(1 answer)
Closed 4 years ago.
This is my first question.
I am trying to increment a variable value in a textbox when a button is clicked using primefaces.
But through debug I found out that whenever I click the p:commandButton, EL bean function call, tries to increment the bean class variable "counter", whenever this happens the value of counter is always 0, so it gets incremented to 1 and that is shown in my webpage. It never reaches 2, 3, 4...
Below is the code:
xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
<h:form>
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel value="Counter:"/>
<h:outputText id="output" value="#{counterView.counter}" />
<p:commandButton value="Count" action="#{counterView.increment}" update="output" />
</h:panelGrid>
</h:form>
</h:body>
</html>
Java:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.view.ViewScoped;
#ManagedBean(name="counterView")
#ViewScoped
public class counterView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2369382392318418242L;
private int counter = 0;
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
public void increment() {
// Counter is 0 always the moment this function is entered...
this.counter = this.counter + 1;
}
}
I cant figure out where I am going wrong as its a classical example in primefaces showcase and I am following that...
Thanks in advance

You use the wrong ViewScoped annotation. You have to use the javax.faces.bean.* annotations in combination with #ManagedBean.
see: #SessionScoped bean looses scope and gets recreated all the time, fields become null

Related

ajax listener inside conditionally rendered element not working [duplicate]

This question already has an answer here:
h:commandButton is not working once I wrap it in a <h:panelGroup rendered>
(1 answer)
Closed 6 years ago.
Here is a test case of my problem:
TestBean:
#ManagedBean
#ViewScoped
public class TestBean implements Serializable {
private static final long serialVersionUID = -2329929006490721388L;
private List<TestObject> testObjects;
private int selectedId;
public TestBean(){
List<TestObject> to = new ArrayList<TestObject>();
for(int i=0; i<10; i++){
TestObject o = new TestObject(i, "object-"+i);
to.add(o);
}
this.setTestObjects(to);
}
public void testAjaxListener(int id){
System.out.println("testAjaxListener("+id+")");
this.setSelectedId(id);
}
//+getters/setters
}
TestObject
public class TestObject {
private int id;
private String name;
public TestObject(int id, String name){
this.setId(id);
this.setName(name);
}
//+getters/setters
}
Test.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head></h:head>
<h:body>
<h:form id="testForm">
<h:panelGroup rendered="#{param['view'] eq 'test'}">
<h2>DataTable</h2>
<h:dataTable var="o" value="#{testBean.testObjects}">
<h:column>
<h:commandLink value="#{o.name}" actionListener="#{testBean.testAjaxListener(o.id)}">
<f:ajax
render=":testForm:outputTest"
/>
</h:commandLink>
</h:column>
</h:dataTable>
<h2>output</h2>
<h:outputText id="outputTest" value="#{testBean.selectedId}" />
</h:panelGroup>
</h:form>
</h:body>
</html>
The problem is, that actionListener won't firing (i'm checking that with System.out.print as you can see). It works fine when i remove conditional render from panelGroup, so i think that is the issue - but how can i fix it?
I have readed those topics:
h:commandLink / h:commandButton is not being invoked,
f:ajax inside conditionally rendered custom tag - backing bean method not invoked
and many more, but it didn't solve my problem :(
Please help
It's because the #{param['view'] eq 'test'} didn't evaluate true while JSF is busy processing the ajax submit. It will then also consult the rendered, disabled and readonly attributes once again as safeguard against hacked requests. JSF namely doesn't include the request parameters in the <form action> URL as generated by <h:form>. This matches point 5 of commandButton/commandLink/ajax action/listener method not invoked or input value not updated.
There are several ways to get around this.
Set it as a property of the view scoped bean via <f:viewParam>.
<f:metadata>
<f:viewParam name="view" value="#{testBean.view}" />
</f:metadata>
...
<h:panelGroup rendered="#{testBean.view eq 'test'}">
Manually retain the param via <f:param> (you need to put it in every submit action!):
<h:commandLink ...>
<f:param name="view" value="#{param.view}" />
...
</h:commandLink>
Replace <h:form> by OmniFaces <o:form> which is capable of telling JSF that it must submit the form to an URL including the request parameters:
<o:form includeRequestParams="true">
...
</o:form>
See also:
Retaining GET request query string parameters on JSF form submit

PrimeFaces Ajax call only once through the entire application

I am developing a fairly large web application. Suddenly the other day, primefaces ajax only work out once and then not work more.
This problem applies to all primefaces ajax call through the entire application.
I've tried everything and even tried to make a new jsf project in netbeans with the code that you see below. And the same thing, backbean method is called only once. I can see the call in the scriptconsolen firefox, but the backbean method is never called, I get no error.
What could this be caused by? If I replace the primefaces ajax call against the regular jsf ajax, it works.
My set:
NetBeans 7.3
JSF 2.2
PrimeFaces 3.5
GlassFish 3.1.2
I've also tried with the following set and get the same results:
Netbeans 7.4
JSF 2.2
PrimeFaces 3.5
GlassFish 4.0
add() only calls at first click.
Backbean:
package temp;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "backbean")
#SessionScoped
public class Backbean implements Serializable{
private int value = 0;
private int temp = 0;
public Backbean()
{
}
public void setTemp(int temp)
{
this.temp = temp;
}
public int getTemp()
{
return temp;
}
public void add()
{
value += temp;
temp = 0;
}
public void setValue(int value)
{
this.value = value;
}
public int getValue()
{
return value;
}
}
View:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
<h:form>
<h:inputText value="#{backbean.temp}"/>
<h:outputText value="#{backbean.value}"/>
<h:commandButton value="Test" type="button">
<p:ajax listener="#{backbean.add()}" update="#form" process="#form" />
</h:commandButton>
</h:form>
</h:body>
</html>
solution:
I tried to replace the primefaces 3.5 the primefaces 4.0 and then worked ajax calls as they should.
Why?
Depend on what you are trying to achieve here, If you want to use JSF h:commandButton then replace p:ajax with f:ajax and add action="#{backbean.add()}" to your h:commandButton (removed the listener) from your p:ajax and replace the update with render and process with execute
If you want to use p:commandButton than remove the p:ajax and add the action="#{backbean.add()}" update="#form" process="#form" to your p:commandButton
In general:
Use <p:ajax inside primefaces components and use <f:ajax inside pure JSF components

Primefaces: Ajax update with RequestContext running only once

I have a component on my view which i want to update from my bean.
It works only once. If i press the second button nothing happen, but the bean method in the actionlistener was called.
I checked the browser log with firebug and have no errors or something else which looks odd.
My Bean is in ViewScope. I'm using primefaces 3.5.
JSFPage:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:body>
<h:form id="myRootForm">
<p:inputText id="text1" styleClass="myChangeClass" disabled="true" />
</h:form>
<h:form>
<p:commandButton value="Activate Insert"
actionListener="#{controller.activate()}" update=":myRootForm" />
<p:commandButton value="Deactivate"
actionListener="#{controller.resetFields()}" update=":myRootForm" />
</h:form>
</h:body>
</html>
This is the EJB code:
import javax.faces.component.UIViewRoot;
import javax.faces.component.html.HtmlInputText;
import javax.faces.context.FacesContext;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ViewAccessScoped;
import java.io.Serializable;
import javax.inject.Named;
#ViewAccessScoped
#Named("controller")
public class Controller {
private UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
public void activate() {
HtmlInputText text = (HtmlInputText)
viewRoot.findComponent("myRootForm:text1");
text.setDisabled(false);
RequestContext.getCurrentInstance().update(text.getClientId());
}
public void deactivate() {
HtmlInputText text = (HtmlInputText)
viewRoot.findComponent("myRootForm:text1");
text.setDisabled(true);
RequestContext.getCurrentInstance().update(text.getClientId());
}
}
** Update:
I made the example a bit better to read.
When i'm using the "RequestScope" it is working, but i need the viewScope to hold my information.
For a better understanding why i want to do it this way:
I have several input components which i want to be available in several mode's.
The mode is indicated in a StyleClass (i.e. myChangeClass).
When i press the button i go through the component tree of my form and searching for the styleclass and activiate the buttons. I don't want to do this by holding for every component an attribute in my bean.
I don't know exactly what you're trying to achieve. I've added example below to help you.
XHTML code
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form id="myRootForm">
<p:inputText id="text1" disabled="#{tBean.enabled}" />
<p:commandButton value="Activate Insert"
actionListener="#{tBean.enable}" update=":myRootForm" />
<p:commandButton value="Deactivate" actionListener="#{tBean.disable}"
update=":myRootForm" />
</h:form>
</h:body>
</html>
ManagedBean Code
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
#ManagedBean(name = "tBean")
#ViewScoped
public class TestBean {
private boolean enabled;
public void enable(ActionEvent e) {
enabled = false;
}
public void disable(ActionEvent e) {
enabled = true;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
Try above and see if that helps.

retaining values across screen sin JSF2.0

I am working on JSF2.0 project where I need to get value in backing bean from previous screen I have explained it below
my first screen
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
>
<h:body>
<h:form>
<h:outputText value="LocationID" />
<h:inputText value="#{getDetails.locationID}"/>
<h:commandButton value="Add OS" action="#{getDetails.addOSDetails}"/>
</h:form>
</h:body>
</html>
My backing bean when the commandButton is invoked
#ManagedBean(name="getDetails")
#RequestScoped
public class GetDetailsBean {
private String locationID;
public String getLocationID() {
return locationID;
}
public void setLocationID(String locationID) {
this.locationID = locationID;
}
public String addOSDetails(){
return "/app_pages/addOS";
}
}
My second screen which is addOS is
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
>
<h:body>
<h:form>
<h:outputText value="Enter Value" />
<h:inputText value="#{addOS.addValue}"/>
<h:commandButton value="Add OS" action="#{addOS.save}"/>
</h:form>
</h:body>
</html>
I want the LocationID entered in the first screen to be available in this backing bean
#ManagedBean(name="addOS")
#RequestScoped
public class AddOS {
private String addValue;
public String getAddValue() {
return addValue;
}
public void setAddValue(String addValue) {
this.addValue = addValue;
}
public String save(){
return "app_pages/success";
}
}
I donot want values to be set in session.Can be used.
Thoughts and help please
Thanks.
If you really intend to do a forward, as you do in your question, the submitted on the first page data is already there when the second page is rendered: remember, the forward is done within the same HTTP request. So, what you ultimately need is to keep the value for a subsequesnt POST request. You can do it, for example, by storing the information is a hidden field on the second page:
<h:inputHidden value="#{getDetails.locationID}" />
And that's basically it.
If you intend to do a redirect, thus by appending ?faces-redirect=true to a navigation case outcome, you need to store that information in EL flash to be able to retrieve it in the recepient page: there are two requests to be done. So, change your first bean's action method to the following:
public String action() {
...
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("locationID", locationID);
return "result?faces-redirect=true";
}
This way on the recepient page it will be available in flash map, thus by
#{flash.locationID}
in EL scope and
(String)FacesContext.getCurrentInstance().getExternalContext()
.getFlash().get("locationID");
in Java code.

Primefaces commandButton calls action method on page refresh

Completely edited:
Maybe I was mixing problems and misinterpreted. After simplifying my code the question simplifies to: How can I prevent the <p:commandButton> from executing it's action method on page refresh (like when you hit F5 inside browser window)?
JSF Code:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:body>
<h:form>
<h:outputText value="#{bugBean.number}" />
<h:outputText value="#{bugBean.isComplete()}" />
<p:commandButton id="entryCommand" value="add"
action="#{bugBean.increase()}" update="#form" oncomplete="#{bugBean.complete()}"/>
</h:form>
</h:body>
</html>
backing bean code:
package huhu.main.managebean;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class BugBean implements Serializable {
private static final long serialVersionUID = 1L;
private int number;
private boolean isComplete = false;
public void increase(){
number++;
}
public void complete(){
isComplete = true;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public boolean isComplete() {
return isComplete;
}
public void setComplete(boolean isComplete) {
this.isComplete = isComplete;
}
}
Update:
Even if I remove the oncomplete stuff like this an click the <p:commandButton> just once, the counter goes up on every page refresh.
<h:form>
<h:outputText value="#{bugBean.number}" />
<p:commandButton id="entryCommand" value="add"
action="#{bugBean.increase()}" update="#form"/>
</h:form>
The construct was lacking Ajax-support due to a missing head definition as it seems. In this case I just added <h:head/> right above the <h:body>-tag and everything worked fine.
Thanks to all contributors!
I think that the action method increase() is not called on each page refresh, but it's called the complete() method instead, and this is probably making you think that the action method has been called.
The oncomplete attribute inside the p:commandButton indicates a client side action, and so a JS method, and not a server action: the EL executes #{bugBean.complete()} when parses it on each page refresh.

Resources