分享基于bootstrap table的左右固定列实现方法

分享 未结 精帖 1 1536
戰士小豬
戰士小豬 VIP2 2018-07-30 08:36:38
收藏
首先引入bootstrap-table-fixed-columns.js 和 bootstrap-table-fixed-columns.css (已完美修复过) bootstrap-table-fixed-columns.js 内容如下,因为过长,分为两段: [pre] (function ($) { 'use strict'; $.extend($.fn.bootstrapTable.defaults, { leftFixedColumns: false, leftFixedNumber: 1, rightFixedColumns: false, rightFixedNumber: 1 }); var BootstrapTable = $.fn.bootstrapTable.Constructor, _initHeader = BootstrapTable.prototype.initHeader, _initBody = BootstrapTable.prototype.initBody, _resetView = BootstrapTable.prototype.resetView; BootstrapTable.prototype.initFixedColumns = function () { if(this.options.leftFixedColumns){ this.$fixedHeader = $([ '<div class="fixed-table-header-columns">', '<table>', '<thead></thead>', '</table>', '</div>'].join('')); this.timeoutHeaderColumns_ = 0; this.$fixedHeader.find('table').attr('class', this.$el.attr('class')); this.$fixedHeaderColumns = this.$fixedHeader.find('thead'); this.$tableHeader.before(this.$fixedHeader); this.$fixedBody = $([ '<div class="fixed-table-body-columns">', '<table>', '<tbody></tbody>', '</table>', '</div>'].join('')); this.timeoutBodyColumns_ = 0; this.$fixedBody.find('table').attr('class', this.$el.attr('class')); this.$fixedBodyColumns = this.$fixedBody.find('tbody'); this.$tableBody.before(this.$fixedBody); } if(this.options.rightFixedColumns){ if(typeof (this.options.height)!=='undefined'){ this.$rightFixedHeader = $([ '<div class="fixed-table-header-columns" style="position: absolute;right:17px;">', '<table>', '<thead></thead>', '</table>', '</div>'].join('')); }else{ this.$rightFixedHeader = $([ '<div class="fixed-table-header-columns" style="position: absolute;right:0px;">', '<table>', '<thead></thead>', '</table>', '</div>'].join('')); } this.timeoutHeaderColumns_ = 0; this.$rightFixedHeader.find('table').attr('class', this.$el.attr('class')); this.$rightFixedHeaderColumns = this.$rightFixedHeader.find('thead'); this.$tableHeader.before(this.$rightFixedHeader); if(typeof (this.options.height)!=='undefined'){ this.$rightFixedBody = $([ '<div class="fixed-table-body-columns" style="position: absolute;right:17px;">', '<table>', '<tbody></tbody>', '</table>', '</div>'].join('')); }else{ this.$rightFixedBody = $([ '<div class="fixed-table-body-columns" style="position: absolute;right:0px;">', '<table>', '<tbody></tbody>', '</table>', '</div>'].join('')); } this.timeoutBodyColumns_ = 0; this.$rightFixedBody.find('table').attr('class', this.$el.attr('class')); this.$rightFixedBodyColumns = this.$rightFixedBody.find('tbody'); this.$tableBody.before(this.$rightFixedBody); } }; BootstrapTable.prototype.initHeader = function () { _initHeader.apply(this, Array.prototype.slice.apply(arguments)); if (!this.options.leftFixedColumns && !this.options.rightFixedColumns) { return; } this.initFixedColumns(); if(this.options.leftFixedColumns){ var that = this, $trs = this.$header.find('tr').clone(); $trs.each(function () { $(this).find('th:gt(' + (that.options.leftFixedNumber-1) + ')').remove(); }); this.$fixedHeaderColumns.html('').append($trs); } if(this.options.rightFixedColumns){ var $trTemp = this.$header.find('tr:eq(0)').clone(), $thsTemp = $trTemp.clone().find('th'); var that = this, $trs = this.$header.find('tr').clone(); $trs.each(function () { $(this).find('th:lt(' + ($thsTemp.length-that.options.leftFixedNumber) + ')').remove(); }); this.$rightFixedHeaderColumns.html('').append($trs); } }; BootstrapTable.prototype.initBody = function () { _initBody.apply(this, Array.prototype.slice.apply(arguments)); if (!this.options.leftFixedColumns && !this.options.rightFixedColumns) { return; } if(this.options.leftFixedColumns){ var that = this, rowspan = 0; this.$fixedBodyColumns.html(''); this.$body.find('> tr[data-index]').each(function () { var $tr = $(this).clone(), $tds = $tr.find('td'); $tr.html(''); var end = that.options.leftFixedNumber; if (rowspan > 0) { --end; --rowspan; } for (var i = 0; i < end; i++) { $tr.append($tds.eq(i).clone()); } that.$fixedBodyColumns.append($tr); if ($tds.eq(0).attr('rowspan')){ rowspan = $tds.eq(0).attr('rowspan') - 1; } }); } if(this.options.rightFixedColumns){ var that = this, rowspan = 0; this.$rightFixedBodyColumns.html(''); this.$body.find('> tr[data-index]').each(function () { var $tr = $(this).clone(), $tds = $tr.find('td'); $tr.html(''); var end = that.options.rightFixedNumber; if (rowspan > 0) { --end; --rowspan; } for (var i = 0; i < end; i++) { var indexTd = $tds.length - that.options.rightFixedNumber + i; var oldTd = $tds.eq(indexTd); var fixTd = oldTd.clone(); var buttons = fixTd.find('button'); //事件转移:冻结列里面的事件转移到实际按钮的事件 buttons.each(function (key, item) { $(item).click(function () { that.$body.find("tr[data-index=" + $tr.attr('data-index') + "] td:eq(" + indexTd + ") button:eq(" + key + ")").click(); }); }); $tr.append(fixTd); } that.$rightFixedBodyColumns.append($tr); if ($tds.eq(0).attr('rowspan')){ rowspan = $tds.eq(0).attr('rowspan') - 1; } }); } }; BootstrapTable.prototype.resetView = function () { _resetView.apply(this, Array.prototype.slice.apply(arguments)); if (!this.options.leftFixedColumns && !this.options.rightFixedColumns) { return; } clearTimeout(this.timeoutHeaderColumns_); this.timeoutHeaderColumns_ = setTimeout($.proxy(this.fitHeaderColumns, this), this.$el.is(':hidden') ? 100 : 0); clearTimeout(this.timeoutBodyColumns_); this.timeoutBodyColumns_ = setTimeout($.proxy(this.fitBodyColumns, this), this.$el.is(':hidden') ? 100 : 0); }; BootstrapTable.prototype.fitHeaderColumns = function () { var that = this, visibleFields = this.getVisibleFields(), headerWidth = 0; if (that.options.leftFixedColumns) { this.$body.find('tr:first-child:not(.no-records-found) > *').each(function (i) { var $this = $(this), index = i; if (i >= that.options.leftFixedNumber) { return false; } if (that.options.detailView && !that.options.cardView) { index = i - 1; } that.$fixedHeader.find('th[data-field="' + visibleFields[index] + '"]') .find('.fht-cell').width($this.innerWidth()); headerWidth += $this.outerWidth(); }); this.$fixedHeader.width(headerWidth + 1).show(); } if (that.options.rightFixedColumns) { var that = this, visibleFields = this.getVisibleFields(), headerWidth = 0; this.$body.find('tr:first-child:not(.no-records-found) > *').each(function (i) { var $this = $(this), index = i; if (i >= visibleFields.length - that.options.rightFixedNumber) { if (that.options.detailView && !that.options.cardView) { index = i - 1; } that.$rightFixedHeader.find('th[data-field="' + visibleFields[index] + '"]') .find('.fht-cell').width($this.innerWidth()); headerWidth += $this.outerWidth(); } }); this.$rightFixedHeader.width(headerWidth - 1).show(); }; }; [/pre] [pre] BootstrapTable.prototype.fitBodyColumns = function () { var that = this, top = -(parseInt(this.$el.css('margin-top')) - 2); // the fixed height should reduce the scorll-x height if(that.options.leftFixedColumns){ if(this.$tableBody[0].scrollWidth>this.$tableBody.width()){ var height = this.$tableBody.height() - 17; }else{ var height = this.$tableBody.height(); }; if (!this.$body.find('> tr[data-index]').length) { this.$fixedBody.hide(); return; } if (!this.options.height) { top = this.$fixedHeader.height(); height = height - top; } this.$fixedBody.css({ width: this.$fixedHeader.width(), height: height, top: top }).show(); this.$body.find('> tr').each(function (i) { that.$fixedBody.find('tr:eq(' + i + ')').height($(this).height()); }); // events this.$tableBody.on('scroll', function () { that.$fixedBody.find('table').css('top', -$(this).scrollTop()); }); this.$body.find('> tr[data-index]').off('hover').hover(function () { var index = $(this).data('index'); that.$fixedBody.find('tr[data-index="' + index + '"]').addClass('hover'); }, function () { var index = $(this).data('index'); that.$fixedBody.find('tr[data-index="' + index + '"]').removeClass('hover'); }); this.$fixedBody.find('tr[data-index]').off('hover').hover(function () { var index = $(this).data('index'); that.$body.find('tr[data-index="' + index + '"]').addClass('hover'); }, function () { var index = $(this).data('index'); that.$body.find('> tr[data-index="' + index + '"]').removeClass('hover'); }); }; console.log(this.$tableBody); if(that.options.rightFixedColumns){ if(this.$tableBody[0].scrollWidth>this.$tableBody.width()){ var height = this.$tableBody.height() - 17; }else{ var height = this.$tableBody.height(); }; if (!this.$body.find('> tr[data-index]').length) { this.$rightFixedBody.hide(); return; } if (!this.options.height) { top = this.$rightFixedHeader.height() height = height - top; } this.$rightFixedBody.css({ width: this.$rightFixedHeader.width(), height: height, top: top }).show(); this.$body.find('> tr').each(function (i) { that.$rightFixedBody.find('tr:eq(' + i + ')').height($(this).height()); }); // events this.$tableBody.on('scroll', function () { that.$rightFixedBody.find('table').css('top', -$(this).scrollTop()); }); this.$body.find('> tr[data-index]').off('hover').hover(function () { var index = $(this).data('index'); that.$rightFixedBody.find('tr[data-index="' + index + '"]').addClass('hover'); }, function () { var index = $(this).data('index'); that.$rightFixedBody.find('tr[data-index="' + index + '"]').removeClass('hover'); }); this.$rightFixedBody.find('tr[data-index]').off('hover').hover(function () { var index = $(this).data('index'); that.$body.find('tr[data-index="' + index + '"]').addClass('hover'); }, function () { var index = $(this).data('index'); that.$body.find('> tr[data-index="' + index + '"]').removeClass('hover'); }); }; }; })(jQuery); [/pre] bootstrap-table-fixed-columns.css 内容如下: [pre] .fixed-table-header-columns, .fixed-table-body-columns { position: absolute; background-color: #fff; display: none; box-sizing: border-box; overflow: hidden; box-shadow:-3px 0px 3px #ddd; } .fixed-table-header-columns .table>thead>tr>th { border-bottom:0px solid #ddd;!important; } .fixed-table-header-columns .table>thead>tr>th > div, .fixed-table-body-columns .table > thead > tr > th > div{ margin-top:1px!important; } .fixed-table-header-columns .table, .fixed-table-body-columns .table { <!-- border-right: 1px solid #ddd; border-bottom: 0px;--> } .fixed-table-header-columns .table.table-no-bordered, .fixed-table-body-columns .table.table-no-bordered { border-right: 1px solid transparent; } .fixed-table-body-columns table { position: absolute; animation: none; } .bootstrap-table .table-hover > tbody > tr.hover > td { background-color: #f5f5f5; } .table > caption + thead > tr:first-child > th, .table > colgroup + thead > tr:first-child > th, .table > thead:first-child > tr:first-child > th, .table > caption + thead > tr:first-child > td, .table > colgroup + thead > tr:first-child > td, .table > thead:first-child > tr:first-child > td{ border-top:1px solid #ddd;!important; } [/pre] 在bootstrap 初始化的时候加入 [pre] leftFixedColumns: true, //左侧冻结列 leftFixedNumber: 1, rightFixedColumns: true, //右侧冻结列 rightFixedNumber: 1, [/pre] 为了高度实现自动跟随bootstrap 变化而变化 需要监控页面的大小变化,代码如下: [pre] $(window).resize(function () { $('#continuousAlarmTable').bootstrapTable('resetView');//请填入你页面对应的TABLE ID }); [/pre]
回帖