user1510044
user1510044

Reputation: 15

How to freeze header of table in JSF

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?

Upvotes: 1

Views: 2585

Answers (1)

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

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;
    }
}

Upvotes: 3

Related Questions