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; } }