Skip to content
This repository has been archived by the owner on Apr 2, 2019. It is now read-only.

Fixed Header #4

Open
wyuenho opened this issue Nov 26, 2012 · 48 comments
Open

Fixed Header #4

wyuenho opened this issue Nov 26, 2012 · 48 comments
Milestone

Comments

@wyuenho
Copy link
Contributor

wyuenho commented Nov 26, 2012

You can already achieve this using a pure CSS.

http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/

A similar approach should probably be baked into the default stylesheet.

The problem is lining up the column widths of the th and tds. This will have to be done together with #5. The JS necessary to calculate a width for each column is trivial. Let me know if you get to it first.

For now, you can give a CSS min-width manually to each column's th and td.

@ekanna
Copy link

ekanna commented Jan 25, 2013

+1

3 similar comments
@dheerajaggarwal
Copy link

+1

@TimNZ
Copy link

TimNZ commented Feb 3, 2013

+1

@ychumak
Copy link

ychumak commented Feb 13, 2013

+1

@TimNZ
Copy link

TimNZ commented Mar 12, 2013

So what are people doing now because I needed fixed headers TODAY :)

@monzou
Copy link

monzou commented Mar 13, 2013

+1 column header + row header

@wyuenho
Copy link
Contributor Author

wyuenho commented Mar 13, 2013

Hi guys,

Thanks for votes. I know this is very important for a lot of you but this is actually non-trivial to implement. To implement this, I either have to wait for #5 and #6, or quickly whip up a hack that basically renders 2 tables, one with a header and one without, and layer the one without the header on top but below the header. I'm open to accept patches for any solution to speed this up.

@TimNZ
Copy link

TimNZ commented Mar 13, 2013

Thanks for quick response.

I was in a rush and ended up wrapping a Marionette.ItemView around the DataTables lib that does exactly that as I am basically trying to replicate a Windows Explorer style list and theirs will do for now.

http://www.datatables.net/examples/basic_init/scroll_xy.html

You may as well look at their code as it does the job, with a few hacks to update columns after container/window resizing. I don't have time in the short term to port this across to backgrid.

define(['require', 'backbone', 'marionette', 'jquery','App', 'swig', 'logger', 'jquery.datatables',
'css!/assets/css/smoothness/datatable'],
function (require, Backbone, Marionette, $, App, Swig, Logger, $Datatables, cssDataTable)
{
    "use strict"

    return Marionette.ItemView.extend(
        {
            template: Swig.compile('<table class="display" style="width: 100%"></table>'),
            tagName: 'div',
            initialize: function (options)
            {
                this.options = _.defaults(options, { multipleSelection: false });
            },
            events:
                {
                    'click tr': 'selectRow'
                },
            onRender: function ()
            {
                var opts = {
                    "bJQueryUI": true,
                    "bPaginate": false,
                    "sScrollY": "100%",
                    "sWidth": "100%",
                    "sScrollX": "100%",
                    "sScrollXInner": "110%",
                    "bFilter": false,
                    "bInfo": false,
                    "sDom": 't',
                    "aoColumns": _.map(this.options.columns, function(col)
                    {
                        return { sTitle: col.label, mData: col.name };
                    }),
                    "aaData": this.toData(this.options.collection)
                };

                this.dataTable = this.$el.find('table').dataTable(opts);
                var self = this;
                $(window).bind('resize', function ()
                {
                    self.updateColumnSizing();
                });

            },
            toData: function(collection)
            {
                return collection.map(function (model)
                {
                    return model.attributes;

                });
            },
            setData: function(collection)
            {
                this.dataTable.fnClearTable();
                this.dataTable.fnAddData(this.toData(collection));
            },
            selectRow: function(e)
            {
                var self = this;
                var $row = $(e.currentTarget);
                if (this.options.multipleSelection)
                    $row.toggleClass('row_selected');
                else
                {
                    if ($row.hasClass('row_selected'))
                    {
                        $row.removeClass('row_selected');
                    }
                    else
                    {
                        self.$el.find('tr.row_selected').removeClass('row_selected');
                        $row.addClass('row_selected');
                    }
                }
            },
            onDomRefresh: function()
            {
                this.updateColumnSizing();
            },
            updateColumnSizing: function ()
            {
                var $parent = this.$el.parents('div.datatable').first();
                var $header = $parent.find('.dataTables_scrollHead');
                var newHeight = $parent.height() - $header.height();
                this.$el.find('.dataTables_scrollBody').css('height', newHeight + 'px');
                this.dataTable.fnAdjustColumnSizing();
            }
        });
}

)

@ghost
Copy link

ghost commented Apr 27, 2013

+1

6 similar comments
@joefitzgerald
Copy link

+1

@halcyonandon
Copy link

+1

@litzebauer
Copy link

+1

@solognt
Copy link

solognt commented May 31, 2013

+1

@irvinebroque
Copy link

+1

@egeste
Copy link
Contributor

egeste commented Jun 4, 2013

+1

@ram-you
Copy link

ram-you commented Jun 6, 2013

+1 for Fixed Header.
The scrolling would be great with : https://github.com/malihu/malihu-custom-scrollbar-plugin

@rjralgar
Copy link

+1

@wyuenho wyuenho mentioned this issue Aug 4, 2013
@brett-shwom
Copy link

Wondering if anyone has any made any improvements on the fixed header issue within the last few months.

@wyuenho
Copy link
Contributor Author

wyuenho commented Oct 10, 2013

As of today, you can use CSS to target individual columns and turn off the rendering of the default header. To implement a fixed header, you can prepend a separate grid that only shows a list of column headers above the grid container that's wrapping the grid containing all the rows. Again, use CSS to target the columns to have the columns of 2 separate grid line up.

A proper fixed header extension will be coming shortly after 0.3.0 has been released.

@oosterholt
Copy link

+1

8 similar comments
@excentris
Copy link

+1

@WRidder
Copy link

WRidder commented Oct 17, 2013

+1

@Wietjerr
Copy link

+1

@ericbeijer
Copy link

+1

@KramerCJ
Copy link

+1

@jurgenkalverboer
Copy link

+1

@beatle01
Copy link

+1

@santomegonzalo
Copy link

+1

@jiviejo
Copy link

jiviejo commented Dec 11, 2013

+1

@santomegonzalo
Copy link

I couldn't find someone who solve this problem, so I made a plugin who works with backgrid to manage fixed header.

https://github.com/gsantome/backgrid.fixedheader

In my project is working GREAT and it's really easy to implement.

@wyuenho
Copy link
Contributor Author

wyuenho commented Dec 28, 2013

Just an update to issue:

You can already achieve this using a pure CSS.

http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/

I might just baked this into the default stylesheet.

@songjiayang
Copy link

+1

1 similar comment
@stereocilia
Copy link

+1

@drewwells
Copy link

The pure css solution doesn't resize width very well.

@amanpatel
Copy link

+1 (might implement myself, but not sure when).

Please check the implementation here, for a good way of doing this (eventually).
http://addepar.github.io/#/ember-table/overview

That would be a dream come true (notice how the first column AND the header stays fixed). They are not using <table> elements at all.

@wyuenho
Copy link
Contributor Author

wyuenho commented Aug 8, 2014

We can still use table elements, we just have to set display: block; on all of the table elements. It's a lot of CSS changes regardless. Will eventually come to this when I have time.

@egeste
Copy link
Contributor

egeste commented Aug 8, 2014

Y'all should check out Oraculum

@aliirz
Copy link

aliirz commented Nov 10, 2014

I am still trying to figure out how to make the header fixed :( any example would be helpful.

@pdg-
Copy link

pdg- commented Nov 26, 2014

Big fan of backgrid!

For a quick/dirty fixed header using jquery+css transform, I have found the following functions handy. Note this is not perfect, just a starting point for an alternate solution to those listed above.

Thanks for all your hard work wyuenho!

$(document).scroll(function(e){
    var delta = $(window).scrollTop() - $(".backgrid thead").offset().top;
    if(delta > 0)
    {
        translate($(".backgrid th"),0,delta-2);
    }
    else
    {
        translate($(".backgrid th"),0,0);
    }
});

$('.backgrid-container').scroll(function(e) {
    var delta = $('.backgrid-container').scrollTop();
    //alternate var delta = Math.abs($('.backgrid thead').position().top);
    if(delta > 0)
    {
        translate($(".backgrid th"),0,delta-2);
    }
    else
    {
        translate($(".backgrid th"),0,0);
    }
});

function translate(element, x, y)
{    
    var translation = "translate(" + x + "px," + y + "px)"
    element.css({
        "transform": translation,
        "-ms-transform": translation,
        "-webkit-transform": translation,
        "-o-transform": translation,
        "-moz-transform": translation
    });
}

@songjiayang
Copy link

@pdg- I added floatThead ( a jquery plugin) for it , i will try your code, thanks for your share .

@ffflabs
Copy link

ffflabs commented Sep 2, 2015

I'm using backgrid.paginator, but the following should apply to the regular usage as well. This is what I did to make the header columns align with the body columns:

pageableGrid.listenTo(rowCollection, "reset", function () {
    pageableGrid.$el.find('tbody tr:first-child td').each(function (index) {
        pageableGrid.$el.find('thead th').eq(index).css('width', jQuery(this).width());
    });
});

As you see, after paginating the collection or sorting a column, there's a collection reset event which means I might need to realign stuff.

@marseille
Copy link

+1

I tried to implement the CSS solution mentioned above by adding those CSS rules, but my grid simply becomes a very large one column table and it does not fix the header.

I also tried using this pageable grid idea just above, but to no avail.

floatThead did fix my table headers, but as soon as I scrolled horizontally, the grid lost its integrity and the columns spanned the entire screen and did not keep up with the cells. I tried implementing the overflow scrolling but I must have been missing something there.

I'm just looking for something to accomplish this with the backgrid I have. I must be missing something, is there any further examples or alternatives people have?

@mkoryak
Copy link

mkoryak commented Dec 30, 2015

floatThead author here. no idea what backgrid is, just browsing related issues. Let me know if I can be of assistance (without installing anything) 🐈

@ffflabs
Copy link

ffflabs commented Dec 30, 2015

@mkoryak I'm using your plugin in production since a couple of months ago and I love it. Thank you from the bottom of my heart.

The only improvement I'd dare to ask would be to have floatHead-slim.js wrapped as UMD module instead of relying in the global scope and IIFE.

@mkoryak
Copy link

mkoryak commented Dec 30, 2015

PRs are welcome :)

@druedaplata
Copy link

+1

1 similar comment
@jorgepvenegas
Copy link

+1

@rcandea
Copy link

rcandea commented Nov 9, 2018

If you are targeting newer browsers you can use:

.backgrid thead th {
    position: sticky;
    top: -1px;
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests