JBoss.orgCommunity Documentation
This chapter covers all components related to the display of tables and grids.
The non-visual <a4j:repeat>
component is used to iterate through a data model. The component renders child content for every iteration according to the current object data.
The <a4j:repeat>
component extends the standard UIRepeat
component to allow partial updates within iterations while sending Ajax requests. The component acts as a base for all the data iteration components detailed in this chapter.
The contents of the collection are determined using Expression Language (EL). The data model for the contents is specified with the value
attribute. The var
attribute names the object to use when iterating through the collection. This object is then referenced in the relevant child components. Example 10.1, “<a4j:repeat> example” shows how to use <a4j:repeat>
to maintain a simple table.
Example 10.1. <a4j:repeat>
example
<table>
<tbody>
<a4j:repeat value="#{repeatBean.items}" var="item">
<tr>
<td><h:outputText value="#{item.code}" id="item1" /></td>
<td><h:outputText value="#{item.price}" id="item2" /></td>
</tr>
</a4j:repeat>
</tbody>
</table>
Each row of a table contains two cells: one showing the item code, and the other showing the item price. The table is generated by iterating through items in the repeatBeans.items
data model.
The <a4j:repeat>
component uses other attributes common to iteration components, such as the first
attribute for specifying the first item for iteration, and the rows
attribute for specifying the number of rows of items to display.
Specific cells, rows, and columns can be updated without sending Ajax requests for the entire collection. Components that cause the change can specify which part of the table to update through the render
attribute. The render
attribute specifies which part of a table to update. The updated parts relate to where the action component is placed relative to the table:
Use
where the component identified by render
=componentID
componentID
is in the same row as the action component. The action component updates the single specified component, as demonstrated in Example 10.2, “Update a single component”.
Example 10.2. Update a single component
<rich:column>
<a4j:commandButton render="col"></a4j:commandButton>
</rich:column>
<rich:column>
<h:outputText value="#{car.model}" id="col"/>
</rich:column>
Use
to specify the cell to update. The action component updates the cell with an identifier of render
=tableId
:rowId
:cellId
cellId
, which is within the row with an identifier of rowId
, which is within the table with an identifier of tableId
.
Instead of a specific identifier, any of the references could be variables, as demonstrated in Example 10.3, “Use variables to specify references”.
Example 10.3. Use variables to specify references
render
=tableId
:#{@rows(bean.rowToUpdate
)}:cellId
The @rows
function accepts a collection of row keys to be updated.
The <rich:dataTable>
component is used to render a table, including the table's caption. It works in conjunction with the <rich:column>
and <rich:columnGroup>
components to list the contents of a data model.
The <rich:dataTable>
component does not include extended table features, such as data scrolling (including lazy Ajax loading), row selection, and column reordering. These features are available as part of the <rich:extendedDataTable>
component; refer to Section 10.6, “<rich:extendedDataTable>” for further details.
The value
attribute points to the data model, and the var
attribute specifies a variable to use when iterating through the data model.
In addition, the table requires a set of <rich:column>
components to define the content of the table.
The first
attribute specifies which item in the data model to start from, and the rows
attribute specifies the number of items to list. The header
, footer
, and caption
facets can be used to display text, and to customize the appearance of the table through skinning. demonstrates a simple table implementation.
The keepSaved
attribute defines whether this iteration component will reset saved children's state before rendering. By default, the state is reset if there are no faces messages with severity error or higher.
Example 10.4. <rich:dataTable>
example
<rich:dataTable value="#{capitalsBean.capitals}" var="cap" rows="5">
<f:facet name="caption">
<h:outputText value="United States Capitals" />
</f:facet>
<f:facet name="header">
<h:outputText value="Capitals and States Table" />
</f:facet>
<rich:column>
<f:facet name="header">State Flag</f:facet>
<h:graphicImage value="#{cap.stateFlag}"/>
<f:facet name="footer">State Flag</f:facet>
</rich:column>
<rich:column>
<f:facet name="header">State Name</f:facet>
<h:outputText value="#{cap.state}"/>
<f:facet name="footer">State Name</f:facet>
</rich:column>
<rich:column >
<f:facet name="header">State Capital</f:facet>
<h:outputText value="#{cap.name}"/>
<f:facet name="footer">State Capital</f:facet>
</rich:column>
<rich:column>
<f:facet name="header">Time Zone</f:facet>
<h:outputText value="#{cap.timeZone}"/>
<f:facet name="footer">Time Zone</f:facet>
</rich:column>
<f:facet name="footer">
<h:outputText value="Capitals and States Table" />
</f:facet>
</rich:dataTable>
For details on filtering and sorting data tables, refer to Section 10.10, “Table filtering” and Section 10.11, “Table sorting”.
As <rich:dataTable>
the component is based on the <a4j:repeat>
component, it can be partially updated with Ajax. Refer to Section 10.1.2, “Limited views and partial updates” for details on partially updating the <rich:dataTable>
component.
The <rich:dataTable>
component supports master-detail markup with collapsible sub-table sections. Refer to Section 10.5, “<rich:collapsibleSubTable>” for full details on using the <rich:collapsibleSubTable>
component.
Use the rows
attribute to specify the number of rows to show at a time. The table is then presented in pages of rows. Pages can be navigated by using a control such as the <rich:dataScroller>
component. Refer to Section 10.9, “<rich:dataScroller>” for full details on using the <rich:dataScroller>
component.
The <rich:dataTable>
component can be controlled through the JavaScript API. The JavaScript API provides the following functions:
expandAllSubTables()
Expand any sub-tables contained in the data table.
collapseAllSubTables()
Collapse any sub-tables contained in the data table.
switchSubTable(subtableId)
Switch the expanded or collapsed state of any sub-tables contained in the data table.
filter(columnId, newFilterValue, [isClearPreviousFilters])
Filter the table based on the column specified with the columnId
parameter. Use the newFilterValue
parameter as the filter value. The optional isClearPreviousFilters
parameter is a boolean value which, if set to true
, will clear any previous filters applied to the table.
sort(columnId, [direction], [isClearPreviousSorting])
Sort the table based on the column specified with the columnId
parameter. The option direction
parameter specifies whether to sort in ascending or descending order. The optional isClearPreviousSorting
parameter is a boolean value which, if set to true
, will clear any previous sorting applied to the table.
component-type
: org.richfaces.DataTable
component-class
: org.richfaces.component.UIDataTable
component-family
: org.richfaces.Data
renderer-type
: org.richfaces.DataTableRenderer
handler-class
: org.richfaces.taglib.DataTableHandler
Table 10.1. Style classes (selectors) and corresponding skin parameters
Class (selector) | Skin Parameters | Mapped CSS properties |
---|---|---|
|
| background-color |
| border-left-width, border-top-width | |
| border-left-color, border-top-color | |
| No skin parameters. | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
|
| border-bottom-width, border-right-width |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size |
The <rich:column>
component facilitates columns in a table. It supports merging columns and rows, sorting, filtering, and customized skinning.
In general usage, the <rich:column>
component is used in the same was as the JavaServer Faces (JSF) <h:column>
component. It requires no extra attributes for basic usage, as shown in Example 10.5, “Basic column example”.
Example 10.5. Basic column example
<rich:dataTable value="#{capitalsBean.capitals}" var="cap" rows="5">
<rich:column>
<f:facet name="header">State Flag</f:facet>
<h:graphicImage value="#{cap.stateFlag}"/>
</rich:column>
<rich:column>
<f:facet name="header">State Name</f:facet>
<h:outputText value="#{cap.state}"/>
</rich:column>
<rich:column >
<f:facet name="header">State Capital</f:facet>
<h:outputText value="#{cap.name}"/>
</rich:column>
<rich:column>
<f:facet name="header">Time Zone</f:facet>
<h:outputText value="#{cap.timeZone}"/>
</rich:column>
</rich:dataTable>
Columns can be merged by using the colspan
attribute to specify how many normal columns to span. The colspan
attribute is used in conjunction with the breakRowBefore
attribute on the next column to determine how the merged columns are laid out. Example 10.6, “Column spanning example”.
Example 10.6. Column spanning example
<rich:dataTable value="#{capitalsBean.capitals}" var="cap" rows="5">
<rich:column colspan="3">
<h:graphicImage value="#{cap.stateFlag}"/>
</rich:column>
<rich:column breakBefore="true">
<h:outputText value="#{cap.state}"/>
</rich:column>
<rich:column >
<h:outputText value="#{cap.name}"/>
</rich:column>
<rich:column>
<h:outputText value="#{cap.timeZone}"/>
</rich:column>
</rich:dataTable>
Similarly, the rowspan
attribute can be used to merge and span rows. Again the breakRowBefore
attribute needs to be used on related <rich:column>
components to define the layout. Example 10.7, “Row spanning example” and the resulting Figure 10.5, “Complex headers using column groups” show the first column of the table spanning three rows.
Example 10.7. Row spanning example
<rich:dataTable value="#{capitalsBean.capitals}" var="cap" rows="5">
<rich:column rowspan="3">
<f:facet name="header">State Flag</f:facet>
<h:graphicImage value="#{cap.stateFlag}"/>
</rich:column>
<rich:column>
<f:facet name="header">State Info</f:facet>
<h:outputText value="#{cap.state}"/>
</rich:column>
<rich:column breakBefore="true">
<h:outputText value="#{cap.name}"/>
</rich:column>
<rich:column breakBefore="true">
<h:outputText value="#{cap.timeZone}"/>
</rich:column>
</rich:dataTable>
For details on filtering and sorting columns, refer to Section 10.10, “Table filtering” and Section 10.11, “Table sorting”.
The <rich:columnGroup>
component combines multiple columns in a single row to organize complex parts of a table. The resulting effect is similar to using the breakRowBefore
attribute of the <rich:column>
component, but is clearer and easier to follow in the source code.
The <rich:columnGroup>
can also be used to create complex headers in a table. Example 10.8, “Complex headers using column groups” and the resulting Figure 10.5, “Complex headers using column groups” demonstrate how complex headers can be achieved.
Example 10.8. Complex headers using column groups
<rich:dataTable value="#{capitalsBean.capitals}" var="cap" rows="5" id="sublist">
<f:facet name="header">
<rich:columnGroup>
<rich:column rowspan="2">
<h:outputText value="State Flag"/>
</rich:column>
<rich:column colspan="3">
<h:outputText value="State Info"/>
</rich:column>
<rich:column breakBefore="true">
<h:outputText value="State Name"/>
</rich:column>
<rich:column>
<h:outputText value="State Capital"/>
</rich:column>
<rich:column>
<h:outputText value="Time Zone"/>
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column>
<h:graphicImage value="#{cap.stateFlag}"/>
</rich:column>
<rich:column>
<h:outputText value="#{cap.state}"/>
</rich:column>
<rich:column>
<h:outputText value="#{cap.name}"/>
</rich:column>
<rich:column>
<h:outputText value="#{cap.timeZone}"/>
</rich:column>
</rich:dataTable>
The <rich:collapsibleSubTable>
component acts as a child element to a <rich:dataTable>
component. The <rich:collapsibleSubTable>
component iterates through the child collections in the currently iterated object to create master-detail tables.
Additionally, the detail part of the table can be collapsed or expanded through different modes. The <rich:collapsibleSubTable>
component works with the <rich:collapsibleSubTableToggler>
component, which expands and collapses the sub-tables.
The <rich:collapsibleSubTable>
component requires the same basic attributes as the <rich:dataTable>
component. The value
attribute points to the collection, and the var
attribute specifies a variable to use when iterating through the collection.
In addition, the <rich:collapsibleSubTable>
component typically needs a corresponding <rich:collapsibleSubTableToggler>
component to allow expanding and collapsing. Declare the id
identifier on the <rich:collapsibleSubTable>
element so that the <rich:collapsibleSubTableToggler>
component can reference it. Refer to Section 10.5.5, “<rich:collapsibleSubTableToggler>” for details on the <rich:collapsibleSubTableToggler>
component.
Example 10.9. Basic usage
<rich:dataTable value="#{carsBean.inventoryVendorLists}" var="list">
<f:facet name="header">
<rich:columnGroup>
<rich:column colspan="6">
<h:outputText value="Cars marketplace" />
</rich:column>
<rich:column breakRowBefore="true">
<h:outputText value="Model" />
</rich:column>
<rich:column>
<h:outputText value="Price" />
</rich:column>
<rich:column>
<h:outputText value="Mileage" />
</rich:column>
<rich:column>
<h:outputText value="VIN Code" />
</rich:column>
<rich:column>
<h:outputText value="Items stock" />
</rich:column>
<rich:column>
<h:outputText value="Days Live" />
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column colspan="6">
<rich:collapsibleSubTableToggler for="sbtbl" />
<h:outputText value="#{list.vendor}" />
</rich:column>
<rich:collapsibleSubTable value="#{list.vendorItems}" var="item" id="sbtbl"
expandMode="client">
<rich:column>
<h:outputText value="#{item.model}" />
</rich:column>
<rich:column>
<h:outputText value="#{item.price}" />
</rich:column>
<rich:column>
<h:outputText value="#{item.mileage}" />
</rich:column>
<rich:column>
<h:outputText value="#{item.vin}" />
</rich:column>
<rich:column>
<h:outputText value="#{item.stock}" />
</rich:column>
<rich:column>
<h:outputText value="#{item.daysLive}" />
</rich:column>
<f:facet name="footer">
<h:outputText value="Total of #{list.vendor} Cars: #{list.count}" />
</f:facet>
</rich:collapsibleSubTable>
</rich:dataTable>
The resulting tables contains multiple sub-tables, grouping the list of cars by vendor. Each sub-table can be expanded or collapsed using the toggle with the vendor's name. The screenshot shows all sub-tables collapsed except for the sub-table for Ford cars.
Use the boolean expanded
attribute to control the current state of the sub-table.
The switching mode for performing submissions is determined by the expandMode
attribute, which can have one of the following three values:
server
The default setting. Expansion of the <rich:collapsibleSubTable>
component performs a common submission, completely re-rendering the page.
ajax
Expansion of the <rich:collapsibleSubTable>
component performs an Ajax form submission, and the content of the data table is rendered.
client
Expansion of the <rich:collapsibleSubTable>
component updates the data table on the client side.
component-type
: org.richfaces.CollapsibleSubTable
component-class
: org.richfaces.component.UICollapsibleSubTable
component-family
: org.richfaces.Data
renderer-type
: org.richfaces.CollapsibleSubTableRenderer
handler-class
: org.richfaces.taglib.CollapsibleSubTableHandler
Table 10.2. Style classes (selectors) and corresponding skin parameters
Class (selector) | Skin Parameters | Mapped CSS properties |
---|---|---|
| No skin parameters. | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
| No skin parameters. | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size |
The <rich:collapsibleSubTableToggler>
component provides a toggle control for the user to expand and collapse sub-tables.
The <rich:collapsibleSubTableToggler>
component requires the for
attribute. The for
attribute references the id
identifier of the <rich:collapsibleSubTable>
component to control.
Refer to Example 10.9, “Basic usage” for an example using the <rich:collapsibleSubTable>
component. In the example, the toggle control is placed in a column that spans the width of the table. Output text next to the toggle control displays the car vendor's name for that sub-table.
The icons and labels of the <rich:collapsibleSubTableToggler>
component can be customized. Use the collapsedIcon
and expandedIcon
attributes to specify icons for the toggler when it is collapsed and expanded respectively. Use the collapsedLabel
and expandedLabel
attributes to specify labels for the toggler when it is collapsed and expanded respectively.
component-type
: org.richfaces.CollapsibleSubTableToggler
component-class
: org.richfaces.component.UICollapsibleSubTableToggler
component-family
: org.richfaces.CollapsibleSubTableToggler
renderer-type
: org.richfaces.CollapsibleSubTableTogglerRenderer
The <rich:extendedDataTable>
component builds on the functionality of the <rich:dataTable>
component, adding features such as scrolling for the table body (both horizontal and vertical), Ajax loading for vertical scrolling, frozen columns, row selection, and rearranging of columns. It also supports all the basic table features such as sorting, filtering, and paging using the <rich:dataScroller>
component.
The <rich:extendedDataTable>
component includes the following main attributes not included in the <rich:dataTable>
component:
clientRows
frozenColumns
height
onselectionchange
selectedClass
selection
selectionMode
Due to the complex mark-up involved in the <rich:extendedDataTable>
component, it does not support the use of the <rich:collapsibleSubTable>
component. The <rich:collapsibleSubTable>
component is only available with the <rich:dataTable>
component.
Similarly, complex row and column spanning using the breakRowBefore
, colSpan
, and rowSpan
attributes is also not available with the <rich:extendedDataTable>
component.
Basic use of the <rich:extendedDataTable>
component requires the value
and var
attributes, the same as with the <rich:dataTable>
component. In addition, a set of columns must be included to define the table content. Refer to Section 10.2, “<rich:dataTable>” for details.
As with the <rich:dataTable>
component, the look of the <rich:extendedDataTable>
component can be customized using the header
and footer
facets.
Example 10.10. <rich:extendedDataTable>
example
This example <rich:extendedDataTable>
component demonstrates horizontal and vertical scrolling and frozen columns. Each feature is detailed in this section.
<rich:extendedDataTable value="#{carsBean.allInventoryItems}"
var="car" id="table" frozenColumns="2"
style="height:300px; width:500px;" selectionMode="none">
<f:facet name="header">
<h:outputText value="Cars marketplace" />
</f:facet>
<rich:column>
<f:facet name="header">
<h:outputText value="vendor" />
</f:facet>
<h:outputText value="#{car.vendor}" />
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Model" />
</f:facet>
<h:outputText value="#{car.model}" />
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Price" />
</f:facet>
<h:outputText value="#{car.price}" />
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Mileage" />
</f:facet>
<h:outputText value="#{car.mileage}" />
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="VIN Code" />
</f:facet>
<h:outputText value="#{car.vin}" />
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Items stock" />
</f:facet>
<h:outputText value="#{car.stock}" />
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Days Live" />
</f:facet>
<h:outputText value="#{car.daysLive}" />
</rich:column>
</rich:extendedDataTable>
The example table shown in Example 10.10, “<rich:extendedDataTable> example” features both horizontal and vertical scrolling. Scrolling occurs automatically when the contents of the table exceed the dimensions specified with the height
and width
attributes. Headers and footers remain in place and visible when the table is scrolled.
Large tables can use Ajax "lazy" loading to cache data on the client during scrolling. Use the clientRows
attribute to specify the number of rows to load. The specified number of rows are loaded on the initial rendering and with every vertical scroll. If the clientRows
attribute is not specified, all the rows are loaded on the client without the use of Ajax.
In addition to Ajax scrolling, the <rich:extendedDataTable>
component can also be used with the <rich:dataScroller>
component in the same way as a regular <rich:dataTable>
component. If both the clientRows
and rows
attributes are included, Ajax loading occurs as defined by the clientRows
attribute, but the loading is limited to the current table page as determined by the rows
attribute. Refer to Section 10.9, “<rich:dataScroller>” for full details on using the <rich:dataScroller>
component.
The example table shown in Example 10.10, “<rich:extendedDataTable> example” has the first two columns frozen so that they remain visible if the user scrolls horizontally through the table. Note that the horizontal scrollbar does not encompass these frozen columns. To freeze columns, use the frozenColumns
attribute to specify the number of columns on the left-hand side of the table to freeze.
Row selection is determined by the selectionMode
attribute. Setting the attribute to none
allows for no row selection capability. The example table shown in Example 10.10, “<rich:extendedDataTable> example” does not allow row selection.
Setting the selectionMode
attribute to single
allows the user to select a single row at a time using the mouse. With the selectionMode
attribute set to multiple
, the user can select multiple rows. Holding down the Ctrl key while clicking selects additional rows with each click. Holding down the Shift key while clicking selects all the rows in a range.
The selection
attribute points to a collection of objects. It holds the rowKey
identifiers to track which rows are selected. Example 10.11, “Selecting multiple rows” shows how to implement multiple row selection in the same table from Example 10.10, “<rich:extendedDataTable> example”.
Example 10.11. Selecting multiple rows
<rich:extendedDataTable value="#{extTableSelectionBean.inventoryItems}"
var="car" selection="#{extTableSelectionBean.selection}"
id="table" frozenColumns="2"
style="height:300px; width:500px;" selectionMode="multiple">
...
The accompanying ExtSelectionBean
bean handles which rows are selected. The rows are identified by their rowKey
identifiers.
package org.richfaces.demo.tables;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.event.AjaxBehaviorEvent;
import org.richfaces.component.UIExtendedDataTable;
import org.richfaces.demo.tables.model.cars.InventoryItem;
@ManagedBean
@SessionScoped
public class ExtTableSelectionBean implements Serializable{
private Collection<Object> selection;
@ManagedProperty(value = "#{carsBean.allInventoryItems}")
private List<InventoryItem> inventoryItems;
private List<InventoryItem> selectionItems = new ArrayList<InventoryItem>();
public void selectionListener(AjaxBehaviorEvent event){
UIExtendedDataTable dataTable = (UIExtendedDataTable)event.getComponent();
Object originalKey = dataTable.getRowKey();
selectionItems.clear();
for (Object selectionKey: selection) {
dataTable.setRowKey(selectionKey);
if (dataTable.isRowAvailable()){
selectionItems.add((InventoryItem)dataTable.getRowData());
}
}
dataTable.setRowKey(originalKey);
}
public Collection<Object> getSelection() {
return selection;
}
public void setSelection(Collection<Object> selection) {
this.selection = selection;
}
public List<InventoryItem> getInventoryItems() {
return inventoryItems;
}
public void setInventoryItems(List<InventoryItem> inventoryItems) {
this.inventoryItems = inventoryItems;
}
public List<InventoryItem> getSelectionItems() {
return selectionItems;
}
public void setSelectionItems(List<InventoryItem> selectionItems) {
this.selectionItems = selectionItems;
}
}
Columns in a <rich:extendedDataTable>
component can be rearranged by the user by dragging each column to a different position. A graphical representation of the column is displayed during dragging. Figure 10.6, “Dragging columns” illustrates the Price column being dragged to a new location. The small blue arrow indicates where the column will be moved to if it is dropped in the current position. Figure 10.7, “Rearranged columns” shows the result of dragging the Price column.
The tableState
attribute of the <rich:extendedDataTable>
component can be used to bind state of the table (column width, sequence, sorting, filtering) to a backing-bean string property, for a later use.
This state can be for example saved to a database, and it is different from standard JSF state saving mechanism.
The <rich:extendedDataTable>
component can include filtering and sorting in the same way as a regular <rich:dataTable>
component. For full details on filtering tables, refer to Section 10.10, “Table filtering”. For full details on sorting tables, refer to Section 10.11, “Table sorting”.
The <rich:extendedDataTable>
component can be controlled through the JavaScript API. The JavaScript API provides the following functions:
sort()
Sort the data table.
filter()
Filter the data table.
clearSorting()
Clear any sorting that is currently applied to the table.
clearFiltering()
Clear any filtering that is currently applied to the table.
selectRow(index)
Select the row specified by the index
parameter.
selectRows([startIndex, stopIndex])
Select all the rows in the table. Optionally, select only those rows between the indexes specified with the startIndex
and stopIndex
parameters.
deselectRow
Deselect the row that is currently selected.
setActiveRow(index)
Set the active row to that specified by the index
parameter.
component-type
: org.richfaces.ExtendedDataTable
component-class
: org.richfaces.component.UIExtendedDataTable
component-family
: org.richfaces.Data
renderer-type
: org.richfaces.ExtendedDataTableRenderer
handler-class
: org.richfaces.taglib.ExtendedDataTableHandler
Table 10.3. Style classes (selectors) and corresponding skin parameters
Class (selector) | Skin Parameters | Mapped CSS properties |
---|---|---|
|
| border |
| background-color | |
| No skin parameters. | |
|
| border-bottom |
| border-right | |
|
| font-family |
| font-size | |
|
| border-bottom |
| color | |
| font-family | |
| font-size | |
| color | |
| No skin parameters. | |
|
| border-bottom |
| border-right | |
|
| font-family |
| font-size | |
| color | |
|
| border-top |
| background-color | |
|
| border-top |
| background-color | |
| No skin parameters. | |
|
| border-bottom |
| border-right | |
|
| font-family |
| font-size | |
| color | |
|
| border-right |
| No skin parameters. | |
| No skin parameters. | |
|
| border-right |
| No skin parameters. | |
| No skin parameters. | |
| No skin parameters. | |
|
| border-left |
|
| border |
| background-color | |
| No skin parameters. | |
| No skin parameters. |
The <rich:dataGrid>
component is used to arrange data objects in a grid. Values in the grid can be updated dynamically from the data model, and Ajax updates can be limited to specific rows. The component supports header
, footer
, and caption
facets.
The <rich:dataGrid>
component is similar in function to the JavaServer Faces <h:panelGrid>
component. However, the <rich:dataGrid>
component additionally allows iteration through the data model rather than just aligning child components in a grid layout.
The <rich:dataGrid>
component requires the value
attribute, which points to the data model, and the var
attribute, which holds the current variable for the collection of data.
The number of columns for the grid is specifed with the columns
attribute, and the number of elements to layout among the columns is determined with the elements
attribute. The first
attribute references the zero-based element in the data model from which the grid starts.
Example 10.12. <rich:dataGrid>
example
<rich:panel style="width:150px;height:200px;">
<h:form>
<rich:dataGrid value="#{dataTableScrollerBean.allCars}" var="car" columns="2" elements="4" first="1">
<f:facet name="header">
<h:outputText value="Car Store"></h:outputText>
</f:facet>
<rich:panel>
<f:facet name="header">
<h:outputText value="#{car.make} #{car.model}"></h:outputText>
</f:facet>
<h:panelGrid columns="2">
<h:outputText value="Price:" styleClass="label"></h:outputText>
<h:outputText value="#{car.price}"/>
<h:outputText value="Mileage:" styleClass="label"></h:outputText>
<h:outputText value="#{car.mileage}"/>
</h:panelGrid>
</rich:panel>
<f:facet name="footer">
<rich:dataScroller></rich:dataScroller>
</f:facet>
</rich:dataGrid>
</h:form>
</rich:panel>
As <rich:dataGrid>
the component is based on the <a4j:repeat>
component, it can be partially updated with Ajax. Refer to Section 10.1.2, “Limited views and partial updates” for details on partially updating the <rich:dataGrid>
component.
component-type
: org.richfaces.DataGrid
component-class
: org.richfaces.component.UIDataGrid
component-family
: org.richfaces.Data
renderer-type
: org.richfaces.DataGridRenderer
handler-class
: org.richfaces.taglib.DataGridHandler
Table 10.4. Style classes (selectors) and corresponding skin parameters
Class (selector) | Skin Parameters | Mapped CSS properties |
---|---|---|
|
| background-color |
| border-left-width, border-top-width | |
| border-left-color, border-top-color | |
| No skin parameters. | |
| No skin parameters. | |
|
| border-bottom-width, border-right-width |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
|
| border-bottom-width, border-right-width |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
|
| border-bottom-width |
| border-bottom-color | |
| No skin parameters. | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size | |
| No skin parameters. | |
| No skin parameters. | |
|
| background-color |
| border-bottom-width, border-right-width | |
| border-bottom-color, border-right-color | |
| color | |
| font-family | |
| font-size |
The <rich:list>
component renders a list of items. The list can be an numerically ordered list, an un-ordered bullet-point list, or a data definition list. The component uses a data model for managing the list items, which can be updated dynamically.
The var
attribute names a variable for iterating through the items in the data model. The items to iterate through are determined with the value
attribute by using EL (Expression Language).
By default, the list is displayed as an un-ordered bullet-point list. The type
attribute is used to specify different list types:
unordered
The default presentation. The list is presented as a series of bullet-points, similar to the <ul>
HTML element.
ordered
The list is presented as a numbered series of items, similar to the <ol>
HTML element.
definitions
The list is presented as a series of data definitions. Part of the data model, specified as the term, is listed prominently. The other associated data is listed after each term.
The term is marked using the term
facet. The facet is required for all definition lists. Use of the facet is shown in Example 10.13, “Data definition list”.
Example 10.13. Data definition list
<h:form>
<rich:list var="car" value="#{dataTableScrollerBean.allCars}" type="definitions" rows="5" title="Cars">
<f:facet name="term">
<h:outputText value="#{car.make} #{car.model}"></h:outputText>
</f:facet>
<h:outputText value="Price:" styleClass="label"></h:outputText>
<h:outputText value="#{car.price}" /><br/>
<h:outputText value="Mileage:" styleClass="label"></h:outputText>
<h:outputText value="#{car.mileage}" /><br/>
</rich:list>
</h:form>
The appearance of bullet points for unordered lists or numeration for ordered lists can be customized through CSS, using the list-style-type property.
The first
attribute specifies which item in the data model to start from, and the rows
attribute specifies the number of items to list. The title
attribute is used for a floating tool-tip. Example 10.14, “<rich:list> example” shows a simple example using the <rich:list>
component.
Example 10.14. <rich:list>
example
<h:form>
<rich:list var="car" value="#{dataTableScrollerBean.allCars}" rows="5" type="unordered" title="Car Store">
<h:outputText value="#{car.make} #{car.model}"/><br/>
<h:outputText value="Price:" styleClass="label"></h:outputText>
<h:outputText value="#{car.price} "/><br/>
<h:outputText value="Mileage:" styleClass="label"></h:outputText>
<h:outputText value="#{car.mileage} "/><br/>
</rich:list>
</h:form>
component-type
: org.richfaces.List
component-class
: org.richfaces.component.UIList
component-family
: org.richfaces.List
renderer-type
: org.richfaces.ListRenderer
handler-class
: org.richfaces.taglib.ListHandler
Table 10.5. Style classes (selectors) and corresponding skin parameters
Class (selector) | Skin Parameters | Mapped CSS properties |
---|---|---|
|
| color |
| font-family | |
| font-size | |
|
| color |
| font-family | |
| font-size | |
|
| color |
| font-family | |
| font-size | |
|
| color |
| font-family | |
| font-size |
The <rich:dataScroller>
component is used for navigating through multiple pages of tables or grids.
The <rich:dataScroller>
must be placed in a facet of the table or grid it needs to control. Alternatively, use the for
attribute to bind the parent table or grid to the scroller.
The bound table or grid should also have the rows
attribute defined to limit the number of rows per page.
The <rich:dataScroller>
component must be re-rendered whenever a filter changes on the bound table, so that the scroller matches the current model for the table.
Example 10.15. Basic usage
<rich:dataTable id="table" value="#{capitalsBean.capitals}" var="cap" rows="5">
<!-- table content -->
...
</rich:dataTable>
<rich:dataScroller for="table" maxPages="5">
<f:facet name="first">
<h:outputText value="First" />
</f:facet>
<f:facet name="last">
<h:outputText value="Last" />
</f:facet>
</rich:dataScroller>
The page
attribute is a value-binding attribute used to define and save the current page number.
The <rich:dataScroller>
component provides a range of controllers for scrolling through tables and grids:
The component includes controls for switching to the first page, the last page, the next page, and the previous page, as well as controls for fast-forwarding or rewinding by a set amount. Use the fastStep
attribute to set the number of pages to skip when fast-forwarding or rewinding.
The appearance of these controls can be customized using the following facets: first
, last
, next
, previous
, fastForward
, and fastRewind
. Additionally, there are facets for the controls' disabled states: first_disabled
, last_disabled
, next_disabled
, previous_disabled
, fastforward_disabled
, and rewind_disabled
.
The component also features a series of numbered controls to jump to a specific page. Use the maxPages
attribute to limit the number of page controls that appear. The current page control is highlighted.
To add optional separators between controls, define the separators with the controlsSeparator
facet.
The <rich:dataScroller>
component can be controlled through the JavaScript API. The JavaScript API provides the following functions:
switchToPage(pageIndex)
Switch to the page specified with the pageIndex
parameter.
next()
Switch to the next page.
previous()
Switch to the previous page.
first()
Switch to the first page.
last()
Switch to the last page.
fastForward()
Step forward through the pages by the fastStep
amount.
fastRewind()
Step backward through the pages by the fastStep
amount.
component-type
: org.richfaces.DataScroller
component-class
: org.richfaces.component.UIDataScroller
component-family
: org.richfaces.DataScroller
renderer-type
: org.richfaces.DataScrollerRenderer
handler-class
: org.richfaces.taglib.DataScrollerHandler
Table 10.6. Style classes (selectors) and corresponding skin parameters
Class (selector) | Skin Parameters | Mapped CSS properties |
---|---|---|
|
| font-family |
| font-size | |
| background | |
|
| color |
| font-family | |
| font-size | |
| border-color | |
| background-color | |
| No skin parameters. | |
| No skin parameters. | |
| No skin parameters. | |
| No skin parameters. | |
| No skin parameters. | |
| No skin parameters. | |
|
| color |
| font-family | |
| font-size | |
| border-color | |
| background-color | |
|
| border-color |
| background | |
|
| color |
|
| color |
Tables entries can be filtered by the user through either the basic built-in filter inputs, or by defining external filter controls.
Refer to Section 10.3, “<rich:column>” for details on using the <rich:column>
component in tables.
To define a filter for a column use either the filter
or filterExpression
attributes, then use the filterValue
attribute to point to an object which holds the current filtering value for the column. The attribute can be used to store filtering conditions in a session.
Use the filterExpression
attribute to define an expression that can be evaluated as a boolean value. The expression checks if each table entry satisfies the filtering condition when the table is rendered. For example, the expression might be a JSTL (JavaServer Pages Standard Tag Library) function such as contains
or equals
.
Use the filter
attribute to define a filter interface. The attribute must use EL (Expression Language) to point to an object which implements the org.richfaces.model.Filter<T>
interface. The object must provide a single accept(T t)
method. The method takes each iteration object as a parameter and returns a boolean value, which determines whether the object satisfies the filter. By defining a custom filter, you can implement complex business logic to filter a table.
The built-in filter controls are only available with the extendedDataTable
component.
Support for built-in filter controls in the dataTable
component will be added in a subsequent release.
The built-in filter controls of the <rich:column>
component allow the user to enter text to use as the filtering value.
The value of the built-in filter control is bound to the filterValue
attribute, which can either be an initial filtering value on the page, or a value binding on the server.
The filterValue is then applied to the filter defined either by the filterExpression
or filter
column attributes.
The filterValue is of type String
.
Conversion is either done implicitly via EL in the filterExpression
, or explicitly within the filter
function.
The filter is processed and the table is rendered when the onblur
event occurs for the column.
Example 10.16. Basic filtering
<rich:extendedDataTable value="#{carsBean.allInventoryItems}" var="car" filterVar="filterValue">
<f:facet name="header">
<h:outputText value="Cars marketplace"/>
</f:facet>
<rich:column filterExpression="#{empty filterValue or fn:startsWith(car.model, filterValue)}"
filterValue="#{carsFilteringBean.modelFilter}">
<f:facet name="header">Model</f:facet>
<h:outputText value="#{car.model}"/>
</rich:column>
<rich:column filterExpression="#{empty filterValue or car.price ge filterValue}"
filterValue="#{carsFilteringBean.priceFilter}"
filterConverterMessage="Error converting the 'Price' filter value">
<f:facet name="header">Price</f:facet>
<h:outputText value="#{car.price}"/>
</rich:column>
</rich:extendedDataTable>
The example uses the basic filtering method on both columns in the table.
If you require more advanced filter controls use the external filtering properties of the <rich:column>
component.
With custom filter controls you can tailor the filter control, allowing for advanced use cases like select menus, checkboxes, etc.
To use a custom filter control with the extendedDataTable
component, one must first disable the built-in filter control.
The built-in search controls can be disabled on a column-by-column basis by setting the column attribute filterType="custom"
.
Alternatively one can disable sort controls for the whole application via the following context-param in the web.xml:
<context-param>
<param-name>org.richfaces.builtin.filter.enabled</param-name>
<param-value>false</param-value>
</context-param>
Example 10.17. Filtering example
<rich:dataTable value="#{capitalsBean.capitals}" var="cap" id="table">
<f:facet name="header">
<rich:columnGroup>
<rich:column>
<h:outputText value="State Name" />
</rich:column>
<rich:column>
<h:outputText value="State Time Zone" />
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column filter="#{filteringBean.stateFilter}">
<f:facet name="header">
<h:inputText value="#{filteringBean.stateFilterValue}" id="input">
<a4j:ajax event="keyup" render="table@body">
<a4j:attachQueue requestDelay="700"
ignoreDupResponses="true" />
</a4j:ajax>
</h:inputText>
</f:facet>
<h:outputText value="#{cap.state}" />
</rich:column>
<rich:column filterExpression="#{fn:containsIgnoreCase(cap.timeZone, filteringBean.zoneFilterValue)}">
<f:facet name="header">
<h:selectOneMenu value="#{filteringBean.zoneFilterValue}">
<f:selectItems value="#{filteringBean.zoneList}" />
<a4j:ajax event="change" render="table@body" />
</h:selectOneMenu>
</f:facet>
<h:outputText value="#{cap.timeZone}" />
</rich:column>
</rich:dataTable>
The example uses a filter expression on the first column and a filter method on the second column.
Tables entries can be sorted by defining external sorting algorithms. Refer to Section 10.3, “<rich:column>” for details on using the <rich:column>
component in tables.
To sort a table whose contents are not in English, add the org.richfaces.datatableUsesViewLocale
context parameter to the project's web.xml
settings file. Set the value of the context parameter to true
.
Use the comparator
attribute of the <rich:column>
to specify the comparator to use when sorting.
If no comparator
is specified, the sorting algorithm will invoke the entries compareTo
method of the sortBy
values if they implement the java.lang.Comparable
interface.
As a final fall back, the algorithm implements a null sort, sorting elements based on whether or not they are null.
The built-in sort controls are only available with the extendedDataTable
component.
Support for built-in sort controls in the dataTable
component will be added in a subsequent release.
The built-in sorting controls of the <rich:column>
component allow a user to click the sort icons of a column to sort it in ascending or descending order.
Set the sortBy
attribute to indicate which value to use when sorting the column. Expressions in the sortBy
attribute must refer to the variable declared in the table's var
attribute, which is used to fill the contents of the table.
Example 10.18. Basic sorting
<rich:dataTable value="#{capitalsBean.capitals}" var="cap" width="300px">
<rich:column sortBy="#{cap.state}">
<f:facet name="header">
<h:outputText value="State Name"/>
</f:facet>
<h:outputText value="#{cap.state}"/>
</rich:column>
<rich:column sortBy="#{cap.name}">
<f:facet name="header">
<h:outputText value="State Capital"/>
</f:facet>
<h:outputText value="#{cap.name}"/>
</rich:column>
</rich:dataTable>
The example uses the basic sorting method on both columns in the table.
Use the sortOrder
attribute to set how the table's contents are sorted when it is first loaded.
By default, the value of the sortOrder
attribute is unsorted
, so that table entries appear in the order the are contained in the data model.
Use sortOrder="ascending"
to sort the entries in ascending alphabetical or numerical order. Use sortOrder="descending"
to sort the entries in descending alphabetical or numerical order.
The sortOrder
attribute can also be used to externally set the sort order of a table when using the external sorting method; refer to Section 10.11.3, “External sort controls” for details.
Set the sortBy
attribute to indicate which iteration object property to use when sorting the column.
If using custom-defined rules for sorting, use the comparator
attribute instead.
Set the comparator
attribute to point to your comparator method, which will be used when sorting the data model.
Bind the sortOrder
attribute to bean properties to manage the sorting order.
The bean must handle all the sorting algorithms.
Example 10.19, “Sorting” demonstrates table sorting using an external control.
Example 10.19. Sorting
<rich:dataTable value="#{capitalsBean.capitals}" var="cap" id="table">
<rich:column>
<f:facet name="header">
State Flag
</f:facet>
<h:graphicImage value="#{cap.stateFlag}" alt="flag" />
</rich:column>
<rich:column sortBy="#{cap.name}" id="name" sortOrder="#{capitalsSortingBean.capitalsOrder}">
<f:facet name="header">
<a4j:commandLink value="Sort by Capital Name" render="table" action="#{capitalsSortingBean.sortByCapitals}" />
</f:facet>
<h:outputText value="#{cap.name}" />
</rich:column>
<rich:column sortBy="#{cap.state}" id="state" sortOrder="#{capitalsSortingBean.statesOrder}">
<f:facet name="header">
<a4j:commandLink value="Sort by State Name" render="table" action="#{capitalsSortingBean.sortByStates}" />
</f:facet>
<h:outputText value="#{cap.state}" />
</rich:column>
<rich:column sortBy="#{cap.timeZone}" id="timeZone" comparator="#{capitalsSortingBean.timeZoneComparator}"
sortOrder="#{capitalsSortingBean.timeZonesOrder}">
<f:facet name="header">
<a4j:commandLink value="Sort by Time Zone" render="table" action="#{capitalsSortingBean.sortByTimeZones}" />
</f:facet>
<h:outputText value="#{cap.timeZone}" />
</rich:column>
</rich:dataTable>
The example uses an external control to manage the table's sorting.
When multiple columns are capable of being sorted at the same time, set the priority by which the columns are sorted with the sortPriorities
attribute. The attribute must contain a list of column identifiers in the order of the sorting sequence.