Seam - sortable data table options
bsmithjj May 1, 2007 10:56 AMI am having some issues setting up a simple Tomahawk datatable that is sortable and as an extra, I've added in the Ajax4jsf tags to try to make the sort requests function as Ajax requests. The issue I am having is that the table renders fine on the initial display. When I click a column header, the data-rows display goes blank and the server log says:
... 08:31:43,564 ERROR org.apache.myfaces.component.html.ext.SortableModel - java.lang.IllegalStateException: row not available ...
This line is repeated 100 times - there are 100 rows in my data set. If I simply click the same column header again, it will display correctly (with sorting). If I then, click again, another blank data display with the same error messages, and so on...
My question is - does anyone know how to 'do' this correctly with Tomahawk and Ajax4Jsf?
Please - no suggestions like use Icefaces - until I can find instructions that tell me exactly what files to edit to integrate it into a Seam JSF app (Seam 1.2) I don't want to waste time. Also, Richfaces doesn't even seem to support clickable sorting on a datatable. That leaves just Tomahawk for this kind of functionality.
Here is my code.
The backing bean:
@Name("tableBacker") @Scope(ScopeType.SESSION) public class TableBacker { @Logger private Log log; @DataModel private List<DataRow> dataRows; @DataModelSelection private DataRow dataRow; @Factory("dataRows") public void getDataRows() { log.info("dataRows"); if (dataRows == null) { generateDataRows(); } } private final void generateDataRows() { log.info("generateDataRows()"); dataRows = new ArrayList<DataRow>(); Random random = new Random(System.currentTimeMillis()); for (long i = 0; i < 100; i++) { //DataRow(long id, String name, Date rowDate, String description) final long randomTime = System.currentTimeMillis() + random.nextInt(86400 * 10) * ((random.nextBoolean()) ? -1 : 1); final byte[] byteArray = new byte[ 25 + random.nextInt(10) * ((random.nextBoolean()) ? -1 : 1) ]; dataRows.add( new DataRow( i, "DataRow #" + i, new java.util.Date(randomTime), new StringBuffer(String.valueOf(i)).append(" - ").append(byteArray).toString() ) ); } } }
The Facelets XHTML view:
<h:form> <a4j:outputPanel id="dataRowsPanel"> The Data: <a4j:status> <f:facet name="start"> <h:graphicImage value="./img/spinner.gif"/> </f:facet> </a4j:status> <br/> <t:dataTable id="dataRows" var="dataRow" value="#{dataRows}" rows="15" sortColumn="#{id}" sortAscending="false" preserveDataModel="true" preserveSort="true"> <t:column defaultSorted="true" sortable="true"> <f:facet name="header"> <t:commandSortHeader columnName="id" arrow="true"> <h:outputText value="Row ID"/> <a4j:support event="onclick" reRender="dataRowsPanel"/> </t:commandSortHeader> </f:facet> <h:outputText value="#{dataRow.id}"/> </t:column> <t:column sortable="true"> <f:facet name="header"> <t:commandSortHeader columnName="name" arrow="true"> <h:outputText value="Row Data"/> <a4j:support event="onclick" reRender="dataRowsPanel"/> </t:commandSortHeader> </f:facet> <h:outputText value="#{dataRow.name}"/> </t:column> <t:column sortable="true"> <f:facet name="header"> <t:commandSortHeader columnName="rowDate" arrow="true"> <h:outputText value="Row Date"/> </t:commandSortHeader> </f:facet> <h:outputText value="#{dataRow.rowDate}"/> </t:column> <t:column sortable="true"> <f:facet name="header"> <t:commandSortHeader columnName="rowDate" arrow="true"> <h:outputText value="description"/> </t:commandSortHeader> </f:facet> <h:outputText value="#{dataRow.description}"/> </t:column> </t:dataTable> </a4j:outputPanel> </h:form>
Thanks,
Brad Smith