Fixed Header showing up after leaving the view

Fixed Header showing up after leaving the view

sangeetsangeet Posts: 3Questions: 1Answers: 0

Fix Header coming on other tables:

Fix header coming on other Views:

My Directive:

          angular.module('datatable.directive', [])
          .directive('datatable', function ($compile) {
            return {
        scope: {
            dtData: '=',
            dtColumns: '=',
            dtSort: '=',
            dtDirection: '=',
            dtFilter: '=',
            dtPagination: '=',
            dtFixed: '='
        },
        transclude: true,
        controller: function($scope, $location) {
            $scope.navigateToListing = function(id) {
                $location.path('/seller/listing/management/' + id);
            };
        },
        link: function (scope, elem, attrs, ctrl) {
            var pagination = true;
            if( attrs.dtPagination == 'no' ) {
                pagination = false;
            }
            $.fn.dataTable.ext.errMode = 'throw';
            $(elem).dataTable({
                bFilter: true,
                data: scope.dtData,
                columns: scope.dtColumns,
                language: {
                    search: '',
                    searchPlaceholder: 'Search'
                },
                createdRow: function ( row, data, index ) {
                    // $(row).attr('ng-class', '{selected: selectedRow['+data.id+']}');
                    $compile(row)(scope.$parent);
                },
                initComplete: function() {
                    var thead = elem.find('thead tr');
                    var ix = 0;
                    var columns = this.api().init().columns;
                    this.api().columns().every( function () {
                        if(!columns[ix].uniqueFilter) {
                            ix++;
                            return;
                        }
                        var column = this;
                        var th = elem.find('thead tr th').eq(ix);
                        var title = columns[ix].sTitle;
                        var select = $('<select class="form-control input-sm"><option value="">' + title.toUpperCase() + '</option></select>');
                        select.on( 'change', function (ev) {
                            var val = $.fn.dataTable.util.escapeRegex(
                                $(this).val()
                            );

                            column
                                .search( val ? '^'+val+'$' : '', true, false )
                                .draw();
                        } );
                        select.on('click', function(ev) {
                            ev.stopPropagation();
                        });
                        select.appendTo(th.empty());

                        column.data().unique().sort().each( function ( d, j ) {
                            select.append( '<option value="'+d+'">'+d+'</option>' );
                        } );
                        ix++;
                    } );
                    if(scope.dtFilter) {
                        var table_id = $(this).attr('id');
                        $("#" + table_id + "_filter").appendTo("#" + scope.dtFilter);
                        $("#" + table_id + "_filter").find("input").first().removeClass("input-sm");
                    }
                },
                lengthChange: false,
                order: scope.dtSort == 'NONE' ? []: [[scope.dtSort || 0, scope.dtDirection || 'desc']],
                paging: pagination,
                fixedHeader: scope.dtFixed == true ? true : false

            });
        }
    };
});

My Controller:

     angular.module('reports.controller', [])
        .controller('ReportsCtrl', ['API_URL', '$scope', '$route', '$location', 'SessionSvc', 'ReportSvc', '$analytics', 
        'CacheFactory', 'ngDialog', '$filter',
        function (API_URL, $scope, $route, $location, SessionSvc, ReportSvc, $analytics, CacheFactory, ngDialog, $filter) {

        $scope.API_URL = API_URL;
        $scope.state = {};
        $scope.state.dtFilterField = 'filter_target';
        $scope.loading = false;

        ReportSvc.getReports().then(function (resp) {
            var reports_var = resp.data.data;
            $scope.reports = _.groupBy(reports_var, 'category');

        });

        $scope.getReport = function (rpt_key, rpt_name) {
            $scope.state.selectedReport = rpt_name;
            $scope.state.values = {};
            $scope.loading = true;
            $scope.error = "";
            ReportSvc.get(rpt_key).then(function (resp) {
                $scope.loading = false;
                $scope.state.reportName = resp.data.data.name;
                $scope.state.reportKey = resp.data.data.key;
                if( resp.data.data.error ) {
                    $scope.error = resp.data.data.error;
                }
                else {
                    $scope.state.reportDesc = resp.data.data.description;
                    $scope.state.colNames = resp.data.data.cols;
                    $scope.state.values = resp.data.data.values;
                    var colSpec = [];
                    _.each($scope.state.colNames, function (colName) {
                        var spec = {'title': colName.replace(/_/g, ' ')};
                        if (reportParams[rpt_key] && reportParams[rpt_key]['colSpec'][colName]) {
                            angular.extend(spec, reportParams[rpt_key]['colSpec'][colName])
                        }
                        colSpec.push(spec)

                    });
                    $scope.state.dtColumns = colSpec;
                }
            }, function(resp) {
                alert("Error running report.")
            });
        };


        var reportParams = {};
        reportParams['TEST'] = {
            'colSpec': {
                'company_name': {'uniqueFilter': true},
                'listing_id': {
                    'render': function (data, type, full, meta) {
                        return '<a ng-href="/listing_details/' + data + '">' + data + '</a>';
                    }
                }
            }
        };

        var sessionCache = CacheFactory.get('sessionCache');
        $scope.$on('$routeChangeStart', function (next, current) {
            sessionCache.put('reportContext', $scope.state)

        });
        if (sessionCache.get('reportContext')) {
            $scope.state = sessionCache.get('reportContext');
        }
    }]);

My Html:

                <ul class="dropdown-menu">
                     <li ng-repeat="report in names">
                          <a href ng-click="getReport(report.key, report.name)">{{ report.name }}</a>
                      </li>
                 </ul>

               <table style="width:100%" class="table table-bordered" dt-fixed="true" dt-sort="'NONE'" dt-direction="desc" datatable dt-data="state.values" dt-filter="state.dtFilterField"
       dt-columns="state.dtColumns" dt-pagination="no">
               </table>

This question has accepted answers - jump to:

Answers

  • colincolin Posts: 15,142Questions: 1Answers: 2,586
    Answer ✓

    Hi @sangeet ,

    The problem is probably because you're not destroying the table when changing views - this means the fixedHeader elements will still exist, even though the table isn't being displayed. Use destroy() when changing the view.

    If no joy, we're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • sangeetsangeet Posts: 3Questions: 1Answers: 0

    Thanks, Colin! But can tell what exactly should I need to write. I have tried to change in my directive and in my report controller but it's not working. Can you help me?

  • colincolin Posts: 15,142Questions: 1Answers: 2,586
    Answer ✓

    You just need to call that destroy() when you change your view.

  • sangeetsangeet Posts: 3Questions: 1Answers: 0

    Thanks, Colin!

  • LimpEmuLimpEmu Posts: 64Questions: 18Answers: 1

    I have the same problem, and unfortunately any attempt to destroy the data table results in an error:

    Uncaught TypeError: Cannot read property 'style' of undefined
        at Fa (jquery.dataTables.min.js:62)
        at $ (jquery.dataTables.min.js:13)
        at s.<anonymous> (jquery.dataTables.min.js:127)
        at s.iterator (jquery.dataTables.min.js:100)
        at s.<anonymous> (jquery.dataTables.min.js:127)
        at Function.adjust (jquery.dataTables.min.js:103)
        at s.<anonymous> (jquery.dataTables.min.js:126)
        at s.visible (jquery.dataTables.min.js:103)
        at s.<anonymous> (jquery.dataTables.min.js:138)
        at s.iterator (jquery.dataTables.min.js:100)
    

    The table apparently cannot be destroyed. It looks like destroy wants to make all the columns visible, when it gets to the the second column (which is invisible), there is trouble. so I tried to manually make the column visible in the console, and I am finding that whenever I run for any column x:

    tablehrif.column(x).visible(true)
    

    I get the same error message. Vice versa, I can set visible to false, and that works just fine.
    The table is complicated, has rowspan and colspan headers, uses colVis to allow custom hiding of columns and column groups.

    I really like the fixedheader extension, have disabled it for now :neutral:

  • colincolin Posts: 15,142Questions: 1Answers: 2,586

    Hi @LimpEmu ,

    We did some improvements in this area recently. Could you try the nightly releases here and see if this resolves your issue. We're hoping to make a release in the next couple of weeks.

    Cheers,

    Colin

  • LimpEmuLimpEmu Posts: 64Questions: 18Answers: 1

    My apologies! I had to focus on something else. I will try the nightly releases tomorrow and let you know, thank you!

  • LimpEmuLimpEmu Posts: 64Questions: 18Answers: 1
    edited September 2019

    Hi @colin:
    I updated my code to use the nightly update, and I am now able to destroy tables to get rid of the fixed header when browsing to other pages without any error message. I will play a bit more for the rest of the day, but so far I am happy with how the revised fixed header extension works. Excellent!!!
    Beate

  • LimpEmuLimpEmu Posts: 64Questions: 18Answers: 1

    Hi again:
    I have been testing the fixed header extension quite a bit more, and I have run into a few snags:

    If the table includes a <thead> section, the error message continues to show up when I try to destroy the table to get rid of the fixed header. For the same table, the error goes away once I remove the <thead> section.

    Uncaught TypeError: Cannot read property 'style' of undefined
        at Fa (jquery.dataTables.min.js:62)
        at $ (jquery.dataTables.min.js:13)
        at s.<anonymous> (jquery.dataTables.min.js:127)
        at s.iterator (jquery.dataTables.min.js:100)
        at s.<anonymous> (jquery.dataTables.min.js:127)
        at Function.adjust (jquery.dataTables.min.js:103)
        at s.<anonymous> (jquery.dataTables.min.js:126)
        at s.visible (jquery.dataTables.min.js:103)
        at s.<anonymous> (jquery.dataTables.min.js:138)
        at s.iterator (jquery.dataTables.min.js:100)
    

    I have a navigation bar on the left that can be hidden by the user (onclick). While the table properly resizes, the fixed header does not. I addressed this problem by adding

    setTimeout(function() {
           if ($.fn.dataTable.tables({visible:true}).length > 0) {$.fn.dataTable.tables({visible:true,api:true}).columns.adjust();}
            },1000)
    

    to the onclick event.

    When a table is not visible at page load (i.e., there is other material on the page above the table with the fixed header) even if I destroy the table when navigating to a different page, the fixed header will still be at the top on subsequent pages when I start scrolling.

    I have trouble getting rid of the fixed header if I have two data tables on the same page both with a fixed header. This is likely related to my lack of understanding how to properly destroy a data table with editor extension and the tinymce extension. Never both tables are visible to the user at the same time, they are set on an accordion, so I should be able to destroy table 1 if the user looks at table 2 and vice versa.

    If ok, I will keep updating as I move on. Thank you,
    Beate

  • colincolin Posts: 15,142Questions: 1Answers: 2,586

    Hi @LimpEmu ,

    I'm not seeing the destroy problem with this example here. Would you be able to modify that please to demonstrate the issue.

    Cheers,

    Colin

  • LimpEmuLimpEmu Posts: 64Questions: 18Answers: 1
    edited September 2019

    Hmm, maybe it's not the <thead>. I thought it was since on other pages, I am using other components (except for responsive!) as well, and I am able to destroy the table. This link takes you to a JS Bin that includes all the features that I am using: live.datatables.net/huvohadu/1/edit

    Then I type table.destroy() in the console, the error comes up. Thank you!

  • colincolin Posts: 15,142Questions: 1Answers: 2,586

    Hi @LimpEmu

    Thanks for that example. The problem is because the column count in the header's first row doesn't match the column count in the bottom row. The bottom row has 36 cells, but the top has 11 with colspan="3" alone (there's the 36) plus an additional 9 with rowspan="2".

    This example here should help - it's showing how to use rowspan and colspan to get those complex headers.

    Cheers,

    Colin

  • LimpEmuLimpEmu Posts: 64Questions: 18Answers: 1

    I think the problem has to do with some invisible columns in the table. For instance, for the first column 'birth year,' I have to use a colspan of 2 as this column is followed by an invisible column. If I don't include the invisible column in the colspan, the complex header does not display correctly. Same goes for the last column that has a colspan of 3 added solely to accommodate the three invisible columns.

    I tried to add three empty <th></th> to accommodate the invisible columns, but the header does not display correctly even though the number of columns is exactly the same for two fixed header rows (and the table).

    I cannot get the thead section to properly display other than with the setting I originally used. Maybe this cannot be done.

  • LimpEmuLimpEmu Posts: 64Questions: 18Answers: 1
    edited October 2019

    I figured it out!
    I added three th tags for the invisible columns:

    <th rowspan="2" style="display:none;"></th>
    

    Works! Thank you!

This discussion has been closed.