Programming tips for various technologies.

lunedì 28 settembre 2009

Tomahawk's library and managing tables.

One of the useful thing while working with some technology is trying to use the provided libraries to avoid every time to "reinvent the Hot Water".
I chose to use Myfaces to develop the web interface so i began to look at its related developing libraries. One of the library is TomaHawk.

Anyway i would like to discuss about displaying Tables and how to manage them in the correct way.
So when you work with databases and data, the things that you would like to do are:
  1. Display the data in tabular way
  2. Manage the pagination on the data
  3. Manage the ordering of the data inside the table
  4. Manage the data in the correct way
  5. As usual write quickly maintainable code
Using Tomahawk to cope with this problem was a very nice solution but i had again to fight against the lack of documentation (or outdated documentation as well).
I won't post links to various documentation because there is a lot of documentation and blogs that talk about managing tabular data and the list would be too long.

Displaying data with tables

What do we need to code to solve this problem? As always you will need to write down a back bean, the web interface code and some more needed java code.
First of all we need a class that will store the fields from the database.

public class TableItem {

private String field1;
//List of fields here
public TableItem(String field1) {
this.field1=field1;
}

public Date getField1() {
return field2;
}

public void setField1(String field1) {
this.field1 = field1;
}
}

After that we code our Back Bean that will keep the data loaded from DB or File and will setup our table. We will use this bean in the JSP or Facelets code to display the data in a table. You basically will need to implement one method to achieve the objective.
For the interface we will use a datascroller to manage the pagination and more we will use a commandSortHeader to manage column sort.
Finally a trick i found after about 2 months of searching. We can handle the latest page visited in the pagination so that when returning to the list (the displayed table) we can remeber the latest visited page inside the paginated table. When you have a list of thousands of records this will be very useful (it is a lot annoying to start always from the first record when we reload the table page).

public class TableBackBean {

private Integer latestpageindex;
private transient ListDataModel model = null;
// This field is transient because it cannot be serialized
// and JSF must be aware of it

public TableBackBean() {
// we load data at the creation of the Bean
model=new ListDataModel(getList());
}

public List< TableItem > getList(){
List< YourDBObject > datalistfromdb = null;
List< TableItem > dataitems = new ArrayList<>();
...
...
...
// You can load data from DB or File or whatever into datalistfromdb
// and after that you must create the List to be returned to JSF
// here is the generic code
if(!datalistfromdb.isEmpty()) {
Iterator it = datalistfromdb.iterator();
while(it.hasNext()) {
YourDBObject dbob = (YourDBObject) it.next();
dataitems.add(new TableItem(dbobj.getFirstField()));
}
}
...
...
...
return items;
}

public Integer getLatestpageindex() {
return latestpageindex;
}

public void setLatestpageindex(Integer latestpageindex) {
this.latestpageindex = latestpageindex;
}
}

Now to the interface code. The dataTable has got 2 parameters, first and rowIndexVar; rowIndexVar will save the first index of the record displayed in the paginated table into a property in the session (you must pass the property name as parameter), while first will pass this saved property as the first index to display next time the page is loaded. So we have done each time we leave the table page and reload it, it will remember latest paginated index.
To sort the list by a field of the record we must add defaultSorted="true" sortable="true" to the column that we want to sort with, and remeber to use t:commandSortHeader inside the column code as below.

< t: dataTable id="table1" first="#{TableBackBean.indicepagina}" rowIndexVar="indicepaginastudi" rows="10" value="#{TableBackBean.items}" var="item" >
< t : column defaultsorted="true" sortable="true">
< f : facet name="header">
< t : commandSortHeader arrow="true" propertyName="field1" >
< h: outputText value="Field1" />
< /t: commandSortHeader >
< /f : facet >
< h : outputText value="#{item.field1}" />
< /t : column >
< /t:dataTable >
< t : dataScroller id="scroller" for="table1" paginator="true" paginatormaxpages="10" immediate="true">
< name="first">First< /f:facet>
< name="last">Last< /f:facet>
< name="previous">& lt;< /f:facet >
< name="next">& gt;< /f:facet >
< / t : dataScroller >

Now remember to register properly the backing bean into faces-config.xml as a session bean.

That worked very well to me. Hope you won't have any problem in running this .
Please comment if you have any problems.

Lettori fissi