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. Otherwis
This code work fine in my project. It's similar to other answers.
$("#my_table").flexigrid({
...
onSuccess: function(){
columnWidth();
$(window).resize(function(){
columnWidth();
});
}
});
function columnWidth(){
var num_col = 0;
//Work with the columns width of the first row of body
$("#row1 td").each(function(td){
//row's column's width greater than header's column's width
if($(this).width() > $("th[axis='col"+num_col+"']").width()){
$("th[axis='col"+num_col+"']").width($(this).width());
$("th[axis='col"+num_col+"']").css({"min-width":$(this).width()});
}
//header's column's width greater than row's column's width
else if($("th[axis='col"+num_col+"']").width() > $(this).width()){
$("td[abbr='"+$(this).prop('abbr')+"']").width($("th[axis='col"+num_col+"']").width());
$("td[abbr='"+$(this).prop('abbr')+"']").css({"min-width":$("th[axis='col"+num_col+"']").width()});
}
++num_col;
});
}
I hope this has solved your problems.
From your own answer, I added setting min-width so that the columns don't get squeezed differently if the flexigrid width was set too narrow or the flexigrid resized, tested only in chrome:
$(this).width(realWidth);
cells.eq(i).width(realWidth);
// these two lines added
$(this).css('min-width', realWidth);
cells.eq(i).css('min-width',realWidth);
Just doing this break column resizing, as that modifies the width of the div inside the th and td, but that can be fixed with a few additional lines in flexigrid in the "dragEnd" function:
. . .
// LINE 211
$('th:visible div:eq(' + n + ')', this.hDiv).css('width', nw);
// ADD THIS AFTER LINE 211
$('th:visible div:eq(' + n + ')', this.hDiv).parent().css('min-width', nw);
$('th:visible div:eq(' + n + ')', this.hDiv).parent().css('width', nw);
. . .
// LINE 214
$('td:visible div:eq(' + n + ')', this).css('width', nw);
// ADD THIS AFTER LINE 214
$('td:visible div:eq(' + n + ')', this).parent().css('width', nw);
$('td:visible div:eq(' + n + ')', this).parent().css('min-width', nw);
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;
}
}
My solution is a lot simpler than the others suggested.
Before you call the flexigrid function, add this:
$("#yourtable th").each(function() {
$(this).attr("width", $(this).width());
});
This will set the width of the column headers to as wide as the text in them is (as opposed to manually setting each header width either with css or in the markup) and make the table body columns the same width.
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.
I ran into the same thing, finding out that the width of my divs containing the column headings and the table cells had the width = 0. So i had to wait a bit until the whole html-table was built, then i had to run the "format" method.
Next thing is that i have the HTML table built in an invisible div at the beginning. So i had to omit the not(:hidden)
selector within my code.
Here we go:
$.fn.flexAddData = function(data) { // function to add data to grid
...
};
// my own method to justify the column headers with the body
$.fn.flexFormat = function() {
return this.each(function() {
var gridContainer = $('.flexigrid');
var headers = gridContainer.find('.hDiv table tr:first th');
var firstDataRow = gridContainer.find('.bDiv table tr:first td');
var offSet = 10;
// for each element in headers
// compare width with firstDataRow elemts
// the greater one sets the width of the lower one
$.each(headers, function(i) {
var thWidth = $(this).find('div').outerWidth();
var tdWidth = $(firstDataRow[i]).find('div').outerWidth();
thWidth > tdWidth ? $(firstDataRow[i]).find('div').width(thWidth - offSet) : $(this).find('div').width(tdWidth - offSet);
});
});
}; // end format
The call for the method as follows:
setTimeout(function() {
$('.flexigrid').flexFormat();
}
, 10
);
Hope to have another solution for the problem ;-) Regards, Christoph