I've created a fixed header/footer table based on a pure javascript program logic.
Basically, after loading the page, what I do is to split the original table in 3 other tables, each one containing part of it, as follows: thead, tbody and tfoot.
As reference, working code can be found bellow: (sorry for the long code statement, but I though, as it is working fine, same could be useful for someone else)
$(window).load(function() {
var mainTable = $('.table-scroll');
// outer contrainer
var tableOuterContainer = $('<div id="table-outer-container"></div>');
$(mainTable).after(tableOuterContainer);
// table header
var theadCopy = detachTableHeader();
$(tableOuterContainer).append(theadCopy);
//table body
var tableContainer = $('<div id="table-inner-container"></div>');
$(tableContainer).css('height', '300px');
$(tableContainer).css('overflow-y', 'auto');
$(tableContainer).append(mainTable);
$(tableOuterContainer).append(tableContainer);
var tfootCopy = detachTableFooter();
$(tableOuterContainer).append(tfootCopy);
function detachTableHeader() {
var clone = $(mainTable).clone();
$(clone).find('tbody').remove();
$(clone).find('tfoot').remove();
$(mainTable).find('thead').remove();
return clone;
}
function detachTableFooter() {
var clone = $(mainTable).clone();
$(clone).find('thead').remove();
$(clone).find('tbody').remove();
$(mainTable).find('tfoot').remove();
return clone;
}
function adjustTableHeaderWidth() {
var tbodyColumns = $(mainTable).find('tbody tr:first').children();
var theadColumns = $(theadCopy).find('thead tr').children();
var width;
$(theadColumns).each(function(i, v) {
width = Math.round($(tbodyColumns[i]).width());
if (i + 1 < $(theadColumns).length) {
$(v).width(width);
$(tbodyColumns[i]).width(width);
}
});
$(theadCopy).css('margin-bottom', '0');
$(theadCopy).css('border-bottom', '0');
}
function adjustTableFooterWidth() {
var tbodyColumns = $(mainTable).find('tbody tr:first').children();
var tfootColumns = $(tfootCopy).find('tfoot tr').children();
var width;
$(tfootColumns).each(function(i, v) {
width = Math.round($(tbodyColumns[i]).width());
if (i + 1 < $(tfootColumns).length) {
$(v).width(width);
$(tbodyColumns[i]).width(width);
}
});
$(mainTable).css('margin-bottom', '0');
$(mainTable).css('border-bottom', '0');
$(tfootCopy).css('border-top', '0');
}
// Adjust the width of thead cells when window resizes
$(window).resize(function() {
adjustTableHeaderWidth();
adjustTableFooterWidth();
}).resize(); // Trigger resize handler
}); //]]>
Problem is now, I'd like to migrate the code above for using it in a Marionette Backbone view, but can't do it, because I need widths to be got, in order to align the columns in the new tables created, but when I try doing it values are zero (0) in the render (onRender) function.
So, my question is: Is there any way for me to get the calculated CSS values, using Backbone, similar to what I have done above?
Solved the problem by adding a script tag inside the $el, forcing it to be executed after the view has been displayed, so the CSS is calculated already:
onShow : function () {
this.$el.append('<script>require(["table_fixedheader"], function () {jq.detachTableHeaderAndFooter();});');
}
Note script tag has not been closed. Did it intentionally as the framework is going to take care of closing it. Otherwise, it does not work as expected.