editing row in data table

Hi. I'm new to JSF and am having a hard time understanding how modifications to data tables are best managed. I'm able to display all my rows with the modifiable columns rendered as a text inputs, but --for lack of a better description-- I don't understand how to instruct the 'backend' on which row was modified. How do I tell some bean to update row X if I can't supply arguments to action methods? What's the standard implementation (I'm not sure if an action method is the solution for this sort of need)? I don't mind posting to some other resource or adding an event listener- I just can't figure out how the target piece would receive the data.

[668 byte] By [rvflannerya] at [2007-10-2 21:28:09]
# 1

There are at least three ways of detecting what row was selected by the user. I will suggest the simplest way here.

Bind the dataTable value to a javax.faces.model.ListDataModel (or ArrayDataModel and so on). Example property getter method:

ListDataModel employeeList;

public ListDataModel getEmployeeList() {

if (employeeList != null) return employeeList;

//Get a list of Employee objects from database

ArrayList list = modelLayer.getAllEmployees();

employeeList = new ListDataModel(list);

return employeeList;

}

Then, define the dataTable:

<h:dataTable value="#{bean.employeeList}" ...>

Add a few commandLink components in the table.

<h:commandLink action="#{bean.editEmployee}">

From the action event handler of the command link, simply do:

public String editEmployee() {

//Get the Employee object for the selected row

Employee selectedEmployee = (Employee) employeeList.getRowData();

//...

}

Also, I recommend storing the managed bean in session scope. This is discussed elsewhere in this group.

bibhas2a at 2007-7-14 0:41:04 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2
perfect- thanks.
rvflannerya at 2007-7-14 0:41:04 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

OK, I'm actually still stuck on this problem. I can implement a 'solution' by specifying an EventChangeListener for each text input, but, rather then executing code for each column change, I want to add a command button for 'update', which then persists all column values in the current row. The problem is, I still can't figure out how to get the current row. Here's my setup:

public class ViewRightBean implements ActionListener,

ValueChangeListener {

private UIData dataModel = new UIData();

public void processAction(ActionEvent event) {

Object rowData = dataModel.getRowData();

new MyOtherBean().doDataUpdate(rowData);

}

}

and my table declaration:

<h:dataTable value="#{ViewRightBean.allViewRights}"

binding="#{ViewRightBean.dataModel}"

var="viewRight">

//all my data columns, then

<h:column>

<f:facet name="header">

<h:outputText value="Action"/>

</f:facet>

<h:commandButton value="save changes">

<f:actionListener type="com.jwt.gui.menus.beans.ViewRightBean"/>

</h:commandButton>

</h:column>

</h:dataTable>

The problem is, getRowData throws an IllegalArgumentException. I'm supposing there must be some error in the binding or field declaration because, within processAction(), the Datatable is non-null, but has a row count of zero and index of -1 (which is probably why I'm getting the IllegalArgumentException). Here's the exact stack Trace. Once again, some pointers would be appreciated.

java.lang.IllegalArgumentExceptionat javax.faces.model.ListDataModel.getRowData(ListDataModel.java:119)at javax.faces.component.UIData.getRowData(UIData.java:286)at com.jwt.gui.menus.beans.ViewRightBean.processAction(ViewRightBean.java:55)at javax.faces.event.ActionEvent.processListener(ActionEvent.java:57)at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:649)at javax.faces.component.UICommand.broadcast(UICommand.java:297)at javax.faces.component.UIData.broadcast(UIData.java:657)at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:267)at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:381)at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:75)at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:200)at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:90)at javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)

rvflannerya at 2007-7-14 0:41:04 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

I figured it out (in case this helps some one else- the previous discussions on datatable in this forum are almost too verbose, focusing on that seesion bug and making it difficult for new JSF developers to find simple answers. ...if they read at my level, at least):

Table Declaration:

//set value to data model instance, not list of value objects

<h:dataTable value="#{ViewRightBean.dataModel}"

var="viewRight">

Bean:

public class ViewRightBean implements ActionListener, ValueChangeListener {

private ListDataModel dataModel;

public ViewRightBean() throws NamingException {

allViewRights = new MenuClient().getMenuFacade().findAllViewRight();

dataModel = new ListDataModel(allViewRights);

}

rvflannerya at 2007-7-14 0:41:04 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5
I have the same issue but I am having a hard time figuring out your final solution. It would be greatly appreciated if you could clearly document your solution.
anonymousea at 2007-7-14 0:41:04 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...