1window.tablelayout = window.tablelayout || {}; 2 3(function (exports) { 4 'use strict'; 5 var atomicrowIndex = null; 6 exports.getNumberOfTableCols = function ($table) { 7 var $rows = $table.find('tr'); 8 var max = 0; 9 $rows.each(function (index, row) { 10 if (max < row.cells.length) { 11 max = row.cells.length; 12 atomicrowIndex = index; 13 } 14 }); 15 return max; 16 }; 17 18 exports.floatTable = function ($table, direction) { 19 if ($table.width() > jQuery('div.page').width()) { 20 return; 21 } 22 var $parentDiv = $table.closest('div.table'); 23 var $elements = jQuery([]); 24 $elements = $elements.add($parentDiv.prev('div.plugin_tablelayout_placeholder')); 25 $elements = $elements.add($parentDiv); 26 $elements = $elements.add($parentDiv.next('div.secedit.editbutton_table')); 27 $elements.wrapAll('<div class="floatwrapper">'); 28 $elements.parent('div.floatwrapper').addClass(direction); 29 }; 30 31 exports.applyStylesToTable = function ($table, layoutdata) { 32 if (!layoutdata.colwidth) { 33 layoutdata.colwidth = []; 34 } 35 exports.styleColumnWidths($table, layoutdata.colwidth); 36 exports.fixColumnWidths($table); 37 if (layoutdata.rowsHeader > 0 && layoutdata.rowsVisible > 0) { 38 exports.freezeTableRows($table, layoutdata.rowsHeader, layoutdata.rowsVisible); 39 } 40 if (layoutdata.float === 'right' || layoutdata.float === 'left' || layoutdata.float === 'center') { 41 exports.floatTable($table, layoutdata.float); 42 } 43 }; 44 45 exports.fixColumnWidths = function ($table) { 46 var $cols = $table.find('colgroup col'); 47 var $atomicrow = $table.find('.row' + atomicrowIndex); 48 $cols.each(function (index, col) { 49 var width = $atomicrow['0'].cells.item(index).offsetWidth; 50 if (!col.style.width) { 51 jQuery(col).css('width', width); 52 } 53 }); 54 $table.addClass('widthsfixed'); 55 }; 56 57 exports.styleColumnWidths = function ($table, colwidths) { 58 var numCols = exports.getNumberOfTableCols($table); 59 var $colgroup = jQuery('<colgroup>'); 60 for (var i = 0; i < numCols; i += 1) { 61 var $col = jQuery('<col>'); 62 if (colwidths[i]) { 63 $col.css('width', colwidths[i]); 64 } 65 $colgroup.append($col); 66 } 67 $table.prepend($colgroup); 68 69 if (colwidths.length === numCols) { 70 // todo: should we throw an error if there are MORE widths defined than cols in the table? 71 $table.addClass('flexiblewidth'); 72 } 73 }; 74 75 exports.freezeTableRows = function ($table, rowsToFreeze, rowsVisible) { 76 rowsToFreeze = parseInt(rowsToFreeze); 77 rowsVisible = parseInt(rowsVisible); 78 if ($table.find('tr').length <= rowsToFreeze + rowsVisible) { 79 return; 80 } 81 var tableWidth = $table.width(); 82 var $frozenTable = $table.clone(); 83 $table.addClass('tablelayout_body'); 84 $frozenTable.addClass('tablelayout_head'); 85 var $frozenRows = $frozenTable.find('tr'); 86 for (var i = $table.find('tr').length - 1; i >= rowsToFreeze; i -= 1) { 87 jQuery($frozenRows[i]).remove(); 88 } 89 if (!$frozenTable.find('tbody').children().length) { 90 $frozenTable.find('tbody').remove(); 91 } 92 var $tableRows = $table.find('tr'); 93 for (i = 0; i < rowsToFreeze; i += 1) { 94 jQuery($tableRows[i]).remove(); 95 } 96 $frozenTable.append($table.find('.searchSortRow')); 97 if (!$table.find('thead').children().length) { 98 $table.find('thead').remove(); 99 } 100 $table.parent().prepend($frozenTable); 101 // move search above the table header 102 if ($table.parent().hasClass('hasSearch')) { 103 $table.parent().prepend($table.parent().find('.globalSearch')); 104 } 105 106 var SCROLLBAR_WIDTH = 17; 107 $frozenTable.wrap(jQuery('<div></div>').width(tableWidth + SCROLLBAR_WIDTH)); 108 var height = 0; 109 for (i = rowsToFreeze; i < rowsToFreeze + rowsVisible; i += 1) { 110 height += jQuery($tableRows[i]).height(); 111 } 112 var tableWrapper = jQuery('<div></div>').css({'overflow-y': 'scroll'}).height(height).width(tableWidth + SCROLLBAR_WIDTH); 113 $table.wrap(tableWrapper); 114 }; 115 116 exports.initLayout = function (json) { 117 var layout = {}; 118 if (json) { 119 layout = JSON.parse(json); 120 } 121 122 if (typeof layout.colwidth === 'undefined') { 123 layout.colwidth = []; 124 } 125 return layout; 126 }; 127 128 exports.sortTable = function ($tableRows, sortColumnIndex, order) { 129 var sortModifier = order === 'asc' ? 1 : -1; 130 var compare = function compare(rowA, rowB) { 131 var tda = jQuery(rowA).find('td,th').eq(sortColumnIndex).text().toLowerCase(); 132 var tdb = jQuery(rowB).find('td,th').eq(sortColumnIndex).text().toLowerCase(); 133 if (tda < tdb) { 134 return -1 * sortModifier; 135 } 136 137 if (tda > tdb) { 138 return sortModifier; 139 } 140 141 return 0; 142 }; 143 return $tableRows.sort(compare); 144 }; 145 146 /** 147 * split all rowspans and colspans in a continuous set of table rows and multiply the content for all rows 148 * 149 * Please note that this functions modifies the argument as well. 150 * 151 * @param {jQuery[]} $tableRows jQuery set of continuoues table rows 152 * 153 * @return {jQuery[]} the adjust array of rows 154 */ 155 exports.splitMerges = function splitMerges($tableRows) { 156 var $splitRows = $tableRows; 157 $splitRows.find('td[colspan],th[colspan]').each(function (index, cell) { 158 var $cell = jQuery(cell); 159 var colspan = $cell.attr('colspan') - 1; 160 $cell.removeAttr('colspan'); 161 for (var i = 0; i < colspan; i += 1) { 162 $cell.after($cell.clone(true, true)); 163 } 164 }); 165 $splitRows.find('td[rowspan],th[rowspan]').each(function (index, cell) { 166 var $cell = jQuery(cell); 167 var rowspan = $cell.attr('rowspan') - 1; 168 $cell.removeAttr('rowspan'); 169 var colIndex = 0; 170 $cell.prevAll('td,th').each(function () { 171 colIndex += this.colSpan; 172 }); 173 for (var i = 0; i < rowspan; i += 1) { 174 var $rowMissingCell = $cell.closest('tr').nextAll().eq(i); 175 var $rowCells = $rowMissingCell.find('td,th'); 176 if ($rowCells.length === colIndex) { 177 $rowCells.last().after($cell.clone(true, true)); 178 } else { 179 $rowCells.eq(colIndex).before($cell.clone(true, true)); 180 } 181 } 182 }); 183 return $splitRows; 184 }; 185 186 return exports; 187}(window.tablelayout)); 188