UNPKG

ecui

Version:

Enterprise Classic User Interface.

476 lines (422 loc) 16.6 kB
/* LockedTable - 定义允许左右锁定若干列显示的高级表格的基本操作。 允许锁定左右两列的高级表格控件,继承自表格控件,内部包含两个部件——锁定的表头区(基础控件)与锁定的行内容区(基础控件)。 锁定列高级表格控件直接HTML初始化的例子: <div ecui="type:locked-table;left-lock:2;right-lock:1"> <table> <!-- 当前节点的列定义,如果有特殊格式,需要使用width样式 --> <thead> <tr> <th>标题</th> ... </tr> </thead> <tbody> <!-- 这里放单元格序列 --> <tr> <td>单元格一</td> ... </tr> ... </tbody> </table> </div> 属性 _nLeft - 最左部未锁定列的序号 _nRight - 最右部未锁定列的后续序号,即未锁定的列序号+1 _aLockedRow - 用于显示锁定区域的行控件数组 _uLockedHead - 锁定的表头区 _uLockedMain - 锁定的行内容区 表格行与锁定行属性 _eFill - 用于控制中部宽度的单元格 */ //{if 0}// (function () { var core = ecui, array = core.array, dom = core.dom, ui = core.ui, util = core.util, MATH = Math, MAX = MATH.max, REGEXP = RegExp, USER_AGENT = navigator.userAgent, indexOf = array.indexOf, children = dom.children, createDom = dom.create, getParent = dom.getParent, getAttribute = dom.getAttribute, insertBefore = dom.insertBefore, removeDom = dom.remove, blank = util.blank, toNumber = util.toNumber, $fastCreate = core.$fastCreate, disposeControl = core.dispose, $bind = core.$bind, inheritsControl = core.inherits, firefoxVersion = /firefox\/(\d+\.\d)/i.test(USER_AGENT) ? REGEXP.$1 - 0 : undefined eventNames = [ 'mousedown', 'mouseover', 'mousemove', 'mouseout', 'mouseup', 'click', 'dblclick', 'focus', 'blur', 'activate', 'deactivate', 'keydown', 'keypress', 'keyup', 'mousewheel' ], UI_CONTROL = ui.Control, UI_CONTROL_CLASS = UI_CONTROL.prototype, UI_TABLE = ui.Table, UI_TABLE_CLASS = UI_TABLE.prototype, UI_TABLE_ROW = UI_TABLE_CLASS.Row, UI_TABLE_ROW_CLASS = UI_TABLE_ROW.prototype; //{/if}// //{if $phase == "define"}// /** * 初始化高级表格控件。 * options 对象支持的属性如下: * left-lock 左边需要锁定的列数 * right-lock 右边需要锁定的列数 * @public * * @param {Object} options 初始化选项 */ //__gzip_original__UI_LOCKED_TABLE //__gzip_original__UI_LOCKED_TABLE_ROW var UI_LOCKED_TABLE = ui.LockedTable = inheritsControl( UI_TABLE, '*locked-table', null, function (el, options) { var i = 0, type = this.getType(), headRows = this._aHeadRows, rows = headRows.concat(this._aRows), lockedEl = createDom('', 'position:absolute;top:0px;left:0px;overflow:hidden'), list = [], lockedRows = this._aLockedRow = [], lockedHeadRows = this._aLockedHeadRow = [], o; this._nLeft = options.leftLock || 0; this._nRight = this.getColumnCount() - (options.rightLock || 0); // 以下使用 options 代替 rows for (; el = rows[i]; ) { el = el.getMain(); list[i++] = '<tr class="' + el.className + '" style="' + el.style.cssText +'"><td style="padding:0px;border:0px"></td></tr>'; } lockedEl.innerHTML = '<div class="' + type + '-locked-head" style="position:absolute;top:0px;left:0px">' + '<div style="white-space:nowrap;position:absolute">' + '<table cellspacing="0">' + '<thead>' + list.splice(0, headRows.length).join('') + '</thead>' + '</table>' + '</div>' +'</div>' +'<div class="' + type + '-locked-layout" style="position:absolute;left:0px;overflow:hidden">' + '<div style="white-space:nowrap;position:absolute;top:0px;left:0px">' + '<table cellspacing="0">' + '<tbody>' + list.join('') + '</tbody>' + '</table>' + '</div>' + '</div>'; // 初始化锁定的表头区域,以下使用 list 表示临时变量 o = this._uLockedHead = $fastCreate(UI_CONTROL, lockedEl.firstChild, this); o.$setBody(el = o.getMain().lastChild.lastChild.firstChild); for (i = 0, list = children(el); o = list[i]; ) { lockedHeadRows[i] = UI_LOCKED_TABLE_CREATE_LOCKEDROW(o, headRows[i++]); } o = this._uLockedMain = $fastCreate(UI_CONTROL, el = lockedEl.lastChild, this); o.$setBody(el = el.lastChild); for (i = 0, list = children(el.lastChild.lastChild); o = list[i]; ) { lockedRows[i] = UI_LOCKED_TABLE_CREATE_LOCKEDROW(o, this._aRows[i++]); } insertBefore(lockedEl.firstChild, this._uHead.getOuter()); insertBefore(lockedEl.firstChild, getParent(this.getBody())); } ); UI_LOCKED_TABLE_CLASS = UI_LOCKED_TABLE.prototype, /** * 初始化高级表格控件的行部件。 * @public * * @param {Object} options 初始化选项 */ UI_LOCKED_TABLE_ROW_CLASS = (UI_LOCKED_TABLE_CLASS.Row = inheritsControl(UI_TABLE_CLASS.Row)).prototype; //{else}// /** * 建立锁定行控件。 * @private * * @param {HTMLElement} el 锁定行的 Element 元素 * @param {ecui.ui.Table.Row} row 表格基本行控件 */ function UI_LOCKED_TABLE_CREATE_LOCKEDROW(el, row) { $bind(el, row); row._eFill = el.lastChild; return row; } /** * 拆分行内的单元格到锁定列或基本列中。 * @private * * @param {ecui.ui.LockedTable.LockedHead|ecui.ui.LockedTable.LockedRow} locked 锁定表头控件或者锁定行控件 */ function UI_LOCKED_TABLE_ROW_SPLIT(locked) { var i = 0, table = locked.getParent(), cols = table.getHCells(), list = locked.$getElements(), baseBody = locked.getBody(), lockedBody = getParent(locked._eFill), el = lockedBody.firstChild, o; for (; cols[i]; ) { if (i == table._nLeft) { el = baseBody.firstChild; } if (o = list[i++]) { if (el != o) { (i <= table._nLeft || i > table._nRight ? lockedBody : baseBody).insertBefore(o, el); } else { el = el.nextSibling; } } if (i == table._nRight) { el = locked._eFill.nextSibling; } } } /** * 拆分所有行内的单元格到锁定列或基本列中。 * @private * * @param {ecui.ui.LockedTable} table 锁定式表格控件 */ function UI_LOCKED_TABLE_ALL_SPLIT(table) { for (var i = 0, o; o = table._aLockedHeadRow[i++]; ) { UI_LOCKED_TABLE_ROW_SPLIT(o); } for (var i = 0, o; o = table._aLockedRow[i++]; ) { UI_LOCKED_TABLE_ROW_SPLIT(o); } } /** * @override */ UI_LOCKED_TABLE_ROW_CLASS.$dispose = function () { this._eFill = null; UI_TABLE_ROW_CLASS.$dispose.call(this); }; /** * @override */ UI_LOCKED_TABLE_CLASS.$cache = function (style, cacheSize) { UI_TABLE_CLASS.$cache.call(this, style, cacheSize); var i = 0, rows = this.getRows(), cols = this.getHCells(), pos = cols[this._nLeft].$$pos; this.$$paddingTop = MAX(this.$$paddingTop, this._uLockedHead.getBody().offsetHeight); this.$$mainWidth -= (this.$$paddingLeft = pos) + (this.$$paddingRight = this._nRight < cols.length ? this.$$mainWidth - cols[this._nRight].$$pos : 0); // 以下使用 style 代替临时变量 o for (; style = cols[i++]; ) { style.$$pos -= pos; } for (i = 0, pos = 0; style = rows[i++]; ) { style.getCell(this._nLeft).cache(false, true); style.$$pos = pos; pos += MAX(style.getHeight(), style._eFill.offsetHeight); } if (pos) { this.$$mainHeight = pos; if (!this._bCreated) { this.$$mainHeight += this.$$paddingTop; } } this._uLockedHead.cache(false, true); this._uLockedMain.cache(false, true); }; /** * @override */ UI_LOCKED_TABLE_CLASS.$pagescroll = function () { UI_TABLE_CLASS.$pagescroll.call(this); if (!this._uVScrollbar) { this._uLockedHead.getOuter().style.top = this._uHead.getOuter().style.top } }; /** * @override */ UI_LOCKED_TABLE_CLASS.$resize = function () { var o = this.getMain().style; o.paddingLeft = o.paddingRight = ''; this.$$paddingLeft = this.$$paddingRight = 0; UI_TABLE_CLASS.$resize.call(this); }; /** * @override */ UI_LOCKED_TABLE_CLASS.$scroll = function () { UI_TABLE_CLASS.$scroll.call(this); this._uLockedMain.getBody().style.top = this.getBody().style.top; }; /** * @override */ UI_LOCKED_TABLE_CLASS.$setSize = function (width, height) { var o = this.getMain().style, i = 0, layout = getParent(this.getBody()), lockedHead = this._uLockedHead, lockedMain = this._uLockedMain, style = getParent(getParent(lockedHead.getBody())).style; o.paddingLeft = this.$$paddingLeft + 'px'; o.paddingRight = this.$$paddingRight + 'px'; UI_TABLE_CLASS.$setSize.call(this, width, height); o = this._uHead.getWidth() + this.$$paddingLeft + this.$$paddingRight; lockedHead.$setSize(o, this.$$paddingTop); style.height = this.$$paddingTop + 'px'; this._uLockedMain.$setSize(o, toNumber(layout.style.height)); try{ //@liuronghan style.width = this._uLockedMain.getBody().lastChild.style.width = o + 'px'; } catch (e) {} this._uLockedMain.getOuter().style.top = this.$$paddingTop + 'px'; width = layout.style.width; // 统一行高 // 分别设置表头与内容区域 var rows = this._aLockedHeadRow, minHeight; // 设置表头, 处理多行表头的问题 height = this.$$paddingTop / rows.length; for (i = 0; o = rows[i]; i++) { o._eFill.style.width = width; o._eFill.style.height = height + 'px'; o = o.getCell(this._nLeft); if (o) { minHeight = firefoxVersion ? 0 : o.$getBasicHeight(); //firefox 16版本出了问题 单独fix一下 by gengpeng if(firefoxVersion && firefoxVersion > 15) { minHeight = o.$getBasicHeight(); } o = o.getOuter(); style = getAttribute(o, 'rowSpan') || 0; if (style) { style = parseInt(style, 10); } if (!isNaN(minHeight)) { o.style.height = MAX(style * height - minHeight, 0) + 'px'; } } } // 设置表格内容行 rows = this._aLockedRow; for (i = 0; o = rows[i]; i++) { o._eFill.style.width = width; // o._eFill.className = this.getClass() + "-layout-main" style = MAX(height = o.getCell(this._nLeft).getOuter().offsetHeight, o._eFill.offsetHeight); if (style > o._eFill.offsetHeight) { o._eFill.style.height = style + 'px'; } else if (height < style) { minHeight = firefoxVersion ? 0 : o.getCell(this._nLeft).$getBasicHeight(); //firefox 16版本出了问题 单独fix一下 by gengpeng if(firefoxVersion && firefoxVersion > 15) { minHeight = o.getCell(this._nLeft).$getBasicHeight() } o.getCell(this._nLeft).getOuter().style.height = MAX(style - minHeight, 0) + 'px'; } } }; /** * @override */ UI_LOCKED_TABLE_CLASS.addColumn = function (options, index) { if (index >= 0) { if (index < this._nLeft) { this._nLeft++; } if (index < this._nRight) { this._nRight++; } } return UI_TABLE_CLASS.addColumn.call(this, options, index); }; /** * @override */ UI_LOCKED_TABLE_CLASS.removeRow = function (index) { var i = 0, row = this._aRows[index], o, lockedTR = row._eFill.parentNode; if (row) { row.hide(); o = row.getOuter(); disposeControl(row); removeDom(o, true); removeDom(lockedTR, true); this._aRows.splice(index, 1); this._aLockedRow.splice(index, 1); this.repaint(); } }; /** * @override */ UI_LOCKED_TABLE_CLASS.addRow = function (data, index) { //__gzip_original__lockedRow var row = UI_TABLE_CLASS.addRow.call(this, data, index), index = indexOf(this.getRows(), row), lockedRow = this._aLockedRow[index], el = row.getMain(), o = createDom(); o.innerHTML = '<table cellspacing="0"><tbody><tr class="' + el.className + '" style="' + el.style.cssText + '"><td style="padding:0px;border:0px"></td></tr></tbody></table>'; o = UI_LOCKED_TABLE_CREATE_LOCKEDROW(el = o.lastChild.lastChild.lastChild, row); lockedRow = lockedRow ? lockedRow._eFill.parentNode : null; this._uLockedMain.getBody().lastChild.lastChild.insertBefore(el, lockedRow); this._aLockedRow.splice(index, 0, o); UI_LOCKED_TABLE_ROW_SPLIT(o); this.repaint(); return row; }; /** * @override */ UI_LOCKED_TABLE_CLASS.init = function () { UI_LOCKED_TABLE_ALL_SPLIT(this); UI_TABLE_CLASS.init.call(this); }; /** * @override */ UI_LOCKED_TABLE_CLASS.removeColumn = function (index) { UI_TABLE_CLASS.removeColumn.call(this, index); if (index >= 0) { if (index < this._nLeft) { this._nLeft--; } if (index < this._nRight) { this._nRight--; } } }; /** * 初始化需要执行关联控制的行控件鼠标事件的默认处理。 * 行控件鼠标事件发生时,需要通知关联的行控件也同步产生默认的处理。 * @protected */ (function () { function build(name) { UI_LOCKED_TABLE_ROW_CLASS[name] = function (event) { UI_CONTROL_CLASS[name].call(this, event); getParent(this._eFill).className = this.getMain().className; }; } for (var i = 0; i < 11; ) { build('$' + eventNames[i++]); } })(); //{/if}// //{if 0}// })(); //{/if}//