/*!
- * Ext JS Library 3.1.0
- * Copyright(c) 2006-2009 Ext JS, LLC
+ * Ext JS Library 3.2.0
+ * Copyright(c) 2006-2010 Ext JS, Inc.
* licensing@extjs.com
* http://www.extjs.com/license
*/
-Ext.ns('Ext.ux.grid');\r
-\r
-Ext.ux.grid.LockingGridView = Ext.extend(Ext.grid.GridView, {\r
- lockText : 'Lock',\r
- unlockText : 'Unlock',\r
- rowBorderWidth : 1,\r
- lockedBorderWidth : 1,\r
- /*\r
- * This option ensures that height between the rows is synchronized\r
- * between the locked and unlocked sides. This option only needs to be used\r
- * when the row heights isn't predictable.\r
- */\r
- syncHeights: false,\r
- initTemplates : function(){\r
- var ts = this.templates || {};\r
- if(!ts.master){\r
- ts.master = new Ext.Template(\r
- '<div class="x-grid3" hidefocus="true">',\r
- '<div class="x-grid3-locked">',\r
- '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{lstyle}">{lockedHeader}</div></div><div class="x-clear"></div></div>',\r
- '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{lstyle}">{lockedBody}</div><div class="x-grid3-scroll-spacer"></div></div>',\r
- '</div>',\r
- '<div class="x-grid3-viewport x-grid3-unlocked">',\r
- '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',\r
- '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',\r
- '</div>',\r
- '<div class="x-grid3-resize-marker"> </div>',\r
- '<div class="x-grid3-resize-proxy"> </div>',\r
- '</div>'\r
- );\r
- }\r
- this.templates = ts;\r
- Ext.ux.grid.LockingGridView.superclass.initTemplates.call(this);\r
- },\r
- getEditorParent : function(ed){\r
- return this.el.dom;\r
- },\r
- initElements : function(){\r
- var E = Ext.Element;\r
- var el = this.grid.getGridEl().dom.firstChild;\r
- var cs = el.childNodes;\r
- this.el = new E(el);\r
- this.lockedWrap = new E(cs[0]);\r
- this.lockedHd = new E(this.lockedWrap.dom.firstChild);\r
- this.lockedInnerHd = this.lockedHd.dom.firstChild;\r
- this.lockedScroller = new E(this.lockedWrap.dom.childNodes[1]);\r
- this.lockedBody = new E(this.lockedScroller.dom.firstChild);\r
- this.mainWrap = new E(cs[1]);\r
- this.mainHd = new E(this.mainWrap.dom.firstChild);\r
- if(this.grid.hideHeaders){\r
- this.lockedHd.setDisplayed(false);\r
- this.mainHd.setDisplayed(false);\r
- }\r
- this.innerHd = this.mainHd.dom.firstChild;\r
- this.scroller = new E(this.mainWrap.dom.childNodes[1]);\r
- if(this.forceFit){\r
- this.scroller.setStyle('overflow-x', 'hidden');\r
- }\r
- this.mainBody = new E(this.scroller.dom.firstChild);\r
- this.focusEl = new E(this.scroller.dom.childNodes[1]);\r
- this.focusEl.swallowEvent('click', true);\r
- this.resizeMarker = new E(cs[2]);\r
- this.resizeProxy = new E(cs[3]);\r
- },\r
- \r
- getLockedRows : function(){\r
- return this.hasRows() ? this.lockedBody.dom.childNodes : [];\r
- },\r
- \r
- getLockedRow : function(row){\r
- return this.getLockedRows()[row];\r
- },\r
- \r
- getCell : function(row, col){\r
- var llen = this.cm.getLockedCount();\r
- if(col < llen){\r
- return this.getLockedRow(row).getElementsByTagName('td')[col];\r
- }\r
- return Ext.ux.grid.LockingGridView.superclass.getCell.call(this, row, col - llen);\r
- },\r
- \r
- getHeaderCell : function(index){\r
- var llen = this.cm.getLockedCount();\r
- if(index < llen){\r
- return this.lockedHd.dom.getElementsByTagName('td')[index];\r
- }\r
- return Ext.ux.grid.LockingGridView.superclass.getHeaderCell.call(this, index - llen);\r
- },\r
- \r
- addRowClass : function(row, cls){\r
- var r = this.getLockedRow(row);\r
- if(r){\r
- this.fly(r).addClass(cls);\r
- }\r
- Ext.ux.grid.LockingGridView.superclass.addRowClass.call(this, row, cls);\r
- },\r
- \r
- removeRowClass : function(row, cls){\r
- var r = this.getLockedRow(row);\r
- if(r){\r
- this.fly(r).removeClass(cls);\r
- }\r
- Ext.ux.grid.LockingGridView.superclass.removeRowClass.call(this, row, cls);\r
- },\r
- \r
- removeRow : function(row) {\r
- Ext.removeNode(this.getLockedRow(row));\r
- Ext.ux.grid.LockingGridView.superclass.removeRow.call(this, row);\r
- },\r
- \r
- removeRows : function(firstRow, lastRow){\r
- var bd = this.lockedBody.dom;\r
- for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){\r
- Ext.removeNode(bd.childNodes[firstRow]);\r
- }\r
- Ext.ux.grid.LockingGridView.superclass.removeRows.call(this, firstRow, lastRow);\r
- },\r
- \r
- syncScroll : function(e){\r
- var mb = this.scroller.dom;\r
- this.lockedScroller.dom.scrollTop = mb.scrollTop;\r
- Ext.ux.grid.LockingGridView.superclass.syncScroll.call(this, e);\r
- },\r
- \r
- updateSortIcon : function(col, dir){\r
- var sc = this.sortClasses,\r
- lhds = this.lockedHd.select('td').removeClass(sc),\r
- hds = this.mainHd.select('td').removeClass(sc),\r
- llen = this.cm.getLockedCount(),\r
- cls = sc[dir == 'DESC' ? 1 : 0];\r
- if(col < llen){\r
- lhds.item(col).addClass(cls);\r
- }else{\r
- hds.item(col - llen).addClass(cls);\r
- }\r
- },\r
- \r
- updateAllColumnWidths : function(){\r
- var tw = this.getTotalWidth(),\r
- clen = this.cm.getColumnCount(),\r
- lw = this.getLockedWidth(),\r
- llen = this.cm.getLockedCount(),\r
- ws = [], len, i;\r
- this.updateLockedWidth();\r
- for(i = 0; i < clen; i++){\r
- ws[i] = this.getColumnWidth(i);\r
- var hd = this.getHeaderCell(i);\r
- hd.style.width = ws[i];\r
- }\r
- var lns = this.getLockedRows(), ns = this.getRows(), row, trow, j;\r
- for(i = 0, len = ns.length; i < len; i++){\r
- row = lns[i];\r
- row.style.width = lw;\r
- if(row.firstChild){\r
- row.firstChild.style.width = lw;\r
- trow = row.firstChild.rows[0];\r
- for (j = 0; j < llen; j++) {\r
- trow.childNodes[j].style.width = ws[j];\r
- }\r
- }\r
- row = ns[i];\r
- row.style.width = tw;\r
- if(row.firstChild){\r
- row.firstChild.style.width = tw;\r
- trow = row.firstChild.rows[0];\r
- for (j = llen; j < clen; j++) {\r
- trow.childNodes[j - llen].style.width = ws[j];\r
- }\r
- }\r
- }\r
- this.onAllColumnWidthsUpdated(ws, tw);\r
- this.syncHeaderHeight();\r
- },\r
- \r
- updateColumnWidth : function(col, width){\r
- var w = this.getColumnWidth(col),\r
- llen = this.cm.getLockedCount(),\r
- ns, rw, c, row;\r
- this.updateLockedWidth();\r
- if(col < llen){\r
- ns = this.getLockedRows();\r
- rw = this.getLockedWidth();\r
- c = col;\r
- }else{\r
- ns = this.getRows();\r
- rw = this.getTotalWidth();\r
- c = col - llen;\r
- }\r
- var hd = this.getHeaderCell(col);\r
- hd.style.width = w;\r
- for(var i = 0, len = ns.length; i < len; i++){\r
- row = ns[i];\r
- row.style.width = rw;\r
- if(row.firstChild){\r
- row.firstChild.style.width = rw;\r
- row.firstChild.rows[0].childNodes[c].style.width = w;\r
- }\r
- }\r
- this.onColumnWidthUpdated(col, w, this.getTotalWidth());\r
- this.syncHeaderHeight();\r
- },\r
- \r
- updateColumnHidden : function(col, hidden){\r
- var llen = this.cm.getLockedCount(),\r
- ns, rw, c, row,\r
- display = hidden ? 'none' : '';\r
- this.updateLockedWidth();\r
- if(col < llen){\r
- ns = this.getLockedRows();\r
- rw = this.getLockedWidth();\r
- c = col;\r
- }else{\r
- ns = this.getRows();\r
- rw = this.getTotalWidth();\r
- c = col - llen;\r
- }\r
- var hd = this.getHeaderCell(col);\r
- hd.style.display = display;\r
- for(var i = 0, len = ns.length; i < len; i++){\r
- row = ns[i];\r
- row.style.width = rw;\r
- if(row.firstChild){\r
- row.firstChild.style.width = rw;\r
- row.firstChild.rows[0].childNodes[c].style.display = display;\r
- }\r
- }\r
- this.onColumnHiddenUpdated(col, hidden, this.getTotalWidth());\r
- delete this.lastViewWidth;\r
- this.layout();\r
- },\r
- \r
- doRender : function(cs, rs, ds, startRow, colCount, stripe){\r
- var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1,\r
- tstyle = 'width:'+this.getTotalWidth()+';',\r
- lstyle = 'width:'+this.getLockedWidth()+';',\r
- buf = [], lbuf = [], cb, lcb, c, p = {}, rp = {}, r;\r
- for(var j = 0, len = rs.length; j < len; j++){\r
- r = rs[j]; cb = []; lcb = [];\r
- var rowIndex = (j+startRow);\r
- for(var i = 0; i < colCount; i++){\r
- c = cs[i];\r
- p.id = c.id;\r
- p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) +\r
- (this.cm.config[i].cellCls ? ' ' + this.cm.config[i].cellCls : '');\r
- p.attr = p.cellAttr = '';\r
- p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);\r
- p.style = c.style;\r
- if(Ext.isEmpty(p.value)){\r
- p.value = ' ';\r
- }\r
- if(this.markDirty && r.dirty && Ext.isDefined(r.modified[c.name])){\r
- p.css += ' x-grid3-dirty-cell';\r
- }\r
- if(c.locked){\r
- lcb[lcb.length] = ct.apply(p);\r
- }else{\r
- cb[cb.length] = ct.apply(p);\r
- }\r
- }\r
- var alt = [];\r
- if(stripe && ((rowIndex+1) % 2 === 0)){\r
- alt[0] = 'x-grid3-row-alt';\r
- }\r
- if(r.dirty){\r
- alt[1] = ' x-grid3-dirty-row';\r
- }\r
- rp.cols = colCount;\r
- if(this.getRowClass){\r
- alt[2] = this.getRowClass(r, rowIndex, rp, ds);\r
- }\r
- rp.alt = alt.join(' ');\r
- rp.cells = cb.join('');\r
- rp.tstyle = tstyle;\r
- buf[buf.length] = rt.apply(rp);\r
- rp.cells = lcb.join('');\r
- rp.tstyle = lstyle;\r
- lbuf[lbuf.length] = rt.apply(rp);\r
- }\r
- return [buf.join(''), lbuf.join('')];\r
- },\r
- processRows : function(startRow, skipStripe){\r
- if(!this.ds || this.ds.getCount() < 1){\r
- return;\r
- }\r
- var rows = this.getRows(),\r
- lrows = this.getLockedRows(),\r
- row, lrow;\r
- skipStripe = skipStripe || !this.grid.stripeRows;\r
- startRow = startRow || 0;\r
- for(var i = 0, len = rows.length; i < len; ++i){\r
- row = rows[i];\r
- lrow = lrows[i];\r
- row.rowIndex = i;\r
- lrow.rowIndex = i;\r
- if(!skipStripe){\r
- row.className = row.className.replace(this.rowClsRe, ' ');\r
- lrow.className = lrow.className.replace(this.rowClsRe, ' ');\r
- if ((idx + 1) % 2 === 0){\r
- row.className += ' x-grid3-row-alt';\r
- lrow.className += ' x-grid3-row-alt';\r
- }\r
- }\r
- if(this.syncHeights){\r
- var el1 = Ext.get(row),\r
- el2 = Ext.get(lrow),\r
- h1 = el1.getHeight(),\r
- h2 = el2.getHeight();\r
- \r
- if(h1 > h2){\r
- el2.setHeight(h1); \r
- }else if(h2 > h1){\r
- el1.setHeight(h2);\r
- }\r
- }\r
- }\r
- if(startRow === 0){\r
- Ext.fly(rows[0]).addClass(this.firstRowCls);\r
- Ext.fly(lrows[0]).addClass(this.firstRowCls);\r
- }\r
- Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);\r
- Ext.fly(lrows[lrows.length - 1]).addClass(this.lastRowCls);\r
- },\r
- \r
- afterRender : function(){\r
- if(!this.ds || !this.cm){\r
- return;\r
- }\r
- var bd = this.renderRows() || [' ', ' '];\r
- this.mainBody.dom.innerHTML = bd[0];\r
- this.lockedBody.dom.innerHTML = bd[1];\r
- this.processRows(0, true);\r
- if(this.deferEmptyText !== true){\r
- this.applyEmptyText();\r
- }\r
- },\r
- \r
- renderUI : function(){\r
- var header = this.renderHeaders();\r
- var body = this.templates.body.apply({rows:' '});\r
- var html = this.templates.master.apply({\r
- body: body,\r
- header: header[0],\r
- ostyle: 'width:'+this.getOffsetWidth()+';',\r
- bstyle: 'width:'+this.getTotalWidth()+';',\r
- lockedBody: body,\r
- lockedHeader: header[1],\r
- lstyle: 'width:'+this.getLockedWidth()+';'\r
- });\r
- var g = this.grid;\r
- g.getGridEl().dom.innerHTML = html;\r
- this.initElements();\r
- Ext.fly(this.innerHd).on('click', this.handleHdDown, this);\r
- Ext.fly(this.lockedInnerHd).on('click', this.handleHdDown, this);\r
- this.mainHd.on({\r
- scope: this,\r
- mouseover: this.handleHdOver,\r
- mouseout: this.handleHdOut,\r
- mousemove: this.handleHdMove\r
- });\r
- this.lockedHd.on({\r
- scope: this,\r
- mouseover: this.handleHdOver,\r
- mouseout: this.handleHdOut,\r
- mousemove: this.handleHdMove\r
- });\r
- this.scroller.on('scroll', this.syncScroll, this);\r
- if(g.enableColumnResize !== false){\r
- this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);\r
- this.splitZone.setOuterHandleElId(Ext.id(this.lockedHd.dom));\r
- this.splitZone.setOuterHandleElId(Ext.id(this.mainHd.dom));\r
- }\r
- if(g.enableColumnMove){\r
- this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);\r
- this.columnDrag.setOuterHandleElId(Ext.id(this.lockedInnerHd));\r
- this.columnDrag.setOuterHandleElId(Ext.id(this.innerHd));\r
- this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);\r
- }\r
- if(g.enableHdMenu !== false){\r
- this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'});\r
- this.hmenu.add(\r
- {itemId: 'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},\r
- {itemId: 'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}\r
- );\r
- if(this.grid.enableColLock !== false){\r
- this.hmenu.add('-',\r
- {itemId: 'lock', text: this.lockText, cls: 'xg-hmenu-lock'},\r
- {itemId: 'unlock', text: this.unlockText, cls: 'xg-hmenu-unlock'}\r
- );\r
- }\r
- if(g.enableColumnHide !== false){\r
- this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'});\r
- this.colMenu.on({\r
- scope: this,\r
- beforeshow: this.beforeColMenuShow,\r
- itemclick: this.handleHdMenuClick\r
- });\r
- this.hmenu.add('-', {\r
- itemId:'columns',\r
- hideOnClick: false,\r
- text: this.columnsText,\r
- menu: this.colMenu,\r
- iconCls: 'x-cols-icon'\r
- });\r
- }\r
- this.hmenu.on('itemclick', this.handleHdMenuClick, this);\r
- }\r
- if(g.trackMouseOver){\r
- this.mainBody.on({\r
- scope: this,\r
- mouseover: this.onRowOver,\r
- mouseout: this.onRowOut\r
- });\r
- this.lockedBody.on({\r
- scope: this,\r
- mouseover: this.onRowOver,\r
- mouseout: this.onRowOut\r
- });\r
- }\r
- \r
- if(g.enableDragDrop || g.enableDrag){\r
- this.dragZone = new Ext.grid.GridDragZone(g, {\r
- ddGroup : g.ddGroup || 'GridDD'\r
- });\r
- }\r
- this.updateHeaderSortState();\r
- },\r
- \r
- layout : function(){\r
- if(!this.mainBody){\r
- return;\r
- }\r
- var g = this.grid;\r
- var c = g.getGridEl();\r
- var csize = c.getSize(true);\r
- var vw = csize.width;\r
- if(!g.hideHeaders && (vw < 20 || csize.height < 20)){\r
- return;\r
- }\r
- this.syncHeaderHeight();\r
- if(g.autoHeight){\r
- this.scroller.dom.style.overflow = 'visible';\r
- this.lockedScroller.dom.style.overflow = 'visible';\r
- if(Ext.isWebKit){\r
- this.scroller.dom.style.position = 'static';\r
- this.lockedScroller.dom.style.position = 'static';\r
- }\r
- }else{\r
- this.el.setSize(csize.width, csize.height);\r
- var hdHeight = this.mainHd.getHeight();\r
- var vh = csize.height - (hdHeight);\r
- }\r
- this.updateLockedWidth();\r
- if(this.forceFit){\r
- if(this.lastViewWidth != vw){\r
- this.fitColumns(false, false);\r
- this.lastViewWidth = vw;\r
- }\r
- }else {\r
- this.autoExpand();\r
- this.syncHeaderScroll();\r
- }\r
- this.onLayout(vw, vh);\r
- },\r
- \r
- getOffsetWidth : function() {\r
- return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth() + this.getScrollOffset()) + 'px';\r
- },\r
- \r
- renderHeaders : function(){\r
- var cm = this.cm,\r
- ts = this.templates,\r
- ct = ts.hcell,\r
- cb = [], lcb = [],\r
- p = {},\r
- len = cm.getColumnCount(),\r
- last = len - 1;\r
- for(var i = 0; i < len; i++){\r
- p.id = cm.getColumnId(i);\r
- p.value = cm.getColumnHeader(i) || '';\r
- p.style = this.getColumnStyle(i, true);\r
- p.tooltip = this.getColumnTooltip(i);\r
- p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) +\r
- (cm.config[i].headerCls ? ' ' + cm.config[i].headerCls : '');\r
- if(cm.config[i].align == 'right'){\r
- p.istyle = 'padding-right:16px';\r
- } else {\r
- delete p.istyle;\r
- }\r
- if(cm.isLocked(i)){\r
- lcb[lcb.length] = ct.apply(p);\r
- }else{\r
- cb[cb.length] = ct.apply(p);\r
- }\r
- }\r
- return [ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'}),\r
- ts.header.apply({cells: lcb.join(''), tstyle:'width:'+this.getLockedWidth()+';'})];\r
- },\r
- \r
- updateHeaders : function(){\r
- var hd = this.renderHeaders();\r
- this.innerHd.firstChild.innerHTML = hd[0];\r
- this.innerHd.firstChild.style.width = this.getOffsetWidth();\r
- this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();\r
- this.lockedInnerHd.firstChild.innerHTML = hd[1];\r
- var lw = this.getLockedWidth();\r
- this.lockedInnerHd.firstChild.style.width = lw;\r
- this.lockedInnerHd.firstChild.firstChild.style.width = lw;\r
- },\r
- \r
- getResolvedXY : function(resolved){\r
- if(!resolved){\r
- return null;\r
- }\r
- var c = resolved.cell, r = resolved.row;\r
- return c ? Ext.fly(c).getXY() : [this.scroller.getX(), Ext.fly(r).getY()];\r
- },\r
- \r
- syncFocusEl : function(row, col, hscroll){\r
- Ext.ux.grid.LockingGridView.superclass.syncFocusEl.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll);\r
- },\r
- \r
- ensureVisible : function(row, col, hscroll){\r
- return Ext.ux.grid.LockingGridView.superclass.ensureVisible.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll);\r
- },\r
- \r
- insertRows : function(dm, firstRow, lastRow, isUpdate){\r
- var last = dm.getCount() - 1;\r
- if(!isUpdate && firstRow === 0 && lastRow >= last){\r
- this.refresh();\r
- }else{\r
- if(!isUpdate){\r
- this.fireEvent('beforerowsinserted', this, firstRow, lastRow);\r
- }\r
- var html = this.renderRows(firstRow, lastRow),\r
- before = this.getRow(firstRow);\r
- if(before){\r
- if(firstRow === 0){\r
- this.removeRowClass(0, this.firstRowCls);\r
- }\r
- Ext.DomHelper.insertHtml('beforeBegin', before, html[0]);\r
- before = this.getLockedRow(firstRow);\r
- Ext.DomHelper.insertHtml('beforeBegin', before, html[1]);\r
- }else{\r
- this.removeRowClass(last - 1, this.lastRowCls);\r
- Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html[0]);\r
- Ext.DomHelper.insertHtml('beforeEnd', this.lockedBody.dom, html[1]);\r
- }\r
- if(!isUpdate){\r
- this.fireEvent('rowsinserted', this, firstRow, lastRow);\r
- this.processRows(firstRow);\r
- }else if(firstRow === 0 || firstRow >= last){\r
- this.addRowClass(firstRow, firstRow === 0 ? this.firstRowCls : this.lastRowCls);\r
- }\r
- }\r
- this.syncFocusEl(firstRow);\r
- },\r
- \r
- getColumnStyle : function(col, isHeader){\r
- var style = !isHeader ? this.cm.config[col].cellStyle || this.cm.config[col].css || '' : this.cm.config[col].headerStyle || '';\r
- style += 'width:'+this.getColumnWidth(col)+';';\r
- if(this.cm.isHidden(col)){\r
- style += 'display:none;';\r
- }\r
- var align = this.cm.config[col].align;\r
- if(align){\r
- style += 'text-align:'+align+';';\r
- }\r
- return style;\r
- },\r
- \r
- getLockedWidth : function() {\r
- return this.cm.getTotalLockedWidth() + 'px';\r
- },\r
- \r
- getTotalWidth : function() {\r
- return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth()) + 'px';\r
- },\r
- \r
- getColumnData : function(){\r
- var cs = [], cm = this.cm, colCount = cm.getColumnCount();\r
- for(var i = 0; i < colCount; i++){\r
- var name = cm.getDataIndex(i);\r
- cs[i] = {\r
- name : (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name),\r
- renderer : cm.getRenderer(i),\r
- id : cm.getColumnId(i),\r
- style : this.getColumnStyle(i),\r
- locked : cm.isLocked(i)\r
- };\r
- }\r
- return cs;\r
- },\r
- \r
- renderBody : function(){\r
- var markup = this.renderRows() || [' ', ' '];\r
- return [this.templates.body.apply({rows: markup[0]}), this.templates.body.apply({rows: markup[1]})];\r
- },\r
- \r
- refreshRow : function(record){\r
- Ext.ux.grid.LockingGridView.superclass.refreshRow.call(this, record);\r
- var index = Ext.isNumber(record) ? record : this.ds.indexOf(record);\r
- this.getLockedRow(index).rowIndex = index;\r
- },\r
- \r
- refresh : function(headersToo){\r
- this.fireEvent('beforerefresh', this);\r
- this.grid.stopEditing(true);\r
- var result = this.renderBody();\r
- this.mainBody.update(result[0]).setWidth(this.getTotalWidth());\r
- this.lockedBody.update(result[1]).setWidth(this.getLockedWidth());\r
- if(headersToo === true){\r
- this.updateHeaders();\r
- this.updateHeaderSortState();\r
- }\r
- this.processRows(0, true);\r
- this.layout();\r
- this.applyEmptyText();\r
- this.fireEvent('refresh', this);\r
- },\r
- \r
- onDenyColumnLock : function(){\r
-\r
- },\r
- \r
- initData : function(ds, cm){\r
- if(this.cm){\r
- this.cm.un('columnlockchange', this.onColumnLock, this);\r
- }\r
- Ext.ux.grid.LockingGridView.superclass.initData.call(this, ds, cm);\r
- if(this.cm){\r
- this.cm.on('columnlockchange', this.onColumnLock, this);\r
- }\r
- },\r
- \r
- onColumnLock : function(){\r
- this.refresh(true);\r
- },\r
- \r
- handleHdMenuClick : function(item){\r
- var index = this.hdCtxIndex,\r
- cm = this.cm,\r
- id = item.getItemId(),\r
- llen = cm.getLockedCount();\r
- switch(id){\r
- case 'lock':\r
- if(cm.getColumnCount(true) <= llen + 1){\r
- this.onDenyColumnLock();\r
- return;\r
- }\r
- if(llen != index){\r
- cm.setLocked(index, true, true);\r
- cm.moveColumn(index, llen);\r
- this.grid.fireEvent('columnmove', index, llen);\r
- }else{\r
- cm.setLocked(index, true);\r
- }\r
- break;\r
- case 'unlock':\r
- if(llen - 1 != index){\r
- cm.setLocked(index, false, true);\r
- cm.moveColumn(index, llen - 1);\r
- this.grid.fireEvent('columnmove', index, llen - 1);\r
- }else{\r
- cm.setLocked(index, false);\r
- }\r
- break;\r
- default:\r
- return Ext.ux.grid.LockingGridView.superclass.handleHdMenuClick.call(this, item);\r
- }\r
- return true;\r
- },\r
- \r
- handleHdDown : function(e, t){\r
- Ext.ux.grid.LockingGridView.superclass.handleHdDown.call(this, e, t);\r
- if(this.grid.enableColLock !== false){\r
- if(Ext.fly(t).hasClass('x-grid3-hd-btn')){\r
- var hd = this.findHeaderCell(t),\r
- index = this.getCellIndex(hd),\r
- ms = this.hmenu.items, cm = this.cm;\r
- ms.get('lock').setDisabled(cm.isLocked(index));\r
- ms.get('unlock').setDisabled(!cm.isLocked(index));\r
- }\r
- }\r
- },\r
- \r
- syncHeaderHeight: function(){\r
- this.innerHd.firstChild.firstChild.style.height = 'auto';\r
- this.lockedInnerHd.firstChild.firstChild.style.height = 'auto';\r
- var hd = this.innerHd.firstChild.firstChild.offsetHeight,\r
- lhd = this.lockedInnerHd.firstChild.firstChild.offsetHeight,\r
- height = (lhd > hd ? lhd : hd) + 'px';\r
- this.innerHd.firstChild.firstChild.style.height = height;\r
- this.lockedInnerHd.firstChild.firstChild.style.height = height;\r
- },\r
- \r
- updateLockedWidth: function(){\r
- var lw = this.cm.getTotalLockedWidth(),\r
- tw = this.cm.getTotalWidth() - lw,\r
- csize = this.grid.getGridEl().getSize(true),\r
- lp = Ext.isBorderBox ? 0 : this.lockedBorderWidth,\r
- rp = Ext.isBorderBox ? 0 : this.rowBorderWidth,\r
- vw = (csize.width - lw - lp - rp) + 'px',\r
- so = this.getScrollOffset();\r
- if(!this.grid.autoHeight){\r
- var vh = (csize.height - this.mainHd.getHeight()) + 'px';\r
- this.lockedScroller.dom.style.height = vh;\r
- this.scroller.dom.style.height = vh;\r
- }\r
- this.lockedWrap.dom.style.width = (lw + rp) + 'px';\r
- this.scroller.dom.style.width = vw;\r
- this.mainWrap.dom.style.left = (lw + lp + rp) + 'px';\r
- if(this.innerHd){\r
- this.lockedInnerHd.firstChild.style.width = lw + 'px';\r
- this.lockedInnerHd.firstChild.firstChild.style.width = lw + 'px';\r
- this.innerHd.style.width = vw;\r
- this.innerHd.firstChild.style.width = (tw + rp + so) + 'px';\r
- this.innerHd.firstChild.firstChild.style.width = tw + 'px';\r
- }\r
- if(this.mainBody){\r
- this.lockedBody.dom.style.width = (lw + rp) + 'px';\r
- this.mainBody.dom.style.width = (tw + rp) + 'px';\r
- }\r
- }\r
-});\r
-\r
-Ext.ux.grid.LockingColumnModel = Ext.extend(Ext.grid.ColumnModel, {\r
- isLocked : function(colIndex){\r
- return this.config[colIndex].locked === true;\r
- },\r
- \r
- setLocked : function(colIndex, value, suppressEvent){\r
- if(this.isLocked(colIndex) == value){\r
- return;\r
- }\r
- this.config[colIndex].locked = value;\r
- if(!suppressEvent){\r
- this.fireEvent('columnlockchange', this, colIndex, value);\r
- }\r
- },\r
- \r
- getTotalLockedWidth : function(){\r
- var totalWidth = 0;\r
- for(var i = 0, len = this.config.length; i < len; i++){\r
- if(this.isLocked(i) && !this.isHidden(i)){\r
- totalWidth += this.getColumnWidth(i);\r
- }\r
- }\r
- return totalWidth;\r
- },\r
- \r
- getLockedCount : function(){\r
- for(var i = 0, len = this.config.length; i < len; i++){\r
- if(!this.isLocked(i)){\r
- return i;\r
- }\r
- }\r
- },\r
- \r
- moveColumn : function(oldIndex, newIndex){\r
- if(oldIndex < newIndex && this.isLocked(oldIndex) && !this.isLocked(newIndex)){\r
- this.setLocked(oldIndex, false, true);\r
- }else if(oldIndex > newIndex && !this.isLocked(oldIndex) && this.isLocked(newIndex)){\r
- this.setLocked(oldIndex, true, true);\r
- }\r
- Ext.ux.grid.LockingColumnModel.superclass.moveColumn.apply(this, arguments);\r
- }\r
-});\r
+Ext.ns('Ext.ux.grid');
+
+Ext.ux.grid.LockingGridView = Ext.extend(Ext.grid.GridView, {
+ lockText : 'Lock',
+ unlockText : 'Unlock',
+ rowBorderWidth : 1,
+ lockedBorderWidth : 1,
+
+ /*
+ * This option ensures that height between the rows is synchronized
+ * between the locked and unlocked sides. This option only needs to be used
+ * when the row heights aren't predictable.
+ */
+ syncHeights: false,
+
+ initTemplates : function(){
+ var ts = this.templates || {};
+
+ if (!ts.master) {
+ ts.master = new Ext.Template(
+ '<div class="x-grid3" hidefocus="true">',
+ '<div class="x-grid3-locked">',
+ '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{lstyle}">{lockedHeader}</div></div><div class="x-clear"></div></div>',
+ '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{lstyle}">{lockedBody}</div><div class="x-grid3-scroll-spacer"></div></div>',
+ '</div>',
+ '<div class="x-grid3-viewport x-grid3-unlocked">',
+ '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
+ '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
+ '</div>',
+ '<div class="x-grid3-resize-marker"> </div>',
+ '<div class="x-grid3-resize-proxy"> </div>',
+ '</div>'
+ );
+ }
+
+ this.templates = ts;
+
+ Ext.ux.grid.LockingGridView.superclass.initTemplates.call(this);
+ },
+
+ getEditorParent : function(ed){
+ return this.el.dom;
+ },
+
+ initElements : function(){
+ var E = Ext.Element,
+ el = this.grid.getGridEl().dom.firstChild,
+ cs = el.childNodes;
+
+ this.el = new E(el);
+ this.lockedWrap = new E(cs[0]);
+ this.lockedHd = new E(this.lockedWrap.dom.firstChild);
+ this.lockedInnerHd = this.lockedHd.dom.firstChild;
+ this.lockedScroller = new E(this.lockedWrap.dom.childNodes[1]);
+ this.lockedBody = new E(this.lockedScroller.dom.firstChild);
+ this.mainWrap = new E(cs[1]);
+ this.mainHd = new E(this.mainWrap.dom.firstChild);
+
+ if (this.grid.hideHeaders) {
+ this.lockedHd.setDisplayed(false);
+ this.mainHd.setDisplayed(false);
+ }
+
+ this.innerHd = this.mainHd.dom.firstChild;
+ this.scroller = new E(this.mainWrap.dom.childNodes[1]);
+
+ if(this.forceFit){
+ this.scroller.setStyle('overflow-x', 'hidden');
+ }
+
+ this.mainBody = new E(this.scroller.dom.firstChild);
+ this.focusEl = new E(this.scroller.dom.childNodes[1]);
+ this.resizeMarker = new E(cs[2]);
+ this.resizeProxy = new E(cs[3]);
+
+ this.focusEl.swallowEvent('click', true);
+ },
+
+ getLockedRows : function(){
+ return this.hasRows() ? this.lockedBody.dom.childNodes : [];
+ },
+
+ getLockedRow : function(row){
+ return this.getLockedRows()[row];
+ },
+
+ getCell : function(row, col){
+ var llen = this.cm.getLockedCount();
+ if(col < llen){
+ return this.getLockedRow(row).getElementsByTagName('td')[col];
+ }
+ return Ext.ux.grid.LockingGridView.superclass.getCell.call(this, row, col - llen);
+ },
+
+ getHeaderCell : function(index){
+ var llen = this.cm.getLockedCount();
+ if(index < llen){
+ return this.lockedHd.dom.getElementsByTagName('td')[index];
+ }
+ return Ext.ux.grid.LockingGridView.superclass.getHeaderCell.call(this, index - llen);
+ },
+
+ addRowClass : function(row, cls){
+ var r = this.getLockedRow(row);
+ if(r){
+ this.fly(r).addClass(cls);
+ }
+ Ext.ux.grid.LockingGridView.superclass.addRowClass.call(this, row, cls);
+ },
+
+ removeRowClass : function(row, cls){
+ var r = this.getLockedRow(row);
+ if(r){
+ this.fly(r).removeClass(cls);
+ }
+ Ext.ux.grid.LockingGridView.superclass.removeRowClass.call(this, row, cls);
+ },
+
+ removeRow : function(row) {
+ Ext.removeNode(this.getLockedRow(row));
+ Ext.ux.grid.LockingGridView.superclass.removeRow.call(this, row);
+ },
+
+ removeRows : function(firstRow, lastRow){
+ var bd = this.lockedBody.dom;
+ for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
+ Ext.removeNode(bd.childNodes[firstRow]);
+ }
+ Ext.ux.grid.LockingGridView.superclass.removeRows.call(this, firstRow, lastRow);
+ },
+
+ syncScroll : function(e){
+ var mb = this.scroller.dom;
+ this.lockedScroller.dom.scrollTop = mb.scrollTop;
+ Ext.ux.grid.LockingGridView.superclass.syncScroll.call(this, e);
+ },
+
+ updateSortIcon : function(col, dir){
+ var sc = this.sortClasses,
+ lhds = this.lockedHd.select('td').removeClass(sc),
+ hds = this.mainHd.select('td').removeClass(sc),
+ llen = this.cm.getLockedCount(),
+ cls = sc[dir == 'DESC' ? 1 : 0];
+ if(col < llen){
+ lhds.item(col).addClass(cls);
+ }else{
+ hds.item(col - llen).addClass(cls);
+ }
+ },
+
+ updateAllColumnWidths : function(){
+ var tw = this.getTotalWidth(),
+ clen = this.cm.getColumnCount(),
+ lw = this.getLockedWidth(),
+ llen = this.cm.getLockedCount(),
+ ws = [], len, i;
+ this.updateLockedWidth();
+ for(i = 0; i < clen; i++){
+ ws[i] = this.getColumnWidth(i);
+ var hd = this.getHeaderCell(i);
+ hd.style.width = ws[i];
+ }
+ var lns = this.getLockedRows(), ns = this.getRows(), row, trow, j;
+ for(i = 0, len = ns.length; i < len; i++){
+ row = lns[i];
+ row.style.width = lw;
+ if(row.firstChild){
+ row.firstChild.style.width = lw;
+ trow = row.firstChild.rows[0];
+ for (j = 0; j < llen; j++) {
+ trow.childNodes[j].style.width = ws[j];
+ }
+ }
+ row = ns[i];
+ row.style.width = tw;
+ if(row.firstChild){
+ row.firstChild.style.width = tw;
+ trow = row.firstChild.rows[0];
+ for (j = llen; j < clen; j++) {
+ trow.childNodes[j - llen].style.width = ws[j];
+ }
+ }
+ }
+ this.onAllColumnWidthsUpdated(ws, tw);
+ this.syncHeaderHeight();
+ },
+
+ updateColumnWidth : function(col, width){
+ var w = this.getColumnWidth(col),
+ llen = this.cm.getLockedCount(),
+ ns, rw, c, row;
+ this.updateLockedWidth();
+ if(col < llen){
+ ns = this.getLockedRows();
+ rw = this.getLockedWidth();
+ c = col;
+ }else{
+ ns = this.getRows();
+ rw = this.getTotalWidth();
+ c = col - llen;
+ }
+ var hd = this.getHeaderCell(col);
+ hd.style.width = w;
+ for(var i = 0, len = ns.length; i < len; i++){
+ row = ns[i];
+ row.style.width = rw;
+ if(row.firstChild){
+ row.firstChild.style.width = rw;
+ row.firstChild.rows[0].childNodes[c].style.width = w;
+ }
+ }
+ this.onColumnWidthUpdated(col, w, this.getTotalWidth());
+ this.syncHeaderHeight();
+ },
+
+ updateColumnHidden : function(col, hidden){
+ var llen = this.cm.getLockedCount(),
+ ns, rw, c, row,
+ display = hidden ? 'none' : '';
+ this.updateLockedWidth();
+ if(col < llen){
+ ns = this.getLockedRows();
+ rw = this.getLockedWidth();
+ c = col;
+ }else{
+ ns = this.getRows();
+ rw = this.getTotalWidth();
+ c = col - llen;
+ }
+ var hd = this.getHeaderCell(col);
+ hd.style.display = display;
+ for(var i = 0, len = ns.length; i < len; i++){
+ row = ns[i];
+ row.style.width = rw;
+ if(row.firstChild){
+ row.firstChild.style.width = rw;
+ row.firstChild.rows[0].childNodes[c].style.display = display;
+ }
+ }
+ this.onColumnHiddenUpdated(col, hidden, this.getTotalWidth());
+ delete this.lastViewWidth;
+ this.layout();
+ },
+
+ doRender : function(cs, rs, ds, startRow, colCount, stripe){
+ var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1,
+ tstyle = 'width:'+this.getTotalWidth()+';',
+ lstyle = 'width:'+this.getLockedWidth()+';',
+ buf = [], lbuf = [], cb, lcb, c, p = {}, rp = {}, r;
+ for(var j = 0, len = rs.length; j < len; j++){
+ r = rs[j]; cb = []; lcb = [];
+ var rowIndex = (j+startRow);
+ for(var i = 0; i < colCount; i++){
+ c = cs[i];
+ p.id = c.id;
+ p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) +
+ (this.cm.config[i].cellCls ? ' ' + this.cm.config[i].cellCls : '');
+ p.attr = p.cellAttr = '';
+ p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
+ p.style = c.style;
+ if(Ext.isEmpty(p.value)){
+ p.value = ' ';
+ }
+ if(this.markDirty && r.dirty && Ext.isDefined(r.modified[c.name])){
+ p.css += ' x-grid3-dirty-cell';
+ }
+ if(c.locked){
+ lcb[lcb.length] = ct.apply(p);
+ }else{
+ cb[cb.length] = ct.apply(p);
+ }
+ }
+ var alt = [];
+ if(stripe && ((rowIndex+1) % 2 === 0)){
+ alt[0] = 'x-grid3-row-alt';
+ }
+ if(r.dirty){
+ alt[1] = ' x-grid3-dirty-row';
+ }
+ rp.cols = colCount;
+ if(this.getRowClass){
+ alt[2] = this.getRowClass(r, rowIndex, rp, ds);
+ }
+ rp.alt = alt.join(' ');
+ rp.cells = cb.join('');
+ rp.tstyle = tstyle;
+ buf[buf.length] = rt.apply(rp);
+ rp.cells = lcb.join('');
+ rp.tstyle = lstyle;
+ lbuf[lbuf.length] = rt.apply(rp);
+ }
+ return [buf.join(''), lbuf.join('')];
+ },
+ processRows : function(startRow, skipStripe){
+ if(!this.ds || this.ds.getCount() < 1){
+ return;
+ }
+ var rows = this.getRows(),
+ lrows = this.getLockedRows(),
+ row, lrow;
+ skipStripe = skipStripe || !this.grid.stripeRows;
+ startRow = startRow || 0;
+ for(var i = 0, len = rows.length; i < len; ++i){
+ row = rows[i];
+ lrow = lrows[i];
+ row.rowIndex = i;
+ lrow.rowIndex = i;
+ if(!skipStripe){
+ row.className = row.className.replace(this.rowClsRe, ' ');
+ lrow.className = lrow.className.replace(this.rowClsRe, ' ');
+ if ((i + 1) % 2 === 0){
+ row.className += ' x-grid3-row-alt';
+ lrow.className += ' x-grid3-row-alt';
+ }
+ }
+ if(this.syncHeights){
+ var el1 = Ext.get(row),
+ el2 = Ext.get(lrow),
+ h1 = el1.getHeight(),
+ h2 = el2.getHeight();
+
+ if(h1 > h2){
+ el2.setHeight(h1);
+ }else if(h2 > h1){
+ el1.setHeight(h2);
+ }
+ }
+ }
+ if(startRow === 0){
+ Ext.fly(rows[0]).addClass(this.firstRowCls);
+ Ext.fly(lrows[0]).addClass(this.firstRowCls);
+ }
+ Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
+ Ext.fly(lrows[lrows.length - 1]).addClass(this.lastRowCls);
+ },
+
+ afterRender : function(){
+ if(!this.ds || !this.cm){
+ return;
+ }
+ var bd = this.renderRows() || [' ', ' '];
+ this.mainBody.dom.innerHTML = bd[0];
+ this.lockedBody.dom.innerHTML = bd[1];
+ this.processRows(0, true);
+ if(this.deferEmptyText !== true){
+ this.applyEmptyText();
+ }
+ },
+
+ renderUI : function(){
+ var header = this.renderHeaders();
+ var body = this.templates.body.apply({rows:' '});
+ var html = this.templates.master.apply({
+ body: body,
+ header: header[0],
+ ostyle: 'width:'+this.getOffsetWidth()+';',
+ bstyle: 'width:'+this.getTotalWidth()+';',
+ lockedBody: body,
+ lockedHeader: header[1],
+ lstyle: 'width:'+this.getLockedWidth()+';'
+ });
+ var g = this.grid;
+ g.getGridEl().dom.innerHTML = html;
+ this.initElements();
+ Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
+ Ext.fly(this.lockedInnerHd).on('click', this.handleHdDown, this);
+ this.mainHd.on({
+ scope: this,
+ mouseover: this.handleHdOver,
+ mouseout: this.handleHdOut,
+ mousemove: this.handleHdMove
+ });
+ this.lockedHd.on({
+ scope: this,
+ mouseover: this.handleHdOver,
+ mouseout: this.handleHdOut,
+ mousemove: this.handleHdMove
+ });
+ this.scroller.on('scroll', this.syncScroll, this);
+ if(g.enableColumnResize !== false){
+ this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
+ this.splitZone.setOuterHandleElId(Ext.id(this.lockedHd.dom));
+ this.splitZone.setOuterHandleElId(Ext.id(this.mainHd.dom));
+ }
+ if(g.enableColumnMove){
+ this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
+ this.columnDrag.setOuterHandleElId(Ext.id(this.lockedInnerHd));
+ this.columnDrag.setOuterHandleElId(Ext.id(this.innerHd));
+ this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
+ }
+ if(g.enableHdMenu !== false){
+ this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'});
+ this.hmenu.add(
+ {itemId: 'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},
+ {itemId: 'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
+ );
+ if(this.grid.enableColLock !== false){
+ this.hmenu.add('-',
+ {itemId: 'lock', text: this.lockText, cls: 'xg-hmenu-lock'},
+ {itemId: 'unlock', text: this.unlockText, cls: 'xg-hmenu-unlock'}
+ );
+ }
+ if(g.enableColumnHide !== false){
+ this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'});
+ this.colMenu.on({
+ scope: this,
+ beforeshow: this.beforeColMenuShow,
+ itemclick: this.handleHdMenuClick
+ });
+ this.hmenu.add('-', {
+ itemId:'columns',
+ hideOnClick: false,
+ text: this.columnsText,
+ menu: this.colMenu,
+ iconCls: 'x-cols-icon'
+ });
+ }
+ this.hmenu.on('itemclick', this.handleHdMenuClick, this);
+ }
+ if(g.trackMouseOver){
+ this.mainBody.on({
+ scope: this,
+ mouseover: this.onRowOver,
+ mouseout: this.onRowOut
+ });
+ this.lockedBody.on({
+ scope: this,
+ mouseover: this.onRowOver,
+ mouseout: this.onRowOut
+ });
+ }
+
+ if(g.enableDragDrop || g.enableDrag){
+ this.dragZone = new Ext.grid.GridDragZone(g, {
+ ddGroup : g.ddGroup || 'GridDD'
+ });
+ }
+ this.updateHeaderSortState();
+ },
+
+ layout : function(){
+ if(!this.mainBody){
+ return;
+ }
+ var g = this.grid;
+ var c = g.getGridEl();
+ var csize = c.getSize(true);
+ var vw = csize.width;
+ if(!g.hideHeaders && (vw < 20 || csize.height < 20)){
+ return;
+ }
+ this.syncHeaderHeight();
+ if(g.autoHeight){
+ this.scroller.dom.style.overflow = 'visible';
+ this.lockedScroller.dom.style.overflow = 'visible';
+ if(Ext.isWebKit){
+ this.scroller.dom.style.position = 'static';
+ this.lockedScroller.dom.style.position = 'static';
+ }
+ }else{
+ this.el.setSize(csize.width, csize.height);
+ var hdHeight = this.mainHd.getHeight();
+ var vh = csize.height - (hdHeight);
+ }
+ this.updateLockedWidth();
+ if(this.forceFit){
+ if(this.lastViewWidth != vw){
+ this.fitColumns(false, false);
+ this.lastViewWidth = vw;
+ }
+ }else {
+ this.autoExpand();
+ this.syncHeaderScroll();
+ }
+ this.onLayout(vw, vh);
+ },
+
+ getOffsetWidth : function() {
+ return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth() + this.getScrollOffset()) + 'px';
+ },
+
+ renderHeaders : function(){
+ var cm = this.cm,
+ ts = this.templates,
+ ct = ts.hcell,
+ cb = [], lcb = [],
+ p = {},
+ len = cm.getColumnCount(),
+ last = len - 1;
+ for(var i = 0; i < len; i++){
+ p.id = cm.getColumnId(i);
+ p.value = cm.getColumnHeader(i) || '';
+ p.style = this.getColumnStyle(i, true);
+ p.tooltip = this.getColumnTooltip(i);
+ p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) +
+ (cm.config[i].headerCls ? ' ' + cm.config[i].headerCls : '');
+ if(cm.config[i].align == 'right'){
+ p.istyle = 'padding-right:16px';
+ } else {
+ delete p.istyle;
+ }
+ if(cm.isLocked(i)){
+ lcb[lcb.length] = ct.apply(p);
+ }else{
+ cb[cb.length] = ct.apply(p);
+ }
+ }
+ return [ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'}),
+ ts.header.apply({cells: lcb.join(''), tstyle:'width:'+this.getLockedWidth()+';'})];
+ },
+
+ updateHeaders : function(){
+ var hd = this.renderHeaders();
+ this.innerHd.firstChild.innerHTML = hd[0];
+ this.innerHd.firstChild.style.width = this.getOffsetWidth();
+ this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();
+ this.lockedInnerHd.firstChild.innerHTML = hd[1];
+ var lw = this.getLockedWidth();
+ this.lockedInnerHd.firstChild.style.width = lw;
+ this.lockedInnerHd.firstChild.firstChild.style.width = lw;
+ },
+
+ getResolvedXY : function(resolved){
+ if(!resolved){
+ return null;
+ }
+ var c = resolved.cell, r = resolved.row;
+ return c ? Ext.fly(c).getXY() : [this.scroller.getX(), Ext.fly(r).getY()];
+ },
+
+ syncFocusEl : function(row, col, hscroll){
+ Ext.ux.grid.LockingGridView.superclass.syncFocusEl.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll);
+ },
+
+ ensureVisible : function(row, col, hscroll){
+ return Ext.ux.grid.LockingGridView.superclass.ensureVisible.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll);
+ },
+
+ insertRows : function(dm, firstRow, lastRow, isUpdate){
+ var last = dm.getCount() - 1;
+ if(!isUpdate && firstRow === 0 && lastRow >= last){
+ this.refresh();
+ }else{
+ if(!isUpdate){
+ this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
+ }
+ var html = this.renderRows(firstRow, lastRow),
+ before = this.getRow(firstRow);
+ if(before){
+ if(firstRow === 0){
+ this.removeRowClass(0, this.firstRowCls);
+ }
+ Ext.DomHelper.insertHtml('beforeBegin', before, html[0]);
+ before = this.getLockedRow(firstRow);
+ Ext.DomHelper.insertHtml('beforeBegin', before, html[1]);
+ }else{
+ this.removeRowClass(last - 1, this.lastRowCls);
+ Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html[0]);
+ Ext.DomHelper.insertHtml('beforeEnd', this.lockedBody.dom, html[1]);
+ }
+ if(!isUpdate){
+ this.fireEvent('rowsinserted', this, firstRow, lastRow);
+ this.processRows(firstRow);
+ }else if(firstRow === 0 || firstRow >= last){
+ this.addRowClass(firstRow, firstRow === 0 ? this.firstRowCls : this.lastRowCls);
+ }
+ }
+ this.syncFocusEl(firstRow);
+ },
+
+ getColumnStyle : function(col, isHeader){
+ var style = !isHeader ? this.cm.config[col].cellStyle || this.cm.config[col].css || '' : this.cm.config[col].headerStyle || '';
+ style += 'width:'+this.getColumnWidth(col)+';';
+ if(this.cm.isHidden(col)){
+ style += 'display:none;';
+ }
+ var align = this.cm.config[col].align;
+ if(align){
+ style += 'text-align:'+align+';';
+ }
+ return style;
+ },
+
+ getLockedWidth : function() {
+ return this.cm.getTotalLockedWidth() + 'px';
+ },
+
+ getTotalWidth : function() {
+ return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth()) + 'px';
+ },
+
+ getColumnData : function(){
+ var cs = [], cm = this.cm, colCount = cm.getColumnCount();
+ for(var i = 0; i < colCount; i++){
+ var name = cm.getDataIndex(i);
+ cs[i] = {
+ name : (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name),
+ renderer : cm.getRenderer(i),
+ id : cm.getColumnId(i),
+ style : this.getColumnStyle(i),
+ locked : cm.isLocked(i)
+ };
+ }
+ return cs;
+ },
+
+ renderBody : function(){
+ var markup = this.renderRows() || [' ', ' '];
+ return [this.templates.body.apply({rows: markup[0]}), this.templates.body.apply({rows: markup[1]})];
+ },
+
+ refreshRow : function(record){
+ Ext.ux.grid.LockingGridView.superclass.refreshRow.call(this, record);
+ var index = Ext.isNumber(record) ? record : this.ds.indexOf(record);
+ this.getLockedRow(index).rowIndex = index;
+ },
+
+ refresh : function(headersToo){
+ this.fireEvent('beforerefresh', this);
+ this.grid.stopEditing(true);
+ var result = this.renderBody();
+ this.mainBody.update(result[0]).setWidth(this.getTotalWidth());
+ this.lockedBody.update(result[1]).setWidth(this.getLockedWidth());
+ if(headersToo === true){
+ this.updateHeaders();
+ this.updateHeaderSortState();
+ }
+ this.processRows(0, true);
+ this.layout();
+ this.applyEmptyText();
+ this.fireEvent('refresh', this);
+ },
+
+ onDenyColumnLock : function(){
+
+ },
+
+ initData : function(ds, cm){
+ if(this.cm){
+ this.cm.un('columnlockchange', this.onColumnLock, this);
+ }
+ Ext.ux.grid.LockingGridView.superclass.initData.call(this, ds, cm);
+ if(this.cm){
+ this.cm.on('columnlockchange', this.onColumnLock, this);
+ }
+ },
+
+ onColumnLock : function(){
+ this.refresh(true);
+ },
+
+ handleHdMenuClick : function(item){
+ var index = this.hdCtxIndex,
+ cm = this.cm,
+ id = item.getItemId(),
+ llen = cm.getLockedCount();
+ switch(id){
+ case 'lock':
+ if(cm.getColumnCount(true) <= llen + 1){
+ this.onDenyColumnLock();
+ return;
+ }
+ if(llen != index){
+ cm.setLocked(index, true, true);
+ cm.moveColumn(index, llen);
+ this.grid.fireEvent('columnmove', index, llen);
+ }else{
+ cm.setLocked(index, true);
+ }
+ break;
+ case 'unlock':
+ if(llen - 1 != index){
+ cm.setLocked(index, false, true);
+ cm.moveColumn(index, llen - 1);
+ this.grid.fireEvent('columnmove', index, llen - 1);
+ }else{
+ cm.setLocked(index, false);
+ }
+ break;
+ default:
+ return Ext.ux.grid.LockingGridView.superclass.handleHdMenuClick.call(this, item);
+ }
+ return true;
+ },
+
+ handleHdDown : function(e, t){
+ Ext.ux.grid.LockingGridView.superclass.handleHdDown.call(this, e, t);
+ if(this.grid.enableColLock !== false){
+ if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
+ var hd = this.findHeaderCell(t),
+ index = this.getCellIndex(hd),
+ ms = this.hmenu.items, cm = this.cm;
+ ms.get('lock').setDisabled(cm.isLocked(index));
+ ms.get('unlock').setDisabled(!cm.isLocked(index));
+ }
+ }
+ },
+
+ syncHeaderHeight: function(){
+ this.innerHd.firstChild.firstChild.style.height = 'auto';
+ this.lockedInnerHd.firstChild.firstChild.style.height = 'auto';
+ var hd = this.innerHd.firstChild.firstChild.offsetHeight,
+ lhd = this.lockedInnerHd.firstChild.firstChild.offsetHeight,
+ height = (lhd > hd ? lhd : hd) + 'px';
+ this.innerHd.firstChild.firstChild.style.height = height;
+ this.lockedInnerHd.firstChild.firstChild.style.height = height;
+ },
+
+ updateLockedWidth: function(){
+ var lw = this.cm.getTotalLockedWidth(),
+ tw = this.cm.getTotalWidth() - lw,
+ csize = this.grid.getGridEl().getSize(true),
+ lp = Ext.isBorderBox ? 0 : this.lockedBorderWidth,
+ rp = Ext.isBorderBox ? 0 : this.rowBorderWidth,
+ vw = (csize.width - lw - lp - rp) + 'px',
+ so = this.getScrollOffset();
+ if(!this.grid.autoHeight){
+ var vh = (csize.height - this.mainHd.getHeight()) + 'px';
+ this.lockedScroller.dom.style.height = vh;
+ this.scroller.dom.style.height = vh;
+ }
+ this.lockedWrap.dom.style.width = (lw + rp) + 'px';
+ this.scroller.dom.style.width = vw;
+ this.mainWrap.dom.style.left = (lw + lp + rp) + 'px';
+ if(this.innerHd){
+ this.lockedInnerHd.firstChild.style.width = lw + 'px';
+ this.lockedInnerHd.firstChild.firstChild.style.width = lw + 'px';
+ this.innerHd.style.width = vw;
+ this.innerHd.firstChild.style.width = (tw + rp + so) + 'px';
+ this.innerHd.firstChild.firstChild.style.width = tw + 'px';
+ }
+ if(this.mainBody){
+ this.lockedBody.dom.style.width = (lw + rp) + 'px';
+ this.mainBody.dom.style.width = (tw + rp) + 'px';
+ }
+ }
+});
+
+Ext.ux.grid.LockingColumnModel = Ext.extend(Ext.grid.ColumnModel, {
+ /**
+ * Returns true if the given column index is currently locked
+ * @param {Number} colIndex The column index
+ * @return {Boolean} True if the column is locked
+ */
+ isLocked : function(colIndex){
+ return this.config[colIndex].locked === true;
+ },
+
+ /**
+ * Locks or unlocks a given column
+ * @param {Number} colIndex The column index
+ * @param {Boolean} value True to lock, false to unlock
+ * @param {Boolean} suppressEvent Pass false to cause the columnlockchange event not to fire
+ */
+ setLocked : function(colIndex, value, suppressEvent){
+ if (this.isLocked(colIndex) == value) {
+ return;
+ }
+ this.config[colIndex].locked = value;
+ if (!suppressEvent) {
+ this.fireEvent('columnlockchange', this, colIndex, value);
+ }
+ },
+
+ /**
+ * Returns the total width of all locked columns
+ * @return {Number} The width of all locked columns
+ */
+ getTotalLockedWidth : function(){
+ var totalWidth = 0;
+ for (var i = 0, len = this.config.length; i < len; i++) {
+ if (this.isLocked(i) && !this.isHidden(i)) {
+ totalWidth += this.getColumnWidth(i);
+ }
+ }
+
+ return totalWidth;
+ },
+
+ /**
+ * Returns the total number of locked columns
+ * @return {Number} The number of locked columns
+ */
+ getLockedCount : function() {
+ var len = this.config.length;
+
+ for (var i = 0; i < len; i++) {
+ if (!this.isLocked(i)) {
+ return i;
+ }
+ }
+
+ //if we get to this point all of the columns are locked so we return the total
+ return len;
+ },
+
+ /**
+ * Moves a column from one position to another
+ * @param {Number} oldIndex The current column index
+ * @param {Number} newIndex The destination column index
+ */
+ moveColumn : function(oldIndex, newIndex){
+ var oldLocked = this.isLocked(oldIndex),
+ newLocked = this.isLocked(newIndex);
+
+ if (oldIndex < newIndex && oldLocked && !newLocked) {
+ this.setLocked(oldIndex, false, true);
+ } else if (oldIndex > newIndex && !oldLocked && newLocked) {
+ this.setLocked(oldIndex, true, true);
+ }
+
+ Ext.ux.grid.LockingColumnModel.superclass.moveColumn.apply(this, arguments);
+ }
+});