/* * (c) 2005-2009 Richard Cowin (http://openrico.org) * (c) 2005-2009 Matt Brown (http://dowdybrown.com) * * 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"); /** * Define methods that are common to both SimpleGrid and LiveGrid */ Rico.GridCommon = { baseInit: function() { this.options = { 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, menuEvent : null, // event that triggers menus - click, dblclick, contextmenu, or none (no menus) defaultWidth : -1, // if -1, then use unformatted column width 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 frozenColumns : 0, exportWindow : "height=400,width=500,scrollbars=1,menubar=1,resizable=1,location=0,toolbar=0,status=0", 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.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) || (Rico.isOpera && parseFloat(window.opera.version())<9.5); this.options[this.options.menuEvent]=Rico.eventHandle(this,'handleMenuClick'); 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) Rico.eventBind(elem, 'click', this.options.click, false); if (this.options.dblclick) { if (Rico.isWebKit || Rico.isOpera) Rico.eventBind(elem, 'click', Rico.eventHandle(this,'handleDblClick'), false); else Rico.eventBind(elem, 'dblclick', this.options.dblclick, false); } if (this.options.contextmenu) { if (Rico.isOpera || Rico.isKonqueror) Rico.eventBind(elem, 'click', Rico.eventHandle(this,'handleContextMenu'), false); else Rico.eventBind(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=Rico.eventElement(e); if (this.dblClickElem == elem) { this.options.dblclick(e); } else { this.dblClickElem = elem; this.safariTimer=Rico.runLater(300,this,'clearDblClick'); } }, 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.cancelmenu(); }, /** * gather info from original headings */ getColumnInfo: function(hdrSrc) { Rico.log('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.log('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.frozenTabs.style.width=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) { var l=Rico.nan2zero(Rico.getStyle(elem,'borderLeftWidth')); var r=Rico.nan2zero(Rico.getStyle(elem,'borderRightWidth')); Rico.log((elem.id || elem.tagName)+' borderWidth: L='+l+', R='+r); return l + r; // return Rico.nan2zero(Rico.getStyle(elem,'borderLeftWidth')) + Rico.nan2zero(Rico.getStyle(elem,'borderRightWidth')); }, 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=Rico.cumulativeOffset(this.outerDiv); return Rico.windowHeight()-divPos.top-2*this.options.scrollBarWidth-15; // allow for scrollbar and some margin }, setHorizontalScroll: function() { var newLeft=(-this.scrollDiv.scrollLeft)+'px'; this.hdrTabs[1].style.marginLeft=newLeft; }, pluginScroll: function() { if (this.scrollPluggedIn) return; Rico.eventBind(this.scrollDiv,"scroll",this.scrollEventFunc, false); this.scrollPluggedIn=true; }, unplugScroll: function() { Rico.eventUnbind(this.scrollDiv,"scroll", this.scrollEventFunc , false); this.scrollPluggedIn=false; }, hideMsg: function() { this.messagePopup.closePopup(); }, showMsg: function(msg) { this.messagePopup.setContent(msg); this.messagePopup.centerPopup(); Rico.log("showMsg: "+msg); }, /** * @return array of column objects which have invisible status */ listInvisible: function(attr) { var hiddenColumns=[]; for (var x=0;x"; } this.exportText+=""; if (this.exportHeader) this.exportText+=this.exportHeader; for (r=0; r 0) { divs=Rico.select('.ricoLG_cell',hdrcell.cell); cell=divs && divs.length>0 ? divs[0] : hdrcell.cell; this.exportText+=" 1) this.exportText+=" colspan='"+newSpan+"'"; this.exportText+=">"+Rico.getInnerText(cell,!this.options.exportImgTags, !this.options.exportFormFields, 'NoExport')+""; } } this.exportText+=""; } this.exportText+=""; }, /** * Support function for printVisible(). */ exportFinish: function() { if (this.hideMsg) this.hideMsg(); window.status=Rico.getPhraseById('exportComplete'); if (this.exportRows.length > 0) this.exportText+=''+this.exportRows.join('')+''; if (this.exportFooter) this.exportText+=this.exportFooter; this.exportText+=""; if (this.cancelMenu) this.cancelMenu(); var w=window.open('','_blank',this.options.exportWindow); if (w == null) { alert(Rico.getPhraseById('disableBlocker')); } else { w.document.open(); w.document.write(this.exportText); w.document.close(); } this.exportText=undefined; this.exportRows=undefined; }, /** * Support function for printVisible() */ exportStyle: function(elem,styleList) { for (var i=0,s=''; i < styleList.length; i++) { try { var curstyle=Rico.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=Rico.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.ColumnConst.USERFILTER; for (var j=0; j 0) return anchors[0].innerHTML; else return Rico.stripTags(el.innerHTML); }, _clear: function(gridCell) { gridCell.innerHTML=' '; }, clearCell: function(rowIndex) { var gridCell=this.cell(rowIndex); this._clear(gridCell,rowIndex); if (this.liveGrid.buffer && this.liveGrid.buffer.options.acceptStyle) gridCell.style.cssText=''; }, dataTable: function() { return this.liveGrid.tabs[this.tabIdx]; }, numRows: function() { return this.dataColDiv.childNodes.length; }, clearColumn: function() { var childCnt=this.numRows(); for (var r=0; r0) this.edge+=Rico.nan2zero(this.liveGrid.tabs[0].offsetWidth); } 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(); Rico.eventStop(e); }, handleMouseMove: function(e) { var delta=Rico.eventClient(e).x-this.resizeStart; var newWidth=(this.liveGrid.direction=='rtl') ? this.origWidth-delta : this.origWidth+delta; if (newWidth < Rico.ColumnConst.MINWIDTH) return; this.liveGrid.resizeDiv.style.left=(this.edge+delta)+"px"; this.colWidth=newWidth; Rico.eventStop(e); }, handleMouseUp: function(e) { this.unplugMouseEvents(); Rico.log('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(); Rico.eventStop(e); }, handleMouseOut: function(e) { var reltg = Rico.eventRelatedTarget(e) || 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.log('hideColumn '+this.liveGrid.tableId); this.hideshow(false,false); }, showColumn: function() { Rico.log('showColumn '+this.liveGrid.tableId); this.hideshow(true,false); }, chooseColumn: function(e) { var elem=Rico.eventElement(e); this.hideshow(elem.checked,false); }, setImage: function() { if ( this.currentSort == Rico.ColumnConst.SORT_ASC ) { this.imgSort.style.display='inline-block'; this.imgSort.className=Rico.theme.sortAsc || 'rico-icon ricoLG_sortAsc'; } else if ( this.currentSort == Rico.ColumnConst.SORT_DESC ) { this.imgSort.style.display='inline-block'; this.imgSort.className=Rico.theme.sortDesc || 'rico-icon ricoLG_sortDesc'; } else { this.imgSort.style.display='none'; } if (this.filterType == Rico.ColumnConst.USERFILTER) { this.imgFilter.style.display='inline-block'; this.imgFilter.title=this.getFilterText(); } else { this.imgFilter.style.display='none'; } }, canHideShow: function() { return this.hideable; } };