David Gras
David Gras

Reputation: 1028

How to get column ID via #{component.id} in EL?

I just want to send the Column ID as a parameter (and I don't want to write it twice, of course).

I used to make use of component.id but it returns DataTable ID instead of Column ID:

<p:dataTable id="table_id" ... >
    <p:column id="column_id"  attr="#{bean.method(component.id)}"
</p:dataTable>

Upvotes: 2

Views: 1640

Answers (1)

BalusC
BalusC

Reputation: 1108742

The DataTableRenderer of PrimeFaces indeed never pushes the UIColumn component into EL as #{component} when it's about to render the header, cell and footer of a column. It's fortunately relatively easy to override it to do so.

Create a class which extends it and then override the encodeColumnHeader(), encodeCell() and encodeColumnFooter() to first push the given Column component (you need to downcast the UIColumn argument first; you may want to perform an instanceof check if you're also using the "dynamic columns" feature) before delegating to super. Don't forget to pop in finally to ensure that EL don't get polluted with wrong #{component} state in case of an exception.

package com.stackoverflow.q25464066;

import java.io.IOException;

import javax.faces.context.FacesContext;

import org.primefaces.component.api.UIColumn;
import org.primefaces.component.column.Column;
import org.primefaces.component.datatable.DataTable;
import org.primefaces.component.datatable.DataTableRenderer;

public class ExtendedDataTableRenderer extends DataTableRenderer {

    @Override
    protected void encodeColumnHeader(FacesContext context, DataTable table, UIColumn column) throws IOException {
        table.pushComponentToEL(context, (Column) column);

        try {
            super.encodeColumnHeader(context, table, column);
        }
        finally {
            table.popComponentFromEL(context);
        }
    }

    @Override
    protected void encodeCell(FacesContext context, DataTable table, UIColumn column, String clientId, boolean selected) throws IOException {
        table.pushComponentToEL(context, (Column) column);

        try {
            super.encodeCell(context, table, column, clientId, selected);
        }
        finally {
            table.popComponentFromEL(context);
        }
    }

    @Override
    protected void encodeColumnFooter(FacesContext context, DataTable table, UIColumn column) throws IOException {
        table.pushComponentToEL(context, (Column) column);

        try {
            super.encodeColumnFooter(context, table, column);
        }
        finally {
            table.popComponentFromEL(context);
        }
    }

}

To get it to run, register it as follows in faces-config.xml:

<render-kit>
    <renderer>
        <description>Overrides the PrimeFaces table renderer with improved #{component} support.</description>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.DataTableRenderer</renderer-type>
        <renderer-class>com.stackoverflow.q25464066.ExtendedDataTableRenderer</renderer-class>
    </renderer>
</render-kit>

Upvotes: 4

Related Questions