I want to take the input from two input fields and simultaneous compute the sum into another input field (total) that must be editable however. I tried like that (I cutted away some code useless to the question):
<p:inputText id="field1"
value="#{ModelBean.object.field1}"
onkeydown="#{BackingBean.updateTotal()}">
</p:inputText>
<p:selectOneMenu id="field2" required="true"
value="#{ModelBean.object.field2}">
<f:selectItem itemLabel="22 %" itemValue="22" />
<f:selectItem itemLabel="10 %" itemValue="10" />
<f:selectItem itemLabel="4 %" itemValue="4" />
<f:selectItem itemLabel="0 %" itemValue="0" />
</p:selectOneMenu>
<!-- TOTAL -->
<p:inputText id="total"
value="#{ModelBean.object.total}">
</p:inputText>
As you can see I delegated tho BackingBean.update() method the compute task. It updates the total value and set it into the total field of the bean. The problem that I saw in debug is that the values of my two fields to sum is null. How I can do to let the model variables filled while I am writing? And What I have to modify to let the result of the compute immediately written in the total input filed?
Rather than this you can use Ajax for this:
<p:inputText id="field1" value="#{ModelBean.object.field1}">
<f:ajax event="change" execute="#this" render="total" listener="#{BackingBean.updateTotal}"></ajax>
</p:inputText>
<p:selectOneMenu id="field2" required="true"
value="#{ModelBean.object.field2}">
<f:selectItem itemLabel="22 %" itemValue="22" />
<f:selectItem itemLabel="10 %" itemValue="10" />
<f:selectItem itemLabel="4 %" itemValue="4" />
<f:selectItem itemLabel="0 %" itemValue="0" />
<f:ajax event="change" execute="#this" render="total" listener="#{BackingBean.updateTotal}"></ajax>
</p:selectOneMenu>
<!-- TOTAL -->
<p:inputText id="total" value="#{ModelBean.object.total}">
</p:inputText>
I think you need to put ajax in both components, because to are getting sum on the basis of values of both. And if you don't want to use "Change" event than you can use some other event of ajax.
create project and include it
<?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:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="3">
<h:outputText value="Keyup: " />
<p:inputText id="counter2" value="#{listenerView.a}">
<p:ajax event="keyup" update="out" listener="#{listenerView.handleKeyEvent}"/>
</p:inputText>
<p:inputText id="counter" value="#{listenerView.b}">
<p:ajax event="keyup" update="out" listener="#{listenerView.handleKeyEvent}" />
</p:inputText>
<h:outputText id="out" value="#{listenerView.c}" />
</h:panelGrid>
</h:form>
</h:body>
</html>
package org.primefaces.showcase.view.ajax;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class ListenerView {
private String text;
private int a;
private int b;
private int c;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public void handleKeyEvent() {
c=a+b;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public int getC() {
return c;
}
public void setC(int c) {
this.c = c;
}
}
If you want to use the inserted value on the server side to do some calculations, you have to (partially) submit the form first. You may do this via AJAX like this:
<p:inputText id="field1"
value="#{ModelBean.object.field1}">
<p:ajax event="keyup" listener="#{BackingBean.updateTotal}" update="total"/>
</p:inputText>
<p:selectOneMenu id="field2" required="true"
value="#{ModelBean.object.field2}">
<f:selectItem itemLabel="22 %" itemValue="22" />
<f:selectItem itemLabel="10 %" itemValue="10" />
<f:selectItem itemLabel="4 %" itemValue="4" />
<f:selectItem itemLabel="0 %" itemValue="0" />
<p:ajax listener="#{BackingBean.updateTotal}" update="total"/>
</p:selectOneMenu>
<!-- TOTAL -->
<p:inputText id="total"
value="#{ModelBean.object.total}">
</p:inputText>
If all information which is required for the calculation is available on the current view and the calculation is quite easy, like it seems to be here, you may also consider to do the job completely on the client side via plain JavaScript.
Related
Hope you could help me
I am learning JSF and Primesface on my own.
I having trouble implementing the following JSF form, and make it work as I require it
Basically
I need to have one Form, and need to execute AJAX whenever a value change in the Form.
I am not able to make that Once Single Ajax call call for entrie form.
Rather I have to call it for every Data Input I have to call.
Second the Date Picker does not work or loses it formatting after selecting date.
Note I have not any additional Java Script... to the JSF.
Please refer additional image that I have attached
Further is that Possible to provide Single Ajax in case any inputs changes in the FORM, instead of each inputs tags.
What is difference between f:ajax and p:ajax
JSF 2.3 Dynamic Web Module 4.0 Redhat JBOSS 7.2 Java 1.8 Primefaces
7.0
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:form styleClass="fill" id="tinputForm">
<div style="color: #FFF; padding-left: 70px"><strong >INPUT PANEL</strong></div>
<hr/>
<h:panelGroup layout="block" styleClass="CustomWell" >
<h:outputLabel value="Server-Class"/>
<h:panelGroup layout="block" styleClass="radio">
<h:selectOneRadio value = "#{sideBarInputsBean.serverClass}" layout="pageDirection" >
<f:selectItem itemValue = "Gateway" itemLabel = "Gateway" />
<f:selectItem itemValue = "Facing Server" itemLabel = "Facing Server" />
<f:selectItem itemValue = "Server Facing" itemLabel = "Server Facing" />
<f:selectItem itemValue = "Central Server" itemLabel = "Central Server" />
<!-- <p:ajax listener="#{sideBarInputsBean.printSelectedCRadioButton()}" /> -->
<f:ajax event="click" listener="#{sideBarInputsBean.printSelectedCRadioButton()}" execute="#form" render="#form :tinputForm" />
</h:selectOneRadio>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="CustomWell" >
<h:outputLabel value="Choose a Parameter:"/>
<h:panelGroup layout="block" styleClass="radio">
<h:selectOneRadio value = "#{sideBarInputsBean.parameter}" layout="pageDirection" >
<f:selectItem itemValue = "IISLOG" itemLabel = "IIS Log Counter" />
<f:selectItem itemValue = "ASPNET" itemLabel = "ASP DOT Net Counters" />
</h:selectOneRadio>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="CustomWell" >
<h:outputLabel value="Select a Server:"/>
<h:panelGroup rendered="#{sideBarInputsBean.serverClass == 'Gateway'}">
<h:panelGroup layout="block" >
<h:selectOneMenu id="CLGWServer" value="#{sideBarInputsBean.serverName}" styleClass="mymenu">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{dataForSideBarInputBean.clientGatewayList}" />
<f:ajax event="change" listener="#{sideBarInputsBean.printSelectedCRadioButton()}" execute="#form" render="#form :tinputForm" />
</h:selectOneMenu>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup rendered="#{sideBarInputsBean.serverClass == 'Facing Server'}">
<h:panelGroup layout="block" >
<h:selectOneMenu id="CFASServer" value="#{sideBarInputsBean.serverName}" styleClass="mymenu">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{dataForSideBarInputBean.clientFacingList}" />
<f:ajax event="change" listener="#{sideBarInputsBean.printSelectedCRadioButton()}" execute="#form" render="#form :tinputForm" />
</h:selectOneMenu>
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="CustomWell" >
<h:panelGroup layout="block" styleClass="datepick">
<p:outputLabel value="Date:" />
<p:datePicker id="DateSelector" value="#{sideBarInputsBean.selectedDate}" showIcon="true" showTime="true" pattern="dd.MM.yyyy">
<f:ajax event="dateSelect" listener="#{sideBarInputsBean.printSelectedCRadioButton()}" execute="#form" render="#form :tinputForm" />
</p:datePicker>
</h:panelGroup>
</h:panelGroup>
</h:form>
Bean Code.
package cdv.mrdataanalytics.bean;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Named;
#Named("sideBarInputsBean")
#SessionScoped
public class SideBarInputsBean implements Serializable {
private static final long serialVersionUID = 1L;
private String serverClass="Gateway";
private String parameter="IISLOG";
private String serverName="";
private Date selectedDate;
public String getServerClass() {
return this.serverClass;
}
public void setServerClass(String strClass) {
this.serverClass = strClass;
}
public String getParameter() {
return this.parameter;
}
public void setParameter(String strClass) {
this.parameter = strClass;
}
public String getServerName() {
return this.serverName;
}
public void setServerName(String strClass) {
this.serverName = strClass;
}
public Date getSelectedDate() {
return this.selectedDate;
}
public void setSelectedDate(Date date7) {
this.selectedDate = date7;
}
public void printSelectedCRadioButton() throws IOException{
System.out.println("Selected value = "+this.getServerClass());
System.out.println("Parameter value = "+this.getParameter());
System.out.println("ServerName = "+this.getServerName());
System.out.println("SelectedDate = "+this.getSelectedDate());
//ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
//ec.redirect(ec.getRequestContextPath() + "/next.xhtml?action=add");
}
}
This question already has answers here:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
(5 answers)
Closed 6 years ago.
I have an selectOneMenu and when Its value at 0, I want to "Add" button does not show up. I have rendered for this situation. Here is code ;
<p:panelGrid id="pnlRegister" columns="6" style="width: 95%" >
<p:inputText id="name" class=" width100" value="#{register.name}" />
<p:selectOneMenu id="numberOfChild" value="#{register.numberOfChild}" >
<p:ajax listener="#{register.listenNumberOfChild()}" update="pnlRegister" />
<f:selectItem itemValue="0" itemLabel="0" />
<f:selectItem itemValue="1" itemLabel="1" />
<f:selectItem itemValue="2" itemLabel="2" />
<f:selectItem itemValue="3" itemLabel="3" />
<f:selectItem itemValue="4" itemLabel="4" />
<f:selectItem itemValue="5" itemLabel="5" />
</p:selectOneMenu>
<p:commandButton id="addPerson" value="Add" actionListener="#{register.openPersonDialog(1)}" rendered="#{register.visibleAddPersonButton}" >
<p:ajax event="dialogReturn" update="pnlPerson" />
</p:commandButton>
And Bean code;
public void listenNumberOfChild() {
if (numberOfChild == 0) {
visibleAddPersonButton = false;
} else {
visibleAddPersonButton = true;
}
System.out.println("ListenerNumberOfChild " + numberOfChild);
}
</panelGrid>
Now problem is, when I change numberOfChild, listener works uptades pnlRegister as expected. However server does not keep inputText values. For example before listener works, I write register.name as "John". After listener works, it does not keep it and it gets as null. I hope I could tell what I'm trying and what is problem. So do you have any suggestion ? Also I tried RequestContext.getCurrentInstance().update but same problem occured.
This is how I made it work:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<f:view>
<h:head>
<title>pfaces</title>
</h:head>
<h:form>
<p:panelGrid id="pnlRegister" columns="3" style="width: 95%">
<p:inputText id="name" value="#{register.name}"/>
<p:selectOneMenu id="numberOfChild" value="#{register.numberOfChild}">
<p:ajax process="name numberOfChild"
listener="#{register.listenNumberOfChild()}" update="pnlRegister"/>
<f:selectItem itemValue="0" itemLabel="0"/>
<f:selectItem itemValue="1" itemLabel="1"/>
<f:selectItem itemValue="2" itemLabel="2"/>
</p:selectOneMenu>
<p:commandButton id="addPerson" value="Add"
rendered="#{register.visibleAddPersonButton}"/>
</p:panelGrid>
</h:form>
<h:body>
</h:body>
</f:view>
</html>
and the backing bean:
package biz.tugay.jsfexampla;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class Register {
private boolean visibleAddPersonButton = false;
private int numberOfChild = 0;
private String name;
public boolean isVisibleAddPersonButton() {
return visibleAddPersonButton;
}
public void setVisibleAddPersonButton(boolean visibleAddPersonButton) {
this.visibleAddPersonButton = visibleAddPersonButton;
}
public int getNumberOfChild() {
return numberOfChild;
}
public void setNumberOfChild(int numberOfChild) {
this.numberOfChild = numberOfChild;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void listenNumberOfChild() {
visibleAddPersonButton = numberOfChild != 0;
System.out.println("ListenerNumberOfChild " + numberOfChild);
}
}
Here, you can see it in action: https://youtu.be/IQN3HAejhcM
I am having a strange issue with the Faces messages.
Sometimes, the <p:growl>, <p:messages> display correctly the notification after executing some method. But there are specific JSF pages where no notification is shown.
For example:
public String create() {
try {
getFacade().create(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("NotaCreated"));
return prepareCreate();
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
return null;
}
}
The method is called in
<h:commandLink action="#{notaController.create}" value="#{bundle.CreateNotaSaveLink}"/>
And it does not show the notification. But for other entities as well as for other operations the messages are displayed correctly. This happens also in other functions, where I need feedback and it is not shown as expected.
I've been searching around and read this post and tried some of the suggested solutions, including setting the ajax=false attribute in commandButtons and commandLinks or using the scripts posted, but none of that worked for me, so I ask this question hoping that someone can help me.
Do I have to configure something to make it work correctly? I need this to get fixed by tomorrow and I don't know what else to do.
Update:
These are the JsfUtil methods:
public static void addSuccessMessage(String msg) {
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
FacesContext.getCurrentInstance().addMessage("successInfo", facesMsg);
}
public static void addErrorMessage(Exception ex, String defaultMsg) {
String msg = ex.getLocalizedMessage();
if (msg != null && msg.length() > 0) {
addErrorMessage(msg);
} else {
addErrorMessage(defaultMsg);
}
}
This is the Create.xhtml
<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"
xmlns:p="http://primefaces.org/ui">
<ui:composition template="/template.xhtml">
<ui:define name="title">
<h:outputText value="#{bundle.CreateNotaTitle}"></h:outputText>
</ui:define>
<ui:define name="body">
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
</h:panelGroup>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="#{bundle.CreateNotaLabel_fecha}" for="fecha" />
<p:calendar value="#{notaController.selected.fecha}" id="fecha"/>
<h:outputLabel value="#{bundle.CreateNotaLabel_observaciones}" for="observaciones" />
<p:inputTextarea rows="4" cols="30" id="observaciones" value="#{notaController.selected.observaciones}" title="#{bundle.CreateNotaTitle_observaciones}" />
<h:outputLabel value="#{bundle.CreateNotaLabel_tipoNota}" for="tipoNota" />
<p:selectOneMenu id="tipoNota" value="#{notaController.selected.tipoNota}" required="true" requiredMessage="#{bundle.CreateNotaRequiredMessage_tipoNota}">
<f:selectItem itemLabel="---"/>
<f:selectItem itemValue="debito" itemLabel="Débito"/>
<f:selectItem itemValue="credito" itemLabel="Crédito"/>
</p:selectOneMenu>
<h:outputLabel value="#{bundle.CreateNotaLabel_monto}" for="monto" />
<p:inputText id="monto" value="#{notaController.selected.monto}" title="#{bundle.CreateNotaTitle_monto}" required="true" requiredMessage="#{bundle.CreateNotaRequiredMessage_monto}"/>
<h:outputLabel value="#{bundle.CreateNotaLabel_factura}" for="factura" />
<p:selectOneMenu id="factura" converter="#{facturaController.convertidor}" value="#{notaController.selected.factura}" filter="true" filterMatchMode="startsWith" required="true" requiredMessage="#{bundle.CreateNotaRequiredMessage_factura}">
<f:selectItem itemLabel="---"/>
<f:selectItems value="#{facturaController.facturas}" var="factura" itemValue="#{factura}" itemLabel="#{factura.idFactura}" />
</p:selectOneMenu>
</h:panelGrid>
<br />
<h:commandLink action="#{notaController.create}" value="#{bundle.CreateNotaSaveLink}">
<f:setPropertyActionListener value="#{cargaController.crearCargaDefault(sesionMB.usuario)}"
target="#{notaController.selected.carga}"/>
</h:commandLink>
<br />
<br />
<h:commandLink action="#{notaController.prepareList}" value="#{bundle.CreateNotaShowAllLink}" immediate="true"/>
<br />
<br />
<h:link outcome="/inicio" value="#{bundle.CreateNotaIndexLink}"/>
</h:form>
</ui:define>
</ui:composition>
I had the same problem. The faces message wasn't rendering it was being lost. I tried this code and it worked.
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
FacesContext context = FacesContext.getCurrentInstance();
context.getExternalContext().getFlash().setKeepMessages(true);
context.addMessage("successInfo", facesMsg);
I hope it works.
I'm developing a webshop and I'm facing problems with getting input values from JSF components in the backing bean. I have a datatable, which dynamically loads records from a database table. I want the user to be able to select the amount of items they want to buy and click a button to add them to their shoppingcart. I'm using a dropdownbox to allow the user to select a value, but no matter what value is selected, the value I get in my backing bean is always 1. Any help would be greatly appreciated.
Here's the code for the jsf page
<!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"
xmlns:p="http://primefaces.org/ui">
<ui:composition template="/WEB-INF/templates/basictemplate.xhtml">
<ui:define name="content">
<h:form id="form">
<p:dataTable var="necklace" value="#{necklaceBean.necklaces}" paginator="true" rows="10" id="necklaceTable" binding="#{necklaceBean.dataTableNecklaces }"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}">
<f:facet name="header">
Kettingen
</f:facet>
<p:column headerText="Foto" id="picture">
<p:lightBox styleClass="imagebox">
<h:outputLink value="#{necklace.picture }" title="#{necklace.productId }">
<h:graphicImage url="#{necklace.picture }" width="175" height="116"/>
</h:outputLink>
</p:lightBox>
</p:column>
<p:column headerText="Omschrijving" id="description">
<p>
#{necklace.description}
</p>
<p>
Prijs: #{necklace.price} Euro
</p>
<p>
<p:selectOneMenu value="#{necklaceBean.amount}">
<f:selectItem itemLabel="1" itemValue="1" />
<f:selectItem itemLabel="2" itemValue="2" />
<f:selectItem itemLabel="3" itemValue="3" />
<f:selectItem itemLabel="4" itemValue="4" />
<f:selectItem itemLabel="5" itemValue="5" />
<f:selectItem itemLabel="6" itemValue="6" />
<f:selectItem itemLabel="7" itemValue="7" />
<f:selectItem itemLabel="8" itemValue="8" />
<f:selectItem itemLabel="9" itemValue="9" />
<f:selectItem itemLabel="10" itemValue="10" />
</p:selectOneMenu>
X
<p:commandButton value="Toevoegen aan winkelwagentje" action="#{necklaceBean.addNecklaceToShoppingCart}"
disabled="#{necklace.soldOut}" ajax="false" />
</p>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
</html>
And here's the backing bean:
import java.util.List;
import org.primefaces.component.datatable.DataTable;
import be.petitefolie.site.controller.controllerobjects.Product;
import be.petitefolie.site.controller.controllerobjects.ProductType;
public class NecklaceBean extends ProductBean {
private List<Product> necklaces;
private int amount;
private DataTable dataTableNecklaces;
public NecklaceBean(){
necklaces = super.listProductsByPoductType(ProductType.NECKLACE);
}
public List<Product> getNecklaces() {
return necklaces;
}
public void setNecklaces(List<Product> necklaces) {
this.necklaces = necklaces;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public DataTable getDataTableNecklaces() {
return dataTableNecklaces;
}
public void setDataTableNecklaces(DataTable dataTableNecklaces) {
this.dataTableNecklaces = dataTableNecklaces;
}
public String addNecklaceToShoppingCart(){
super.addProductToShoppingCart((Product)this.dataTableNecklaces.getRowData(), amount);
return null;
}
}
The problem is that you are binding a single bean to the components of each row in your table.
If you have multiple rows and in the first one you select 3 in the dropdown box and press "add to shopping cart", then if there is another row with 1 selected in the dropdown box, the bean will get updated to 1 (prcisely: firstly it will get updated according to the first row to 3, then according to the second row to 1, and so on).
I believe that this is the source of your problems.
One solution would be to create an object like:
class ProductPurchase{
Necklace necklace;
int amount;
}
change the List<Product> to List<ProductPurchase>, bind the drop down list value to necklace.amount and set the action of "add to cart" to action="#{necklaceBean.addToShoppingCart(necklace)".
I am using schedule component of Primefaces. I am filling it with values from database and when the user selects sth from the selectonemenu an ajax event is triggered (I tried to put just the related code, if there is sth missing pls remind me):
xhtml:
<h:outputText value="Scope :" />
<h:selectOneMenu id="scope" value="#{scheduleView.scope}">
<f:selectItems value="#{lookup.scopeCombo}"/>
<p:ajax process="scope" update="schedule, scheduleForm, scheduleFormPG" listener="#{scheduleView.changeScopeType()}"/>
</h:selectOneMenu>
<p:schedule id="schedule" value="#{scheduleView.model}" editable="true"/>
Backing bean:
#ManagedBean
#ViewScoped
public class ScheduleView implements Serializable {
#PostConstruct
public void init() {
System.out.println("Init ");
scopeChange();
}
public void scopeChange(String scope){
System.out.println("scopeChange ");
model.clear();
events = (List<Event>) commonServis.bringEverythingByCriteria(Event.class, "scope" , scope);
for(int i= 0; i<events.size();i++){
model.addEvent(new DefaultScheduleEvent(events.get(i).getAd(), events.get(i).getStartDate(),events.get(i).getEndDate()));
}
public void changeScopeType() {
System.out.println("changeScopeType ");
scopeChange (scope);
}
The output of the above code is:
Init
scopeChange
When the user changes the value in the selectonemenu:
changeScopeType
Init
scopeChange
It is supposed to go into init method just once. But after the changeScopeType function is triggered it gets into the init method and fills the schedule with unrelated data. I thought it might be related to #Postconstruct annotation but I couldn't find any related explanation. Can anyone understand the reason and offer a solution?
Here is the full page:
<?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">
<ui:composition 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://prime.primefaces.org/ui"
template="templates/layout.xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<ui:define name="title">#{labels.schedule}</ui:define>
<ui:define name="content">
<h:form id="scheduleForm">
<h:panelGrid id="scheduleFormPG">
<p:growl id="msgs" />
<p:dialog modal="true" widgetVar="statusDialog" header="Status" draggable="false">
<h:graphicImage value="resources/images/ajax-loader.gif" />
</p:dialog>
<p:dialog showEffect="explode" hideEffect="explode" resizable="false"
header="warning" widgetVar="confirmationErase" appendToBody="true" modal="true">
<h:outputText value="Are you sure?"/>
<br/>
<p:commandButton value="Yes" actionListener="#{scheduleView.deleteEvent(AE)}"
update="msgs, scheduleFormPG, schedule, wrapperPanel"
onstart="statusDialog.show(),confirmationErase.hide()"
oncomplete="statusDialog.hide(), eventDialog.hide()" process="#parent, scope" />
<p:commandButton value="No" onclick="confirmationErase.hide()" type="button" />
</p:dialog>
<h:outputText value="scope :" />
<h:selectOneMenu id="scope" value="#{scheduleView.scope}">
<f:selectItems value="#{lookup.scopeTypeCombo}"/>
<p:ajax process="scope" update="schedule, scheduleForm, scheduleFormPG" listener="#{scheduleView.changeScopeType()}"/>
</h:selectOneMenu>
</h:panelGrid>
<p:schedule onDateSelectUpdate="wrapperPanel"
onEventSelectUpdate="wrapperPanel" onEventSelectComplete="eventDialog.show()" eventSelectListener="#{scheduleView.onEventSelect}"
onDateSelectComplete="eventDialog.show();" dateSelectListener="#{scheduleView.onDateSelect}" id="schedule" value="#{scheduleView.model}" editable="true"/>
<p:dialog id="dialog111" widgetVar="eventDialog" header="Event Information" showEffect="clip" hideEffect="clip">
<p:panel id="wrapperPanel">
<h:panelGrid id="eventDetails" columns="2">
<h:outputLabel for="eventName" value="Event Name *: " />
<p:inputText id="eventName" value="#{scheduleView.event.title}" required="true"/>
<h:outputLabel value="Start Date:" />
<p:calendar id="sKalender" value="#{scheduleView.event.startDate}">
<f:convertDateTime pattern="dd/MM/yyyy" />
</p:calendar>
<h:outputLabel value="End Date:" />
<p:calendar id="eKalender" value="#{scheduleView.event.endDate}">
<f:convertDateTime pattern="dd/MM/yyyy" />
</p:calendar>
<h:outputLabel value="All Day:" />
<h:selectBooleanCheckbox id="allDay" value="#{scheduleView.event.allDay}" />
<h:outputLabel value="scope: " />
<h:selectOneMenu id="scopeChoice" value="#{scheduleView.event.scope}">
<f:selectItems value="#{lookup.scopeTypeCombo}"/>
</h:selectOneMenu>
<p:commandButton onclick="confirmationErase.show()" oncomplete="eventDialog.hide()" update="wrapperPanel, msgs, schedule" type="reset" value="Delete" />
<p:commandButton value="Save" actionListener="#{scheduleView.addEvent(AE)}" process="#parent, scope" update="schedule wrapperPanel msgs scheduleForm" oncomplete="eventDialog.hide();"/>
</h:panelGrid>
</p:panel>
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
The problem was this line of code:
<p:ajax process="scope" update="schedule, scheduleForm, scheduleFormPG" listener="#{scheduleView.changeScopeType()}"/>
update was refreshing the whole page, instead it should've only update schedule. When I change it to:
update="schedule"
the problem solved.
Thanks everyone for their effort.