bootstrap-table-fixed-columns.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /**
  2. * 基于bootstrap-table-fixed-columns修改
  3. * 支持左右列冻结
  4. * Copyright (c) 2019 ruoyi
  5. */
  6. (function ($) {
  7. 'use strict';
  8. $.extend($.fn.bootstrapTable.defaults, {
  9. fixedColumns: false,
  10. fixedNumber: 1,
  11. rightFixedColumns: false,
  12. rightFixedNumber: 1
  13. });
  14. var BootstrapTable = $.fn.bootstrapTable.Constructor,
  15. _initHeader = BootstrapTable.prototype.initHeader,
  16. _initBody = BootstrapTable.prototype.initBody,
  17. _resetView = BootstrapTable.prototype.resetView;
  18. BootstrapTable.prototype.initFixedColumns = function () {
  19. this.timeoutHeaderColumns_ = 0;
  20. this.timeoutBodyColumns_ = 0;
  21. if (this.options.fixedColumns) {
  22. this.$fixedBody = $([
  23. '<div class="left-fixed-table-columns">',
  24. '<table>',
  25. '<thead></thead>',
  26. '<tbody></tbody>',
  27. '</table>',
  28. '</div>'].join(''));
  29. this.$fixedBody.find('table').attr('class', this.$el.attr('class'));
  30. this.$fixedHeaderColumns = this.$fixedBody.find('thead');
  31. this.$fixedBodyColumns = this.$fixedBody.find('tbody');
  32. this.$tableBody.before(this.$fixedBody);
  33. }
  34. if (this.options.rightFixedColumns) {
  35. this.$rightfixedBody = $([
  36. '<div class="right-fixed-table-columns">',
  37. '<table>',
  38. '<thead></thead>',
  39. '<tbody style="background-color: #fff;"></tbody>',
  40. '</table>',
  41. '</div>'].join(''));
  42. this.$rightfixedBody.find('table').attr('class', this.$el.attr('class'));
  43. this.$rightfixedHeaderColumns = this.$rightfixedBody.find('thead');
  44. this.$rightfixedBodyColumns = this.$rightfixedBody.find('tbody');
  45. this.$tableBody.before(this.$rightfixedBody);
  46. if (this.options.fixedColumns) {
  47. $('.right-fixed-table-columns').attr('style','right:0px');
  48. }
  49. }
  50. };
  51. BootstrapTable.prototype.initHeader = function () {
  52. _initHeader.apply(this, Array.prototype.slice.apply(arguments));
  53. if (!this.options.fixedColumns && !this.options.rightFixedColumns){
  54. return;
  55. }
  56. this.initFixedColumns();
  57. var $ltr = this.$header.find('tr:eq(0)').clone(true),
  58. $rtr = this.$header.find('tr:eq(0)').clone(),
  59. $lths = $ltr.clone(true).find('th'),
  60. $rths = $rtr.clone().find('th');
  61. $ltr.html('');
  62. $rtr.html('');
  63. //右边列冻结
  64. if (this.options.rightFixedColumns) {
  65. for (var i = 0; i < this.options.rightFixedNumber; i++) {
  66. $rtr.append($rths.eq($rths.length - this.options.rightFixedNumber + i).clone());
  67. }
  68. this.$rightfixedHeaderColumns.html('').append($rtr);
  69. }
  70. //左边列冻结
  71. if (this.options.fixedColumns) {
  72. for (var i = 0; i < this.options.fixedNumber; i++) {
  73. $ltr.append($lths.eq(i).clone(true));
  74. }
  75. this.$fixedHeaderColumns.html('').append($ltr);
  76. this.$selectAll = $ltr.find('[name="btSelectAll"]');
  77. this.$selectAll.on('click', function () {
  78. var checked = $(this).prop('checked');
  79. $(".left-fixed-table-columns input[name=btSelectItem]").filter(':enabled').prop('checked', checked);
  80. });
  81. }
  82. };
  83. BootstrapTable.prototype.initBody = function () {
  84. _initBody.apply(this, Array.prototype.slice.apply(arguments));
  85. if (!this.options.fixedColumns && !this.options.rightFixedColumns) {
  86. return;
  87. }
  88. var that = this;
  89. if (this.options.fixedColumns) {
  90. this.$fixedBodyColumns.html('');
  91. this.$body.find('> tr[data-index]').each(function () {
  92. var $tr = $(this).clone(true),
  93. $tds = $tr.clone(true).find('td');
  94. $tr.html('');
  95. for (var i = 0; i < that.options.fixedNumber; i++) {
  96. $tr.append($tds.eq(i).clone(true));
  97. }
  98. that.$fixedBodyColumns.append($tr);
  99. });
  100. }
  101. if (this.options.rightFixedColumns) {
  102. this.$rightfixedBodyColumns.html('');
  103. this.$body.find('> tr[data-index]').each(function () {
  104. var $tr = $(this).clone(),
  105. $tds = $tr.clone().find('td');
  106. $tr.html('');
  107. for (var i = 0; i < that.options.rightFixedNumber; i++) {
  108. var indexTd = $tds.length - that.options.rightFixedNumber + i;
  109. var oldTd = $tds.eq(indexTd);
  110. var fixTd = oldTd.clone();
  111. var buttons = fixTd.find('button');
  112. //事件转移:冻结列里面的事件转移到实际按钮的事件
  113. buttons.each(function (key, item) {
  114. $(item).click(function () {
  115. that.$body.find("tr[data-index=" + $tr.attr('data-index') + "] td:eq(" + indexTd + ") button:eq(" + key + ")").click();
  116. });
  117. });
  118. $tr.append(fixTd);
  119. }
  120. that.$rightfixedBodyColumns.append($tr);
  121. });
  122. }
  123. };
  124. BootstrapTable.prototype.resetView = function () {
  125. _resetView.apply(this, Array.prototype.slice.apply(arguments));
  126. if (!this.options.fixedColumns && !this.options.rightFixedColumns) {
  127. return;
  128. }
  129. clearTimeout(this.timeoutHeaderColumns_);
  130. this.timeoutHeaderColumns_ = setTimeout($.proxy(this.fitHeaderColumns, this), this.$el.is(':hidden') ? 100 : 0);
  131. clearTimeout(this.timeoutBodyColumns_);
  132. this.timeoutBodyColumns_ = setTimeout($.proxy(this.fitBodyColumns, this), this.$el.is(':hidden') ? 100 : 0);
  133. };
  134. BootstrapTable.prototype.fitHeaderColumns = function () {
  135. var that = this,
  136. visibleFields = this.getVisibleFields(),
  137. headerWidth = 0;
  138. if (that.options.fixedColumns) {
  139. this.$body.find('tr:first-child:not(.no-records-found) > *').each(function (i) {
  140. var $this = $(this),
  141. index = i;
  142. if (i >= that.options.fixedNumber) {
  143. return false;
  144. }
  145. if (that.options.detailView && !that.options.cardView) {
  146. index = i - 1;
  147. }
  148. that.$fixedBody.find('thead th[data-field="' + visibleFields[index] + '"]')
  149. .find('.fht-cell').width($this.innerWidth() - 1);
  150. headerWidth += $this.outerWidth();
  151. });
  152. this.$fixedBody.width(headerWidth - 1).show();
  153. }
  154. if (that.options.rightFixedColumns) {
  155. this.$body.find('tr:first-child:not(.no-records-found) > *').each(function (i) {
  156. var $this = $(this),
  157. index = i;
  158. if (i >= visibleFields.length - that.options.rightFixedNumber) {
  159. return false;
  160. if (that.options.detailView && !that.options.cardView) {
  161. index = i - 1;
  162. }
  163. that.$rightfixedBody.find('thead th[data-field="' + visibleFields[index] + '"]')
  164. .find('.fht-cell').width($this.innerWidth() - 1);
  165. headerWidth += $this.outerWidth();
  166. }
  167. });
  168. this.$rightfixedBody.width(headerWidth - 1).show();
  169. }
  170. };
  171. BootstrapTable.prototype.fitBodyColumns = function () {
  172. var that = this,
  173. top = -(parseInt(this.$el.css('margin-top')) - 2),
  174. height = this.$tableBody.height() - 2;
  175. if (that.options.fixedColumns) {
  176. if (!this.$body.find('> tr[data-index]').length) {
  177. this.$fixedBody.hide();
  178. return;
  179. }
  180. this.$body.find('> tr').each(function (i) {
  181. that.$fixedBody.find('tbody tr:eq(' + i + ')').height($(this).height());
  182. });
  183. $("#" + $.table._option.id).on("check.bs.table uncheck.bs.table", function (e, rows, $element) {
  184. var index= $element.data('index');
  185. $(this).find('.bs-checkbox').find('input[data-index="' + index + '"]').prop("checked", true);
  186. var selectFixedItem = $('.left-fixed-table-columns input[name=btSelectItem]');
  187. var checkAll = selectFixedItem.filter(':enabled').length &&
  188. selectFixedItem.filter(':enabled').length ===
  189. selectFixedItem.filter(':enabled').filter(':checked').length;
  190. $(".left-fixed-table-columns input[name=btSelectAll]").prop('checked', checkAll);
  191. });
  192. //// events
  193. this.$tableBody.on('scroll', function () {
  194. that.$fixedBody.find('table').css('top', -$(this).scrollTop());
  195. });
  196. this.$body.find('> tr[data-index]').off('hover').hover(function () {
  197. var index = $(this).data('index');
  198. that.$fixedBody.find('tr[data-index="' + index + '"]').addClass('hover');
  199. }, function () {
  200. var index = $(this).data('index');
  201. that.$fixedBody.find('tr[data-index="' + index + '"]').removeClass('hover');
  202. });
  203. this.$fixedBody.find('tr[data-index]').off('hover').hover(function () {
  204. var index = $(this).data('index');
  205. that.$body.find('tr[data-index="' + index + '"]').addClass('hover');
  206. }, function () {
  207. var index = $(this).data('index');
  208. that.$body.find('> tr[data-index="' + index + '"]').removeClass('hover');
  209. });
  210. }
  211. if (that.options.rightFixedColumns) {
  212. if (!this.$body.find('> tr[data-index]').length) {
  213. this.$rightfixedBody.hide();
  214. return;
  215. }
  216. this.$body.find('> tr').each(function (i) {
  217. that.$rightfixedBody.find('tbody tr:eq(' + i + ')').height($(this).height());
  218. });
  219. //// events
  220. this.$tableBody.on('scroll', function () {
  221. that.$rightfixedBody.find('table').css('top', -$(this).scrollTop());
  222. });
  223. this.$body.find('> tr[data-index]').off('hover').hover(function () {
  224. var index = $(this).data('index');
  225. that.$rightfixedBody.find('tr[data-index="' + index + '"]').addClass('hover');
  226. }, function () {
  227. var index = $(this).data('index');
  228. that.$rightfixedBody.find('tr[data-index="' + index + '"]').removeClass('hover');
  229. });
  230. this.$rightfixedBody.find('tr[data-index]').off('hover').hover(function () {
  231. var index = $(this).data('index');
  232. that.$body.find('tr[data-index="' + index + '"]').addClass('hover');
  233. }, function () {
  234. var index = $(this).data('index');
  235. that.$body.find('> tr[data-index="' + index + '"]').removeClass('hover');
  236. });
  237. }
  238. };
  239. })(jQuery);