views:

1405

answers:

4

So I'm trying to use the flexigrid plugin. It looks like it's going to work great aside from the fact that it looks like you have to manually set the column widths. Otherwise, the column headers do not match up with the body columns.

Is there any way of automatically matching these up, while still allowing the column widths to be defined by the length of the content in the columns (as is the normal table behavior).

Thanks!

+1  A: 

I've been working on this today, too. What I've come up with involves adding an onSuccess handler and figuring out what the maximum size of each column is between the header and the body, then setting the width of both to the maximum for that column.

grid.flexigrid({

  ...other setup...

  onSuccess: function() {
       format();
    });
  }
});

function format() {
    var gridContainer = this.Grid.closest('.flexigrid');
    var headers = gridContainer.find('div.hDiv table tr:first th:not(:hidden)');
    var drags = gridContainer.find('div.cDrag div');
    var offset = 0;
    var firstDataRow = this.Grid.find('tr:first td:not(:hidden)');
    var columnWidths = new Array( firstDataRow.length );
    this.Grid.find( 'tr' ).each( function() {
        $(this).find('td:not(:hidden)').each( function(i) {
            var colWidth = $(this).outerWidth();
            if (!columnWidths[i] || columnWidths[i] < colWidth) {
                columnWidths[i] = colWidth;
            }
        });
    });
    for (var i = 0; i < columnWidths.length; ++i) {
        var bodyWidth = columnWidths[i];

        var header = headers.eq(i);
        var headerWidth = header.outerWidth();

        var realWidth = bodyWidth > headerWidth ? bodyWidth : headerWidth;

        firstDataRow.eq(i).css('width',realWidth);
        header.css('width',realWidth);            
        drags.eq(i).css('left',  offset + realWidth );
        offset += realWidth;
    }
}
tvanfosson
Hmm, I actually ended up writing extremely similar code earlier :-P however, I was getting some strange error in IE only. Let me try your version and let's see how it goes :-)
Joel Martinez
+2  A: 

I've gotten this to work (at least partially). The problem I was having with my previous iteration (which was also a problem with tvanfosson's implementation) was that once you resized the headers, then the "drag" bars would not be aligned with the new column widths.

My current implementation is below, which works in Firefox 3.5 and Chrome. Unfortunately, there is some exception being thrown in IE (all versions) that is rather disconcerting. I will debug further on Monday:

$(".flexigrid").each(function() {
    var grid = $(this);
    var headers = grid.find(".hDiv thead th");
    var row = grid.find(".bDiv tbody tr:first");
    var drags = grid.find("div.cDrag div");
    if (row.length >= 1) {
        var cells = row.find("td");
        var offsetAccumulator = 0;
        headers.each(function(i) {
            var headerWidth = $(this).width();
            var bodyWidth = cells.eq(i).width();
            var realWidth = bodyWidth > headerWidth ? bodyWidth : headerWidth;

            $(this).width(realWidth);
            cells.eq(i).width(realWidth);

            var drag = drags.eq(i);
            var dragPos = drag.position();
            var offset = (realWidth - headerWidth);
            var newPos = dragPos.left + offset + offsetAccumulator;
            offsetAccumulator += offset;
            drag.css("left", newPos);
        });
    }
});
Joel Martinez
I had to fix a few gotchas in Flexigrid as well. Around line 1000 it needs to check the results of the parseInt calls to make sure they are numbers (set to 0 otherwise). Around line 960 it needs to check if this.width has a value (set to 'auto') before appending 'px' to it.
tvanfosson
yeah, that was the cause of the IE issue I described above. Once it was patched it started working a peach
Joel Martinez
Updated my code to handle the drags as well. Note that my code now finds the widest column in the table and uses that as the default width.
tvanfosson
I found that I needed to use outerWidth() on IE or I had an off by 1px error on the headers. I'm still using IE7 so YMMV.
tvanfosson
+2  A: 

I had this problem as well. Here is my fix, and it works great. In flexigrid.js around line 678, change this line.

$(tdDiv).css({textAlign:pth.align,width: $('div:first',pth)[0].style.width});

to this

$(tdDiv).css({textAlign:pth.align,width: $('div:first',pth).width() + "px"});

And you are all set.

Brian
A: 

Thanks. Based on the post of line 678, mine got fixed with the following:

$(tdDiv).css({textAlign:pth.align,width: $('div:first',pth).width()-10 + "px"});

For some reason, the header font is larger than the detail font... hope this helps.

Joe