I am having difficulty re-rendering a PrimeFaces Datatable once a cell has been edited. Changing the value in one cell may change entries in the other cells, hence the need to refresh the entire table.
Here's the JSF page:
<h:form id="testForm">
<p:outputPanel id="testContainer">
<p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
<p:column headerText="Col1">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{entry.col1}" /></f:facet>
<f:facet name="input"><p:inputText value="#{entry.col1}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Col2">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{entry.col2}" /></f:facet>
<f:facet name="input"><p:inputText value="#{entry.col2}" /></f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
<p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />
</p:outputPanel>
</h:form>
And here's the backing bean:
#ManagedBean(name = "tableBean", eager = false)
#ViewScoped
public class TableBean {
public TableBean() {
RowData entry = new RowData("a1", "b1");
entries.add(entry);
entry = new RowData("a2", "b2");
entries.add(entry);
entry = new RowData("a3", "b3");
entries.add(entry);
}
public class RowData {
private String col1;
private String col2;
public RowData(String col1, String col2) {
this.col1 = col1;
this.col2 = col2;
}
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
}
private ArrayList<RowData> entries = new ArrayList<RowData>();
public List<RowData> getData() {
return entries;
}
public void onCellEdit(CellEditEvent event) {
entries.get(event.getRowIndex()).setCol1("Dummy Col 1");
entries.get(event.getRowIndex()).setCol2("Dummy Col 2");
}
}
When including update=":testForm:testContainer" within the cellEdit AJAX event, changing a cell value deletes the datatable on screen and only renders the cell content (along with the button) -- I do not understand why this is. When the update attribute is not specified, the table remains on screen with the active cell updated, but none of the other cells are updated (as to be expected).
The desired behaviour can be achieved (in a non-automated way) by not specifying the update attribute within the AJAX cellEdit event and clicking the Redisplay button after editing a cell's value. How can I achieve this in an automated way, and why does the update attribute not work as I expect?
I am using PrimeFaces 4.0.
The rowEdit and cellEdit events does by design inside the table not update/re-render anything else than the current row, even not when explicitly specified in update attribute. It's the consequence of PrimeFaces' a bit overzealous attempt to minimize the response size. This makes sense in most of the cases, but not in specifically your case. It's worth an issue report.
In the meanwhile, until they fix this behavior, your best bet is using <p:remoteCommand> to invoke the desired listener method and perform a full update of the table.
Rewrite
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
...
</p:dataTable>
to
<p:remoteCommand name="onCellEdit" action="#{tableBean.onCellEdit}" update="testContainer" />
<p:dataTable ...>
<p:ajax event="cellEdit" oncomplete="onCellEdit()" />
...
</p:dataTable>
The BaLusC solution has not worked directly for me. The onCellEdit needs a CellEditEvent as param. My workaround is as following:
<p:remoteCommand name="onCellEdit" update="testContainer" />
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="onCellEdit()" />
...
</p:dataTable>
If none of the solutions worked for you, this worked for me
<p:dataTable ... id="theId" widgetVar="theWidget" ...>
<p:ajax event="rowEdit" listener="#{...}"
oncomplete="PF('theWidget').filter()"/>
....
I'm calling the filter method on the PF widget on ajax complete, any method that does a "reload" of the table should work, I used filter because my table had column filters.
I tested your code. First I moved p:commandButton out of p:outputPanel. Here is modified code:
<h:form id="testForm">
<p:outputPanel id="testContainer">
<p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
(...)
</p:dataTable>
</p:outputPanel>
<p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />
</h:form>
I think this code doesn't work correctly. if you change anything in table, the p:ajax every time render full table. So, the program load basic data from TableBean constructor and deleted new data.
If I omit your p:ajax code there is not disapears any new data from screen. The refreshButton p:commandButton work correctly.
When including update=":testForm:testContainer" within the cellEdit
AJAX event, changing a cell value deletes the datatable on screen and
only renders the cell content (along with the button) -- I do not
understand why this is.
I think it is bad design add update=":testForm:testContainer" to ajax, because it's update your outputPanel more than as exepted (first time work correctly, second time couldn't edit cell, because the program update to many times table).
I don't know what is your goal. If you want render table without a commandButton, then could you specify one javascript event or p:message and this disappear you can render table.
I think if you omit update in p:ajax or specify update of one p:message, and move p.commandButton out of testContainer your code start work correctly.
After 5 years, this problem still exists. Unfortunately, while Baukes solution is extremly helpful and includes important insights it's still incomplete, as ltlBeBoy already pointed out in his comment. Subsequent edits without change lead to an inconsistent table state, where no more edits are possible. The reason is, that the oncomplete remote update comes after the edit mode of the new cell is already activated. So the edit mode of the new cell is destroyed by the update. However, the update can't be done in Ajax listener tableBean#onCellEdit, as this would display the table erroneously with one cell only.
The solution is, to execute the update in the remote commands listener and only, if a change happend. So, in tableBean you implement a programmatic update, a remote listener and a flag that indicates change:
public static void update(String id) {
PrimeFaces pf = PrimeFaces.current(); //RequestContext.getCurrentInstance() for <PF 6.2
if(pf.isAjaxRequest()) pf.ajax().update(id);
}
/** Whether onCellEdit changed the value */
boolean onCellEditChange;
public void onCellEditRemote() {
if(!onCellEditChange) update("testContainer");
}
public void onCellEdit(CellEditEvent event) {
... onCellEditChange= /*Change happend*/ ...
}
The remote command has no update attribute any more:
<p:remoteCommand name="onCellEdit" actionListener="#{tabelBean.onCellEditRemote}"/>
try using process
<p:remoteCommand name="onCellEdit" update="testContainer" process="#this" />
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="onCellEdit()" process="#this" />
...
</p:dataTable>
This is my first post ever in here. As ltlBeBoy mentioned, BalusC's solution works only if the cell editing is done with an enter key hit.
None of the other suggestions listed in here worked for me.
In my case, I just wanted to update a specific row (that has each column's average) in the table on cellEdit event. I'm posting this in case if someone out there is looking for a solution: I managed to achieve this by separating that row in a second datatable right below the main one. Here's the code:
<pf:ajax event="cellEdit"
listener="#{newAgentMetricBacking.onCellEdit}"
update="c21413" />
<pf:dataTable id="c21413"
styleClass="noHeader"
value="">
<pf:column>
<h:outputText value="#{bundle.TeamAverage}"/>
</pf:column>
<pf:columns columnIndexVar="j"
value="#{newAgentMetricBacking.averageArray}"
var="avg">
<h:outputText value="#{newAgentMetricBacking.
averageArray[j]}"/>
</pf:columns>
</pf:dataTable>
Otherwise, as of today, I couldn't find a better solution for updating either the whole table or a specific row specifically upon success of cellEdit event.
Cheers!
Related
Primefaces 6.0. I understand that update attribute of p:remoteCommand should be used to specify clientIds of the components that should be updated by AJAX. I am trying to understand how PF works. In combination with DataTable it doesn't seem to work as expected. When I try to directly set update="form:dataTable:2:bColumn", it has no efect. However, doing this (commented out in the below code) RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn"); will force PF to update the specified outputText.
Why is this happening? I will be happy for technical explanation - I am trying to find the answer by debugging PF Java/Javascript sources.
<h:form id="form">
<p:remoteCommand name="remoteCall"
action="#{grid4.onEdit}"
update="form:dataTable:2:bColumn"
/>
<p:dataTable id="dataTable"
var="gridItem"
value="#{grid4.gridItems}"
editable="true" editMode="cell"
>
<p:ajax event="cellEdit"
oncomplete="remoteCall()">
</p:ajax>
<p:column headerText="A">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{gridItem.a}" /></f:facet>
<f:facet name="input"><p:inputText value="#{gridItem.a}"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="B">
<h:outputText id="bColumn" value="#{gridItem.b}" />
</p:column>
</p:dataTable>
</h:form>
Bean
#ManagedBean
#ViewScoped
public class Grid4 {
private List<GridItem> gridItems = new ArrayList<>();
public Grid4() {
gridItems.add(new GridItem("1", "a","b"));
gridItems.add(new GridItem("2", "a","b"));
gridItems.add(new GridItem("3", "a","b"));
}
public void onEdit() {
System.out.println("onEdit()");
gridItems.get(2).setB("CHANGED VALUE");
// RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn");
}
public List<GridItem> getGridItems() {
return gridItems;
}
public void setGridItems(List<GridItem> gridItems) {
this.gridItems = gridItems;
}
}
basically jsf ids an client side ids are two different things (check this answer and this post for a better understanding).
When you use RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn"); that method use the client id to find the components that have to be updated, but in the case of the update property of p:remoteCommand it is expecting a jsf id, not the generated client id, so that´s why your update doesn't work. However, primefaces support jquery selectors to update components, so you could use a client side id on an update property like this update="#(#yourElementId)"
Let me start by mentioning that this is not specific to the p:remoteCommand. The reason for the behaviour you notice is rather simple although not directly obvious maybe since it is unfortunately not in the PrimeFaces documentation.
The update attribute in:
<p:remoteCommand name="remoteCall"
action="#{grid4.onEdit}"
update="form:dataTable:2:bColumn"
/>
uses a relative path if it does not start with a : and since the p:remoteCommand is already in the naming container with id='form', the form in the update attribute is superfluous and even makes it not work (run your app in dev mode, add a messages tag and see the errors).
So
<p:remoteCommand name="remoteCall"
action="#{grid4.onEdit}"
update="dataTable:2:bColumn"
/>
Should work, as should
<p:remoteCommand name="remoteCall"
action="#{grid4.onEdit}"
update=":form:dataTable:2:bColumn"
/>
The
RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn");
is always absolute, so the colon is not needed here and it will find the element starting from the root (form 'prefix' is needed then)
I have a need to display a list of Strings on a page, which a user will need to be able to add, edit, and delete entries. I figured I would use a DataTable to accomplish this.
The page appears to work properly - values are displayed in the DataTable, rows are deleted when the Delete icon is clicked, and rows are added when the Add button is clicked. However, when engaging the RowEditor by clicking the pencil icon, changes are never reflected when clicking the checkmark; the value of the row just goes back to being blank.
Here is a GIF showing the problem happening - http://imgur.com/a/dxlht
I've copied the majority of the DataTable markup from other pages in my project, which all work properly. The only difference I can see here is that this is a DataTable of Strings, not a complex object. Does this affect the "input" facet of the RowEditor when the value of the InputText is just a simple String?
Here is the DataTable markup:
<h:form>
<p:dataTable id="configTable" value="#{bean.configs}" var="config"
editable="true" editMode="row" emptyMessage="No entries exist.">
<p:column>
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{config}" /></f:facet>
<f:facet name="input"><p:inputText value="#{config}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column>
<p:rowEditor />
</p:column>
<p:column>
<p:commandLink update="configTable" styleClass="ui-icon ui-icon-trash" process="#this"
actionListener="#{bean.removeEntry(config)}" />
</p:column>
<f:facet name="footer">
<p:commandButton value="Add Entry" update="configTable" icon="ui-icon-plus" style="float:right;" process="#this"
actionListener="#{bean.addEntry()}" />
</f:facet>
</p:dataTable>
</h:form>
Here is the relevant bean code:
private List<String> configs;
public List<String> getConfigs() {
return this.configs;
}
public void setConfigs(List<String> configs) {
this.configs = configs;
}
public void removeEntry(String entry) {
this.configs.remove(entry);
}
public void addEntry() {
this.configs.add("");
}
I am using PrimeFaces 5.3/JSF 2.0.
Please note that when you press the check mark (to finish editing a row) JSF calls the setter method of whatever class your table rows are.
String class doesn't have a setter method, thus you will need to create a wrapper class with just one field (with getter and setter) and change your configs object to a List of yourClass objects.
Prerequisites:
JSF 2.1
Primefaces 5.2
Glassfish 3.1
Story:
I got a datatable displaying some editable values.
The amount of columns is dynamic.
In the same form is a button calling a save-action of my bean to save all edited data.
The function it self is working perfectly fine
Implementation:
<p:dataTable id="dataTable" scrollable="true"
widgetVar="wigVardataTable"
value="#{myBean.dataList}"
var="data"
editable="true"
editMode="cell"
rowKey="rowkey">
<p:columns var="col"
value="#{myModel.columnList}"
style="font-size: 12px">
<f:facet name="header">
<h:outputText
value="#{col.header}" />
</f:facet>
<p:cellEditor>
<f:facet name="output">
<h:outputText
value="#{myModel.getValueForTableCell(data, col).value}" />
</f:facet>
<f:facet name="input">
<p:inputText
id="inputTxt"
value="#{myModel.getValueForTableCell(data, col).value}"
style="width:100%">
</p:inputText>
</f:facet>
</p:cellEditor>
</p:columns>
</p:dataTable>
Problem:
When pressing the save button while a table cell is being edited and didn't loose its focus yet, the new value inside the inputtext of the tablecell won't be written back into my bean and due to that won't be saved.
Question:
How can i write back the data into my backing bean, before the button action is executed?
This behavior is caused by wrong ordering of ajax events. When the command button is invoked while having a cell editor open, then the ajax event of the command button is fired before the ajax event of the cell edit.
We'd thus like to swap around them. Without editing the PrimeFaces source code, you could achieve this by explicitly invoking saveCell() function of the <p:dataTable> widget when there's a cell editor open.
So, given a
<h:form>
<p:dataTable ... widgetVar="wigVardataTable" />
<p:commandButton ... />
</h:form>
you can achieve the desired behavior by adding the below onclick to the <p:commandButton>:
onclick="var d=PF('wigVardataTable'), c=d.jq.find('td:has(.ui-cell-editor-input:visible)'); if(c.length)d.saveCell(c)"
Basically, it first finds the cell with an open cell editor and then invokes saveCell() on it.
Another, less elegant, way is explicitly invoking showCellEditor() function of the <p:dataTable> widget without passing the expected target cell in a try-catch block where the exception is ignored.
onclick="try{PF('wigVardataTable').showCellEditor()}catch(ignore){}"
It will save any opened cell first and later throw an error that no new target cell was specified as argument, but that could be ignored as shown above.
Noted should be that this all works regardless of whether you use <p:columns> or <p:column>, and also regardless of whether you use a normal model or an overcomplicated model ;) This trick is tested on both your PrimeFaces 5.2 version and the current PrimeFaces 6.0 version.
Here is a generic solution inspired by BalusC answer if you have other datatables with cell editMode :
<script type="application/javascript">
function saveAllCellsBeforeSubmit() {
for (var widgetName in PrimeFaces.widgets) {
if (PrimeFaces.widgets[widgetName].hasOwnProperty('cfg') && PrimeFaces.widgets[widgetName].cfg.hasOwnProperty('editMode') && PrimeFaces.widgets[widgetName].cfg.editMode === 'cell') {
var d = PF(widgetName);
var c = d.jq.find('td:has(.ui-cell-editor-input:visible)');
if (c.length) {
d.saveCell(c);
}
}
}
}
</script>
I am having difficulty re-rendering a PrimeFaces Datatable once a cell has been edited. Changing the value in one cell may change entries in the other cells, hence the need to refresh the entire table.
Here's the JSF page:
<h:form id="testForm">
<p:outputPanel id="testContainer">
<p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
<p:column headerText="Col1">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{entry.col1}" /></f:facet>
<f:facet name="input"><p:inputText value="#{entry.col1}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Col2">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{entry.col2}" /></f:facet>
<f:facet name="input"><p:inputText value="#{entry.col2}" /></f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
<p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />
</p:outputPanel>
</h:form>
And here's the backing bean:
#ManagedBean(name = "tableBean", eager = false)
#ViewScoped
public class TableBean {
public TableBean() {
RowData entry = new RowData("a1", "b1");
entries.add(entry);
entry = new RowData("a2", "b2");
entries.add(entry);
entry = new RowData("a3", "b3");
entries.add(entry);
}
public class RowData {
private String col1;
private String col2;
public RowData(String col1, String col2) {
this.col1 = col1;
this.col2 = col2;
}
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
}
private ArrayList<RowData> entries = new ArrayList<RowData>();
public List<RowData> getData() {
return entries;
}
public void onCellEdit(CellEditEvent event) {
entries.get(event.getRowIndex()).setCol1("Dummy Col 1");
entries.get(event.getRowIndex()).setCol2("Dummy Col 2");
}
}
When including update=":testForm:testContainer" within the cellEdit AJAX event, changing a cell value deletes the datatable on screen and only renders the cell content (along with the button) -- I do not understand why this is. When the update attribute is not specified, the table remains on screen with the active cell updated, but none of the other cells are updated (as to be expected).
The desired behaviour can be achieved (in a non-automated way) by not specifying the update attribute within the AJAX cellEdit event and clicking the Redisplay button after editing a cell's value. How can I achieve this in an automated way, and why does the update attribute not work as I expect?
I am using PrimeFaces 4.0.
The rowEdit and cellEdit events does by design inside the table not update/re-render anything else than the current row, even not when explicitly specified in update attribute. It's the consequence of PrimeFaces' a bit overzealous attempt to minimize the response size. This makes sense in most of the cases, but not in specifically your case. It's worth an issue report.
In the meanwhile, until they fix this behavior, your best bet is using <p:remoteCommand> to invoke the desired listener method and perform a full update of the table.
Rewrite
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
...
</p:dataTable>
to
<p:remoteCommand name="onCellEdit" action="#{tableBean.onCellEdit}" update="testContainer" />
<p:dataTable ...>
<p:ajax event="cellEdit" oncomplete="onCellEdit()" />
...
</p:dataTable>
The BaLusC solution has not worked directly for me. The onCellEdit needs a CellEditEvent as param. My workaround is as following:
<p:remoteCommand name="onCellEdit" update="testContainer" />
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="onCellEdit()" />
...
</p:dataTable>
If none of the solutions worked for you, this worked for me
<p:dataTable ... id="theId" widgetVar="theWidget" ...>
<p:ajax event="rowEdit" listener="#{...}"
oncomplete="PF('theWidget').filter()"/>
....
I'm calling the filter method on the PF widget on ajax complete, any method that does a "reload" of the table should work, I used filter because my table had column filters.
I tested your code. First I moved p:commandButton out of p:outputPanel. Here is modified code:
<h:form id="testForm">
<p:outputPanel id="testContainer">
<p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
(...)
</p:dataTable>
</p:outputPanel>
<p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />
</h:form>
I think this code doesn't work correctly. if you change anything in table, the p:ajax every time render full table. So, the program load basic data from TableBean constructor and deleted new data.
If I omit your p:ajax code there is not disapears any new data from screen. The refreshButton p:commandButton work correctly.
When including update=":testForm:testContainer" within the cellEdit
AJAX event, changing a cell value deletes the datatable on screen and
only renders the cell content (along with the button) -- I do not
understand why this is.
I think it is bad design add update=":testForm:testContainer" to ajax, because it's update your outputPanel more than as exepted (first time work correctly, second time couldn't edit cell, because the program update to many times table).
I don't know what is your goal. If you want render table without a commandButton, then could you specify one javascript event or p:message and this disappear you can render table.
I think if you omit update in p:ajax or specify update of one p:message, and move p.commandButton out of testContainer your code start work correctly.
After 5 years, this problem still exists. Unfortunately, while Baukes solution is extremly helpful and includes important insights it's still incomplete, as ltlBeBoy already pointed out in his comment. Subsequent edits without change lead to an inconsistent table state, where no more edits are possible. The reason is, that the oncomplete remote update comes after the edit mode of the new cell is already activated. So the edit mode of the new cell is destroyed by the update. However, the update can't be done in Ajax listener tableBean#onCellEdit, as this would display the table erroneously with one cell only.
The solution is, to execute the update in the remote commands listener and only, if a change happend. So, in tableBean you implement a programmatic update, a remote listener and a flag that indicates change:
public static void update(String id) {
PrimeFaces pf = PrimeFaces.current(); //RequestContext.getCurrentInstance() for <PF 6.2
if(pf.isAjaxRequest()) pf.ajax().update(id);
}
/** Whether onCellEdit changed the value */
boolean onCellEditChange;
public void onCellEditRemote() {
if(!onCellEditChange) update("testContainer");
}
public void onCellEdit(CellEditEvent event) {
... onCellEditChange= /*Change happend*/ ...
}
The remote command has no update attribute any more:
<p:remoteCommand name="onCellEdit" actionListener="#{tabelBean.onCellEditRemote}"/>
try using process
<p:remoteCommand name="onCellEdit" update="testContainer" process="#this" />
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="onCellEdit()" process="#this" />
...
</p:dataTable>
This is my first post ever in here. As ltlBeBoy mentioned, BalusC's solution works only if the cell editing is done with an enter key hit.
None of the other suggestions listed in here worked for me.
In my case, I just wanted to update a specific row (that has each column's average) in the table on cellEdit event. I'm posting this in case if someone out there is looking for a solution: I managed to achieve this by separating that row in a second datatable right below the main one. Here's the code:
<pf:ajax event="cellEdit"
listener="#{newAgentMetricBacking.onCellEdit}"
update="c21413" />
<pf:dataTable id="c21413"
styleClass="noHeader"
value="">
<pf:column>
<h:outputText value="#{bundle.TeamAverage}"/>
</pf:column>
<pf:columns columnIndexVar="j"
value="#{newAgentMetricBacking.averageArray}"
var="avg">
<h:outputText value="#{newAgentMetricBacking.
averageArray[j]}"/>
</pf:columns>
</pf:dataTable>
Otherwise, as of today, I couldn't find a better solution for updating either the whole table or a specific row specifically upon success of cellEdit event.
Cheers!
i've got a question concerning Primefaces (version 5.0) and their datatable.
If I have a p:datatable and I want to edit a cell or row (doesn't matter - behaviour is the same in that case) AND someone added a new entry to that database, I edit the new entry instead of the old.
Well. Here are some code-snippets:
my index.xhtml:
<h:form id="viewChanges">
<p:dataTable id="changeTable"
widgetVar="changeTable"
value="#{changeController.list}" var="item"
selection="#{changeController.selectedChangeEntry}"
selectionMode="single" rowKey="#{item.id}"
sortBy="#{item.id}" sortOrder="descending"
editable="#{lDAPUserController.loggedIn}"
style="width: auto">
<p:ajax event="rowEdit"
listener="#{changeController.onRowEdit}"
update=":growlInfo, :growlError, :viewChanges:changeTable" />
..output of columns..
<p:column style="width:32px">
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
my changeController.java
#ManagedBean(name = "changeController")
#ViewScoped
public class ChangeController implements java.io.Serializable {
attributes, getter, setter, other methods etc..
public void onRowEdit(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Change Edited", ((Change) event.getObject()).getId());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
Well with this it's already possible to replicate the error.
Little Example: We have a dataset with 3 entries. - id=1,2,3
We open a browser[1] and see the 3 datasets. We now open a private tab[2] and go to the same site and add a new entry. Without refreshing [1] we edit the entry with id=3. All of the sudden we edited entry with id=4.
Could someone explain me why this is happening? Is it me or is it bug in primefaces? Wrong Scope?