OneMenu & 2 ajax inside won't work - ajax

I'm facing a huge problem since 2 weeks.
I tested 2 ajax method one by one and they work. But when I want to have both in a oneMenu, the dropdown supposed to update the third oneMenu of the page does'nt work.
<h:body>
<h:form>
<p:growl id="growl" showDetail="true" />
<p:outputLabel value="Sélectionner une section " for="sectionBox"/>
<p:selectOneMenu id="sectionBox"
value="#{evaluationViewController.currentSection}"
converter="sectionConverter"
var="c"
filter="true"
filterMatchMode="startsWith"
effect="fade"
>
<p:ajax listener="#{evaluationViewController.onSectionSelected}" update="ue,ueO,growl"/>
<f:selectItem itemLabel="Sélectionnez uen section" itemValue="" noSelectionOption="true"/>
<f:selectItems value="#{evaluationViewController.currentSections}"
var="currentSection"
itemLabel="#{currentSection.name}"
itemValue="#{currentSection}"
/>
<p:column>
<h:outputText value="#{c.name}"/>
</p:column>
</p:selectOneMenu>
<p:outputLabel value="Sélectionner une UE " for="ue"/>
<p:selectOneMenu id="ue"
value="#{evaluationViewController.ue}"
converter="ueConverter"
var="u"
filter="true"
filterMatchMode="startsWith"
>
<p:ajax listener="#{evaluationViewController.onUeSelected}" update="ueO,growl"/>
<p:ajax event="change" update="capacities" listener="#{evaluationViewController.listenerCapacitiesUpdate}"/>
<f:selectItem itemLabel="Sélectionnez une UE" itemValue="" noSelectionOption="true"/>
<f:selectItems value="#{evaluationViewController.ues}"
var="ues"
itemLabel="#{ues.name}"
itemValue="#{ues}"
/>
<p:column>
<h:outputText value="#{u.name}"/>
</p:column>
</p:selectOneMenu>
<p:outputLabel value="Sélectionner l'UE enseignée" for="ueO"/>
<p:selectOneMenu id="ueO"
value="#{evaluationViewController.organizedUe}"
converter="organizedUeConverter"
var="o"
filter="true"
filterMatchMode="startsWith"
>
<f:selectItem itemLabel="Sélectionnez une année" itemValue="" noSelectionOption="true"/>
<f:selectItems
value="#{evaluationViewController.organizedUes}"
var="organizedUes"
itemLabel="#{organizedUes.name}"
itemValue="#{organizedUes}"
/>
<p:column>
<h:outputText value="#{o.name}"/>
</p:column>
<p:column>
<h:outputText value="#{o.level.name}"/>
</p:column>
</p:selectOneMenu>
<p:separator/>
<p:separator/>
<p:dataTable id="capacities"
var="cap"
value="#{evaluationViewController.capacities}"
editable="true"
editMode="cell"
widgetVar="cellCap"
>
<f:facet name ="header">
Capacitées
</f:facet>
<p:ajax event="cellEdit"
listener="#{evaluationViewController.onCellEdit}"
update="#this"/>
<p:column headerText="Dénomination">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{cap.name}"/></f:facet>
<f:facet name="input"><p:inputText value="#{cap.name}" style="width: 30%" label="Dénomination"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Description">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{cap.description}"/></f:facet>
<f:facet name="input"><h:inputText value="#{cap.description}" style="width: 90%" label="Description"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Réussite obligatoire">
<p:selectBooleanCheckbox value="#{cap.isThresholdOfSuccess}" style="alignment-adjust: central"/>
</p:column>
</p:dataTable>
<p:separator/>
</h:form>
</h:body>
I followed the primefaces demo as well for the bean :
public class EvaluationViewController implements Serializable {
#EJB
private SectionFacade ejbSectionFacade;
private List<Section> currentSections;
private Section currentSection;
#EJB
private UeFacade ejbUeFacade;
private List<Ue> ues;
private Ue ue;
#EJB
private OrganizedUeFacade ejbOrganizedUeFacade;
private List<OrganizedUe> organizedUes;
private OrganizedUe organizedUe;
#EJB
private CapacityFacade ejbCapacity;
private List<Capacity> capacities;
private Capacity capacity;
#PostConstruct
public void init() {
currentSections = ejbSectionFacade.findAll();
ues = new ArrayList<>();
organizedUes = new ArrayList<>();
capacities = new ArrayList<>();
}
public void onSectionSelected() {
if (currentSection != null && !currentSection.getName().equals("")) {
ues = ejbUeFacade.findBySection(currentSection);
ue = null;
capacity = null;
FacesMessage facesMessage = new FacesMessage("Sélection", currentSection.getName());
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
} else {
ues = null;
}
}
public void onUeSelected() {
if ((currentSection != null && !currentSection.getName().equals(""))
&& (ue != null && !ue.getName().equals(""))) {
organizedUes = ejbOrganizedUeFacade.findByUe(ue);
capacities = ejbCapacity.findByUe(ue);
capacity = null;
FacesMessage facesMessage = new FacesMessage("Sélection de l'UE : ", ue.getName());
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
} else {
organizedUes = null;
}
}
public void listenerCapacitiesUpdate() {
capacities = ejbCapacity.findByUe(ue);
}
The DataTable is updated and rendered but not the last oneMenu. I really don't get it. I would be very gratefull for the answer.

There are two things at hand here:
If you do not provide an explict event, then a default one is taken
You cannot add two ajax tags to the same component listening to the same event
So if in this case the default ajax event of the p:selectOneMenu is change, only the second one will be processed. Adding an explicit event other than change to the first ajax handler will make it work
Off-topic but important things you should normally do debugging issues like this:
Find the differences between the two and see and try to make them as identical as possible
See if the order plays a role by switching them
See if using a different component makes it work

Related

Unable to update p:datatable cell after ajax call on another cell's cellEdit event

In my cell edit event in my backing bean, if the cell value is changed I want to update the value of another column as well of the datatable. The value is getting correctly set in my list object but is not getting reflected in my datatable. I tried updating using the datatable using RequestContext as well, but still the list is not getting refreshed. What am I doing wrong? Should I call any row event for this change?
Code snippet :
Bean
#Named("editView")
#ViewScoped
public class EditTableView implements Serializable {
private List<Cars> carList;
private List<String> brands;
#PostConstruct
public void init() {
brands = new ArrayList<String>();
brands.add("BMW");
brands.add( "Mercedes");
brands.add("Volvo");
brands.add("Audi");
brands.add("Renault");
brands.add("Fiat");
brands.add("Volkswagen");
brands.add("Honda");
brands.add("Jaguar");
brands.add( "Ford");
brands.add("Maruti Suzuki");
carList = new ArrayList<Cars>();
modifiedList = new ArrayList<Cars>();
Cars car =new Cars();
car.setCarId(1);
car.setBrand("BMW");
car.setColor("Grey");
car.setModelNumber("2323");
car.setSelfDriven("Y");
car.setYear("1980");
car.setStatus("");
carList.add(car);
}
public void onCellEdit(CellEditEvent event) {
int rowIndex = event.getRowIndex();
Cars car = null;
LOGGER.info("Car Edited"+rowIndex);
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
DataTable carTable = (DataTable) event.getSource();
String index = carTable.getClientId(FacesContext.getCurrentInstance());
LOGGER.info(index);
if(newValue != null && !newValue.equals(oldValue)) {
LOGGER.info("Cell Changed Old: " + oldValue + ", New:" + newValue);
car=carList.get(rowIndex);
carList.get(event.getRowIndex()).setStatus("Changed");
modifiedList.add(car);
}
}
}
xhtml
<h:form id="cellEditForm">
<p:dataTable id="cars" var="car" value="#{editView.carList}"
editable="true" editMode="cell" widgetVar="cellCars">
<f:facet name="header">Cell Editing</f:facet>
<p:ajax event="cellEdit" listener="#{editView.onCellEdit}"
update=":cellEditForm:cars" />
<p:column headerText="Id">
#{car.carId}
</p:column>
<p:column headerText="Model Name" style="background-color:yellow">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{car.modelNumber}" />
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput" value="#{car.modelNumber}"
style="width:96%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Year" style="background-color:yellow">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{car.year}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{car.year}" style="width:96%" label="Year" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Brand" style="background-color:yellow">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{car.brand}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{car.brand}" style="width:100%">
<f:selectItems value="#{editView.brands}" var="man"
itemLabel="#{man}" itemValue="#{man}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Self Driven" style="background-color:yellow">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{car.selfDriven}" />
</f:facet>
<f:facet name="input">
<p:inplace>
<p:inputText value="#{car.selfDriven}" />
</p:inplace>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Color" style="background-color:yellow">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{car.color}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{car.color}" style="width:96%" label="Color" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column>
<h:outputText value="#{car.status}" id="statusLabel"></h:outputText>
</p:column>
</p:dataTable>
</h:form>
I used jquery eventually. Got the index of the updated row and called jquery function from my bean.
RequestContext requestContext = RequestContext.getCurrentInstance();
String call = "updateCell(" + event.getRowIndex() + ")";
requestContext.execute(call);
Jquery code
function updateCell(i) {
var index = "cellEditForm:cars:"+i+":statusLabel";
document.getElementById(index).innerHTML="Changed";
}
OmniFaces has a great util for this, called 'Ajax'
A StackOverflow post about this shows how to use it: How to use OmniFaces Ajax.updateColumn() or Ajax.updateRow() via p:ajax
Update form not table or put table in panel and update panel.
to be safe
<h:form id="cellEditForm">
<p:panel id="something" styleclass="pero">
<p:dataTable id="cars
update="#(.pero)"
be sure to put id on panel because class update will search for that id and use it. This solution is because i don't know rest of the code and it is one that will work on any code.

Add Dynamic Row in <p:datatable> Using <p:commandButto> and <f:ajax>

in following code commandbutton not properly work for the datatable.
<p:dataTable id="invoiceTable" var="ipsDetail"
value="#{invoiceBean.ipsDetails}" border="1">
<p:column headerText="Sr. No.">
<h:inputText id="serialN7umber" value="#{ipsDetail.serialNumber}"
size="3" />
</p:column>
<p:column headerText="Description of Goods">
<p:inputText value="#{ipsDetail.descriptionOfGoodsOrService}" />
</p:column>
<p:column headerText="HSN Code">
<p:inputText value="#{ipsDetail.hsnCode}" styleClass="Alingment" />
</p:column>
<p:column headerText="Quantity">
<p:inputText value="#{ipsDetail.quantity}" styleClass="Alingment" />
</p:column>
<p:column headerText="Rate">
<p:inputText value="#{ipsDetail.rate}" styleClass="Alingment" />
</p:column>
<p:column headerText="Percentage Discount">
<p:inputText value="hello" rendered="#{ipsDetail.percentDiscount}"
styleClass="Alingment" />
</p:column>
<p:column headerText="Amount">
<p:inputText value="#{invoiceBean.amount}" styleClass="Alingment" />
</p:column>
<f:facet name="footer">
<p:commandButton value="Add New Row" action="#{invoiceBean.addRow}" update=":form:invoiceTable">
<!-- <f:ajax execute=":form:invoiceTable" render=":invoiceTable:addColumn" /> -->
</p:commandButton>
</f:facet>
</p:dataTable>
</h:form>
I want To add dynamic row with inputtext using primefaces commandbutton in java. it work but re-render not possible.
public class InvoiceBean implements Serializable {
public List getInvoices() {
InvoiceDao invoiceDao = new InvoiceDao();
invoices = invoiceDao.getInvoiceData();
return invoices;
}
public void setInvoices(List<Invoice> invoices) {
if (invoices != null) {
this.invoices.add(new Invoice());
}
}
public void getInvoiceData() {
InvoiceDao invoiceDao = new InvoiceDao();
ipsDetail = new InvoiceProductsServicesDetail();
if ( ipsDetail != null) {
ipsDetail
.setDescriptionOfGoodsOrService(descriptionOfGoodsOrService);
ipsDetail.setHsnCode(hsnCode);
ipsDetail.setInvoiceId(invoice.getId());
ipsDetail.setPercentDiscount(percentDiscount);
ipsDetail.setQuantity(quantity);
ipsDetail.setRate(rate);
ipsDetail.setSerialNumber(serialNumber);
ipsDetail.setServiceTax((float) 12.5);
ipsDetail.setVat(5);
System.out.println("InvoiceBean.insertInvoice");
}
invoiceDao.insertInvoice(invoice, ipsDetail);
}
public Row addRow() {
Row row = new Row();
InputText inputText = new InputText();
inputText.setSubmittedValue("Hello");
Column column = new Column();
row.setParent(inputText);
column.setHeader(inputText);
column.setHeaderText("Hardik");
return row;
}
}
This Is code for add row or column with inputtext
Since you are using Primefaces you can also Update any component from ManagedBean itself using org.primefaces.context.RequestContext object.
For example:
Facelet:
<h:form id="form1">
<p:dataTable id="myTab">
...
</p:dataTable>
</h:form>
ManagedBean:
RequestContext reqCtx = Requestcontext.getCurrentInstance();
req.Ctx.update("form1:myTab");
You can't update the table from inside the table. You can do the following:
<p:dataTable id="invoiceTable" var="ipsDetail" value="#{invoiceBean.ipsDetails}"
border="1">
...
<f:facet name="footer">
<p:commandButton value="Add New Row" onclick="updateTable();">
</p:commandButton>
</f:facet>
</p:dataTable>
...
<p:remoteCommand name="updateTable" update=":form:invoiceTable"
actionListener="#{invoiceBean.addRow}" />
Thank For Your Response and Solution regarding my question is below edit addRow().
public void addRow() {
ipsDetail = new InvoiceProductsServicesDetail();
if (descriptionOfGoodsOrService != null
&& hsnCode != null && quantity != 0 && rate != 0) {
ipsDetail.setSerialNumber(serialNumber);
ipsDetail
.setDescriptionOfGoodsOrService(descriptionOfGoodsOrService);
ipsDetail.setHsnCode(hsnCode);
ipsDetail.setPercentDiscount(percentDiscount);
ipsDetail.setQuantity(quantity);
ipsDetail.setRate(rate);
ipsDetails.add(ipsDetail);
}
FacesContext facesContext = FacesContext.getCurrentInstance();
try {
DataTable table = (DataTable) facesContext.getViewRoot()
.findComponent("form:invoiceTable");
UIComponent uiTable = ComponentUtils.findParentForm(facesContext,
table);
final AjaxBehavior behavior = new AjaxBehavior();
RowEditEvent rowEditEvent = new RowEditEvent(uiTable, behavior,
table.getRowData());
rowEditEvent.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
table.broadcast(rowEditEvent);
} catch (AbortProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

JSF/Primefaces Action Listener not invoked from p:commandButton

I am migrating an JSP/Servlets website to JSF and am having difficulty in implementing some of the more interesting abilities of JSF. The current problem that I have attempted to resolve for several days is deleting one or more rows from a <p:dataTable>. The following code snippet defines the table:
<ui:composition template="/templates/RescueDBAdminTemplate.xhtml" ... >
<ui:define name="body">
<div id="mainContent">
<h1> Pet Information Edit </h1>
<p>
This page allows the detailed information for an animal to be inserted or edited.
</p>
<br />
<!--
~~~~ The first row contains the AIF number, and two optional hyperlinks to the History and Cage Card
~~~~ pages. Since we have at most three entries, and a layout of 4 columns, we will need a sub-table
~~~~ to evenly space out these objects.
~~~~ -->
<table class="w100pct">
<tr>
<!--
~~~~ Display the AIF_NO for the animal at the top of the page. For Reference Only.
~~~~ -->
<td class="label" align="left" >
AIF Number: #{animals.aifNo}
</td>
<td align="center"> Display History </td>
<td align="right"> Display Cage Card </td>
</tr>
</table>
<p:accordionPanel id="profile" multiple="true" activeIndex="0,1,2,3,4,5,6,7">
<p:tab title="Cage Card Information">
<h:form id="cageCardForm">
<p:panelGrid styleClass="rdbGrid w100pct">
<p:row>
<p:column styleClass="block"> Child Friendly: </p:column>
<p:column>
<p:selectOneMenu id="childFriendly" value="#{animals.isChildFriendly}">
<f:selectItem itemValue="Y" itemLabel="Yes" />
<f:selectItem itemValue="N" itemLabel="No" />
<f:selectItem itemValue="U" itemLabel="Unknown" />
<f:selectItem itemValue="O" itemLabel="Older Children Only" />
</p:selectOneMenu>
</p:column>
<p:column styleClass="block"> Dog Friendly: </p:column>
<p:column>
<p:selectOneMenu id="dogFriendly" value="#{animals.isDogFriendly}">
<f:selectItem itemValue="Y" itemLabel="Yes" />
<f:selectItem itemValue="N" itemLabel="No" />
<f:selectItem itemValue="U" itemLabel="Unknown" />
<f:selectItem itemValue="T" itemLabel="Tolerates" />
<f:selectItem itemValue="S" itemLabel="Some" />
</p:selectOneMenu>
</p:column>
</p:row>
<p:row>
<p:column styleClass="block"> Cat Friendly: </p:column>
<p:column>
<p:selectOneMenu id="catFriendly" value="#{animals.isCatFriendly}">
<f:selectItem itemValue="Y" itemLabel="Yes" />
<f:selectItem itemValue="N" itemLabel="No" />
<f:selectItem itemValue="U" itemLabel="Unknown" />
<f:selectItem itemValue="T" itemLabel="Tolerates" />
<f:selectItem itemValue="S" itemLabel="Some" />
</p:selectOneMenu>
</p:column>
<p:column styleClass="block"> Housebroken: </p:column>
<p:column>
<p:selectOneMenu id="housebroken" value="#{animals.isHousebroken}">
<f:selectItem itemValue="Y" itemLabel="Yes" />
<f:selectItem itemValue="N" itemLabel="No" />
<f:selectItem itemValue="U" itemLabel="Unknown" />
</p:selectOneMenu>
</p:column>
</p:row>
<p:row>
<p:column styleClass="block" style="text-align:top;"> Cage Card Comments: </p:column>
<p:column> <p:inputTextarea name="previousOwner" rows="11" cols="40" value="#{animals.cageCardComment}" /> </p:column>
<p:column styleClass="block" style="text-align:top;"> Lifestyle Needs: </p:column>
<p:column> <p:inputTextarea name="reasonObtained" rows="11" cols="40" value="#{animals.lifestyleNeeds}" /> </p:column>
</p:row>
</p:panelGrid>
</h:form>
</p:tab>
<p:tab title="Fees and Expenditures">
<h:form id="feesForm">
<p:panelGrid styleClass="rdbGrid w100pct">
<p:row>
<p:column styleClass="block"> Adoption Fee: </p:column>
<p:column>
<p:inputText size="16" value="#{animals.adoptionFee}" maxlength="64" />
</p:column>
<p:column styleClass="block"> Normal Costs: </p:column>
<p:column>
<p:inputText size="16" value="#{animals.costRegular}" maxlength="64" />
</p:column>
</p:row>
<p:row>
<p:column styleClass="block"> Extra Costs: </p:column>
<p:column>
<p:inputText size="16" value="${aifBean.costNonRegular}" maxlength="64" />
</p:column>
<p:column styleClass="block"> Extra Cost Description </p:column>
<p:column>
<p:inputTextarea rows="4" cols="40" value="#{animals.nonRegularDesc}" />
</p:column>
</p:row>
<p:row>
<p:column styleClass="block"> Comments </p:column>
<p:column colspan="3">
<p:inputTextarea rows="2" cols="80" value="#{animals.comments}" />
</p:column>
</p:row>
</p:panelGrid>
</h:form>
</p:tab>
<p:tab title="Medical History">
<p:dataTable styleClass="w100pct" var="current" value="#{medical.getMedHistoryByAifNo(param.AIF_NO)}">
<p:column headerText="Delete">
Delete
</p:column>
<p:column headerText="Procedure Name">
#{current.shortName}
</p:column>
<p:column headerText="Date">
#{current.treatmentDate}
</p:column>
<p:column headerText="Vet Information">
#{current.vetName} #{current.vetClinic}
</p:column>
<p:column headerText="Comments">
#{current.comments}
</p:column>
</p:dataTable>
</p:tab>
<p:tab title="Documents">
<h:form id="docListForm">
<p:dataTable id="docListTable" styleClass="w100pct" var="current" value="#{documents.currentDocList}"
paginator="true" rows="10" selection="#{documents.selectedDocs}">
<p:column selectionMode="multiple" style="width:2%" />
<p:column headerText="Date">
<h:outputText value="#{current.treatmentDate}" />
</p:column>
<p:column headerText="Document Type">
<h:outputText value="#{current.group}" converter="com.rescuedb.DocGroupName" />
</p:column>
<p:column headerText="Description">
#{current.description}
</p:column>
<f:facet name="footer">
<p:commandButton id="docListDelete" value="Delete Selected Records"
icon="ui-icon-search"
update=":#{p:component('docListTable')}"
actionListener="#{documents.deleteReference}" >
<f:param name="docNo" value="#{current.docNo}" />
<f:param name="refNo" value="#{animals.aifNo}" />
<f:param name="group" value="#{current.group}" />
</p:commandButton>
</f:facet>
</p:dataTable>
</h:form>
</p:tab>
</p:accordionPanel>
</div>
</ui:define>
</ui:composition>
The managed bean that backs this page is as follows (this is fairly preliminary code, as I am still experimenting with PrimeFaces and JSF):
package com.rescuedb.beans.managed;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.apache.log4j.Logger;
import com.rescuedb.Beans.DocMasterBean;
import com.rescuedb.Beans.DAO.DocMaster;
import com.rescuedb.Beans.DAO.DocXref;
import com.rescuedb.Beans.Models.DocMasterDataModel;
import com.rescuedb.Core.RescueException;
#ManagedBean(name="documents")
#ViewScoped
public class DocumentManagedBean implements Serializable
{
static final long serialVersionUID = 5L;
static Logger logger = Logger.getLogger(DocumentManagedBean.class);
private transient DocMaster docInfo; // Document Master accessor object
private transient DocXref xrfInfo; // Document Master accessor object
private String currentAifNo;
private String refNo;
private String docNo;
/**
* Contains a list of document records, wrapped in a DataModel, for the currently
* active foster animal.
*/
private DocMasterDataModel currentDocList = null;
private DocMasterBean[] selectedDocs;
public DocumentManagedBean()
{
logger.trace ("DocumentManagedBean.constructor");
try {
//
// Retrieve the URL parameter from the context.
//
FacesContext context = FacesContext.getCurrentInstance();
Map<String,String> paramMap = context.getExternalContext().getRequestParameterMap();
String paramAifNo = paramMap.get("AIF_NO");
if (paramAifNo != null) {
if (!paramAifNo.isEmpty()) {
currentAifNo = paramAifNo;
loadCurrentDocList();
}
}
} catch (Exception e) {
logger.error ("Exception caught in DocumentManagedBean() constructor :: " + e.getMessage(), e);
}
}
/**
* Initialize the bean from the database.
*/
#PostConstruct
public void initialize ()
{
logger.trace ("DocumentManagedBean.initialize");
try {
docInfo = new DocMaster();
xrfInfo = new DocXref();
} catch (Exception e) {
logger.error ("Exception in DocumentsManagedBean.initialize() : " + e.getMessage(), e);
}
}
public List<DocMasterBean> getDocList()
{
logger.trace ("DocumentManagedBean.getDocList");
return docInfo.getRecordList();
}
/**
* Retrieve the list of documents that are associated wit a specific foster animal.
* <p>
* #param aifNo
* #return
*/
public DocMasterDataModel getCurrentDocList()
{
logger.trace ("DocumentManagedBean.getCurrentDocList");
return currentDocList;
}
/**
* Load the document list for the currently active foster animal.
*/
private void loadCurrentDocList()
{
DocMaster docMaster = null;
logger.info ("DocumentManagedBean.loadCurrentDocList");
try {
docMaster = new DocMaster();
if (currentAifNo != null) {
if (!currentAifNo.isEmpty()) {
docMaster.queryByRefNo (Integer.parseInt(currentAifNo));
currentDocList = new DocMasterDataModel (docMaster.getRecordList());
logger.info ("DocumentManagedBean.loadCurrentDocList :: currentDocList reloaded, length = " + docMaster.getRecordCount());
} else {
logger.info ("DocumentManagedBean.loadCurrentDocList :: currentAifNo is empty, no records loaded.");
}
} else {
logger.info ("DocumentManagedBean.loadCurrentDocList :: currentAifNo is null, no records loaded.");
}
} catch (Exception e) {
logger.error ("Exception in DocumentsManagedBean.loadCurrentDocList() : " + e.getMessage(), e);
}
}
public void deleteReference(ActionEvent event)
{
boolean status; // Status of the update.
int refNo = 0;
int docNo = 0;
logger.info ("DocumentManagedBean.deleteReference");
try {
//
// Retrieve the parameter of the request.
//
FacesContext context = FacesContext.getCurrentInstance();
Map<String,String> paramMap = context.getExternalContext().getRequestParameterMap();
String paramDocNo = paramMap.get("docNo");
String paramRefNo = paramMap.get("refNo");
logger.info (String.format("DocumentManagedBean.deleteReference :: paramDocNo = [%s]", paramDocNo));
logger.info (String.format("DocumentManagedBean.deleteReference :: paramRefNo = [%s]", paramRefNo));
//
// Retrieve the items necessary to delete the proper records.
// The refNo parameter will only be specified when a specific cross-referenced
// record is to be deleted. If this value is missing, then the master document
// is to be deleted.
//
if (paramRefNo != null) {
try {
refNo = Integer.parseInt (paramRefNo);
this.refNo = paramRefNo;
} catch (NumberFormatException e) {
refNo = 0;
}
}
//
// The docNo has to be present. If the refNo is zero, then we will delete the
// master document. If a refNo is present, then we will delete a cross reference.
//
if (paramDocNo != null) {
try {
docNo = Integer.parseInt (paramDocNo);
this.docNo = paramDocNo;
} catch (NumberFormatException e) {
docNo = 0;
String message = String.format ("Illegal value for docNo (%d)", docNo);
logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message));
throw new RescueException ("DS000091", message, "DocumentsManagedBean", "deleteReference");
}
} else {
logger.error("DocumentManagedBean.deleteReference :: paramDocNo is null");
}
//
// Delete the cross reference record.
//
if (refNo != 0) {
xrfInfo = new DocXref();
status = xrfInfo.queryByCrossRef (docNo, refNo);
if (status != true) {
String message = String.format ("Error querying DOC_xref for refNo = %d, docNo = %d", refNo, docNo);
logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message));
throw new RescueException ("DS000092", message, "DocumentsManagedBean", "deleteReference");
} else {
status = xrfInfo.delete();
logger.warn("DocumentManagedBean.deleteReference :: Document XRef deleted");
// logger.warn("DocumentManagedBean.deleteReference :: TEST TEST TEST Document XRef not actually deleted");
if (status != true) {
String message = String.format ("Error deleting DOC_xref for refNo = %d, docNo = %d", refNo, docNo);
logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message));
throw new RescueException ("DS000093", message, "DocumentsManagedBean", "deleteReference");
} else {
loadCurrentDocList();
logger.error("DocumentManagedBean.deleteReference :: currentDocList reloaded");
}
}
} else {
logger.error("DocumentManagedBean.deleteReference :: refNo is 0. No Records were deleted.");
}
} catch (RescueException e) {
logger.error ("RescueException in DocumentsManagedBean.deleteReference() :: " + e.getMessage(), e);
} catch (Exception e) {
logger.error ("Exception in DocumentsManagedBean.deleteReference()", e);
}
}
public DocMaster getDocInfo()
{
logger.info ("DocumentManagedBean.getDocInfo");
return docInfo;
}
public void setDocInfo(DocMaster docInfo)
{
logger.info ("DocumentManagedBean.setDocInfo");
this.docInfo = docInfo;
}
public String getRefNo()
{
logger.info ("DocumentManagedBean.getRefNo");
return refNo;
}
public void setRefNo(String refNo)
{
logger.info ("DocumentManagedBean.setRefNo");
this.refNo = refNo;
}
public String getDocNo()
{
logger.info ("DocumentManagedBean.getDocNo");
return docNo;
}
public void setDocNo(String docNo)
{
logger.info ("DocumentManagedBean.setDocNo");
this.docNo = docNo;
}
public DocMasterBean[] getSelectedDocs()
{
logger.info ("DocumentManagedBean.getSelectedDocs");
return selectedDocs;
}
public void setSelectedDocs(DocMasterBean[] selectedDocs)
{
logger.info ("DocumentManagedBean.setSelectedDocs");
this.selectedDocs = selectedDocs;
}
}
I have tried a number of different strategies, and have read a fair number of very detailed explanations of this process in other StackOverflow threads (Thank you, BalusC!), but have still been unable to actually invoke the action listener.
My Environment is as follows:
Java 1.6
Eclipse Kepler (originally Juno)
GlassFish 3.1.2
PrimeFaces 3.5.0
From a presentation perspective, the XHTML displays correctly. The <p:dataTable> element is rendered just like the documentation and examples indicate, but when I attempt to delete a a row, the listener is never invoked.
I have tried changing the update name several times. Currently, the value of the update parameter is profile:docListForm:docListTable.
Other posts seem to indicate that there was a problem with <p:commandButton> from within a <p:accordianPanel>, but that was for a previous version of PrimeFaces (3.2).
I have tried moving the <p:commandButton> outside the <p:dataTable> and also on each row, yet the behavior does not change.
If your Listener does not trigger try this, it work fine in p:tables
<p:column id="delete" headerText="Action" width="65">
<h:commandLink value="Delete"
action="#{documents.deleteReference(current.docNo,animals.aifNo,current.group)}" ajax="false" />
</p:column>
And in your documents bean:
public void deleteReference(String docNo, String aifNo, String group)
You can actually pass the 2 string that you eventually cast as int but as Integer wrapper in the method not the primitive.
Cheers,
Thierry
Try to add ajax="false" attribute in commandbutton ,Something like this.
<p:commandButton value="Non-Ajax Submit" actionListener="#{pprBean.savePerson}"
ajax="false" />
Or use h:commandButton with ajax="false" here also .
In my application i got same issue plenty of time and i got answer few week back that issue with the page or code somewhere in the page or managed bean throwing exception or some logic going fail which is generating exception for JSF that is the main reason behind firing the event.It is JSF2 feature not to fire event if code or logic fail somewhere . May be this will help you

PrimeFaces commandButton ajax does not work

I have simple JSF page and simple backing bean. I have p:commandButton on the page and p:datatable. With commandButton I need to update dataTable with ajax, but it does not happens. What could be the reason?
Here is the page:
<ui:define name="content">
<h2>#{menu['management.roles.perms']}</h2>
<h:form id="form">
<p:fieldset style="border: 0px" toggleable="false" collapsed="false">
<p:tabView>
<p:tab title="#{messages['roles']}">
<p:dataTable id="dataTable" value="#{rolesBean.roles}" var="role"
editable="true" rows="10" rowKey="#{role.id}">
<p:ajax event="rowEdit" listener="#{rolesBean.onEdit}"/>
<f:facet name="footer">
<p:commandButton value="#{misc['add.role']}"
actionListener="#{rolesBean.addRole}" update="dataTable"/>
</f:facet>
<p:column headerText="#{misc['name.database']}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{role.name}"/>
</f:facet>
<f:facet name="input">
<h:inputText value="#{role.name}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="#{misc['date']}">
<f:facet name="output">
<h:outputText value="#{role.creationDate}">
<f:convertDateTime pattern="dd.MM.yyyy" />
</h:outputText>
</f:facet>
</p:column>
<p:column headerText="#{misc['description']}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{role.description}"/>
</f:facet>
<f:facet name="input">
<h:inputText value="#{role.description}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="#{messages['edit']}">
<p:rowEditor />
</p:column>
</p:dataTable>
</p:tab>
<p:tab title="#{messages['perms']}">
</p:tab>
<p:tab title="#{clients['history']}">
</p:tab>
</p:tabView>
</p:fieldset>
</h:form>
</ui:define>
And here is the code of backingBean:
#ViewScoped
#ManagedBean(name = "rolesBean")
public class RolesViewBean extends BasicViewBean<Role> {
private static final long serialVersionUID = 27377603187254821L;
#Inject
RoleDao dao;
private List<Role> roles;
#Override
protected BasicDao<Role> getDAO() {
return dao;
}
public void onEdit(RowEditEvent event){
this.entity = (Role) event.getObject();
dao.update(this.entity);
}
public void addRole(){
roles.add(new Role());
}
public List<Role> getRoles() {
roles = dao.getRoleList();
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
}
At first glance, the problem is that your addRole method modifes the "roles" list, while the getRoles (which gets called by the dataTable) resets it to whatever is saved in the database.
So your datatabe gets updated, it' just that it gets updated with the same values.
Think about that ;)

DataTable Order by column erase values

I have PrimeFaces dataTable that is been filled by a Ajax call.
When I click on a column title, to order its values, the values disappear.
<p:commandButton value="Pesquisar" actionListener="#{requestController.listRequests}" update="dataTable" />
Here is my view:
<p:dataTable id="dataTable" var="order" value="#{requestController.backing.requestsList}"
paginator="true" rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}">
<p:column sortBy="#{order.companyRequest}">
<f:facet name="header">
<h:outputText value="Pedido" />
</f:facet>
<h:outputText value="#{order.companyRequest}" />
</p:column>
<p:column sortBy="#{order.company.companyName}">
<f:facet name="header">
<h:outputText value="Cliente" />
</f:facet>
<h:outputText value="#{order.company.companyName}" />
</p:column>
<p:column sortBy="#{order.emissionDate}">
<f:facet name="header">
<h:outputText value="Data" />
</f:facet>
<h:outputText value="#{order.emissionDate}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
</p:column>
<p:column sortBy="#{order.requestSituation.description}">
<f:facet name="header">
<h:outputText value="Status" />
</f:facet>
<h:outputText value="#{order.requestSituation.description}" />
</p:column>
<p:column>
<f:facet name="header">
</f:facet>
<h:form>
<h:commandLink value="Detalhes"/>
</h:form>
</p:column>
</p:dataTable>
EDIT
RequestController
#ManagedBean
#RequestScoped
public class RequestController implements Serializable
{
private RequestBacking backing;
public RequestController()
{
backing = new RequestBacking();
}
public void changeEventListener(ValueChangeEvent e)
{
backing.requestSearchType = e.getNewValue().toString();
}
public void change()
{
switch (backing.requestSearchType)
{
case "data":
backing.mask = "99/99/9999";
backing.maskSize = "10";
break;
case "cnpj":
backing.mask = " 99.999.999/9999-99";
backing.maskSize = "20";
break;
default:
backing.mask = "";
backing.maskSize = "50";
}
}
public void listRequests() throws ParseException
{
CompanyVO companyVO = new CompanyVO();
switch (backing.requestSearchType)
{
case "cnpj":
companyVO.setCnpj(backing.requestSearchValue);
break;
case "cliente":
companyVO.setCompanyName(backing.requestSearchValue);
break;
case "pedido":
backing.requestVO.setCompanyRequest(Integer.parseInt(backing.requestSearchType));
break;
}
SupplierVO supplierVO = new Support().getUserSession().getSupplier();
backing.requestVO.setEmissionDate(new Support().convertDate(backing.requestSearchValue));
backing.requestVO.setSupplier(supplierVO);
backing.requestVO.setCompany(companyVO);
backing.requestsList = new ArrayList<>(backing.getBo().getRequest(backing.requestVO));
if (backing.requestsList.isEmpty())
{
FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_WARN, "Nenhum registro encontrado!", null);
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
backing.requestsList = null;
}
}
..backing getter and setter
}
My requestsList is on my RequestBacking where I have all my getters and setters, please correct me if there is a better way of doing this, I'm using it because it leaves my controller cleaner.
public List<RequestVO> requestsList;
Apparently the value="#{requestController.backing.requestsList}" didn't return the same value as it did on the initial request. That can happen if it's a request scoped bean and/or if the requestsList is populated on every request based on a request based variable.
That's just a design mistake. Put the managed bean in the view scope and make sure that you aren't doing any business logic in a getter method. The nested class backing is also suspicious or it must be a poor naming.
See also:
Why JSF calls getters multiple times
How to choose the right bean scope?
Update in a nutshell, your bean should look something like this:
#ManagedBean
#ViewScoped
public class Orders {
private String query; // +getter +setter
private List<Order> results; // +getter (no setter required)
#EJB
private OrderService service;
public void search() {
results = service.search(query);
}
// Add/generate normal getters/setters (don't change them!)
}
and your view should look like this:
<h:form>
<p:inputText value="#{orders.query}" />
<p:commandButton value="Search" action="#{orders.search}" update=":tableForm" />
</h:form>
<h:form id="tableForm">
<p:dataTable value="#{orders.results}" var="order" ... rendered="#{not empty orders.results}">
...
</p:dataTable>
<h:outputText value="No results found" rendered="#{facesContext.postback and empty orders.results}" />
</h:form>

Resources