Posting List in backing bean ?
Hi,
I'm new to JSF, and have been just stumbling around so far. I've got data coming from an EJB into my managed bean, then storing that in a ListDataModel which I iterate over in the page.
Now I've got a command button to call a method in my backing bean, and I want to pick up all the rows that I iterated over on the page, and update my DB.
My problem is, the backing bean only represents one row/record. I'm using it to get many rows/records and populate the form via a dataTable.
I've probably broken a few rules here, any tips or examples would be terrific.
[599 byte] By [
tfindlaya] at [2007-11-27 8:50:43]

# 1
when u click on the command button, in side the Action or actionListner u can directly refer the arrayList u bind to dataTable and Iterate over it.
# 2
Ok, so I have a JSP like so....
<f:view>
<a4j:region>
<h:form>
<r:dataTable id="stocktable" value="#{StockTakeBean.stockList}" var="stock" columns="7" >
<h:column>
<h:outputText value="#{stock.whStore}"/>
</h:column>
</r:dataTable>
<a4j:commandButton value="Review" action="review" reRender="jsfTable,richTable" />
</h:form>
</a4j:region>
</f:view>
Then I have a request scope backing bean like so....
public final class StockTakeBean extends Object {
private Integer stocktakekey;
private ListDataModel myModel;
public ListDataModel getStockList()
{
try {
Context ctx = new InitialContext();
String jndiName = "stocktake/SessionFacade/local";
SessionFacadeLocal sf = (SessionFacadeLocal) ctx.lookup( jndiName );
myModel.setWrappedData(sf.findAll());
} catch (Exception e) {
// TODO: handle exception
System.out.println("Exception caused "+e.getMessage());
}
return myModel;
}
public String setStockList()
{
System.out.println("+++++++++++ StockTakeBean:setStockList() - Entering ");
int rowCount = myModel.getRowCount();
System.out.println("+++++++++++ StockTakeBean:setStockList() - Row count is:"+ Integer.toString( rowCount ) );
try {
Context ctx = new InitialContext();
String jndiName = "stocktake/SessionFacade/local";
SessionFacadeLocal sf = (SessionFacadeLocal) ctx.lookup( jndiName );
//sf.saveAll( );
} catch (Exception e) {
// TODO: handle exception
System.out.println("Exception caused "+e.getMessage());
}
return "success";
}
}
So... when I call getStockList() I can get my list from where ? request.getAttribute() ? and then somehow hand the list back to my EJB I guess <shrug>
# 3
There are no input components in your code example, but I gather that is what you are driving at?
Consider what happens when the request is sent to the server. First, the restore view phase occurs. During this phase the dataTable component is recreated; part of this is that the EL expression for the value is invoked, which means StockTakeBean.getStockList() is executed, which means that the myModel property is populated with a list of fresh EJB instances. Next comes the Apply Request Values and Process Validation phases, which are not interesting for this discussion. Then comes the Update Model Values phase; during this phase, any of the input components in the table which were bound to the "stock" var are applied to each object in the data model. So now the myModel property holds EJB instances with values updated from the request. Next is the Invoke Application phase; you need to bind an action or action listener to the button so you can save the EJBs in this phase. Finally comes the Render Response phase, which is also uninteresting.
# 4
Your right, sorry, the form is quite big, I do have the following inputs:
<h:column>
<h:inputText value="#{stock.actualStock}"/>
</h:column>
I have been reading this article here:
http://www.ibm.com/developerworks/library/j-jsf2/
Which talks about the lifecycle of JSF, but I'm not sure I follow it. The examples give in the article only seem to talk about updating/editing a single row/record at a time. I want to be able to submit and update the whole list.
How can I make my <CommandButton> activate or call a method later in the lifecycle (after the been has the values applied & validated) ?
My faces config currently looks like this:
<navigation-rule>
<from-view-id>/stocktakeinput.jsp</from-view-id>
<navigation-case>
<from-action>#{StockTakeBean.setStockList}</from-action>
<from-outcome>success</from-outcome>
<to-view-id>/saved.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<managed-bean>
<managed-bean-name>StockTakeBean</managed-bean-name>
<managed-bean-class>au.com.ubf.stocktake.StockTakeBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>
# 5
In general, action listeners and action methods are called during the Invoke Application phase, which is after the request values have been applied to the model. I see you are using ajax4jsf, I'm not familiar with that library; however, likely what you want to do is use an EL expression to bind a method to the action attribute of the command tag. If you were using standard components, something like
<h:commandButton value="Submit" action="#{myBean.saveBeans}" />
and
public String saveBeans()
{
// persist beans to database
return null;
}
# 6
Thanks,
That looks like what I'm currently doing, I have my command button, which calls saveBeans(), but inside saveBeans(), the data model is still only refreshed with the original data used to create the view (the Restore View phase).
My log messages show:
11:12:25,225 INFO [STDOUT] +++++++++++ StockTakeBean:getStockList() - Data Received Ok
11:12:25,225 INFO [STDOUT] +++++++++++ StockTakeBean:getStockList() - Leaving
11:12:25,366 INFO [STDOUT] +++++++++++ StockTakeBean:setStockList() - Entering
11:12:25,366 INFO [STDOUT] +++++++++++ StockTakeBean:setStockList() - Row count is:214
11:12:25,366 INFO [STDOUT] +++++++++++ StockTakeBean:setStockList() - Data Match
11:12:25,366 INFO [STDOUT] +++++++++++ StockTakeBean:setStockList() - Leaving
I wonder if it has something to do with my backing bean, it currently declared as:
public final class StockTakeBean extends Object {
}
Any other tips or suggestions would be appreciated.
# 7
My best guess is that you are re-populating the list from the database after the Update Model Values phase.