Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Footer Rows in a JSF dataTable

I am wanting to know if there is any way to have multiple footer rows in a h:dataTable (or t:datatable) I want to do somthing like this (which does not compile)

<h:dataTable ... var="row">
  <h:column>
    <f:facet name="header">
     Header
    </f:facet>
    <h:outputText value="#{row.value}"/>
    <f:facet name="footer">
     FirstFooter
    </f:facet>
    <f:facet name="footer">
     Second Footer in a new tr
    </f:facet>
  </h:column>
</h:dataTable>

With the result being somthing like this

<table border=1 style="border:1px solid">
<thead><tr><th>Header</th></tr></thead>
<tbody><tr><td>Data Value 1</td></tr>
<tr><td>Data Value 2</td></tr>
<tr><td>Data Value ...</td></tr>
<tr><td>Data Value n</td></tr>
</tbody>
<tfoot>
<tr><td>FirstFooter</td></tr>
<tr><td>Second Footer in a new tr</td></tr>
</tfoot>
</table>

Any ideas how best to accomplish this? Thanks.

EDIT: It would be great if I could avoid using a custom control/custom renderer

like image 763
David Waters Avatar asked Apr 15 '09 14:04

David Waters


4 Answers

The Richfaces column has the breakBefore attribute that would allow you to do something like this:

<f:facet name="footer">
    <rich:column>
        <h:outputText value="First Footer"/>
    </rich:column>
    <rich:column breakBefore="true">
        <h:outputText value="Second Footer"/>
    </rich:column>
</f:facet>

Which is what you're after but unfortunately not using the library you've indicated.

If you're using Facelets you could always just build up a regular table with ui:repeat.

like image 83
Damo Avatar answered Nov 20 '22 13:11

Damo


As McDowell said, panelGrid will do what you're asking without custom controls, unless I'm missing something.

<f:facet name="footer">
    <h:panelGrid columns="1"> 
        <h:outputText value="FirstFooter" />
        <h:outputText value="Second Footer in a new tr" />
    </h:panelGrid>
</f:facet>

This renders as follows

<tfoot>
    <tr>
        <td colspan="3">
            <table>
                <tbody>
                    <tr>
                        <td>FirstFooter</td>
                    </tr>
                    <tr>
                        <td>Second Footer in a new tr</td>
                    </tr>
                </tbody>
            </table>
        </td>
    </tr>
</tfoot>

You can use tags other than outputText in the panelGrid as well to get whatever effect you're looking for (just make sure that you wrap them in a panelGroup or something similar).

like image 40
Matt McMinn Avatar answered Nov 20 '22 15:11

Matt McMinn


The solution I ended up using was a custom renderer associated with t:datatable (the tomahawk extension to datatable)

public class HtmlMultiHeadTableRenderer extends HtmlTableRenderer

I only had to override one method

protected void renderFacet(FacesContext facesContext,   
  ResponseWriter writer, UIComponent component, boolean header)

with in which I looked for facets with names header, header2, header3 ... headerN (I stop looking as soon as there is one missing) and the same with footer. This has allowed me do do code like

<h:dataTable ... var="row">
  <h:column>
    <f:facet name="header">
     Header
    </f:facet>
    <f:facet name="header2">
     A second Tr with th's
    </f:facet>
    <h:outputText value="#{row.value}"/>
    <f:facet name="footer">
     FirstFooter
    </f:facet>
    <f:facet name="footer2">
     Second Footer in a new tr
    </f:facet>
  </h:column>
</h:dataTable>

This took about one day(with some other extensions like allowing colspans based on groups) to code and document,

like image 40
David Waters Avatar answered Nov 20 '22 14:11

David Waters


(Facets must have unique names (they are stored in a facet map).)

Two ways to do this spring to mind:

  1. Just put a panelGrid in the footer and use style sheets to get the look you want.
  2. Create a custom component that renders the markup you want.
like image 1
McDowell Avatar answered Nov 20 '22 14:11

McDowell