JSF 2 dataTable sorting example – DataModel

In the previous JSF 2 dataTable sorting example, showed the simplest way, a custom comparator to sort a list and display in dataTable.

DataModel Decorator

In this example, it shows another way to sort the list in dataTable, which is mentioned in the “Core JavaServer Faces (3rd Edition)“, called DataModel Decorator.

1. DataModel

Create a decorator class to extends the javax.faces.model.DataModel class, and add an extra sorting behavior. Well, a bit complicated to explain, please refer to the book for detail :)


package com.mkyong;

import java.util.Arrays;
import java.util.Comparator;
import javax.faces.model.DataModel;

public class SortableDataModel<E> extends DataModel<E>{

	DataModel<E> model;
	private Integer[] rows;
	
	SortableDataModel(DataModel<E> model){
		this.model = model;
		initRows();
	}
	
	public void initRows(){
		int rowCount = model.getRowCount();
		if(rowCount != -1){
			this.rows = new Integer[rowCount];
			for(int i = 0; i < rowCount; ++i){
				rows[i] = i;
			}
		}
	}
	
	public void sortBy(final Comparator<E> comparator){
		Comparator<Integer> rowComp = new Comparator<Integer>() {
			public int compare(Integer i1, Integer i2){
				E o1 = getData(i1);
				E o2 = getData(i2);
				return comparator.compare(o1, o2);
			}
		};
		Arrays.sort(rows, rowComp);
		
	}
	
	private E getData(int row){
		int originalRowIndex = model.getRowIndex();
		
		model.setRowIndex(row);
		E newRowData = model.getRowData();
		model.setRowIndex(originalRowIndex);
		
		return newRowData;
	}
	
	@Override
	public void setRowIndex(int rowIndex) {

		if(0 <= rowIndex && rowIndex < rows.length){
			model.setRowIndex(rows[rowIndex]);
		}else{
			model.setRowIndex(rowIndex);
		}
	}
	
	@Override
	public boolean isRowAvailable() {
		return model.isRowAvailable();
	}

	@Override
	public int getRowCount() {
		return model.getRowCount();
	}

	@Override
	public E getRowData() {
		return model.getRowData();
	}

	@Override
	public int getRowIndex() {
		return model.getRowIndex();
	}

	@Override
	public Object getWrappedData() {
		return model.getWrappedData();
	}

	@Override
	public void setWrappedData(Object data) {
		
		model.setWrappedData(data);
		initRows();
		
	}
	
}

2. Managed Bean

A managed bean to provide a dummy list for testing, and shows the use of custom DataModel to sort the dataTable list.


package com.mkyong;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Comparator;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.model.ArrayDataModel;
import javax.faces.model.DataModel;
 
@ManagedBean(name="order")
@SessionScoped
public class OrderBean implements Serializable{

	private static final long serialVersionUID = 1L;

	private SortableDataModel<Order> sotableDataModel;

	private boolean sortAscending = true; 
	
	private static final Order[] orderList = {
		new Order("A0002", "Harddisk 100TB", 
				new BigDecimal("500.00"), 3),
		new Order("A0001", "Intel CPU", 
				new BigDecimal("4200.00"), 6),
		new Order("A0004", "Samsung LCD", 
				new BigDecimal("5200.00"), 10),
		new Order("A0003", "Dell Laptop", 
				new BigDecimal("11600.00"), 9),
		new Order("A0005", "A4Tech Mouse", 
				new BigDecimal("200.00"), 20)
	};
	
	public OrderBean(){

		sotableDataModel = new SortableDataModel<Order>(
			new ArrayDataModel<Order>(orderList));

	}
	
	public DataModel<Order> getOrderList() {
		 
		return sotableDataModel;
 
	}

	//sort by order no
	public String sortByOrderNo() {
	    
		if(sortAscending){
			
		  sotableDataModel.sortBy(new Comparator<Order>() {
				
			@Override
			public int compare(Order o1, Order o2) {
					
				return o1.getOrderNo().compareTo(o2.getOrderNo());
					
			}
		});
			
		sortAscending = false;
			
	  }else{

		//descending order
		sotableDataModel.sortBy(new Comparator<Order>() {
				
			@Override
			public int compare(Order o1, Order o2) {
					
				return o2.getOrderNo().compareTo(o1.getOrderNo());
					
			}
		});
		sortAscending = true;
	  }

	  return null;
	}

	public static class Order{
		
		String orderNo;
		String productName;
		BigDecimal price;
		int qty;

		public Order(String orderNo, String productName, 
				BigDecimal price, int qty) {
			this.orderNo = orderNo;
			this.productName = productName;
			this.price = price;
			this.qty = qty;
		}

		//getter and setter methods

	}
}

2. dataTable Tag

A JSF page, put a commandLink tag in the "Order No" column header, if click, sort the dataTable list.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"   
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      >
    <h:head>
    	<h:outputStylesheet library="css" name="table-style.css"  />
    </h:head>
    <h:body>
    	
    	<h1>JSF 2 dataTable sorting example</h1>
		  <h:form>
    		<h:dataTable value="#{order.orderList}" var="o"
    			styleClass="order-table"
    			headerClass="order-table-header"
    			rowClasses="order-table-odd-row,order-table-even-row"
    		>
 
    		<h:column>
    			<f:facet name="header">
    			   <h:commandLink action="#{order.sortByOrderNo}">
    				Order No
    			   </h:commandLink>
    			</f:facet>
    			#{o.orderNo}
    		</h:column>
 
    		<h:column>
    			<f:facet name="header">
    				Product Name
			</f:facet>
    			#{o.productName}
    		</h:column>
 
    		<h:column>
    			<f:facet name="header">Price</f:facet>
    			#{o.price}
    		</h:column>
 
    		<h:column>
    			<f:facet name="header">Quantity</f:facet>
    			#{o.qty}
    		</h:column>
 
    	    </h:dataTable>
    	  </h:form>
    </h:body>
</html>

3. Demo

From top to bottom, shows a dataTable list being sorted in ascending and descending order.

jsf2-dataTable-Sorting-Example-1
jsf2-dataTable-Sorting-Example-2
jsf2-dataTable-Sorting-Example-3

Download Source Code

Reference

  1. JSF 2 dataTable sorting example
  2. Java object sorting example

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

avatar
3 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
velskibraddersLeslie Recent comment authors
newest oldest most voted
velski
Guest
velski

Hello,

Works fine, but problem occured when form is reloaded. Program sort ascending and after reload site sort descending without clicking sort button. I’m not sure why? Maybe, because something in function initRows() or in one of constructors?

bradders
Guest
bradders

Great example and works fine.

However I seem to have a issue when deleting rows when using SortableDataModel. The changes do not get reflected to the table in the UI. I am removing from the database, my list of beans. The edit functionality works fine though :s

Leslie
Guest
Leslie

Hi,
I was trying this sample cod, the zip file. I try to deploy it in my Jboss AS 6.0 with eclipse 3.6. I manage to open up the default.xhtml and I can see the header but no data. Can you please let me know what I have missed ?

Thanks.
Lesltan