/* * (c) 2005-2009 Richard Cowin (http://openrico.org) * (c) 2005-2009 Matt Brown (http://dowdybrown.com) * * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this * file except in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions * and limitations under the License. */ if(typeof Rico=='undefined') throw("GridCommon requires the Rico JavaScript framework"); if(typeof RicoUtil=='undefined') throw("GridCommon requires the RicoUtil Library"); /** * @class Define methods that are common to both SimpleGrid and LiveGrid */ Rico.GridCommon = function() {}; Rico.GridCommon.prototype = { baseInit: function() { this.options = { resizeBackground : 'resize.gif', saveColumnInfo : {width:true, filter:false, sort:false}, // save info in cookies? cookiePrefix : 'RicoGrid.', allowColResize : true, // allow user to resize columns windowResize : true, // Resize grid on window.resize event? Set to false when embedded in an accordian. click : null, dblclick : null, contextmenu : null, useUnformattedColWidth : true, menuEvent : 'dblclick', // event that triggers menus - click, dblclick, contextmenu, or none (no menus) defaultWidth : 100, // in the absence of any other width info, columns will be this many pixels wide scrollBarWidth : 19, // this is the value used in positioning calculations, it does not actually change the width of the scrollbar minScrollWidth : 100, // min scroll area width when width of frozen columns exceeds window width exportWindow : "height=400,width=500,scrollbars=1,menubar=1,resizable=1", exportStyleList : ['background-color','color','text-align','font-weight','font-size','font-family'], exportImgTags : false, // applies to grid header and to SimpleGrid cells (not LiveGrid cells) exportFormFields : true, FilterLocation : null, // heading row number to place filters. -1=add a new heading row. FilterAllToken : '___ALL___', // select box value to use to indicate ALL columnSpecs : [] }; this.colWidths = []; this.hdrCells=[]; this.headerColCnt=0; this.headerRowIdx=0; // row in header which gets resizers (no colspan's in this row) this.tabs=new Array(2); this.thead=new Array(2); this.tbody=new Array(2); }, attachMenuEvents: function() { var i; if (!this.options.menuEvent || this.options.menuEvent=='none') return; this.hideScroll=navigator.userAgent.match(/Macintosh\b.*\b(Firefox|Camino)\b/i) || (Prototype.Browser.Opera && parseFloat(window.opera.version())<9.5); this.options[this.options.menuEvent]=this.handleMenuClick.bindAsEventListener(this); if (this.highlightDiv) { switch (this.options.highlightElem) { case 'cursorRow': this.attachMenu(this.highlightDiv[0]); break; case 'cursorCell': for (i=0; i<2; i++) { this.attachMenu(this.highlightDiv[i]); } break; } } for (i=0; i<2; i++) { this.attachMenu(this.tbody[i]); } }, attachMenu: function(elem) { if (this.options.click) Event.observe(elem, 'click', this.options.click, false); if (this.options.dblclick) { if (Prototype.Browser.WebKit || Prototype.Browser.Opera) Event.observe(elem, 'click', this.handleDblClick.bindAsEventListener(this), false); else Event.observe(elem, 'dblclick', this.options.dblclick, false); } if (this.options.contextmenu) { if (Prototype.Browser.Opera || Rico.isKonqueror) Event.observe(elem, 'click', this.handleContextMenu.bindAsEventListener(this), false); else Event.observe(elem, 'contextmenu', this.options.contextmenu, false); } }, /** * implement double-click for browsers that don't support a double-click event (e.g. Safari) */ handleDblClick: function(e) { var elem=Event.element(e); if (this.dblClickElem == elem) { this.options.dblclick(e); } else { this.dblClickElem = elem; this.safariTimer=setTimeout(this.clearDblClick.bind(this),300); } }, clearDblClick: function() { this.dblClickElem=null; }, /** * implement right-click for browsers that don't support contextmenu event (e.g. Opera, Konqueror) * use control-click instead */ handleContextMenu: function(e) { var b; if( typeof( e.which ) == 'number' ) b = e.which; //Netscape compatible else if( typeof( e.button ) == 'number' ) b = e.button; //DOM else return; if (b==1 && e.ctrlKey) { this.options.contextmenu(e); } }, cancelMenu: function() { if (this.menu && this.menu.isVisible()) this.menu.cancelmenu(); }, /** * gather info from original headings */ getColumnInfo: function(hdrSrc) { Rico.writeDebugMsg('getColumnInfo: len='+hdrSrc.length); if (hdrSrc.length == 0) return 0; this.headerRowCnt=hdrSrc.length; var r,c,colcnt; for (r=0; r= this.hdrCells.length) this.hdrCells[r]=[]; for (c=0; c 0) wiLimit=Math.min(this.outerDiv.parentNode.clientWidth, wiLimit); var overage=this.frzWi+this.scrWi-wiLimit; Rico.writeDebugMsg('baseSizeDivs '+this.tableId+': scrWi='+this.scrWi+' wiLimit='+wiLimit+' overage='+overage+' clientWidth='+this.outerDiv.parentNode.clientWidth); if (overage > 0 && this.options.frozenColumns < this.columns.length) this.scrWi=Math.max(this.scrWi-overage, this.options.minScrollWidth); this.scrollDiv.style.width=this.scrWi+'px'; this.scrollDiv.style.top=this.hdrHt+'px'; this.frozenTabs.style.width=this.scrollDiv.style[this.align[0]]=this.innerDiv.style[this.align[0]]=this.frzWi+'px'; this.outerDiv.style.width=(this.frzWi+this.scrWi)+'px'; }, /** * Returns the sum of the left & right border widths of an element */ borderWidth: function(elem) { return RicoUtil.nan2zero(Element.getStyle(elem,'border-left-width')) + RicoUtil.nan2zero(Element.getStyle(elem,'border-right-width')); }, setOtherHdrCellWidths: function() { var c,i,j,r,w,hdrcell,cell,origSpan,newSpan,divs; for (r=0; r'; }, /** * Returns a div for the cell at the specified row and column index. * In SimpleGrid, r can refer to any row in the grid. * In LiveGrid, r refers to a visible row (row 0 is the first visible row). */ cell: function(r,c) { return (0<=c && c=0) ? this.columns[c].cell(r) : null; }, /** * Returns the screen height available for a grid */ availHt: function() { var divPos=Position.page(this.outerDiv); return RicoUtil.windowHeight()-divPos[1]-2*this.options.scrollBarWidth-15; // allow for scrollbar and some margin }, setHorizontalScroll: function() { var newLeft=(-this.scrollDiv.scrollLeft)+'px'; this.hdrTabs[1].style.left=newLeft; }, pluginScroll: function() { if (this.scrollPluggedIn) return; Event.observe(this.scrollDiv,"scroll",this.scrollEventFunc, false); this.scrollPluggedIn=true; }, unplugScroll: function() { Event.stopObserving(this.scrollDiv,"scroll", this.scrollEventFunc , false); this.scrollPluggedIn=false; }, hideMsg: function() { if (this.messageDiv.style.display=="none") return; this.messageDiv.style.display="none"; this.messageShadow.hide(); }, showMsg: function(msg) { this.messageDiv.innerHTML=msg; this.centerMsg(this.messageDiv); this.messageShadow.show(); Rico.writeDebugMsg("showMsg: "+msg); }, centerMsg: function(div) { Element.show(div); var msgWidth=div.offsetWidth; var msgHeight=div.offsetHeight; var divwi=this.outerDiv.offsetWidth; var divht=this.outerDiv.offsetHeight; div.style.top=parseInt((divht-msgHeight)/2,10)+'px'; div.style.left=parseInt((divwi-msgWidth)/2,10)+'px'; }, /** * @return array of column objects which have invisible status */ listInvisible: function() { var hiddenColumns=[]; for (var x=0;x"; } this.exportText+=""; if (this.exportHeader) this.exportText+=this.exportHeader; for (r=0; r 0) { divs=Element.select(hdrcell.cell,'.ricoLG_cell'); cell=divs && divs.length>0 ? divs[0] : hdrcell.cell; this.exportText+=" 1) this.exportText+=" colspan='"+newSpan+"'"; this.exportText+=">"+RicoUtil.getInnerText(cell,!this.options.exportImgTags, !this.options.exportFormFields, 'NoExport')+""; } } this.exportText+=""; } this.exportText+=""; }, /** * Support function for printVisible(). * exportType is optional and defaults 'plain'; 'owc' can be used for IE users with Office Web Components. */ exportFinish: function(exportType) { if (this.hideMsg) this.hideMsg(); window.status=RicoTranslate.getPhraseById('exportComplete'); if (this.exportRows.length > 0) this.exportText+=''+this.exportRows.join('')+''; if (this.exportFooter) this.exportText+=this.exportFooter; this.exportText+=""; this.exportDiv.innerHTML=this.exportText; this.exportText=undefined; this.exportRows=undefined; if (this.cancelMenu) this.cancelMenu(); var w=window.open(Rico.htmDir+'export-'+(exportType || 'plain')+'.html?'+this.exportDiv.id,'',this.options.exportWindow); if (w == null) alert(RicoTranslate.getPhraseById('disableBlocker')); }, /** * Support function for printVisible() */ exportStyle: function(elem) { var styleList=this.options.exportStyleList; for (var i=0,s=''; i < styleList.length; i++) { try { var curstyle=Element.getStyle(elem,styleList[i]); if (curstyle) s+=styleList[i]+':'+curstyle+';'; } catch(e) {}; } return s; }, /** * Gets the value of the grid cookie and interprets the contents. * All information for a particular grid is stored in a single cookie. * This may include column widths, column hide/show status, current sort, and any column filters. */ getCookie: function() { var c=RicoUtil.getCookie(this.options.cookiePrefix+this.tableId); if (!c) return; var cookieVals=c.split(','); for (var i=0; i= this.columns.length) continue; var col=this.columns[colnum]; switch (v[0].charAt(0)) { case 'w': col.setColWidth(v[1]); col.customWidth=true; break; case 'h': if (v[1].toLowerCase()=='true') col.hideshow(true,true); else col.hideshow(false,true); break; case 's': if (!this.options.saveColumnInfo.sort || !col.sortable) break; col.setSorted(v[1]); break; case 'f': if (!this.options.saveColumnInfo.filter || !col.filterable) break; var filterTemp=v[1].split('~'); col.filterOp=filterTemp.shift(); col.filterValues = []; col.filterType = Rico.TableColumn.USERFILTER; for (var j=0; j 0) return anchors[0].innerHTML; else return el.innerHTML.stripTags(); }, _clear: function(gridCell) { gridCell.innerHTML=' '; }, clearCell: function(rowIndex) { var gridCell=this.cell(rowIndex); this._clear(gridCell,rowIndex); if (!this.liveGrid.buffer) return; var acceptAttr=this.liveGrid.buffer.options.acceptAttr; for (var k=0; k0) this.edge+=RicoUtil.nan2zero(this.liveGrid.tabs[0].offsetWidth)-this.liveGrid.scrollDiv.scrollLeft; } this.liveGrid.resizeDiv.style.left=this.edge+"px"; this.liveGrid.resizeDiv.style.display=""; this.liveGrid.outerDiv.style.cursor='e-resize'; this.tmpHighlight=this.liveGrid.highlightEnabled; this.liveGrid.highlightEnabled=false; this.pluginMouseEvents(); Event.stop(e); }, handleMouseMove: function(e) { var delta=e.clientX-this.resizeStart; var newWidth=(this.liveGrid.direction=='rtl') ? this.origWidth-delta : this.origWidth+delta; if (newWidth < Rico.TableColumn.MINWIDTH) return; this.liveGrid.resizeDiv.style.left=(this.edge+delta)+"px"; this.colWidth=newWidth; Event.stop(e); }, handleMouseUp: function(e) { this.unplugMouseEvents(); Rico.writeDebugMsg('handleMouseUp '+this.liveGrid.tableId); this.liveGrid.outerDiv.style.cursor=''; this.liveGrid.resizeDiv.style.display="none"; this.setColWidth(this.colWidth); this.customWidth=true; this.liveGrid.setCookie(); this.liveGrid.highlightEnabled=this.tmpHighlight; this.liveGrid.sizeDivs(); Event.stop(e); }, handleMouseOut: function(e) { var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement; while (reltg != null && reltg.nodeName.toLowerCase() != 'body') reltg=reltg.parentNode; if (reltg!=null && reltg.nodeName.toLowerCase() == 'body') return true; this.handleMouseUp(e); return true; }, setDisplay: function(d) { this.hdrCell.style.display=d; this.hdrColDiv.style.display=d; this.dataCell.style.display=d; this.dataColDiv.style.display=d; }, hideshow: function(visible,noresize) { this.setDisplay(visible ? '' : 'none'); this.liveGrid.cancelMenu(); this.visible=visible; this.customVisible=true; if (noresize) return; this.liveGrid.setCookie(); this.liveGrid.sizeDivs(); }, hideColumn: function() { Rico.writeDebugMsg('hideColumn '+this.liveGrid.tableId); this.hideshow(false,false); }, showColumn: function() { Rico.writeDebugMsg('showColumn '+this.liveGrid.tableId); this.hideshow(true,false); }, chooseColumn: function(e) { var elem=Event.element(e); this.hideshow(elem.checked,false); }, setImage: function() { if ( this.currentSort == Rico.TableColumn.SORT_ASC ) { this.imgSort.style.display=''; this.imgSort.src=Rico.imgDir+this.options.sortAscendImg; } else if ( this.currentSort == Rico.TableColumn.SORT_DESC ) { this.imgSort.style.display=''; this.imgSort.src=Rico.imgDir+this.options.sortDescendImg; } else { this.imgSort.style.display='none'; } if (this.filterType == Rico.TableColumn.USERFILTER) { this.imgFilter.style.display=''; this.imgFilter.title=this.getFilterText(); } else { this.imgFilter.style.display='none'; } }, canHideShow: function() { return this.hideable; } }; Rico.includeLoaded('ricoGridCommon.js');