I am having issue in firing an ajax call on the cellEdit event of a Data Table. The table shows up just fine on the UI but nothing happens when I click any of the cell.
xhtml
<h:form>
<p:dataTable id="decisionTree" var="tree"
value="#{treeBean.content}" editable="true" editMode="cell"
styleClass="smallGrid">
<f:facet name="header">
Notes Decision Tree
</f:facet>
<p:ajax event="cellEdit" listener="#{treeBean.onCellEdit}"
immediate="true" update=":#{p:component('notesTextArea')}" />
<p:column headerText="Comment Type">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{tree.commentType}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{tree.commentType}" disabled="true" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="MTCNs">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{tree.mtcns}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{tree.mtcns}" disabled="true" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Call Type">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{tree.callType}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{tree.callType}" disabled="true" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Phone">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{tree.phone}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{tree.phone}" disabled="true" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Dispute Reason">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{tree.disputeReason}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{tree.disputeReason}" disabled="true" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Placement Decision">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{tree.placementDescision}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{tree.placementDescision}" disabled="true" />
</f:facet>
</p:cellEditor>
</p:column>
<!--
<p:column>
<p:rowEditor />
</p:column>
-->
</p:dataTable>
</h:form>
Here is the Bean.
#Component("treeBean")
#Scope(value = "view", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class TreeBean {
private List<TreeDto> content;
private String result="";
public List<TreeDto> getContent() {
return content;
}
public void setContent(List<TreeDto> content) {
this.content = content;
}
#PostConstruct
public void init() {
content=new ArrayList<TreeDto>();
TreeDto dto1=new TreeDto();
dto1.setCommentType("First Attempt");
dto1.setMtcns("mtcn1");
dto1.setCallType("OBC");
dto1.setPhone("8975730838");
dto1.setDisputeReason("Fraud");
dto1.setPlacementDescision("Write Off");
content.add(dto1);
}
public void onCellEdit(CellEditEvent event) {
RequestContext.getCurrentInstance().showMessageInDialog(new FacesMessage(FacesMessage.SEVERITY_INFO, "Status","something clicked"));
}
}
My intention to capture the value of the cells clicked. But I am not able to get an event fired in the first place on cell edit. Please give me some suggestions on how to resolve this.
Try to add a widgetVar to your dataTable and then edit your cell with a contextMenu for your data table, which call onclick="PF('yourWidgetVar').showCellEditor();return false;"
Somenthing like this
<p:contextMenu for="decisionTree" widgetVar="cMenu">
<p:menuitem value="Edit Cell" icon="ui-icon-search" onclick="PF('yourWidgetVar').showCellEditor();return false;"/>
<p:menuitem value="Hide Menu" icon="ui-icon-close" onclick="PF('cMenu').hide()"/>
</p:contextMenu>
You can take a look to Primefaces documentation too:
https://www.primefaces.org/showcase/ui/data/datatable/edit.xhtml
Related
I have the following code
<p:ajax id="rowEditInit" event="rowEditInit"
listener="#{assignIssueController.onEditInit}" />
<p:commandLink id="linkId" action="#{assignIssueController.initMethod}" >
<p:rowEditor>
</p:rowEditor>
</p:commandLink>
This is part of my editable datatable is there any way I can call my ajax event "rowEditInit" after commadlink is called?
Following is my Datatable
<h:form id="formId">
<p:dataTable id="dTable" var="il"
value="#{assignIssueController.issueList}" editable="true"
style="margin-bottom:20px">
<f:facet name="header">
Assign Issues
</f:facet>
<p:ajax event="rowEdit"
listener="#{assignIssueController.onRowEdit}" />
<p:ajax event="rowEditCancel"
listener="#{assignIssueController.onRowCancel}" />
<p:ajax id="rowEditInit" event="rowEditInit"
listener="#{assignIssueController.onEditInit}" />
<p:column headerText="Issue Number">
<h:outputText value="#{il.issueNumber}" />
</p:column>
<p:column headerText="Issue Discribtion">
<h:outputText value="#{il.issueDescribtion}" />
</p:column>
<p:column headerText="Assign To">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{il.assignToUserId}" id="userId" />
</f:facet>
<f:facet name="input">
<p:autoComplete id="assignUserId" multiple="true"
value="#{assignIssueController.selectedUserList}"
completeMethod="#{assignIssueController.complete}" var="usr"
itemLabel="#{usr.userId}" itemValue="#{usr}"
converter="#{userConverter}">
</p:autoComplete>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Updated By">
<h:outputText value="#{il.updatedByUserId}" />
</p:column>
<p:column headerText="Issue Type">
<h:outputText value="#{il.issueStatus}" />
</p:column>
<p:column style="display: none">
<f:facet name="output">
<h:outputText value="#{il.issueType}" />
</f:facet>
</p:column>
<p:column style="width:32px">
<p:commandLink id="linkId" action="#{assignIssueController.initMethod}">
<p:rowEditor>
</p:rowEditor>
</p:commandLink>
</p:column>
</p:dataTable>
</h:form>
And here are the methods that are called by ajax events
public void onEditInit(RowEditEvent event) {
System.out.println(event.getObject());
AssignIssueList obj = (AssignIssueList) event.getObject();
issueName = obj.getIssueNumber();
System.out.println(obj.getAssignToUserId().toString());
selectedUserList = usersBo.getUserNameList(obj.getAssignToUserId().toString());
}
public void initMethod() {
System.out.println("Hello world");
}
My web app is built on the Spring boot + JSF and Primefaces.
To update my dataTable I am using roweditor primefaces element.
Here is my dataTable:
<p:dataTable id="table" var="categoryLevel"
value="#{cardCategoryLevelController.categoryLevels}"
editable="true">
<p:ajax event="rowEdit"
listener="#{cardCategoryLevelController.onRowEdit}"
update=":categoryLevelForm:msgs" />
<p:ajax event="rowEditCancel"
listener="#{cardCategoryLevelController.onRowCancel}"
update=":categoryLevelForm:msgs" />
<p:column headerText="Id">
<h:outputText value="#{categoryLevel.id}" />
</p:column>
<p:column headerText="Category Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{categoryLevel.cardCategory.name}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu id="category"
value="#{categoryLevel.cardCategory}"
style="width:125px">
<f:selectItems value="#{cardCategoryLevelController.categories}"
var="category" itemLabel="#{category.name}"
itemValue="#{category}" />
<f:converter binding="#{categoryConverter}"/>
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Level Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{categoryLevel.level.name}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu id="level"
value="#{categoryLevel.level}"
style="width:125px">
<f:selectItems value="#{cardCategoryLevelController.levels}"
var="level" itemLabel="#{level.name}" itemValue="#{level}" />
<f:converter binding="#{levelConverter}"/>
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Card Drop Rate">
<h:outputText value="#{categoryLevel.cardDropRate}" />
</p:column>
<p:column headerText="Created Date">
<h:outputText value="#{categoryLevel.createdDate}">
<f:convertDateTime type="time" pattern="MM-dd-yyyy HH:mm:ss" />
</h:outputText>
</p:column>
<p:column headerText="Updated Date">
<h:outputText value="#{categoryLevel.updatedDate}">
<f:convertDateTime type="time" pattern="MM-dd-yyyy HH:mm:ss" />
</h:outputText>
</p:column>
<p:column headerText="Actions">
<p:rowEditor style="float:left; padding:5px;"/>
<p:commandButton styleClass="no-btn" icon="ui-icon-trash"
rendered="#{not empty categoryLevel}"
action="#{cardCategoryLevelController.delete(categoryLevel.id)}"
update="table">
<p:confirm header="Confirmation"
message="Are you sure you want to delete this card category level"
icon="ui-icon-alert" />
</p:commandButton>
</p:column>
</p:dataTable>
And roweditor method:
public void onRowEdit(RowEditEvent event) {
CardCategoryLevel cardCategoryLevel = (CardCategoryLevel) event.getObject();
cardCategoryLevel = cardCategoryLevelService.update(cardCategoryLevel);
if (cardCategoryLevel != null) {
FacesMessage msg = new FacesMessage("Card Category Level Edited", cardCategoryLevel.getId().toString());
FacesContext.getCurrentInstance().addMessage(null, msg);
} else {
FacesMessage msg = new FacesMessage("Such card category level already exists");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
The problem is when I edit some dataTable row, and the update on the my db was not performed successfully, wrong values (instead of old ones) are displayed on the updated row.
How can I solved that?
Nice work around is to implement custom validator, which is called before back end logic. In case validation failed, the data table row becomes red, and appropriate message is displayed.
I am calling a rowEdit event and I want to refresh the table only when the event performs the db update successfully. Below are my code.
XHTML
<p:dataTable id="xobjTable" var="xobj" value="#{xListView.xListResponseObject}"
scrollRows="20" scrollable="true" liveScroll="true" scrollHeight="600"
rowKey="#{xobj.X}"
selection="#{xListView.selectedObject}" selectionMode="single"
style="margin-top: 20px; margin-bottom:20px" editable="true">
<f:facet name="header">
Search Results
<p:spacer width="20"/>
<h:commandLink id="csv">
<p:graphicImage value="csv.png" width="24"/>
<p:dataExporter type="csv" target="xobj" fileName="xListSearch" />
<p:tooltip id="toolTipFade" for="csv" value="Click on CSV to download entire table as a csv file. " />
</h:commandLink>
</f:facet>
<p:ajax event="rowEdit" listener="#{xListView.onRowEdit}" update=":xListform:xobjTable" />
<p:column headerText="X" style="width:60px;text-align: center">
<h:outputText value="#{xobj.X}" />
</p:column>
<p:column headerText="Y" style="width:60px;text-align: center">
<h:outputText value="#{xobj.Y}" />
</p:column>
<p:column headerText="Modified Date" style="width:160px;text-align: center">
<h:outputText value="#{xobj.modifiedDate}" />
</p:column>
<p:column headerText="Active" style="width:160px;text-align: center">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{xobj.active}"/>
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{xobj.active}">
<f:selectItems value="#{xListView.activeList}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Location" style="width:160px;text-align: center">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{xobj.location}"/>
</f:facet>
<f:facet name="input">
<p:inputText id="location" value="#{xobj.location}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="State" style="width:160px;text-align: center">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{xobj.state}"/>
</f:facet>
<f:facet name="input">
<p:inputText id="state" value="#{xobj.state}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="x Country Code" style="width:160px;text-align: center">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{xobj.xCountryCode}"/>
</f:facet>
<f:facet name="input">
<p:inputText id="xCountryCode" value="#{xobj.xCountryCode}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="xrarier" style="width:160px;text-align: center">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{xobj.carrier}"/>
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{xobj.carrier}">
<f:selectItems value="#{xListView.xarrierList}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:32px" headerText="Edit" rendered="#{allTabs.isShow(xListView.title)}">
<p:rowEditor />
</p:column>
<p:column style="width:160px;text-align: center" rendered="#{allTabs.isShow(xListView.title)}" headerText="Delete">
<p:commandButton id="deleteDid" actionListener="#{xListView.deletexy(xobj)}"
icon="ui-icon ui-icon-trash red" title="Delete" update="#form">
<p:confirm header="Confirmation" message="#{xListView.finalDeleteMessage}" icon="ui-icon-alert" />
</p:commandButton>
</p:column>
</p:dataTable>
Here is the event method
public void onRowEdit(RowEditEvent event) {
xListResponseObject editObject = (xListResponseObject) event.getObject();
logger.debug("Coming to edit the row.");
String editXYStatus = xListDAO.editxy(editObject);
if (editxyStatus.equals(SUCCESS_RESPONSE)) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "INFO", "X/Y edit successful!");
FacesContext.getCurrentInstance().addMessage(null, msg);
} else {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "INFO", "X/Y edit failed :" + editxyStatus);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
I would like the update to happen only when the rowEdit event updates the db.
Can I have a boolean set in my method and access data in the update in the p:ajax ?
Add to end of your SUCCESS_RESPONSE
RequestContext.getCurrentInstance().update("form:npaobjTable");
Or whatever your table real id is.
I was having the same problem.
Below URL will solve your problem.
http://forum.primefaces.org/viewtopic.php?f=3&t=38412&p=153402#p153402
actual response :
public void onRowEdit(RowEditEvent event) {
NpaListResponseObject editObject = (NpaListResponseObject) event.getObject();
logger.debug("Coming to edit the row.");
String editNpaNxxStatus = npaListDAO.editNpaNxx(editObject);
if (editNpaNxxStatus.equals(SUCCESS_RESPONSE)) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "INFO", "NPA/NXX edit successful!");
FacesContext.getCurrentInstance().addMessage(null, msg);
} else {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "INFO", "NPA/NXX edit failed :" + editNpaNxxStatus);
FacesContext.getCurrentInstance().addMessage(null, msg);
FacesContext.getCurrentInstance().validationFailed();
}
}
added FacesContext.getCurrentInstance().validationFailed(); at last in failure scenario.
So I am trying to use a PrimeFaces data table to set data to a list as follows;
<h:form id="frmSalarySupplement">
<p:panel>
<p:dataTable id="tblSalarySupplement"
value="#{salSupplementMB.dataListFromDB}"
var="salSupp"
rowIndexVar="rowSn"
scrollable="true"
rows="10"
paginator="true"
editable="true"
editMode="cell"
rowsPerPageTemplate="10,20,50,100">
<p:ajax event="cellEdit"
listener="#{salSupplementMB.onCellEdit}"
update="#this" />
<p:column headerText="#" escape="false"
style="white-space:pre-line;
word-break:break-all;
width:20px;
text-align:center;">
<h:outputText value="#{rowSn+1}" />
</p:column>
<p:column headerText="Name"
style="white-space:pre-line;
word-break:break-all;
width:250px;">
<h:outputText value="#{salSupp.empId.name}" />
</p:column>
<p:column headerText="Designation"
style="white-space:pre-line;
word-break:break-all;
width:150px;">
<h:outputText value="#{salSupp.empId.designation.designationName}" />
</p:column>
<p:column headerText="Allowance"
style="white-space:pre-line;
word-break:break-all;
width:100px;">
<p:cellEditor>
<f:facet name="input">
<h:inputText value="#{salSupp.allowance}"
style="width:100%" />
</f:facet>
<f:facet name="output">
<h:outputText value="#{salSupp.allowance}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Special
Allowance"
style="white-space:pre-line;
word-break:break-all;
width:100px;">
<p:cellEditor>
<f:facet name="input">
<h:inputText value="#{salSupp.specialAllowance}"
style="width:100%" />
</f:facet>
<f:facet name="output">
<h:outputText value="#{salSupp.specialAllowance}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Transport
Allowance"
style="white-space:pre-line;
word-break:break-all;
width:100px;">
<p:cellEditor>
<f:facet name="input">
<h:inputText value="#{salSupp.transportAllowance}"
style="width:100%" />
</f:facet>
<f:facet name="output">
<h:outputText value="#{salSupp.transportAllowance}" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</p:panel>
</h:form>
So I want to be able to save the data I have edited on the cell to set it on the list. When I do the following, I don't get an updated value.
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
}
Can someone suggest what shall I do with it?
Update
Also, can anyone tell me why my table loads multiple times when I edit the value? Maybe that's what's giving me the problem.
is that I have a grid that dynamically genre, I mean I add empty rows to the grid, first thought to use primefaces in Cell Editor, so that the value is stored in the list of beans
List, works but the problem that I have is on the calendar, when I select one and is stored, it is stored in the list, I checked it does not execute the ajax event, you lose the value of the date.
<p:commandButton value="AƱadir dia" update="dataTable" actionListener="#{regDPNL.registrarNuevoDia}" />
<p:dataTable id="dataTable" var="dpnl" value="#{regDPNL.listdpnl}" paginatorPosition="top"
rows="20" rowIndexVar="rowIndex" editable="true" editMode="cell"
<p:ajax event="cellEdit" listener="#{regDPNL.onCellEdit}" />
<p:column width="25%">
<f:facet name="header">
<h:outputText value="NOMBRE" />
</f:facet>
<p:cellEditor>
<f:facet name="output"><p:inputText value="#{dpnl.nombre}" /></f:facet>
<f:facet name="input"><p:inputText value="#{dpnl.nombre}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column width="20%">
<f:facet name="header">
<h:outputText value="DESDE" />
</f:facet>
<p:cellEditor>
<f:facet name="output"><p:inputText value="#{dpnl.fechaDesde}" /></f:facet>
<f:facet name="input"><p:calendar value="#{dpnl.fechaDesde}" pattern="dd/MM/yyyy" /></f:facet>
</p:cellEditor>
</p:column>
<p:column width="20%">
<f:facet name="header">
<h:outputText value="HASTA" />
</f:facet>
<p:cellEditor>
<f:facet name="output"><p:inputText value="#{dpnl.fechaHasta}" /></f:facet>
<f:facet name="input"><p:calendar value="#{dpnl.fechaHasta}" pattern="dd/MM/yyyy" /></f:facet>
</p:cellEditor>
</p:column>
<p:column width="5%">
<f:facet name="header">
<h:outputText value="ELIMINAR" />
</f:facet>
<p:commandButton icon="ui-icon-editar" title="Delete Periodo" style="background:#fff">
</p:commandButton>
</p:column>
</p:dataTable>
Java code:
private List<DetallePeriodoBean> listdpnl = new PeriodoNoLaborable();
private DetallePeriodoBean detallePeriodoNoLaborable = new ArrayList<DetallePeriodoBean>();
public void registrarNuevoDia() {
detallePeriodoNoLaborable = new DetallePeriodoBean();
this.listdpnl.add(detallePeriodoNoLaborable);
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
if(newValue != null && !newValue.equals(oldValue)) {
System.out.println("==> Old: " + oldValue + ", New:" + newValue);
}
}
http://s2.subirimagenes.com/imagen/previo/thump_8690487captura.png
I have faced this problem.
The solution is very simple (after a lot of testing and error)
You must add id attribute to your tag,
for instance:
<p:calendar id="date_selector" value="#{dpnl.fechaHasta}" pattern="dd/MM/yyyy" />
At the facet named output use the tag h:outputText instead of p:inputText
make sure you use java.util.date for your date fields(i.e fechaDesde etc) in your bean.