forked from fanruan/fineui
366 lines
13 KiB
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); |