primefaces datatable :rowedit not working - jsf

I'm trying to edit row data in primfaces dataTable but not working
I try the same code of primefaces showcases in below link
http://www.primefaces.org/showcase/ui/data/datatable/edit.xhtml
my jsf page
<h:form id="form">
<p:dataTable id="depTable" value="#{departmentBean.departments}"
var="dep" editable="true">
<f:facet name="header">
All departments
</f:facet>
<p:ajax event="rowEdit" listener="#{departmentBean.onRowEdit}"
update=":form:depTable" />
<p:ajax event="rowEditCancel"
listener="#{departmentBean.onRowCancel}" update=":form:depTable" />
<p:column headerText="Id">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{dep.id}" />
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput" value="#{dep.id}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{dep.name}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{dep.name}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:32px">
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
and method in bean
public void onRowEdit(RowEditEvent event) {
System.out.println(((Department) event.getObject()).getName());
FacesMessage msg = new FacesMessage("Car Edited",
((Department) event.getObject()).getName());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onRowCancel(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Edit Cancelled",
((Department) event.getObject()).getName());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
I'm using primfaces 4.0

In my case it was the problem that my backing bean was #SessionScoped (in PF example it is #ViewScoped) so I need to modify dataTabe value:
<p:dataTable id="settingsTbl" value="#{settingsBean.settingsList}" var="item" editable="true">
.....
public List<Settings> getSettingsList() {
if(settingsList==null){
settingsList = settingsFacade.findAll();
}
return settingsList;
}

I had encountered this issue and my workaround was to put the dataTable within a Form.

https://plnkr.co/edit/nYxHfY8PsGH586Om?open=lib%2Fscript.js
<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" ui-grid-edit ui-grid-row-edit ui-grid-cellNav class="grid">
</div>
<button id='flushDirty' ng-click='flushDirty()'>Flush Dirty</button>
<button id='addRow' ng-click='addRow()'>Add Row</button>
<br/>
<p>Dirty rows: {{dirtyRows.length}}</p>
<div ng-repeat="row in dirtyRows">
{{row.entity.id}}, {{row.entity.gender}}
</div>
</div>

Related

using <p:dataTable> cellEdit event is never fired in Primefaces

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

How to call <p:ajax> from <p:commandLink> in JSF inside Editable Datatable

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");
}

<p:rowEditor display new values, even update db was not performed successfully

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.

primefaces rowEdit Event to update table only if the event is a success

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.

p:dialog shows empty values when when I go to the next page of the p:datatable using paginator

I have been using onEdit in the p:datatable and it works fine.My data table has a pagintor and shows 5 records per page.so when I click on the onEdit in the first page event.getObject gets the changed value in the bean.Now when I go the next page the event.getObject does not work and returns the old value only.
Same with the dialog box.In the table I have a link when clicked opens a dialog box in whcih I am populating few fields with the values from the row selected.It works fine in the first page and When I navigate to other pages gives empty values.
Here is my jsf code:
<p:dataTable value="#{mybean.userList}"
var="item"
id="dataTab"
widgetVar="usersTable"
tableStyleClass="data" paginator="true" rows="5"
filteredValue="#{userController.filteredUsers}"
editable="true"
rowKey="#{item}"
>
<p:ajax event="rowEdit" listener="#{mybean.onEdit}" update=":userForm:growl" />
<p:ajax event="rowEditCancel" listener="#{mybean.onCancel}" update=":userForm:growl" />
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Search all fields:" />
<p:inputText id="globalFilter" onkeyup="('usersTable').filter()" style="width:150px" />
</p:outputPanel>
</f:facet>
<p:column sortBy="#{item.firstName}" filterBy="#{item.firstName}"
filterMatchMode="startsWith">
<p:cellEditor>
<f:facet name="header">
<h:outputText value="First Name" />
</f:facet>
<f:facet name="output">
<h:outputText value="#{item.firstName}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{item.firstName}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column sortBy="#{item.lastName}" filterBy="#{item.lastName}" filterMatchMode="startsWith">
<p:cellEditor>
<f:facet name="header">
<h:outputText value="Last Name" />
</f:facet>
<p:column headerText="Update" style="width:6%">
<p:rowEditor />
</p:column>
</p:dataTable>
<p:dialog id="modalDialog"
header="Delete User?"
modal="true"
resizable="false"
draggable="false"
widgetVar="delUserConf"
>
<h:panelGrid id="display" columns="2" style="width: 150px;">
<h:outputLabel value="Firat Name" style="font-weight: bold"/>
<h:outputText value="Last Name" style="border: none"/>
</h:panelGrid>
</p:dialog>
Here is the code in my bean for the edit functionality:
public String onEdit(RowEditEvent event)
{
User user=(User)event.getObject());
user.getFirstName();
}
I did not add the link that I have in my form which pops up the dialog.Also I read that this might be because of Lazy loading and I am not sure about it.I am populating my table with a list and not the model.
Could you let me know what should I do to make it work?
maybe you should switch to SessionBean scope because the scope view is released when there are changes in the view. Try SessionBean. Also you can call from view scope any sessionbean like this, where controladorMB is a sessionbean
public void detallesPersona() {
try {
FacesContext ctx = FacesContext.getCurrentInstance();
ValueExpression vex = ctx.getApplication().getExpressionFactory().createValueExpression(ctx.getELContext(), "#{controladorMB}", ControladorMB.class);
ControladorMB gMB = (ControladorMB) vex.getValue(ctx.getELContext());
this.setSelectedPersona(gMB.getPersonaBean().detallesPersonas(this.selectedPersona.getIdPersona()));
} catch (Exception e) {
JsfUtil.addErrorMessage(e, "Error: " + e.getMessage());
}
}

Resources