window.tablelayout = window.tablelayout || {}; (function (exports) { 'use strict'; var atomicrowIndex = null; exports.getNumberOfTableCols = function ($table) { var $rows = $table.find('tr'); var max = 0; $rows.each(function (index, row) { if (max < row.cells.length) { max = row.cells.length; atomicrowIndex = index; } }); return max; }; exports.floatTable = function ($table, direction) { if ($table.width() > jQuery('div.page').width()) { return; } var $parentDiv = $table.closest('div.table'); var $elements = jQuery([]); $elements = $elements.add($parentDiv.prev('div.plugin_tablelayout_placeholder')); $elements = $elements.add($parentDiv); $elements = $elements.add($parentDiv.next('div.secedit.editbutton_table')); $elements.wrapAll('
'); $elements.parent('div.floatwrapper').addClass(direction); }; exports.applyStylesToTable = function ($table, layoutdata) { if (!layoutdata.colwidth) { layoutdata.colwidth = []; } exports.styleColumnWidths($table, layoutdata.colwidth); exports.fixColumnWidths($table); if (layoutdata.rowsHeader > 0 && layoutdata.rowsVisible > 0) { exports.freezeTableRows($table, layoutdata.rowsHeader, layoutdata.rowsVisible); } if (layoutdata.float === 'right' || layoutdata.float === 'left' || layoutdata.float === 'center') { exports.floatTable($table, layoutdata.float); } }; exports.fixColumnWidths = function ($table) { var $cols = $table.find('colgroup col'); var $atomicrow = $table.find('.row' + atomicrowIndex); $cols.each(function (index, col) { var width = $atomicrow['0'].cells.item(index).offsetWidth; if (!col.style.width) { jQuery(col).css('width', width); } }); $table.addClass('widthsfixed'); }; exports.styleColumnWidths = function ($table, colwidths) { var numCols = exports.getNumberOfTableCols($table); var $colgroup = jQuery(''); for (var i = 0; i < numCols; i += 1) { var $col = jQuery(''); if (colwidths[i]) { $col.css('width', colwidths[i]); } $colgroup.append($col); } $table.prepend($colgroup); if (colwidths.length === numCols) { // todo: should we throw an error if there are MORE widths defined than cols in the table? $table.addClass('flexiblewidth'); } }; exports.freezeTableRows = function ($table, rowsToFreeze, rowsVisible) { rowsToFreeze = parseInt(rowsToFreeze); rowsVisible = parseInt(rowsVisible); if ($table.find('tr').length <= rowsToFreeze + rowsVisible) { return; } var tableWidth = $table.width(); var $frozenTable = $table.clone(); $table.addClass('tablelayout_body'); $frozenTable.addClass('tablelayout_head'); var $frozenRows = $frozenTable.find('tr'); for (var i = $table.find('tr').length - 1; i >= rowsToFreeze; i -= 1) { jQuery($frozenRows[i]).remove(); } if (!$frozenTable.find('tbody').children().length) { $frozenTable.find('tbody').remove(); } var $tableRows = $table.find('tr'); for (i = 0; i < rowsToFreeze; i += 1) { jQuery($tableRows[i]).remove(); } $frozenTable.append($table.find('.searchSortRow')); if (!$table.find('thead').children().length) { $table.find('thead').remove(); } $table.parent().prepend($frozenTable); // move search above the table header if ($table.parent().hasClass('hasSearch')) { $table.parent().prepend($table.parent().find('.globalSearch')); } var SCROLLBAR_WIDTH = 17; $frozenTable.wrap(jQuery('
').width(tableWidth + SCROLLBAR_WIDTH)); var height = 0; for (i = rowsToFreeze; i < rowsToFreeze + rowsVisible; i += 1) { height += jQuery($tableRows[i]).height(); } var tableWrapper = jQuery('
').css({'overflow-y': 'scroll'}).height(height).width(tableWidth + SCROLLBAR_WIDTH); $table.wrap(tableWrapper); }; exports.initLayout = function (json) { var layout = {}; if (json) { layout = JSON.parse(json); } if (typeof layout.colwidth === 'undefined') { layout.colwidth = []; } return layout; }; exports.sortTable = function ($tableRows, sortColumnIndex, order) { var sortModifier = order === 'asc' ? 1 : -1; var compare = function compare(rowA, rowB) { var tda = jQuery(rowA).find('td,th').eq(sortColumnIndex).text().toLowerCase(); var tdb = jQuery(rowB).find('td,th').eq(sortColumnIndex).text().toLowerCase(); if (tda < tdb) { return -1 * sortModifier; } if (tda > tdb) { return sortModifier; } return 0; }; return $tableRows.sort(compare); }; /** * split all rowspans and colspans in a continuous set of table rows and multiply the content for all rows * * Please note that this functions modifies the argument as well. * * @param {jQuery[]} $tableRows jQuery set of continuoues table rows * * @return {jQuery[]} the adjust array of rows */ exports.splitMerges = function splitMerges($tableRows) { var $splitRows = $tableRows; $splitRows.find('td[colspan],th[colspan]').each(function (index, cell) { var $cell = jQuery(cell); var colspan = $cell.attr('colspan') - 1; $cell.removeAttr('colspan'); for (var i = 0; i < colspan; i += 1) { $cell.after($cell.clone(true, true)); } }); $splitRows.find('td[rowspan],th[rowspan]').each(function (index, cell) { var $cell = jQuery(cell); var rowspan = $cell.attr('rowspan') - 1; $cell.removeAttr('rowspan'); var colIndex = 0; $cell.prevAll('td,th').each(function () { colIndex += this.colSpan; }); for (var i = 0; i < rowspan; i += 1) { var $rowMissingCell = $cell.closest('tr').nextAll().eq(i); var $rowCells = $rowMissingCell.find('td,th'); if ($rowCells.length === colIndex) { $rowCells.last().after($cell.clone(true, true)); } else { $rowCells.eq(colIndex).before($cell.clone(true, true)); } } }); return $splitRows; }; return exports; }(window.tablelayout));