cloudflarearchive / backgrid

Finally, an easily stylable semantic HTML data grid widget with a Javascript API that doesn't suck.
http://backgridjs.com
MIT License
2.01k stars 324 forks source link

Fixed Header #4

Open wyuenho opened 11 years ago

wyuenho commented 11 years ago

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 https://github.com/wyuenho/backgrid/issues/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 commented 11 years ago

+1

dheerajaggarwal commented 11 years ago

+1

TimNZ commented 11 years ago

+1

ychumak commented 11 years ago

+1

TimNZ commented 11 years ago

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

monzou commented 11 years ago

+1 column header + row header

wyuenho commented 11 years ago

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 commented 11 years ago

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 commented 11 years ago

+1

joefitzgerald commented 11 years ago

+1

halcyonandon commented 11 years ago

+1

litzebauer commented 11 years ago

+1

solognt commented 11 years ago

+1

irvinebroque commented 11 years ago

+1

egeste commented 11 years ago

+1

ram-you commented 11 years ago

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

rjralgar commented 11 years ago

+1

brett-shwom commented 10 years ago

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

wyuenho commented 10 years ago

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 commented 10 years ago

+1

excentris commented 10 years ago

+1

WRidder commented 10 years ago

+1

Wietjerr commented 10 years ago

+1

ericbeijer commented 10 years ago

+1

KramerCJ commented 10 years ago

+1

jurgenkalverboer commented 10 years ago

+1

beatle01 commented 10 years ago

+1

santomegonzalo commented 10 years ago

+1

jiviejo commented 10 years ago

+1

santomegonzalo commented 10 years ago

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 commented 10 years ago

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 commented 10 years ago

+1

stereocilia commented 10 years ago

+1

drewwells commented 10 years ago

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

amanpatel commented 9 years ago

+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 commented 9 years ago

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 commented 9 years ago

Y'all should check out Oraculum

aliirz commented 9 years ago

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

pdg- commented 9 years ago

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 commented 9 years ago

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

ffflabs commented 8 years ago

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 commented 8 years ago

+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 commented 8 years ago

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

ffflabs commented 8 years ago

@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 commented 8 years ago

PRs are welcome :)

druedaplata commented 8 years ago

+1

jorgepvenegas commented 8 years ago

+1

rcandea commented 5 years ago

If you are targeting newer browsers you can use:

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