More problems with commandButtons / commandLinks in datatables

We are facing a serious problem with using commandButtons and commandLinks inside datatables. Clicking on the button on start_page transitions to data_page, but clicking on the buttons on data_page does NOT transition to end_page as expected. Giving the bean a session scope fixes the problem, but that is very undesirable for our application, and we cannot understand why that's necessary.

A very simplied version is shown below. What is going on here?

faces-config.xml:

<navigation-rule>

<from-view-id>/start_page.jsp</from-view-id>

<navigation-case>

<from-outcome>success</from-outcome>

<to-view-id>/data_page.jsp</to-view-id>

</navigation-case>

</navigation-rule>

<navigation-rule>

<from-view-id>/data_page.jsp</from-view-id>

<navigation-case>

<from-outcome>done</from-outcome>

<to-view-id>/end_page.jsp</to-view-id>

</navigation-case>

</navigation-rule>

<managed-bean>

<managed-bean-name>DataBean</managed-bean-name>

<managed-bean-class>test.DataBean</managed-bean-class>

<managed-bean-scope>request</managed-bean-scope>

</managed-bean>

start_page.jsp:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<html><body><f:view><h:form>

<h:commandButton value="Show Data" action="#{DataBean.makeData}" />

</h:form></f:view></body></html>

data_page.jsp:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<html><body><f:view><h:form>

<h:dataTable var="v" value="#{DataBean.data}">

<h:column>

<h:commandButton value="Done" action="done" />

</h:column>

</h:dataTable>

</h:form></f:view></body></html>

end_page.jsp:

<html><body>Done</body></html>

DataBean.java:

package test;

publicclass DataBean{

private String[] data;

public DataBean(){}

public String[] getData( ){

return this.data;

}

public String makeData(){

this.data =new String[]{"item1","item2"};

return"success";

}

}

[3623 byte] By [boot1780a] at [2007-10-3 1:21:00]
# 1

I tried your example without the bean deployed and the transition worked correctly from start to finish - one thing I noticed in your post regarding the bean scope - were you attempting to use the bean without a scope? if so - this may have been the problem - when attempting to use a bean - there is an assertion that the bean has to have a scope - maybe this was just a misunderstanding on my part - other than that - there should be no reason that the transition is not working

paroconsulta at 2007-7-14 18:18:13 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

Sorry - looking at your code again - I've just realized what you were saying - the problem lies in the scope itself - because the scope you are trying to use is "request" and NOT "session" - the bean is regenerated during each request - this.data is null when its being presented to generate the buttons on the request for the end page probably after the state handling phase of the request, but is not null after the start page is generated - again due to the state handling I assume - so probably why the data page gets the buttons generated. This is probably something to do with when the new bean gets generated in between requests. When the session scope is set the bean never goes away so this.data is never a new object its the same one that been kicking around in between requests.

Hope this helps

Lee

paroconsulta at 2007-7-14 18:18:13 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3
I figured out the best thing to do. Use a Tomahawk datatable and set preserveDataModel to true.
boot1780a at 2007-7-14 18:18:13 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

just remember that using preserveDataModel will serialize the data - either to the server or the client depending on how you have the server setup - this maybe the approach you want to use for "important" data - here is a reference to an article I came across that explains in simple terms what happens - maybe this will help in your decision:

http://wiki.apache.org/myfaces/Working_With_DataTable_And_PreserveDataModel

glad you resolved the problem though.

paroconsulta at 2007-7-14 18:18:13 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5
actually, it doesn't fully solve the problem, because now i need which row was selected and preserveDataModel doesn't preserve the selected row!
boot1780a at 2007-7-14 18:18:13 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6

that I imagine you would have to handle outside of the datatable - remembering this is just a rendered html <table>; one way - I'm sure others may have other suggestions - would be to have a hidden <h:inputHidden> - and update the inputs value with some id of the clicked row using the onclick() event. Then get that value from the form on submission. I use this when trying to maintain relationships across pages. There maybe some other ways but for quickness this is a easy way and doesn't require session scope beans.

paroconsulta at 2007-7-14 18:18:13 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 7
In order to get the row value you can use var attribute in dataTable:<t:dataTable ... var="currentObj">and in bean action method:externalContext = ...Object curObj = externalContext.getRequestMap().get("currentObj");
Alexusa at 2007-7-14 18:18:13 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...