DataTable Dynamic Columns

Table of Contents

Support for dynamic columns on the DataTable is provided by an iterative rendering of a normal ace:column component with its properties bound to instances of some POJO column 'model' . With this binding, the application can alter the set of models to easily add, remove or edit datatable column definitions dynamically.

This tutorial will cover the definition of the iterative column, the definition of the column models and the binding of the two.

Column Model

The column model is an object that defines the configuration of the ace:column. A simple use case of ace:column may define the properties sortBy, filterBy and headerText, so for the purposes of this example, these fields will make up our ColumnModel object.

public class ColumnModel {
    String value; // represents sortBy / filterBy as one field
    String headerText;

    public ColumnModel(String value, String headerText) {
        this.value = value;
        this.headerText = headerText;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getHeaderText() {
        return headerText;
    }

    public void setHeaderText(String headerText) {
        this.headerText = headerText;
    }
}

Using this definition of a column, given a dummy row datatype used in this sample, we can define our columns & data now as part of our application backing bean.

 public class Task {
    int id;
    String topic;
    String action;
    String notes;

    public Task(int id, String topic, String action, String notes) {
        this.id = id;
        this.topic = topic;
        this.action = action;
        this.notes = notes;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTopic() {
        return topic;
    }

    public void setTopic(String topic) {
        this.topic = topic;
    }

    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public String getNotes() {
        return notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }
}
@ManagedBean
@SessionScoped
public class DynamicColumnsBean implements Serializable {
    List<Task> data = new ArrayList<Task>() {{
        int i = 0;
        while (i != 10)
            add(new Task(i, "Topic " + i, "Action " + i, "Notes " + i++));
    }};

    List<ColumnModel> columns = new ArrayList<ColumnModel>() {{
        add(new ColumnModel("id", "ID"));
        add(new ColumnModel("topic", "Topic"));
        add(new ColumnModel("action", "Action"));
        add(new ColumnModel("notes", "Notes"));
    }};

    public List<Task> getData() {
        return data;
    }

    public void setData(ArrayList<Task> data) {
        this.data = data;
    }

    public List<ColumnModel> getColumns() {
        return columns;
    }

    public void setColumns(ArrayList<ColumnModel> columns) {
        this.columns = columns;
    }
}

Iterative Column Component Definition

Now to use our column definitions to display data, we need to iteratively create column components from them inside an ace:dataTable component. In the facelet:

    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:ace="http://www.icefaces.org/icefaces/components">
...
<ace:dataTable value="#{backing.data}" var="row">
    <c:forEach items="#{backing.columns}" var="colModel">
        <ace:column headerText="#{colModel.headerText}" filterMatchMode="contains"
                sortBy="#{row[colModel.value]}" filterBy="#{row[colModel.value]}">
            #{row[colModel.value]}
        </ace:column>
    </c:forEach>
</ace:dataTable>

And, with that, c:forEach will create multiple ace:column components with the intended configuration dynamically from the application model.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

© Copyright 2018 ICEsoft Technologies Canada Corp.