How update attribute of p:remoteCommand works - jsf

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)

Related

Update primefaces datatable from actionListener [duplicate]

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!

Updating entire <p:dataTable> on complete of <p:ajax event="cellEdit">

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!

JSF lazy loading component value

Consider a simple h:outputText component:
<h:outputText value="#{myBean.myValue}"/>
How can I lazy load that value after the page has been rendered, and display custom 'ajax loading' icon instead of the value while this is being done?
I am using PrimeFaces 3.5 in my project so any PF-specific implementation will be welcome.
A suggest to do this by calling remoteCommand after on page load (it is done by setting autoRun attribute to true) and update your outputText.
private String myValue;
// getter and setter
public void initMyValue() {
// init myValue
}
On page you should have ajaxStatus component for viewing loading image, and your outputText. Also there should be p:remoteCommand component:
<p:ajaxStatus style="width:16px;height:16px;" id="ajaxStatusPanel">
<f:facet name="start">
<h:graphicImage value="ajaxloading.gif" />
</f:facet>
<f:facet name="complete">
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
<h:outputText id="myText" value="#{myBean.myValue}"/>
<p:remoteCommand autoRun="true" actionListener="#{myBean.initMyValue}" update="myText"/>
EDIT: I supposed that you want to lazy load value of outputText because it contains some long running calculations, but if you want to completely deffer rendering of outputText first add boolean property in your backing bean, and set this property to true at the end of initMyValue method:
private boolean loaded;
// getter and setter
public void initMyValue() {
// init myValue
loaded = true;
}
on the page reorganize it as follows:
<h:panelGroup id="myPanel" layout="block">
<h:graphicImage value="ajaxloading.gif" rendered="#{!myBean.loaded}"/>
<h:outputText value="#{myBean.myValue}" rendered="#{myBean.loaded}"/>
</h:panelGroup>
<p:remoteCommand autoRun="true" actionListener="#{myBean.initMyValue}" update="myPanel"/>
You can use a BlockUI to conditionally block the component while it loads.
Define a preRenderComponent event on the <h:outputText/>
<h:outputText id="myText">
<f:event name="preRenderComponent" id="started"/>
</h:outputText>
Define a <p:blockUI/> with the id of the event as the trigger
<p:blockUI block="myText" trigger="started" />
You can customize the blockui to display an image or whatever.
A word of caution: I presume you require this because you're doing some heavy lifting in the getter of that component. Know that the getter will be called several times in the lifecycle of that page. So hiding the fact that the operation is taking a long time will not change the fact. A better design would be to preload and cache the value for that component in a durable scope, rather than the theatrics of a "loading" throbber.
This is how I ended up implementing it:
<h:panelGroup id="loginLocation">
<p:graphicImage library="assets" name="small-kit-loader.gif" width="16" height="16" rendered="#{empty mybean.lastLoginLocation}"></p:graphicImage>
<h:outputText value="#{myBean.lastLoginLocation}" rendered="#{!empty myBean.lastLoginLocation}"/>
</h:panelGroup>
<p:remoteCommand global="false" actionListener="#{actionBean.getUserLoginLocation(myBean.selectedUser)}" name="refreshLoginLocation" id="rc1" autoRun="true" update="loginLocation" process="#this"></p:remoteCommand>
Personally I am not entirely happy with this implementation:
lazy loading state is stored server-side, not client-side where it should be
I have to implement separate method on my backing bean (getUserLoginLocation) to retrieve the value, and explicitly store it in another property (lastLoginLocation). It would have been much cleaner just to have a single getter that is lazy-called after rendering the page in browser
Not easily reusable - depends on backing bean 'loaded' flag (#{empty myBean.lastLoginLocation} in this case), and requires action listener to actually set the value. Any composite component based on this approach would also depend on specific code in backing bean.
Any recommendations on how to improve this code are welcome! :)

Primefaces- JSF, data in a list can't be displayed in a p:datatabe

I have a list of users that I want to display in a JSF page using the primefaces p:datatable. I have no exception, but I can't display the data that a have into the list,even the column titles are not shown, in fact, I user the 'getUserListe()'method to get the data from the database calling my service layer, to be sure of that, I added a sysprint() of some userDomain properties (my model class), when I access to the URL, I want to populate my datatable with the data from the UserListe, so I call it by value="#{userMB.userListe}", the problem is that the list is not displayed. but when the page is charged, with means that getUserListe() is called, in my console, the proprties are printed successfullty, someone has any idea about this ?? :
a part of my managed bean :
#ManagedBean(name="userMB")
#RequestScoped
public class UserManagedBean implements Serializable {
private List<UserDomain> userListe ;
public List<UserDomain> getUserListe() {
this.userListe = new ArrayList<UserDomain>();
this.userListe.addAll(getUserServicee().getAll());
for(UserDomain u : userListe)
System.out.println(u.getFirstName());
return userListe;
}
public void setUserListe(List<UserDomain> userListe) {
this.userListe = userListe;
}
part of my jsf.xhtml file:
<h:form>
<h:outputText value="USER's rights list: "></h:outputText>
<p:dataTable id="userss" var="userr" value="#{userMB.userListe}" style="width: 10%">
<h:column>
<f:facet name="header"><h:outputText value="FirstName" /></f:facet>
<h:outputText value="#{userr.firstName}" />
</h:column>
<h:column>
<f:facet name="header"><h:outputText value="LastName" /></f:facet>
<h:outputText value="#{userr.lastName}" />
</h:column>
<h:column>
<f:facet name="header"><h:outputText value="Action" /></f:facet>
<h:commandLink value="Edit" action="#{userMB.editAction(userr)}" />
</h:column>
</p:dataTable>
<h:commandButton value="OK" action="#{userMB.userProp}" />
</h:form>
Note that my user has all the getters and setters of his properties setted correctly,
thank you for help
I did as #luiggi said in his comment by changing the <h:column> by the <p:column> and it's work fine, so thank you.
I also changed my managed bean from an #RequestScoped to an #ViewScoped one.
the other thing that I want to add and share with you , is that I did some research after reading the comments of this post, so I found an other solution that seems better than others to load the list only one time, It's by attaching a listener to a system event, so in my jsf file I add
<f:view>
<f:event type="preRenderView" listener="#{userMB.loadUserListe}" />
...
the loadUserListe() method in my bean call the business logic code which instantiate the list of users.
Of course, the jsf page is enclosed in an f:view. Note also that the use of this listener requires at least the JSF 2.0
thank you all for your help, and excuse me for my english, I hope this response helps others

JSF - p:dataTable - p:commandButton doesn't work even inside p:column

I have a commandButton inside a DataTable. However the "action" isn't called when I click on it (same effect with an actionListener); I added logs at the beginning of the server action, and it never shows.
Please note that the button works fine when outside from the datalist.
Here is my code:
<h:form id="compSearchForm">
<p:dataTable var="competency" value="#{competencySearchBean.matchingCompetencies.toArray()}">
<p:column>
<f:facet name="header">
<h:outputLabel value="Title" />
</f:facet>
<h:outputText value="#{competency.title}" />
</p:column>
<p:column>
<p:commandButton value="Go" id="actionButton" action="#{myBean.doAction}" />
</p:column>
</p:dataTable>
</h:form>
Would you have any idea as to what the issue might be?
I added your button column code to an existing of mine along with a dummy method in by backing bean. The method is called correctly when I press the button it works correctly. Here is the code I added to my dataTable:
<p:column>
<p:commandButton value="Go" id="actionButton" action="#{tableBean.buttonAction()}" />
</p:column>
Here is the buttonAction method in my backing bean:
public void buttonAction()
{
int a = 0;
for(int i = 0; i < 100; i++)
a = i;
}
I put a breakpoint on this method, so I know it is getting called when I click the button.
I went a step further and used your datatable code (with my data source) and the method is still being called when I press the button. I don't know what development environment you are using, but if it has a debug mode put a breakpoint on your doAction method, and a few other strategic locations in your bean, then run your project in debug mode to see what is going on.
I think you have to change to:
<h:form id="compSearchForm">
<p:dataTable var="competency" value="#{competencySearchBean.matchingCompetencies.toArray()}">
<p:column>
<f:facet name="header">
<h:outputLabel value="Title" />
</f:facet>
<h:outputText value="#{competency.title}" />
</p:column>
</p:dataTable>
<p:commandButton value="Go" id="actionButton" action="#{myBean.doAction}" />
</h:form>
I don't think you can have the button inside the dataTable. Try this.
see this example - http://www.primefaces.org/showcase/ui/datatableRowSelectionByColumn.jsf
I think you must prefix the id with the form ID
see how it updates ":form:display" instead of only "display"
worked for me
I had the same problem and after trying different ways, I resolved it by initializing my List (the list that I use in the p:datatable) in the init method of the Bean.
With this form, the list goes to the page with some values.
Even when I put List<Paciente> myList = new ArrayList<Paciente>(); it didn't work.
I have to put some values in the list. That was the only way that resolved the problem.

Resources