Bug in sWidth Handling
Bug in sWidth Handling
scottsb
Posts: 2Questions: 0Answers: 0
Problem:
Specified sWidth values are thrown off by cell padding and borders.
Demonstration:
The following table has its solitary column set to a sWidth of 10px. With its only contents that exact width, the 's width should be set to 10px. Instead it is set to 32px (10px cell contents + 20px padding + 2px border).
[code]
th, td {
border: 1px solid #000;
padding: 10px;
}
table div {
width: 10px;
}
$(document).ready(function(){
$('table').dataTable({
aoColumns: [{ sWidth: '10px' }]
});
});
[/code]
Cause:
In the function _fnCalculateColumnWidths(), each column is set to the wider of (a) the specified sWidth or (b) the width of the widest cell contents in the column. This is not a problem in itself; however, when the width of the widest data cell is calculated, it incorrectly includes the horizontal padding and border widths on the cell. Thus, when the table is finally displayed, the padding and border widths will be duplicated: once as part of the element width (set by DataTables) and once as the actual padding and border set in the CSS.
Solution:
This will solve the problem. A better solution would involve more changes "upstream" in the code, but this works. Change the following line in the DataTables class (#4255 in version 1.6.1):
oSettings.aoColumns[iIndex].sWidth = $("td", nCalcTmp)[i].offsetWidth +"px";
To:
var iContentWidth = $("td", nCalcTmp).eq(i).width();
var iSetWidth = oSettings.aoColumns[i].sWidth.slice(0, -2);
oSettings.aoColumns[iIndex].sWidth = Math.max(iContentWidth, iSetWidth) + "px";
Specified sWidth values are thrown off by cell padding and borders.
Demonstration:
The following table has its solitary column set to a sWidth of 10px. With its only contents that exact width, the 's width should be set to 10px. Instead it is set to 32px (10px cell contents + 20px padding + 2px border).
[code]
th, td {
border: 1px solid #000;
padding: 10px;
}
table div {
width: 10px;
}
$(document).ready(function(){
$('table').dataTable({
aoColumns: [{ sWidth: '10px' }]
});
});
[/code]
Cause:
In the function _fnCalculateColumnWidths(), each column is set to the wider of (a) the specified sWidth or (b) the width of the widest cell contents in the column. This is not a problem in itself; however, when the width of the widest data cell is calculated, it incorrectly includes the horizontal padding and border widths on the cell. Thus, when the table is finally displayed, the padding and border widths will be duplicated: once as part of the element width (set by DataTables) and once as the actual padding and border set in the CSS.
Solution:
This will solve the problem. A better solution would involve more changes "upstream" in the code, but this works. Change the following line in the DataTables class (#4255 in version 1.6.1):
oSettings.aoColumns[iIndex].sWidth = $("td", nCalcTmp)[i].offsetWidth +"px";
To:
var iContentWidth = $("td", nCalcTmp).eq(i).width();
var iSetWidth = oSettings.aoColumns[i].sWidth.slice(0, -2);
oSettings.aoColumns[iIndex].sWidth = Math.max(iContentWidth, iSetWidth) + "px";
This discussion has been closed.
Replies
var iContentWidth = $("td", nCalcTmp).eq(i).width();
var iSetWidth = oSettings.aoColumns[i].sWidth ? oSettings.aoColumns[i].sWidth.slice(0, -2) : 0;
oSettings.aoColumns[iIndex].sWidth = Math.max(iContentWidth, iSetWidth) + "px";
Nice one! Thanks very much indeed for your detailed commentary on this issue - and the fix :-). _fnCalculateColumnWidths is one of the oldest functions in DataTables, and has been almost untouched since when it was first written - so it's nice to see it get some love! I do have plans to rewrite it at some point to be more efficient - but this will certainly help along the way.
I'll see if I can integrate this change into the next release.
Regards,
Allan