2 * (c) 2005-2007 Richard Cowin (http://openrico.org)
3 * (c) 2005-2007 Matt Brown (http://dowdybrown.com)
5 * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6 * file except in compliance with the License. You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
11 if(typeof Rico=='undefined') throw("GridCommon requires the Rico JavaScript framework");
12 if(typeof RicoUtil=='undefined') throw("GridCommon requires the RicoUtil Library");
16 * Define methods that are common to both SimpleGrid and LiveGrid
18 Rico.GridCommon = function() {};
20 Rico.GridCommon.prototype = {
22 baseInit: function() {
24 resizeBackground : 'resize.gif',
25 saveColumnInfo : {width:true, filter:false, sort:false}, // save info in cookies?
26 allowColResize : true, // allow user to resize columns
27 windowResize : true, // Resize grid on window.resize event? Set to false when embedded in an accordian.
31 useUnformattedColWidth : true,
32 menuEvent : 'dblclick', // event that triggers menus - click, dblclick, contextmenu, or none (no menus)
33 defaultWidth : 100, // in the absence of any other width info, columns will be this many pixels wide
34 scrollBarWidth : 19, // this is the value used in positioning calculations, it does not actually change the width of the scrollbar
35 minScrollWidth : 100, // min scroll area width when width of frozen columns exceeds window width
38 this.colWidths = new Array();
39 this.hdrCells=new Array();
42 this.tabs=new Array(2);
43 this.thead=new Array(2);
44 this.tbody=new Array(2);
47 attachMenuEvents: function() {
48 if (!this.options.menuEvent || this.options.menuEvent=='none') return;
49 this.hideScroll=navigator.userAgent.match(/Macintosh\b.*\b(Firefox|Camino)\b/i) || Prototype.Browser.Opera;
50 this.options[this.options.menuEvent]=this.handleMenuClick.bindAsEventListener(this);
51 if (this.highlightDiv) {
52 switch (this.options.highlightElem) {
54 this.attachMenu(this.highlightDiv);
57 for (var i=0; i<2; i++)
58 this.attachMenu(this.highlightDiv[i]);
62 for (var i=0; i<2; i++)
63 this.attachMenu(this.tbody[i]);
66 attachMenu: function(elem) {
67 if (this.options.click)
68 Event.observe(elem, 'click', this.options.click, false);
69 if (this.options.dblclick) {
70 if (Prototype.Browser.WebKit || Prototype.Browser.Opera)
71 Event.observe(elem, 'click', this.handleDblClick.bindAsEventListener(this), false);
73 Event.observe(elem, 'dblclick', this.options.dblclick, false);
75 if (this.options.contextmenu) {
76 if (Prototype.Browser.Opera)
77 Event.observe(elem, 'click', this.handleContextMenu.bindAsEventListener(this), false);
79 Event.observe(elem, 'contextmenu', this.options.contextmenu, false);
83 // implement double-click for browsers that don't support a double-click event (e.g. Safari)
84 handleDblClick: function(e) {
85 var elem=Event.element(e);
86 if (this.dblClickElem == elem) {
87 this.options.dblclick(e);
89 this.dblClickElem = elem;
90 this.safariTimer=setTimeout(this.clearDblClick.bind(this),300);
94 clearDblClick: function() {
95 this.dblClickElem=null;
98 // implement right-click for browsers that don't support contextmenu event (e.g. Opera)
99 // use control-click instead
100 handleContextMenu: function(e) {
101 if( typeof( e.which ) == 'number' )
102 var b = e.which; //Netscape compatible
103 else if( typeof( e.button ) == 'number' )
104 var b = e.button; //DOM
107 if (b==1 && e.ctrlKey)
108 this.options.contextmenu(e);
111 cancelMenu: function() {
112 if (this.menu && this.menu.isVisible()) this.menu.cancelmenu();
115 // gather info from original headings
116 getColumnInfo: function(hdrSrc) {
117 Rico.writeDebugMsg("getColumnInfo start");
118 //alert(hdrSrc.tagName+' '+hdrSrc.id+' len='+hdrSrc.length);
119 if (hdrSrc.length == 0) return;
120 this.headerRowCnt=hdrSrc.length;
122 for (r=0; r<this.headerRowCnt; r++) {
123 var headerRow = hdrSrc[r];
124 var headerCells=headerRow.cells;
125 if (r >= this.hdrCells.length) this.hdrCells[r]=new Array();
126 for (c=0; c<headerCells.length; c++) {
128 obj.cell=headerCells[c];
129 obj.colSpan=headerCells[c].colSpan || 1; // Safari & Konqueror return default colspan of 0
130 if (this.options.useUnformattedColWidth) obj.initWidth=headerCells[c].offsetWidth
131 this.hdrCells[r].push(obj);
133 if (headerRow.id.slice(-5)=='_main') {
134 colcnt=this.hdrCells[r].length;
138 Rico.writeDebugMsg("getColumnInfo end");
140 this.headerRowIdx=this.headerRowCnt-1;
141 colcnt=this.hdrCells[this.headerRowIdx].length
146 // create column array
147 createColumnArray: function() {
148 this.direction=Element.getStyle(this.outerDiv,'direction').toLowerCase(); // ltr or rtl
149 this.align=this.direction=='rtl' ? ['right','left'] : ['left','right'];
150 //alert(this.direction+' : '+this.align[0]);
151 this.columns = new Array();
152 for (var c=0 ; c < this.headerColCnt; c++) {
153 Rico.writeDebugMsg("createColumnArray: c="+c);
154 var tabidx=c<this.options.frozenColumns ? 0 : 1;
155 this.columns.push(new Rico.TableColumn(this, c, this.hdrCells[this.headerRowIdx][c], tabidx));
160 // create div structure
161 createDivs: function() {
162 Rico.writeDebugMsg("createDivs start");
163 this.outerDiv = this.createDiv("outer");
164 this.scrollDiv = this.createDiv("scroll",this.outerDiv);
165 this.frozenTabs = this.createDiv("frozenTabs",this.outerDiv);
166 this.innerDiv = this.createDiv("inner",this.outerDiv);
167 this.resizeDiv = this.createDiv("resize",this.outerDiv);
168 this.resizeDiv.style.display="none";
169 this.exportDiv = this.createDiv("export",this.outerDiv);
170 this.exportDiv.style.display="none";
171 //this.frozenTabs.style[this.align[0]]='0px';
172 //this.innerDiv.style[this.align[0]]='0px';
173 Rico.writeDebugMsg("createDivs end");
176 createDiv: function(elemName,elemParent) {
177 var id=this.tableId+"_"+elemName+"Div";
180 var newdiv = document.createElement("div");
182 if (elemParent) elemParent.appendChild(newdiv);
184 newdiv.className = "ricoLG_"+elemName+"Div";
188 baseSizeDivs: function() {
189 this.setOtherHdrCellWidths();
190 this.tabs[0].style.display=this.options.frozenColumns ? '' : 'none';
191 this.hdrHt=Math.max(RicoUtil.nan2zero(this.thead[0].offsetHeight),this.thead[1].offsetHeight);
192 this.dataHt=Math.max(RicoUtil.nan2zero(this.tbody[0].offsetHeight),this.tbody[1].offsetHeight);
193 this.frzWi=this.borderWidth(this.tabs[0]);
194 var borderWi=this.borderWidth(this.columns[0].dataCell);
195 Rico.writeDebugMsg('baseSizeDivs '+this.tableId+': hdrHt='+this.hdrHt+' dataHt='+this.dataHt);
196 //alert(this.tableId+' frzWi='+this.frzWi+' borderWi='+borderWi);
197 for (var i=0; i<this.options.frozenColumns; i++)
198 if (this.columns[i].visible) this.frzWi+=parseInt(this.columns[i].colWidth)+borderWi;
199 this.scrTabWi=this.borderWidth(this.tabs[1]);
200 for (var i=this.options.frozenColumns; i<this.columns.length; i++)
201 if (this.columns[i].visible) this.scrTabWi+=parseInt(this.columns[i].colWidth)+borderWi;
202 this.scrWi=this.scrTabWi+this.options.scrollBarWidth;
203 var wiLimit=RicoUtil.windowWidth()-this.options.scrollBarWidth-8;
204 if (this.outerDiv.parentNode.clientWidth > 0)
205 wiLimit=Math.min(this.outerDiv.parentNode.clientWidth, wiLimit);
206 var overage=this.frzWi+this.scrWi-wiLimit;
207 Rico.writeDebugMsg('baseSizeDivs '+this.tableId+': scrWi='+this.scrWi+' wiLimit='+wiLimit+' overage='+overage+' clientWidth='+this.outerDiv.parentNode.clientWidth);
208 if (overage > 0 && this.options.frozenColumns < this.columns.length)
209 this.scrWi=Math.max(this.scrWi-overage, this.options.minScrollWidth);
210 this.scrollDiv.style.width=this.scrWi+'px';
211 this.scrollDiv.style.top=this.hdrHt+'px';
212 this.frozenTabs.style.width=this.scrollDiv.style[this.align[0]]=this.innerDiv.style[this.align[0]]=this.frzWi+'px';
213 this.outerDiv.style.width=(this.frzWi+this.scrWi)+'px';
216 borderWidth: function(elem) {
217 return RicoUtil.nan2zero(Element.getStyle(elem,'border-left-width')) + RicoUtil.nan2zero(Element.getStyle(elem,'border-right-width'));
220 setOtherHdrCellWidths: function() {
221 for (var r=0; r<this.hdrCells.length; r++) {
222 if (r==this.headerRowIdx) continue;
223 Rico.writeDebugMsg('setOtherHdrCellWidths: r='+r);
225 while (i<this.headerColCnt && c<this.hdrCells[r].length) {
226 var hdrcell=this.hdrCells[r][c];
227 var cell=hdrcell.cell;
228 var origSpan=newSpan=hdrcell.colSpan;
229 for (var w=j=0; j<origSpan; j++, i++) {
230 if (this.columns[i].hdrCell.style.display=='none')
232 else if (this.columns[i].hdrColDiv.style.display!='none')
233 w+=parseInt(this.columns[i].colWidth);
235 if (!hdrcell.hdrColDiv || !hdrcell.hdrCellDiv) {
236 var divs=cell.getElementsByTagName('div');
237 hdrcell.hdrColDiv=(divs.length<1) ? RicoUtil.wrapChildren(cell,'ricoLG_col') : divs[0];
238 hdrcell.hdrCellDiv=(divs.length<2) ? RicoUtil.wrapChildren(hdrcell.hdrColDiv,'ricoLG_cell') : divs[1];
241 cell.style.display='none';
243 hdrcell.hdrColDiv.style.display='none';
244 cell.colSpan=newSpan;
246 cell.style.display='';
247 hdrcell.hdrColDiv.style.display='';
248 cell.colSpan=newSpan;
249 hdrcell.hdrColDiv.style.width=w+'px';
256 cell: function(r,c) {
257 return (0<=c && c<this.columns.length && r>=0) ? this.columns[c].cell(r) : null;
260 availHt: function() {
261 var divPos=Position.page(this.outerDiv);
262 return RicoUtil.windowHeight()-divPos[1]-2*this.options.scrollBarWidth-15; // allow for scrollbar and some margin
265 handleScroll: function(e) {
266 var newTop=(this.hdrHt-this.scrollDiv.scrollTop)+'px';
267 this.tabs[0].style.top=newTop;
268 this.setHorizontalScroll();
271 setHorizontalScroll: function() {
272 var newLeft=(-this.scrollDiv.scrollLeft)+'px';
273 this.hdrTabs[1].style.left=newLeft;
276 pluginScroll: function() {
277 if (this.scrollPluggedIn) return;
278 Event.observe(this.scrollDiv,"scroll",this.scrollEventFunc, false);
279 this.scrollPluggedIn=true;
282 unplugScroll: function() {
283 Event.stopObserving(this.scrollDiv,"scroll", this.scrollEventFunc , false);
284 this.scrollPluggedIn=false;
287 printVisible: function(exportType) {
289 var limit=this.pageSize;
290 if (this.buffer && this.buffer.totalRows < limit) limit=this.buffer.totalRows;
291 for(var r=0; r < limit; r++) {
292 this.exportText+="<tr>";
293 for (var c=0; c<this.columns.length; c++) {
294 if (this.columns[c].visible)
295 this.exportText+="<td style='"+this.exportStyle(this.columns[c].cell(r))+"'>"+this.columns[c].getFormattedValue(r)+"</td>";
297 this.exportText+="</tr>";
299 this.exportFinish(exportType);
302 exportStart: function() {
303 this.exportText="<table border='1' cellspacing='0'><thead style='display: table-header-group;'>";
305 for (var r=0; r<this.hdrCells.length; r++) {
306 if (this.hdrCells[r].length==0 || Element.getStyle(this.hdrCells[r][0].cell.parentNode,'display')=='none') continue;
307 this.exportText+="<tr>";
308 for (var c=0,i=0; c<this.hdrCells[r].length; c++) {
309 var hdrcell=this.hdrCells[r][c];
310 var newSpan=hdrcell.colSpan;
311 for (var j=0; j<hdrcell.colSpan; j++, i++)
312 if (!this.columns[i].visible) newSpan--;
314 var divs=Element.getElementsByClassName(hdrcell.cell,'ricoLG_cell');
315 var cell=divs && divs.length>0 ? divs[0] : hdrcell.cell;
316 this.exportText+="<td style='"+this.exportStyle(cell)+"'";
317 if (hdrcell.colSpan > 1) this.exportText+=" colspan='"+newSpan+"'";
318 this.exportText+=">"+RicoUtil.getInnerText(cell)+"</td>";
321 this.exportText+="</tr>";
324 for (var c=0; c<this.columns.length; c++)
325 this.exportText+="</thead><tbody>";
328 exportFinish: function(exportType) {
329 if (this.hideMsg) this.hideMsg();
330 this.exportText+="</tbody></table>";
331 this.exportDiv.innerHTML=this.exportText;
332 this.exportText=undefined;
333 if (this.cancelMenu) this.cancelMenu();
334 window.open(Rico.htmDir+'export-'+(exportType || 'plain')+'.html?'+this.exportDiv.id,'',this.options.exportWindow);
337 exportStyle: function(elem) {
338 var styleList=['background-color','color','text-align','font-weight']
339 for (var i=0,s=''; i < styleList.length; i++) {
340 var curstyle=Element.getStyle(elem,styleList[i]);
341 if (curstyle) s+=styleList[i]+':'+curstyle+';';
346 // Gets the value of the specified cookie
347 getCookie: function() {
348 var c=RicoUtil.getCookie(this.tableId);
350 var cookieVals=c.split(',');
351 for (var i=0; i<cookieVals.length; i++) {
352 var v=cookieVals[i].split(':');
353 if (v.length!=2) continue;
354 var colnum=parseInt(v[0].slice(1));
355 if (colnum < 0 || colnum >= this.columns.length) continue;
356 var col=this.columns[colnum];
357 switch (v[0].charAt(0)) {
359 col.setColWidth(v[1]);
360 col.customWidth=true;
363 if (v[1].toLowerCase()=='true')
364 col.showColumn(true);
366 col.hideColumn(true);
372 var filterTemp=v[1].split('~');
373 col.filterOp=filterTemp.shift();
374 col.filterValues = [];
375 col.filterType = Rico.TableColumn.USERFILTER;
376 for (var j=0; j<filterTemp.length; j++)
377 col.filterValues.push(unescape(filterTemp[j]));
383 // Write information to cookie
384 setCookie: function() {
386 for (var i=0; i<this.columns.length; i++) {
387 var col=this.columns[i];
388 if (this.options.saveColumnInfo.width) {
389 if (col.customWidth) cookieVals.push('w'+i+':'+col.colWidth);
390 if (col.customVisible) cookieVals.push('h'+i+':'+col.visible);
392 if (this.options.saveColumnInfo.sort) {
393 if (col.currentSort != Rico.TableColumn.UNSORTED)
394 cookieVals.push('s'+i+':'+col.currentSort);
396 if (this.options.saveColumnInfo.filter && col.filterType == Rico.TableColumn.USERFILTER) {
397 var filterTemp=[col.filterOp];
398 for (var j=0; j<col.filterValues.length; j++)
399 filterTemp.push(escape(col.filterValues[j]));
400 cookieVals.push('f'+i+':'+filterTemp.join('~'));
403 if (cookieVals.length > 0)
404 RicoUtil.setCookie(this.tableId, cookieVals.join(','), this.options.cookieDays, this.options.cookiePath, this.options.cookieDomain);
409 Rico.TableColumn = Class.create();
411 Rico.TableColumn.UNFILTERED = 0;
412 Rico.TableColumn.SYSTEMFILTER = 1; /* system-generated filter, not shown to user */
413 Rico.TableColumn.USERFILTER = 2;
415 Rico.TableColumn.UNSORTED = 0;
416 Rico.TableColumn.SORT_ASC = "ASC";
417 Rico.TableColumn.SORT_DESC = "DESC";
418 Rico.TableColumn.MINWIDTH = 10; // min column width when user is resizing
420 Rico.TableColumn.DOLLAR = {type:'number', prefix:'$', decPlaces:2, ClassName:'alignright'};
421 Rico.TableColumn.EURO = {type:'number', prefix:'€', decPlaces:2, ClassName:'alignright'};
422 Rico.TableColumn.PERCENT = {type:'number', suffix:'%', decPlaces:2, multiplier:100, ClassName:'alignright'};
423 Rico.TableColumn.QTY = {type:'number', decPlaces:0, ClassName:'alignright'};
424 Rico.TableColumn.DEFAULT = {type:"raw"};
426 Rico.TableColumn.prototype = {
428 baseInit: function(liveGrid,colIdx,hdrInfo,tabIdx) {
429 Rico.writeDebugMsg("TableColumn.init index="+colIdx+" tabIdx="+tabIdx);
430 this.liveGrid = liveGrid;
432 this.hideWidth = Rico.isKonqueror || Prototype.Browser.WebKit || liveGrid.headerRowCnt>1 ? 5 : 2; // column width used for "hidden" columns. Anything less than 5 causes problems with Konqueror. Best to keep this greater than padding used inside cell.
433 this.options = liveGrid.options;
434 this.tabIdx = tabIdx;
435 this.hdrCell = hdrInfo.cell;
436 this.body = document.getElementsByTagName("body")[0]; // work around FireFox bug (document.body doesn't exist after XSLT)
437 this.displayName = this.getDisplayName(this.hdrCell);
438 var divs=this.hdrCell.getElementsByTagName('div');
439 this.hdrColDiv=(divs.length<1) ? RicoUtil.wrapChildren(this.hdrCell,'ricoLG_col') : divs[0];
440 this.hdrCellDiv=(divs.length<2) ? RicoUtil.wrapChildren(this.hdrColDiv,'ricoLG_cell') : divs[1];
441 var sectionIndex= tabIdx==0 ? colIdx : colIdx-liveGrid.options.frozenColumns;
442 this.dataCell = liveGrid.tbody[tabIdx].rows[0].cells[sectionIndex];
443 var divs=this.dataCell.getElementsByTagName('div');
444 this.dataColDiv=(divs.length<1) ? RicoUtil.wrapChildren(this.dataCell,'ricoLG_col') : divs[0];
446 this.mouseDownHandler= this.handleMouseDown.bindAsEventListener(this);
447 this.mouseMoveHandler= this.handleMouseMove.bindAsEventListener(this);
448 this.mouseUpHandler = this.handleMouseUp.bindAsEventListener(this);
449 this.mouseOutHandler = this.handleMouseOut.bindAsEventListener(this);
451 this.fieldName = 'col'+this.index;
452 var spec = liveGrid.options.columnSpecs[colIdx];
453 this.format=Object.extend( {}, Rico.TableColumn.DEFAULT);
454 switch (typeof spec) {
456 if (typeof spec.format=='string') Object.extend(this.format, Rico.TableColumn[spec.format.toUpperCase()]);
457 Object.extend(this.format, spec);
460 if (spec.slice(0,4)=='spec') spec=spec.slice(4).toUpperCase(); // for backwards compatibility
461 this.format=typeof Rico.TableColumn[spec]=='object' ? Rico.TableColumn[spec] : Rico.TableColumn.DEFAULT;
464 this.dataColDiv.className += (this.format.ClassName) ? ' '+this.format.ClassName : ' '+liveGrid.tableId+'_col'+colIdx;
466 if (typeof this.format.visible=='boolean') this.visible=this.format.visible;
467 if (typeof this.format.type!='string') this.format.type='raw';
468 Rico.writeDebugMsg("TableColumn.init index="+colIdx+" fieldName="+this.fieldName+' type='+this.format.type);
469 this.sortable = typeof this.format.canSort=='boolean' ? this.format.canSort : liveGrid.options.canSortDefault;
470 this.currentSort = Rico.TableColumn.UNSORTED;
471 this.filterable = typeof this.format.canFilter=='boolean' ? this.format.canFilter : liveGrid.options.canFilterDefault;
472 this.filterType = Rico.TableColumn.UNFILTERED;
473 this.hideable = typeof this.format.canHide=='boolean' ? this.format.canHide : liveGrid.options.canHideDefault;
474 if (typeof this.isNullable!='boolean') this.isNullable = /number|date/.test(this.format.type);
475 this.isText = /raw|text/.test(this.format.type);
477 var wi=(typeof(this.format.width)=='number') ? this.format.width : hdrInfo.initWidth;
478 wi=(typeof(wi)=='number') ? Math.max(wi,Rico.TableColumn.MINWIDTH) : liveGrid.options.defaultWidth;
479 this.setColWidth(wi);
480 if (!this.visible) this.setDisplayNone();
481 if (this.options.allowColResize && !this.format.noResize) this.insertResizer();
484 insertResizer: function() {
485 this.hdrCell.style.width='';
486 var resizer=this.hdrCellDiv.appendChild(document.createElement('div'));
487 resizer.className='ricoLG_Resize';
488 resizer.style[this.liveGrid.align[1]]='0px';
489 if (this.options.resizeBackground) {
490 var resizePath=Rico.imgDir+this.options.resizeBackground;
491 if (Prototype.Browser.IE) resizePath=location.protocol+resizePath;
492 resizer.style.backgroundImage='url('+resizePath+')';
494 Event.observe(resizer,"mousedown", this.mouseDownHandler, false);
497 // get the display name of a column
498 getDisplayName: function(el) {
499 var anchors=el.getElementsByTagName("A");
500 //Check the existance of A tags
501 if (anchors.length > 0)
502 return anchors[0].innerHTML;
504 return el.innerHTML.stripTags();
507 _clear: function(gridCell) {
508 gridCell.innerHTML=' ';
511 clearCell: function(rowIndex) {
512 var gridCell=this.cell(rowIndex);
513 this._clear(gridCell,rowIndex);
514 if (!this.liveGrid.buffer) return;
515 var acceptAttr=this.liveGrid.buffer.options.acceptAttr;
516 for (var k=0; k<acceptAttr.length; k++) {
517 switch (acceptAttr[k]) {
518 case 'style': gridCell.style.cssText=''; break;
519 case 'class': gridCell.className=''; break;
520 default: gridCell['_'+acceptAttr[k]]=''; break;
525 dataTable: function() {
526 return this.liveGrid.tabs[this.tabIdx];
529 numRows: function() {
530 return this.dataColDiv.childNodes.length;
533 clearColumn: function() {
534 var childCnt=this.numRows();
535 for (var r=0; r<childCnt; r++)
540 return this.dataColDiv.childNodes[r];
543 getFormattedValue: function(r) {
544 return RicoUtil.getInnerText(this.cell(r));
547 setColWidth: function(wi) {
548 if (typeof wi=='number') {
550 if (wi < Rico.TableColumn.MINWIDTH) return;
553 Rico.writeDebugMsg('setColWidth '+this.index+': '+wi);
555 this.hdrColDiv.style.width=wi;
556 this.dataColDiv.style.width=wi;
559 pluginMouseEvents: function() {
560 if (this.mousePluggedIn==true) return;
561 Event.observe(this.body,"mousemove", this.mouseMoveHandler, false);
562 Event.observe(this.body,"mouseup", this.mouseUpHandler , false);
563 Event.observe(this.body,"mouseout", this.mouseOutHandler , false);
564 this.mousePluggedIn=true;
567 unplugMouseEvents: function() {
568 Event.stopObserving(this.body,"mousemove", this.mouseMoveHandler, false);
569 Event.stopObserving(this.body,"mouseup", this.mouseUpHandler , false);
570 Event.stopObserving(this.body,"mouseout", this.mouseOutHandler , false);
571 this.mousePluggedIn=false;
574 handleMouseDown: function(e) {
575 this.resizeStart=e.clientX;
576 this.origWidth=parseInt(this.colWidth);
577 var p=Position.positionedOffset(this.hdrCell);
578 if (this.liveGrid.direction=='rtl') {
579 this.edge=p[0]+this.liveGrid.options.scrollBarWidth;
580 switch (this.tabIdx) {
581 case 0: this.edge+=this.liveGrid.innerDiv.offsetWidth; break;
582 case 1: this.edge-=this.liveGrid.scrollDiv.scrollLeft; break;
585 this.edge=p[0]+this.hdrCell.offsetWidth;
586 if (this.tabIdx>0) this.edge+=RicoUtil.nan2zero(this.liveGrid.tabs[0].offsetWidth)-this.liveGrid.scrollDiv.scrollLeft;
588 this.liveGrid.resizeDiv.style.left=this.edge+"px";
589 this.liveGrid.resizeDiv.style.display="";
590 this.liveGrid.outerDiv.style.cursor='e-resize';
591 this.tmpHighlight=this.liveGrid.highlightEnabled;
592 this.liveGrid.highlightEnabled=false;
593 this.pluginMouseEvents();
597 handleMouseMove: function(e) {
598 var delta=e.clientX-this.resizeStart;
599 var newWidth=(this.liveGrid.direction=='rtl') ? this.origWidth-delta : this.origWidth+delta;
600 if (newWidth < Rico.TableColumn.MINWIDTH) return;
601 this.liveGrid.resizeDiv.style.left=(this.edge+delta)+"px";
602 this.colWidth=newWidth;
606 handleMouseUp: function(e) {
607 this.unplugMouseEvents();
608 Rico.writeDebugMsg('handleMouseUp '+this.liveGrid.tableId);
609 this.liveGrid.outerDiv.style.cursor='';
610 this.liveGrid.resizeDiv.style.display="none";
611 this.setColWidth(this.colWidth);
612 this.customWidth=true;
613 this.liveGrid.setCookie();
614 this.liveGrid.highlightEnabled=this.tmpHighlight;
615 this.liveGrid.sizeDivs();
619 handleMouseOut: function(e) {
620 var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
621 while (reltg != null && reltg.nodeName.toLowerCase() != 'body')
622 reltg=reltg.parentNode;
623 if (reltg!=null && reltg.nodeName.toLowerCase() == 'body') return true;
624 this.handleMouseUp(e);
628 setDisplayNone: function() {
629 this.hdrCell.style.display='none';
630 this.hdrColDiv.style.display='none';
631 this.dataCell.style.display='none';
632 this.dataColDiv.style.display='none';
635 // recalcTableWidth defaults to true
636 hideColumn: function(noresize) {
637 Rico.writeDebugMsg('hideColumn '+this.liveGrid.tableId);
638 this.setDisplayNone();
639 this.liveGrid.cancelMenu();
641 this.customVisible=true;
642 if (noresize) return;
643 this.liveGrid.setCookie();
644 this.liveGrid.sizeDivs();
647 showColumn: function(noresize) {
648 Rico.writeDebugMsg('showColumn '+this.liveGrid.tableId);
649 this.hdrCell.style.display='';
650 this.hdrColDiv.style.display='';
651 this.dataCell.style.display='';
652 this.dataColDiv.style.display='';
653 this.liveGrid.cancelMenu();
655 this.customVisible=true;
656 if (noresize) return;
657 this.liveGrid.setCookie();
658 this.liveGrid.sizeDivs();
661 setImage: function() {
662 if ( this.currentSort == Rico.TableColumn.SORT_ASC ) {
663 this.imgSort.style.display='';
664 this.imgSort.src=Rico.imgDir+this.options.sortAscendImg;
665 } else if ( this.currentSort == Rico.TableColumn.SORT_DESC ) {
666 this.imgSort.style.display='';
667 this.imgSort.src=Rico.imgDir+this.options.sortDescendImg;
669 this.imgSort.style.display='none';
671 if (this.filterType == Rico.TableColumn.USERFILTER) {
672 this.imgFilter.style.display='';
673 this.imgFilter.title=this.getFilterText();
675 this.imgFilter.style.display='none';
679 canHideShow: function() {
680 return this.hideable;
685 Rico.includeLoaded('ricoGridCommon.js');