One of the common and simple requirements of enterprise projects is that stylising your columns based on the data it contains like if the column is displaying a date it should be centered, if its a number it should be aligned right. The following will show you how you can make a smart enough datatable which knows what type needs what style.
I did this on the richfaces datatable but same logic could be used with other datatables.
1. Define the renderer
Since we are using rich faces we need to override the default renderer it comes with:
<renderer>
<component-family>org.richfaces.Column</component-family>
<renderer-type>
org.richfaces.renderkit.CellRenderer
</renderer-type>
<renderer-class>
org.mca.example.web.renderkit.html.CellAutoAlignedRenderer
</renderer-class>
</renderer>
render-class tag is now CellAutoAlignedRenderer which we will implement.2. Define the Renderer
The default rich faces renderer is org.richfaces.renderkit.CellRenderer.
We could achive the desired effect by simply overriding the
public String styleClass(FacesContext context, UIComponent component)
"getValueOfTheOnlyChild" method gets the data from the column to determine the data type. "if (value instanceof Number) {" part does determines the style.
method.
import org.richfaces.renderkit.CellRenderer;
public class CellAutoAlignedRenderer extends CellRenderer {
@Override
public String styleClass(FacesContext context, UIComponent component) {
ValueExpression styleExpression = component.getValueExpression("styleClass");
if (styleExpression == null) {
Object value = getValueOfTheOnlyChild(context, component);
if (value instanceof Number) {
return super.styleClass(context, component) + " " + getNumberColumnStyle();
}
else if (value instanceof Date) {
return super.styleClass(context, component) + " " + getDateColumnStyle();
}
}
return super.styleClass(context, component);
}
public String getDateColumnStyle() {
return "dateColumn";
}
public String getNumberColumnStyle() {
return "numberColumn";
}
private Object getValueOfTheOnlyChild(FacesContext context, UIComponent component) {
if (component.getChildCount() == 1) {
UIComponent child = component.getChildren().get(0);
if (child instanceof ValueHolder) {
ValueHolder aValue = (ValueHolder) child;
return aValue.getValue();
}
}
return null;
}
}
"getValueOfTheOnlyChild" method gets the data from the column to determine the data type. "if (value instanceof Number) {" part does determines the style.
"copy paste"
I did similar thing to use dojo.dnd with standard JSF dataTable, but I don't know why renderer doesn't work - it's not use by JSF even I put overriding configuration in my faces-config
ReplyDeleterender-kit
renderer
component-family javax.faces.Data /component-family
renderer-type javax.faces.Table /renderer-type
renderer-class lalala.MyTableRenderer /renderer-class
/renderer
/render-kit
Should I configure that somewhere else?