fineui是帆软报表和BI产品线所使用的前端框架。
 
 
 

366 lines
13 KiB

/**
* 自适应宽度的表格
*
* Created by GUY on 2016/2/3.
* @class BI.ResponisveTable
* @extends BI.Widget
*/
BI.ResponisveTable = BI.inherit(BI.Widget, {
_const: {
perColumnSize: 100
},
_defaultConfig: function () {
return BI.extend(BI.ResponisveTable.superclass._defaultConfig.apply(this, arguments), {
baseCls: "bi-responsive-table",
isNeedFreeze: false, // 是否需要冻结单元格
freezeCols: [], // 冻结的列号,从0开始,isNeedFreeze为true时生效
logic: { // 冻结的页面布局逻辑
dynamic: false
},
isNeedMerge: false, // 是否需要合并单元格
mergeCols: [], // 合并的单元格列号
mergeRule: function (row1, row2) { // 合并规则, 默认相等时合并
return BI.isEqual(row1, row2);
},
columnSize: [],
headerRowSize: 25,
footerRowSize: 25,
rowSize: 25,
regionColumnSize: false,
header: [],
footer: false,
items: [], // 二维数组
// 交叉表头
crossHeader: [],
crossItems: []
});
},
_init: function () {
BI.ResponisveTable.superclass._init.apply(this, arguments);
var self = this, o = this.options;
this.table = BI.createWidget({
type: "bi.table_view",
element: this,
logic: o.logic,
isNeedFreeze: o.isNeedFreeze,
freezeCols: o.freezeCols,
isNeedMerge: o.isNeedMerge,
mergeCols: o.mergeCols,
mergeRule: o.mergeRule,
columnSize: o.columnSize,
headerRowSize: o.headerRowSize,
footerRowSize: o.footerRowSize,
rowSize: o.rowSize,
regionColumnSize: o.regionColumnSize,
header: o.header,
footer: o.footer,
items: o.items,
// 交叉表头
crossHeader: o.crossHeader,
crossItems: o.crossItems
});
this.table.on(BI.Table.EVENT_TABLE_AFTER_INIT, function () {
self._initRegionSize();
self.table.resize();
self._resizeHeader();
self.fireEvent(BI.Table.EVENT_TABLE_AFTER_INIT, arguments);
});
this.table.on(BI.Table.EVENT_TABLE_RESIZE, function () {
self._resizeRegion();
self._resizeHeader();
self.fireEvent(BI.Table.EVENT_TABLE_RESIZE, arguments);
});
this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () {
self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments);
});
this.table.on(BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE, function () {
self.fireEvent(BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE, arguments);
});
this.table.on(BI.Table.EVENT_TABLE_REGION_RESIZE, function () {
// important:在冻结并自适应列宽的情况下要随时变更表头宽度
if (o.isNeedResize === true && self._isAdaptiveColumn()) {
self._resizeHeader();
}
self.fireEvent(BI.Table.EVENT_TABLE_REGION_RESIZE, arguments);
});
this.table.on(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, function () {
self._resizeHeader();
self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, arguments);
});
this.table.on(BI.Table.EVENT_TABLE_BEFORE_COLUMN_RESIZE, function () {
self._resizeBody();
self.fireEvent(BI.Table.EVENT_TABLE_BEFORE_COLUMN_RESIZE, arguments);
});
this.table.on(BI.Table.EVENT_TABLE_COLUMN_RESIZE, function () {
self.fireEvent(BI.Table.EVENT_TABLE_COLUMN_RESIZE, arguments);
});
this.table.on(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, function () {
self._resizeRegion();
self._resizeHeader();
self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, arguments);
});
},
_initRegionSize: function () {
var o = this.options;
if (o.isNeedFreeze === true) {
var regionColumnSize = this.table.getRegionColumnSize();
var maxWidth = this.table.element.width();
if (!regionColumnSize[0] || (regionColumnSize[0] === "fill") || regionColumnSize[0] > maxWidth || regionColumnSize[1] > maxWidth) {
var freezeCols = o.freezeCols;
if (freezeCols.length === 0) {
this.table.setRegionColumnSize([0, "fill"]);
} else if (freezeCols.length > 0 && freezeCols.length < o.columnSize.length) {
var size = maxWidth / 3;
if (freezeCols.length > o.columnSize.length / 2) {
size = maxWidth * 2 / 3;
}
this.table.setRegionColumnSize([size, "fill"]);
} else {
this.table.setRegionColumnSize(["fill", 0]);
}
}
}
},
_getBlockSize: function () {
var o = this.options;
var columnSize = this.table.getCalculateColumnSize();
if (o.isNeedFreeze === true) {
var columnSizeLeft = [], columnSizeRight = [];
BI.each(columnSize, function (i, size) {
if (o.freezeCols.contains(i)) {
columnSizeLeft.push(size);
} else {
columnSizeRight.push(size);
}
});
// 因为有边框,所以加上数组长度的参数调整
var sumLeft = BI.sum(columnSizeLeft) + columnSizeLeft.length,
sumRight = BI.sum(columnSizeRight) + columnSizeRight.length;
return {
sumLeft: sumLeft,
sumRight: sumRight,
left: columnSizeLeft,
right: columnSizeRight
};
}
return {
size: columnSize,
sum: BI.sum(columnSize) + columnSize.length
};
},
_isAdaptiveColumn: function (columnSize) {
return !(BI.last(columnSize || this.table.getColumnSize()) > 1.05);
},
_resizeHeader: function () {
var self = this, o = this.options;
if (o.isNeedFreeze === true) {
// 若是当前处于自适应调节阶段
if (this._isAdaptiveColumn()) {
var columnSize = this.table.getCalculateColumnSize();
this.table.setHeaderColumnSize(columnSize);
} else {
var regionColumnSize = this.table.getClientRegionColumnSize();
var block = this._getBlockSize();
var sumLeft = block.sumLeft, sumRight = block.sumRight;
var columnSizeLeft = block.left, columnSizeRight = block.right;
columnSizeLeft[columnSizeLeft.length - 1] += regionColumnSize[0] - sumLeft;
columnSizeRight[columnSizeRight.length - 1] += regionColumnSize[1] - sumRight;
var newLeft = BI.clone(columnSizeLeft), newRight = BI.clone(columnSizeRight);
newLeft[newLeft.length - 1] = "";
newRight[newRight.length - 1] = "";
this.table.setColumnSize(newLeft.concat(newRight));
block = self._getBlockSize();
if (columnSizeLeft[columnSizeLeft.length - 1] < block.left[block.left.length - 1]) {
columnSizeLeft[columnSizeLeft.length - 1] = block.left[block.left.length - 1];
}
if (columnSizeRight[columnSizeRight.length - 1] < block.right[block.right.length - 1]) {
columnSizeRight[columnSizeRight.length - 1] = block.right[block.right.length - 1];
}
self.table.setColumnSize(columnSizeLeft.concat(columnSizeRight));
}
} else {
if (!this._isAdaptiveColumn()) {
var regionColumnSize = this.table.getClientRegionColumnSize();
var block = this._getBlockSize();
var sum = block.sum;
var size = block.size;
size[size.length - 1] += regionColumnSize[0] - sum;
var newSize = BI.clone(size);
newSize[newSize.length - 1] = "";
this.table.setColumnSize(newSize);
block = this._getBlockSize();
if (size[size.length - 1] < block.size[block.size.length - 1]) {
size[size.length - 1] = block.size[block.size.length - 1];
}
this.table.setColumnSize(size);
}
}
},
_resizeBody: function () {
if (this._isAdaptiveColumn()) {
var columnSize = this.table.getCalculateColumnSize();
this.setColumnSize(columnSize);
}
},
_adjustRegion: function () {
var o = this.options;
var regionColumnSize = this.table.getCalculateRegionColumnSize();
if (o.isNeedFreeze === true && o.freezeCols.length > 0 && o.freezeCols.length < o.columnSize.length) {
var block = this._getBlockSize();
var sumLeft = block.sumLeft, sumRight = block.sumRight;
if (sumLeft < regionColumnSize[0] || regionColumnSize[0] >= (sumLeft + sumRight)) {
this.table.setRegionColumnSize([sumLeft, "fill"]);
}
this._resizeRegion();
}
},
_resizeRegion: function () {
var o = this.options;
var regionColumnSize = this.table.getCalculateRegionColumnSize();
if (o.isNeedFreeze === true && o.freezeCols.length > 0 && o.freezeCols.length < o.columnSize.length) {
var maxWidth = this.table.element.width();
if (regionColumnSize[0] < 15 || regionColumnSize[1] < 15) {
var freezeCols = o.freezeCols;
var size = maxWidth / 3;
if (freezeCols.length > o.columnSize.length / 2) {
size = maxWidth * 2 / 3;
}
this.table.setRegionColumnSize([size, "fill"]);
}
}
},
resize: function () {
this.table.resize();
this._resizeRegion();
this._resizeHeader();
},
setColumnSize: function (columnSize) {
this.table.setColumnSize(columnSize);
this._adjustRegion();
this._resizeHeader();
},
getColumnSize: function () {
return this.table.getColumnSize();
},
getCalculateColumnSize: function () {
return this.table.getCalculateColumnSize();
},
setHeaderColumnSize: function (columnSize) {
this.table.setHeaderColumnSize(columnSize);
this._adjustRegion();
this._resizeHeader();
},
setRegionColumnSize: function (columnSize) {
this.table.setRegionColumnSize(columnSize);
this._resizeHeader();
},
getRegionColumnSize: function () {
return this.table.getRegionColumnSize();
},
getCalculateRegionColumnSize: function () {
return this.table.getCalculateRegionColumnSize();
},
getCalculateRegionRowSize: function () {
return this.table.getCalculateRegionRowSize();
},
getClientRegionColumnSize: function () {
return this.table.getClientRegionColumnSize();
},
getScrollRegionColumnSize: function () {
return this.table.getScrollRegionColumnSize();
},
getScrollRegionRowSize: function () {
return this.table.getScrollRegionRowSize();
},
hasVerticalScroll: function () {
return this.table.hasVerticalScroll();
},
setVerticalScroll: function (scrollTop) {
this.table.setVerticalScroll(scrollTop);
},
setLeftHorizontalScroll: function (scrollLeft) {
this.table.setLeftHorizontalScroll(scrollLeft);
},
setRightHorizontalScroll: function (scrollLeft) {
this.table.setRightHorizontalScroll(scrollLeft);
},
getVerticalScroll: function () {
return this.table.getVerticalScroll();
},
getLeftHorizontalScroll: function () {
return this.table.getLeftHorizontalScroll();
},
getRightHorizontalScroll: function () {
return this.table.getRightHorizontalScroll();
},
getColumns: function () {
return this.table.getColumns();
},
attr: function () {
BI.ResponisveTable.superclass.attr.apply(this, arguments);
this.table.attr.apply(this.table, arguments);
},
populate: function (items) {
var self = this, o = this.options;
this.table.populate.apply(this.table, arguments);
if (o.isNeedFreeze === true) {
BI.nextTick(function () {
self._initRegionSize();
self.table.resize();
self._resizeHeader();
});
}
}
});
BI.shortcut("bi.responsive_table", BI.ResponisveTable);