17 Ocak 2012 Salı

Richfaces DataTable Fixed Header

Hi folks,
for people who want to have a datatable with a fixed header but not want to use richfaces:extendeddatatable you may use following solution. I seeked internet a lot to find a better solution but couldn't find any solution for this. anyway here is my solution:

first i need to tell you that you need to have jQuery for following solution:
please note that "#customerForm\\:custTable" is the id of the datatable
                    jQuery(document).ready(function() {
                        initFixedHeader();
                    });
                    
                    function initFixedHeader(){
                        if(jQuery('#myDiv').scroll())
                           jQuery('#myDiv').scroll(moveScroll); 
                        var componentId = '#{rich:clientId('custTable')}';
                        componentId = componentId.replace(/:/g, "\\\:");
                        jQuery('#inDiv').empty();
                        jQuery('#inDiv').height(jQuery('#'+componentId+' thead').children( 'tr:is(:first)' ).height());
                        var scrollBarWidth= jQuery('#myDiv').width()-jQuery('#myDiv')[0].clientWidth;
                        jQuery('#inDiv').width(jQuery('#myDiv').width()-scrollBarWidth);
                        clone_table=jQuery('#'+componentId).clone().attr('id', 'clone');
                        clone_table.find('*').removeAttr('id');
                        clone_table.find('*').removeAttr('onclick');
                        clone_table.find('*').removeAttr('onkeyup');
                        clone_table.find('*').removeAttr('onkeydown');
                        clone_table.find('*').removeAttr('name');
                        jQuery('#inDiv').append(clone_table).hide().slideToggle("fast");
                        jQuery('#inDiv').scrollLeft(jQuery('#myDiv').scrollLeft());
                        jQuery('#clone').css({'background-color': 'transparent'});
                        jQuery('#clone tbody').css({'visibility':'hidden'});
                        jQuery('#clone thead').children( 'tr:not(:first)' ).css({'visibility':'hidden'});
                    }
                    
                    
                    function moveScroll(){
                        jQuery('#inDiv').scrollLeft(jQuery('#myDiv').scrollLeft());
                    }

and you need to encapsulate your datatable component like below:

<div style="position:relative;width:100%;height:390px;" id="mainDiv">
<div style="position:absolute;top:0;overflow:hidden;" id="inDiv">
</div>
<div style="width:100%;height:390px;overflow: auto;" id="myDiv">
<rich:dataTable id="custTable" /> 
</div>
</div>


please not that each time you make an ajax request you need to recall initFixedHeader method to redraw heading cause each time size of the table may change. And in a page you may make ajax requests from several places. But luckliy i mostly use a4j:queue component to queue and limit my ajax requests. And i manage to recall initFixedHeader method like below after each ajax request :

<a4j:queue  ignoreDupResponce="true" requestDelay="10" oncomplete="initFixedHeader();"/>

1 yorum: