Using rich:dataTable and rich:columns together to display th
anandsaranath May 29, 2009 7:25 AMHi,
I have a requirement where my columns in a table will be picked up from configuration (web.xml). So, displaying the table content using rich:column is ruled out. I tried using rich:columns and I am able to display the information. But, when it comes to sorting of columns, it is not working.
I have a runningJobs.xhtml file which displays information from RunningJobsBean (request scope). The columns are picked up from web.xml. I manually build column objects using Column class which also has the Ordering field set by default to the first column. But the requirement here is that I should be able to sort the column values on any column.
When I get the output on the tab, I am able to sort it once. But, after that, the sorting functionality does not work.
I am attaching the code. Please help!
Regards
Anand
The runningJobs.xhtml page is as follows:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich" xmlns:a4j="http://richfaces.org/a4j" xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:form id="runningJobsForm">
<a4j:loadScript src="../../javascript/saSov.js" />
<rich:contextMenu attached="false" id="menu" submitMode="ajax">
<rich:menuItem onclick="stopJobConfirm('{jobId}', '#{SOV_JobAction.stopMsg}');"
submitMode="ajax" oncomplete="alert('#{SOV_JobAction.errMsg}');document.location.href='/activator/jsf/sov/results.jsf'">
<a4j:actionparam assignTo="#{SOV_JobAction.jobId}" value="{jobId}" actionListener="#{SOV_JobAction.stopJob}"/>
<h:outputText value="Stop Job ({jobId})" />
</rich:menuItem>
<rich:menuItem onclick="stopJobConfirm('{jobId}', '#{SOV_JobAction.stopMsg}');" submitMode="ajax"
oncomplete="alert('#{SOV_JobAction.errMsg}');document.location.href='/activator/jsf/sov/results.jsf'" rendered="#{SOV_JobAction.admin}">
<h:outputText value="Forced Stop Job ({jobId})" />
<a4j:actionparam assignTo="#{SOV_JobAction.jobId}" value="#{jobId}" actionListener="#{SOV_JobAction.stopJobForce}" />
</rich:menuItem>
<rich:menuItem onclick="return changeRoles('{jobId}', 'RunningJobs');" rendered="#{SOV_JobAction.admin}">
<h:outputText value="Change Roles for Job ({jobId})"/>
</rich:menuItem>
<rich:menuItem onclick="return changePriority('{jobId}');" rendered="#{SOV_JobAction.admin}">
<h:outputText value="Change Priority for Job ({jobId})"/>
</rich:menuItem>
</rich:contextMenu>
<div align="center">
<rich:dataTable value="#{SOV_RunningJobsBean.valueList}" var="row" width="100%" rows="#{SOV_RunningJobsBean.maxRecords}"
onRowMouseOver="this.style.backgroundColor='#F8F888'"
onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"
id="testDataTable1" sortMode="multiple">
<rich:columns id="#{row.data[index]}_#{index}" value="#{SOV_RunningJobsBean.columns}" var="col" index="index"
sortBy="#{row.data[index]}" sortOrder="#{col.ordering}">
<f:facet name="header">
<h:outputText value="#{col.name}" />
</f:facet>
<h:outputText value="#{row.data[index]}" />
</rich:columns>
<rich:componentControl event="onRowContextMenu" for="menu" operation="show" disableDefault="true">
<f:param value="#{row.jobDesc.jobId}" name="jobId" />
<f:param value="#{row.jobDesc.name}" name="name" />
</rich:componentControl>
</rich:dataTable>
</div>
</h:form>
</html>
The RunningJobsBean code is as follows
package com.hp.ov.activator.jsf.sov;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.TreeSet;
import java.util.Vector;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.richfaces.model.Ordering;
import com.hp.ov.activator.mwfm.JobResponseDescriptor;
import com.hp.ov.activator.mwfm.RunningJobDescriptor;
import com.hp.ov.activator.mwfm.WFManager;
public class RunningJobsBean implements Serializable, com.hp.ov.activator.mwfm.servlet.Constants
{
private TreeSet<RunningJobDescriptor> runningJobs = null;
private LinkedList<Column> columns;
private DisplayBean[] valueList;
private int maxRecords = 0;
private WFManager session = null;
Vector<String> configuredColumns = null;
public LinkedList<Column> getColumns()
{
return columns;
}
public void setColumns(LinkedList<Column> columns)
{
this.columns = columns;
}
public int getMaxRecords()
{
return maxRecords;
}
public void setMaxRecords(int maxRecords)
{
this.maxRecords = maxRecords;
}
public RunningJobsBean()
{
System.out.println("running jobs bean constructor");
FacesContext context = FacesContext.getCurrentInstance();
Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
String temp = (String) sessionMap.get(SOV_JOB_MAX_RECORDS);
session = (WFManager) sessionMap.get(MWFM_SESSION);
try {
maxRecords = Integer.parseInt(temp);
} catch (Exception e) {
// ignore exception. This exception will never be thrown
}
configuredColumns = (Vector<String>) sessionMap.get(SOV_JOBS_COLUMNS);
Locale locale = context.getExternalContext().getRequestLocale();
ResourceBundle resourceBundle = ResourceBundle.getBundle(SOV_RESOURCE_BUNDLE, locale);
populateWithRB(resourceBundle);
ValueChangeListener listener = (ValueChangeListener) sessionMap.get(TAB_LISTENER);
// query the backend only in case the selected tab is messages tab.
if (listener != null) {
String selectedTab = listener.getJobsTab();
if (selectedTab.equals(RJ_TAB)) {
queryJobs();
}
}
}
/*private void populateWithRB(ResourceBundle bundle)
{
columns = new LinkedList<Column>();
for (int i = 0; i < configuredColumns.size(); i ++) {
String configuredColName = configuredColumns.get(i);
// String replaceString = bundle.getString(configuredColName);
String replaceString = configuredColName;
if (configuredColName.equals(JOB_ID_LABEL)) {
columns.add(new Column(replaceString, Ordering.ASCENDING));
} else {
columns.add(new Column(replaceString, Ordering.UNSORTED));
}
}
}*/
private void populateWithRB(ResourceBundle bundle)
{
columns = new LinkedList<Column>();
for (int i = 0; i < configuredColumns.size(); i ++) {
String column = configuredColumns.get(i);
if (column.equals(JOB_ID_LABEL)) {
columns.add(new Column(JOB_ID_LABEL, Ordering.ASCENDING));
} else if (column.equals(SERVICE_ID_LABEL)) {
columns.add(new Column(SERVICE_ID_LABEL, Ordering.UNSORTED));
} else if (column.equals(HOST_NAME_LABEL)) {
columns.add(new Column(HOST_NAME_LABEL, Ordering.UNSORTED));
} else if (column.equals(WORKFLOW_LABEL)) {
columns.add(new Column(WORKFLOW_LABEL, Ordering.UNSORTED));
} else if (column.equals(WORKFLOW_TYPE_LABEL)) {
columns.add(new Column(WORKFLOW_TYPE_LABEL, Ordering.UNSORTED));
} else if (column.equals(WORKFLOW_STATE_LABEL)) {
columns.add(new Column(WORKFLOW_STATE_LABEL, Ordering.UNSORTED));
} else if (column.equals(ORDER_ID_LABEL)) {
columns.add(new Column(ORDER_ID_LABEL, Ordering.UNSORTED));
} else if (column.equals(STEP_LABEL)) {
columns.add(new Column(STEP_LABEL, Ordering.UNSORTED));
} else if (column.equals(START_TIME_LABEL)) {
columns.add(new Column(START_TIME_LABEL, Ordering.UNSORTED));
} else if (column.equals(DESCRIPTION_LABEL)) {
columns.add(new Column(DESCRIPTION_LABEL, Ordering.UNSORTED));
} else if (column.equals(STATUS_LABEL)) {
columns.add(new Column(STATUS_LABEL, Ordering.UNSORTED));
} else {
System.out.println(
MessageFormat.format("><Ignoring column {0} in Service Order View (Running Jobs Tab) as this parameter is not recognizable",
new Object[] {column}));
}
}
}
public DisplayBean[] getValueList()
{
return valueList;
}
public void setValueList(DisplayBean[] valueList)
{
this.valueList = valueList;
}
public DisplayBean[] queryJobs()
{
JobResponseDescriptor jobRespDesc;
FacesMessage message = new FacesMessage();
FacesContext context = FacesContext.getCurrentInstance();
Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
HashMap<String, String> queryParams = (HashMap<String, String>)sessionMap.get(QUERY_PARAMS);
try {
jobRespDesc = WorkflowManagerUtils.getRunningJobs(queryParams, maxRecords, session);
} catch (Exception e) {
String errMsg = MessageFormat.format("><Exception received while retrieving running jobs for query parameters {0} : {1}",
new Object[] {queryParams, e.getMessage()});
System.err.println(errMsg);
message.setSeverity(FacesMessage.SEVERITY_ERROR);
message.setSummary(errMsg);
message.setDetail(errMsg);
context.addMessage("errorMessageForm:errorMessage", message);
return null;
}
if (jobRespDesc != null && jobRespDesc.getExceptionMap().size() != 0) {
HashMap<String, Exception> responseMap = null;
String hosts = "";
responseMap = jobRespDesc.getExceptionMap();
for (Iterator<String> it = responseMap.keySet().iterator(); it.hasNext();) {
String hostName = it.next();
Exception e = responseMap.get(hostName);
if (e != null) {
hosts += " " + hostName;
}
}
if (!hosts.equals("")) {
String errMsg = MessageFormat.format("><Unable to retrieve running jobs from hosts : {0}", new Object[] {hosts});
message.setSeverity(FacesMessage.SEVERITY_WARN);
message.setSummary(errMsg);
message.setDetail(errMsg);
context.addMessage("errorMessageForm:errorMessage", message);
}
}
runningJobs = jobRespDesc.getRunningJobDescriptorsAsSet();
return orderOutput(runningJobs);
}
private DisplayBean[] orderOutput(TreeSet<RunningJobDescriptor> runningJobs)
{
if (columns.size() == 0) {
System.out.println("><No columns to display for Running Jobs tab");
return null;
}
valueList = new DisplayBean[runningJobs.size()];
int index = 0;
for (Iterator<RunningJobDescriptor> it = runningJobs.iterator(); it.hasNext(); index++) {
RunningJobDescriptor runningJob = it.next();
ArrayList<String> values = new ArrayList<String>();
for (int i = 0; i < configuredColumns.size(); i ++) {
String name = configuredColumns.get(i);
if (name.equals(JOB_ID_LABEL)) {
values.add(Long.toString(runningJob.jobId));
} else if (name.equals(SERVICE_ID_LABEL)) {
values.add(runningJob.serviceId);
} else if (name.equals(ORDER_ID_LABEL)) {
values.add(runningJob.workflowOrderId);
} else if (name.equals(WORKFLOW_LABEL)) {
values.add(runningJob.name);
} else if (name.equals(HOST_NAME_LABEL)) {
values.add(runningJob.hostName);
} else if (name.equals(WORKFLOW_TYPE_LABEL)) {
values.add(runningJob.workflowType);
} else if (name.equals(WORKFLOW_STATE_LABEL)) {
values.add(runningJob.workflowState);
} else if (name.equals(STEP_LABEL)) {
values.add(runningJob.stepName);
} else {
values.add(DateFormat.getDateTimeInstance().format(runningJob.startTime));
}
}
if (values.size() != 0) {
DisplayBean bean = new DisplayBean(values, runningJob);
valueList[index] = bean;
}
}
return valueList;
}
}
Column class is as follows:
package com.hp.ov.activator.jsf.sov;
import java.io.Serializable;
import org.richfaces.model.Ordering;
public class Column implements Serializable
{
private String name;
Ordering ordering = Ordering.ASCENDING;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Ordering getOrdering()
{
return ordering;
}
public void setOrdering(Ordering ordering)
{
this.ordering = ordering;
}
public Column(String name, Ordering ordering)
{
super();
this.name = name;
this.ordering = ordering;
}
}