I have a databale on index.xhtml
What you can do is to use the [getRowData()][1]
method on the Java bean to directly get the object located on the line that hosts the button on which the user clicked.
An example of code:
public void editBook(ActionEvent evt) {
// We get the table object
HtmlDataTable table = getParentDatatable((UIComponent) evt.getSource());
// We get the object on the selected line.
Object o = table.getRowData();
// Eventually, if you need the index of the line, simply do:
int index = table.getRowIndex();
// ...
}
// Method to get the HtmlDataTable.
private HtmlDataTable getParentDatatable(UIComponent compo) {
if (compo == null) {
return null;
}
if (compo instanceof HtmlDataTable) {
return (HtmlDataTable) compo;
}
return getParentDataTable(compo.getParent());
}
The JSF code now looks like:
<h:commandButton value="Edit" actionListener="#{IndexBean.editBook}"/>
In addition, do not forget to change the signature of editBook()
method, by setting a javax.faces.event.ActionEvent
argument.
If you use EL 2.2, for example with Tomcat7 you can try
<h:commandLink action="#{IndexBean.editBook(item)}" immediate="true">
I hope to help
You've already bound the <h:dataTable>
component to the bean. All you need to do is:
public void editBook() throws IOException{
int index = datatableBooks.getRowIndex(); // Actually not interesting info.
Book book = (Book) datatableBooks.getRowData(); // This is what you want.
}
The <f:param>
is also not needed here. For more hints also see this article.
Update: I can reproduce your problem. This is likely a bug with @ViewScoped
. When the bean is set to @RequestScoped
, it works as expected. Also when you remove the component binding and obtain the component from the viewroot yourself, it works as expected. I've filed issue 1658 about this.