1

In my JSF 2.1 project, I am using a table where I have issues with header. If I use a single table for both header and data, the header is scrolling along with data.

If I use separate table for header and data i have alignment issues.

So is there any tag or any possible way to freeze header using single table for header and data?

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • Its better to have seperate data and header tables. Work on the alignment issues. You can play with the width attribute to fix alignment.. I dont think you can make header fixed with single table. – Mukul Goel Nov 11 '12 at 14:41
  • @MukulGoel remember that JSF will just generate plain HTML, and what OP's asking is a HTML feature. Check my answer to see that what OP's asking is possible to mix with JSF. – Luiggi Mendoza Nov 11 '12 at 18:26

1 Answers1

3

There is a good answer to this for HTML: HTML table with fixed headers?. You just need to remember that JSF will generate plain HTML. Adapting the code from that answer, it comes with this solution (Note: You need to add the CDATA validation in order to use the "<" and ">" in JavaScript in Facelets):

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"> 
    <h:head>
        <title>Table Body Scroll Test</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js">
        </script>

        <script>
        /* <![CDATA[ */
            function scrolify(tblAsJQueryObject, height) {
                var oTbl = tblAsJQueryObject;
                // for very large tables you can remove the four lines below
                // and wrap the table with <div> in the mark-up and assign
                // height and overflow property
                var oTblDiv = $("<div/>");
                oTblDiv.css('height', height);
                oTblDiv.css('overflow','scroll');
                oTbl.wrap(oTblDiv);
                // save original width
                oTbl.attr("data-item-original-width", oTbl.width());
                oTbl.find('thead tr td').each(function() {
                    $(this).attr("data-item-original-width",$(this).width());
                });
                oTbl.find('tbody tr:eq(0) td').each(function() {
                    $(this).attr("data-item-original-width",$(this).width());
                });
                // clone the original table
                var newTbl = oTbl.clone();
                // remove table header from original table
                oTbl.find('thead tr').remove();
                // remove table body from new table
                newTbl.find('tbody tr').remove();
                oTbl.parent().parent().prepend(newTbl);
                newTbl.wrap("<div/>");
                // replace ORIGINAL COLUMN width
                newTbl.width(newTbl.attr('data-item-original-width'));
                newTbl.find('thead tr td').each(function() {
                    $(this).width($(this).attr("data-item-original-width"));
                });
                oTbl.width(oTbl.attr('data-item-original-width'));
                oTbl.find('tbody tr:eq(0) td').each(function() {
                    $(this).width($(this).attr("data-item-original-width"));
                });
            }

            $(document).ready(function() {
                scrolify($('#tblNeedsScrolling'), 160); // 160 is height
            });
        /* ]]> */
        </script>
    </h:head>
    <h:body>
        <h:form id="myForm" prependId="false">
            <div style="width:300px;border:6px green solid;">
                <h:dataTable id="tblNeedsScrolling" value="#{tableScroll.data}" var="data" border="1" width="100%">
                    <h:column>
                        <f:facet name="header">
                            <h:outputText value="Data" />
                        </f:facet>
                        <h:outputText value="#{data}" />
                    </h:column>
                </h:dataTable>
            </div>
        </h:form>
    </h:body>
</html>

The managed bean for the example:

@ManagedBean
@RequestScoped
public class TableScroll {
    private List<String> data;
    public TableScroll() {
        data = new ArrayList<String>();
        for(int i = 1; i <= 20; i++) {
        data.add("Name" + i);
        }
    }

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

    public void setData(List<String> data) {
        this.data = data;
    }
}
Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332