diff options
Diffstat (limited to 'includes/js/dojox/grid/_grid')
29 files changed, 5309 insertions, 0 deletions
diff --git a/includes/js/dojox/grid/_grid/Grid.css b/includes/js/dojox/grid/_grid/Grid.css new file mode 100644 index 0000000..655be54 --- /dev/null +++ b/includes/js/dojox/grid/_grid/Grid.css @@ -0,0 +1,201 @@ +.dojoxGrid { + position: relative; + background-color: #EBEADB; + font-family: Geneva, Arial, Helvetica, sans-serif; + -moz-outline-style: none; + outline: none; + overflow: hidden; + height: 0; +} +.dojoxGrid table { + padding: 0; +} +.dojoxGrid td { + -moz-outline: none; +} +.dojoxGrid-master-header { + position: relative; +} +.dojoxGrid-master-view { + position: relative; +} +.dojoxGrid-view { + position: absolute; + overflow: hidden; +} +.dojoxGrid-header { + position: absolute; + overflow: hidden; +} +.dojoxGrid-header { + background-color: #E8E1CF; +} +.dojoxGrid-header table { + text-align: center; +} +.dojoxGrid-header .dojoxGrid-cell-content { + text-align: center; +} +.dojoxGrid-header .dojoxGrid-cell { + border: 1px solid; + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x; + padding-bottom: 2px; +} +.dojoxGrid-header .dojoxGrid-cell-over { + background-image: none; + background-color: white; + border-bottom-color: #FEBE47; + margin-bottom: 0; + padding-bottom: 0; + border-bottom-width: 3px; +} +.dojoxGrid-sort-down { + background: url(images/grid_sort_down.gif) left no-repeat; + padding-left:16px; + margin-left:4px; +} +.dojoxGrid-sort-up { + background: url(images/grid_sort_up.gif) left no-repeat; + padding-left:16px; + margin-left:4px; +} +.dojoxGrid-scrollbox { + position: relative; + overflow: scroll; + background-color: white; + width: 100%; +} +.dojoxGrid-content { + position: relative; + overflow: hidden; + -moz-outline-style: none; + outline: none; +} +.dojoxGrid-rowbar { + border: 1px solid; + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + border-top: none; + background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x; +} +.dojoxGrid-rowbar-inner { + border-top: 1px solid #F6F4EB; +} +.dojoxGrid-rowbar-over { + background-image: none; + background-color: white; + border-top-color: #FEBE47; + border-bottom-color: #FEBE47; +} +.dojoxGrid-rowbar-selected { + background-color: #D9E8F9; + background-image: none; + + background-position: center; + background-repeat: no-repeat; +} +.dojoxGrid-row { + position: relative; + width: 9000em; +} +.dojoxGrid-row { + + border: 1px solid #E8E4D8; + border-color: #F8F7F1; + + border-left: none; + border-right: none; + background-color: white; + border-top: none; +} +.dojoxGrid-row-over { + border-top-color: #FEBE47; + border-bottom-color: #FEBE47; + + + +} +.dojoxGrid-row-odd { + background-color: #FFFDF3; + +} +.dojoxGrid-row-selected { + background-color: #D9E8F9; +} +.dojoxGrid-row-table { + table-layout: fixed; + width: 0; +} +.dojoxGrid-invisible { + visibility: hidden; +} +.Xdojo-ie .dojoxGrid-invisible { + display: none; +} +.dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td { + border-top-width: 0; + border-bottom-width: 0; + padding-top: 0; + padding-bottom: 0; + height: 0; + overflow: hidden; +} +.dojoxGrid-cell { + border: 1px solid; + border-color: #EBEADB; + border-right-color: #D5CDB5; + padding: 3px 3px 3px 3px; + text-align: left; + overflow: hidden; +} +.dojoxGrid-cell-focus { + border: 1px dashed blue; +} +.dojoxGrid-cell-over { + border: 1px dotted #FEBE47; +} +.dojoxGrid-cell-focus.dojoxGrid-cell-over { + border: 1px dotted green; +} +.dojoxGrid-cell-clip { + width: 100%; + overflow: hidden; + white-space:nowrap; + text-overflow: ellipsis; +} +.dojoxGrid-row-editing td { + background-color: #F4FFF4; +} +.dojoxGrid-row-inserting td { + background-color: #F4FFF4; +} +.dojoxGrid-row-inflight td { + background-color: #F2F7B7; +} +.dojoxGrid-row-error td { + background-color: #F8B8B6; +} +.dojoxGrid-input, .dojoxGrid-select, .dojoxGrid-textarea { + margin: 0; + padding: 0; + border-style: none; + width: 100%; + font-size: 100%; + font-family: inherit; +} +.dojoxGrid-hidden-focus { + position: absolute; + left: -1000px; + top: -1000px; + height: 0px, width: 0px; +} +.gridArrowButtonChar { + display:none !important; +} +.dijit_a11y .gridArrowButtonChar { + display:inline !important; +} +.dijit_a11y .dojoxGrid-sort-down, .dijit_a11y .dojoxGrid-sort-up { + margin-left: 0; + padding-left: 0; +} diff --git a/includes/js/dojox/grid/_grid/Grid.css.commented.css b/includes/js/dojox/grid/_grid/Grid.css.commented.css new file mode 100644 index 0000000..227ffa3 --- /dev/null +++ b/includes/js/dojox/grid/_grid/Grid.css.commented.css @@ -0,0 +1,258 @@ +.dojoxGrid { + position: relative; + background-color: #EBEADB; + font-family: Geneva, Arial, Helvetica, sans-serif; + -moz-outline-style: none; + outline: none; + overflow: hidden; + height: 0; +} + +.dojoxGrid table { + padding: 0; +} + +.dojoxGrid td { + -moz-outline: none; +} + +/* master header */ + +.dojoxGrid-master-header { + position: relative; +} + +/* master view */ + +.dojoxGrid-master-view { + position: relative; +} + +/* views */ + +.dojoxGrid-view { + position: absolute; + overflow: hidden; +} + +/* header */ + +.dojoxGrid-header { + position: absolute; + overflow: hidden; +} + +.dojoxGrid-header { + background-color: #E8E1CF; +} + +.dojoxGrid-header table { + text-align: center; +} + +.dojoxGrid-header .dojoxGrid-cell-content { + text-align: center; +} + +.dojoxGrid-header .dojoxGrid-cell { + border: 1px solid; + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x; + padding-bottom: 2px; +} + +.dojoxGrid-header .dojoxGrid-cell-over { + background-image: none; + background-color: white; + border-bottom-color: #FEBE47; + margin-bottom: 0; + padding-bottom: 0; + border-bottom-width: 3px; +} + +.dojoxGrid-sort-down { + background: url(images/grid_sort_down.gif) left no-repeat; + padding-left:16px; + margin-left:4px; +} + +.dojoxGrid-sort-up { + background: url(images/grid_sort_up.gif) left no-repeat; + padding-left:16px; + margin-left:4px; +} + +/* content */ + +.dojoxGrid-scrollbox { + position: relative; + overflow: scroll; + background-color: white; + width: 100%; +} + +.dojoxGrid-content { + position: relative; + overflow: hidden; + -moz-outline-style: none; + outline: none; +} + +/* rowbar */ + +.dojoxGrid-rowbar { + border: 1px solid; + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + border-top: none; + background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x; +} + +.dojoxGrid-rowbar-inner { + border-top: 1px solid #F6F4EB; +} + +.dojoxGrid-rowbar-over { + background-image: none; + background-color: white; + border-top-color: #FEBE47; + border-bottom-color: #FEBE47; +} + +.dojoxGrid-rowbar-selected { + background-color: #D9E8F9; + background-image: none; + /*background-image: url(images/grid_green_dot.gif);*/ + background-position: center; + background-repeat: no-repeat; +} + +/* rows */ + +.dojoxGrid-row { + position: relative; + width: 9000em; +} + +.dojoxGrid-row { + /*border: 1px solid #E8E4D8;*/ + border: 1px solid #E8E4D8; + border-color: #F8F7F1; + /*padding: 0 0 1px 0;*/ + border-left: none; + border-right: none; + background-color: white; + border-top: none; +} + +.dojoxGrid-row-over { + border-top-color: #FEBE47; + border-bottom-color: #FEBE47; + /*border-bottom-width: 2px; + padding-bottom: 0;*/ + /*background-color: #FFDD9D;*/ + /*background-color: #FDFDFD;*/ +} + +.dojoxGrid-row-odd { + background-color: #FFFDF3; + /*background-color: #F9F7E8;*/ +} + +.dojoxGrid-row-selected { + background-color: #D9E8F9; +} + +.dojoxGrid-row-table { + table-layout: fixed; + width: 0; +} + +.dojoxGrid-invisible { + visibility: hidden; +} + +.Xdojo-ie .dojoxGrid-invisible { + display: none; +} + +.dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td { + border-top-width: 0; + border-bottom-width: 0; + padding-top: 0; + padding-bottom: 0; + height: 0; + overflow: hidden; +} + +/* cells */ + +.dojoxGrid-cell { + border: 1px solid; + border-color: #EBEADB; + border-right-color: #D5CDB5; + padding: 3px 3px 3px 3px; + text-align: left; + overflow: hidden; +} + +.dojoxGrid-cell-focus { + border: 1px dashed blue; +} + +.dojoxGrid-cell-over { + border: 1px dotted #FEBE47; +} + +.dojoxGrid-cell-focus.dojoxGrid-cell-over { + border: 1px dotted green; +} + +.dojoxGrid-cell-clip { + width: 100%; + overflow: hidden; + white-space:nowrap; + text-overflow: ellipsis; +} + +/* editing */ + +.dojoxGrid-row-editing td { + background-color: #F4FFF4; +} + +.dojoxGrid-row-inserting td { + background-color: #F4FFF4; +} +.dojoxGrid-row-inflight td { + background-color: #F2F7B7; +} +.dojoxGrid-row-error td { + background-color: #F8B8B6; +} + +.dojoxGrid-input, .dojoxGrid-select, .dojoxGrid-textarea { + margin: 0; + padding: 0; + border-style: none; + width: 100%; + font-size: 100%; + font-family: inherit; +} + +.dojoxGrid-hidden-focus { + position: absolute; + left: -1000px; + top: -1000px; + height: 0px, width: 0px; +} + +.gridArrowButtonChar { + display:none !important; +} +.dijit_a11y .gridArrowButtonChar { + display:inline !important; +} +.dijit_a11y .dojoxGrid-sort-down, .dijit_a11y .dojoxGrid-sort-up { + margin-left: 0; + padding-left: 0; +} diff --git a/includes/js/dojox/grid/_grid/Grid_rtl.css b/includes/js/dojox/grid/_grid/Grid_rtl.css new file mode 100644 index 0000000..88ab215 --- /dev/null +++ b/includes/js/dojox/grid/_grid/Grid_rtl.css @@ -0,0 +1,8 @@ +.dijitRtl .dojoxGrid-header table { +} +.dj_ie .dijitRtl .dojoxGrid-header table { + float:none; +} +.dijitRtl .dojoxGrid-content { + float:left; +} diff --git a/includes/js/dojox/grid/_grid/Grid_rtl.css.commented.css b/includes/js/dojox/grid/_grid/Grid_rtl.css.commented.css new file mode 100644 index 0000000..c240b4c --- /dev/null +++ b/includes/js/dojox/grid/_grid/Grid_rtl.css.commented.css @@ -0,0 +1,10 @@ +.dijitRtl .dojoxGrid-header table { +} + +.dj_ie .dijitRtl .dojoxGrid-header table { + float:none; +} + +.dijitRtl .dojoxGrid-content { + float:left; +} diff --git a/includes/js/dojox/grid/_grid/builder.js b/includes/js/dojox/grid/_grid/builder.js new file mode 100644 index 0000000..dccf7e2 --- /dev/null +++ b/includes/js/dojox/grid/_grid/builder.js @@ -0,0 +1,522 @@ +if(!dojo._hasResource["dojox.grid._grid.builder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.builder"] = true; +dojo.provide("dojox.grid._grid.builder"); +dojo.require("dojox.grid._grid.drag"); + +dojo.declare("dojox.grid.Builder", + null, + { + // summary: + // Base class to produce html for grid content. + // Also provide event decoration, providing grid related information inside the event object + // passed to grid events. + constructor: function(inView){ + this.view = inView; + this.grid = inView.grid; + }, + + view: null, + // boilerplate HTML + _table: '<table class="dojoxGrid-row-table" border="0" cellspacing="0" cellpadding="0" role="wairole:presentation">', + + // generate starting tags for a cell + generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){ + var result = [], html; + if (isHeader){ + html = [ '<th tabIndex="-1" role="wairole:columnheader"' ]; + }else{ + html = [ '<td tabIndex="-1" role="wairole:gridcell"' ]; + } + inCell.colSpan && html.push(' colspan="', inCell.colSpan, '"'); + inCell.rowSpan && html.push(' rowspan="', inCell.rowSpan, '"'); + html.push(' class="dojoxGrid-cell '); + inCell.classes && html.push(inCell.classes, ' '); + inMoreClasses && html.push(inMoreClasses, ' '); + // result[0] => td opener, style + result.push(html.join('')); + // SLOT: result[1] => td classes + result.push(''); + html = ['" idx="', inCell.index, '" style="']; + html.push(inCell.styles, inMoreStyles||''); + inCell.unitWidth && html.push('width:', inCell.unitWidth, ';'); + // result[2] => markup + result.push(html.join('')); + // SLOT: result[3] => td style + result.push(''); + html = [ '"' ]; + inCell.attrs && html.push(" ", inCell.attrs); + html.push('>'); + // result[4] => td postfix + result.push(html.join('')); + // SLOT: result[5] => content + result.push(''); + // result[6] => td closes + result.push('</td>'); + return result; // Array + }, + + // cell finding + isCellNode: function(inNode){ + return Boolean(inNode && inNode.getAttribute && inNode.getAttribute("idx")); + }, + + getCellNodeIndex: function(inCellNode){ + return inCellNode ? Number(inCellNode.getAttribute("idx")) : -1; + }, + + getCellNode: function(inRowNode, inCellIndex){ + for(var i=0, row; row=dojox.grid.getTr(inRowNode.firstChild, i); i++){ + for(var j=0, cell; cell=row.cells[j]; j++){ + if(this.getCellNodeIndex(cell) == inCellIndex){ + return cell; + } + } + } + }, + + findCellTarget: function(inSourceNode, inTopNode){ + var n = inSourceNode; + while(n && (!this.isCellNode(n) || (dojox.grid.gridViewTag in n.offsetParent.parentNode && n.offsetParent.parentNode[dojox.grid.gridViewTag] != this.view.id)) && (n!=inTopNode)){ + n = n.parentNode; + } + return n!=inTopNode ? n : null + }, + + // event decoration + baseDecorateEvent: function(e){ + e.dispatch = 'do' + e.type; + e.grid = this.grid; + e.sourceView = this.view; + e.cellNode = this.findCellTarget(e.target, e.rowNode); + e.cellIndex = this.getCellNodeIndex(e.cellNode); + e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null); + }, + + // event dispatch + findTarget: function(inSource, inTag){ + var n = inSource; + while(n && (n!=this.domNode) && (!(inTag in n) || (dojox.grid.gridViewTag in n && n[dojox.grid.gridViewTag] != this.view.id))){ + n = n.parentNode; + } + return (n != this.domNode) ? n : null; + }, + + findRowTarget: function(inSource){ + return this.findTarget(inSource, dojox.grid.rowIndexTag); + }, + + isIntraNodeEvent: function(e){ + try{ + return (e.cellNode && e.relatedTarget && dojo.isDescendant(e.relatedTarget, e.cellNode)); + }catch(x){ + // e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427 + return false; + } + }, + + isIntraRowEvent: function(e){ + try{ + var row = e.relatedTarget && this.findRowTarget(e.relatedTarget); + return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex); + }catch(x){ + // e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427 + return false; + } + }, + + dispatchEvent: function(e){ + if(e.dispatch in this){ + return this[e.dispatch](e); + } + }, + + // dispatched event handlers + domouseover: function(e){ + if(e.cellNode && (e.cellNode!=this.lastOverCellNode)){ + this.lastOverCellNode = e.cellNode; + this.grid.onMouseOver(e); + } + this.grid.onMouseOverRow(e); + }, + + domouseout: function(e){ + if(e.cellNode && (e.cellNode==this.lastOverCellNode) && !this.isIntraNodeEvent(e, this.lastOverCellNode)){ + this.lastOverCellNode = null; + this.grid.onMouseOut(e); + if(!this.isIntraRowEvent(e)){ + this.grid.onMouseOutRow(e); + } + } + }, + + domousedown: function(e){ + if (e.cellNode) + this.grid.onMouseDown(e); + this.grid.onMouseDownRow(e) + } + +}); + +dojo.declare("dojox.grid.contentBuilder", + dojox.grid.Builder, + { + // summary: + // Produces html for grid data content. Owned by grid and used internally + // for rendering data. Override to implement custom rendering. + update: function(){ + this.prepareHtml(); + }, + + // cache html for rendering data rows + prepareHtml: function(){ + var defaultGet=this.grid.get, rows=this.view.structure.rows; + for(var j=0, row; (row=rows[j]); j++){ + for(var i=0, cell; (cell=row[i]); i++){ + cell.get = cell.get || (cell.value == undefined) && defaultGet; + cell.markup = this.generateCellMarkup(cell, cell.cellStyles, cell.cellClasses, false); + } + } + }, + + // time critical: generate html using cache and data source + generateHtml: function(inDataIndex, inRowIndex){ + var + html = [ this._table ], + v = this.view, + obr = v.onBeforeRow, + rows = v.structure.rows; + + obr && obr(inRowIndex, rows); + for(var j=0, row; (row=rows[j]); j++){ + if(row.hidden || row.header){ + continue; + } + html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGrid-invisible">'); + for(var i=0, cell, m, cc, cs; (cell=row[i]); i++){ + m = cell.markup, cc = cell.customClasses = [], cs = cell.customStyles = []; + // content (format can fill in cc and cs as side-effects) + m[5] = cell.format(inDataIndex); + // classes + m[1] = cc.join(' '); + // styles + m[3] = cs.join(';'); + // in-place concat + html.push.apply(html, m); + } + html.push('</tr>'); + } + html.push('</table>'); + return html.join(''); // String + }, + + decorateEvent: function(e){ + e.rowNode = this.findRowTarget(e.target); + if(!e.rowNode){return false}; + e.rowIndex = e.rowNode[dojox.grid.rowIndexTag]; + this.baseDecorateEvent(e); + e.cell = this.grid.getCell(e.cellIndex); + return true; // Boolean + } + +}); + +dojo.declare("dojox.grid.headerBuilder", + dojox.grid.Builder, + { + // summary: + // Produces html for grid header content. Owned by grid and used internally + // for rendering data. Override to implement custom rendering. + + bogusClickTime: 0, + overResizeWidth: 4, + minColWidth: 1, + + // FIXME: isn't this getting mixed from dojox.grid.Builder, -1 character? + _table: '<table class="dojoxGrid-row-table" border="0" cellspacing="0" cellpadding="0" role="wairole:presentation"', + + update: function(){ + this.tableMap = new dojox.grid.tableMap(this.view.structure.rows); + }, + + generateHtml: function(inGetValue, inValue){ + var html = [this._table], rows = this.view.structure.rows; + + // render header with appropriate width, if possible so that views with flex columns are correct height + if(this.view.viewWidth){ + html.push([' style="width:', this.view.viewWidth, ';"'].join('')); + } + html.push('>'); + dojox.grid.fire(this.view, "onBeforeRow", [-1, rows]); + for(var j=0, row; (row=rows[j]); j++){ + if(row.hidden){ + continue; + } + html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGrid-invisible">'); + for(var i=0, cell, markup; (cell=row[i]); i++){ + cell.customClasses = []; + cell.customStyles = []; + markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true); + // content + markup[5] = (inValue != undefined ? inValue : inGetValue(cell)); + // styles + markup[3] = cell.customStyles.join(';'); + // classes + markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : ''); + html.push(markup.join('')); + } + html.push('</tr>'); + } + html.push('</table>'); + return html.join(''); + }, + + // event helpers + getCellX: function(e){ + var x = e.layerX; + if(dojo.isMoz){ + var n = dojox.grid.ascendDom(e.target, dojox.grid.makeNotTagName("th")); + x -= (n && n.offsetLeft) || 0; + var t = e.sourceView.getScrollbarWidth(); + if(!dojo._isBodyLtr() && e.sourceView.headerNode.scrollLeft < t) + x -= t; + //x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0; + } + var n = dojox.grid.ascendDom(e.target, function(){ + if(!n || n == e.cellNode){ + return false; + } + // Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width + // when parent has border, overflow: hidden, and is positioned + // handle this problem here ... not a general solution! + x += (n.offsetLeft < 0 ? 0 : n.offsetLeft); + return true; + }); + return x; + }, + + // event decoration + decorateEvent: function(e){ + this.baseDecorateEvent(e); + e.rowIndex = -1; + e.cellX = this.getCellX(e); + return true; + }, + + // event handlers + // resizing + prepareResize: function(e, mod){ + var i = dojox.grid.getTdIndex(e.cellNode); + e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null); + e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1); + return Boolean(e.cellNode); + }, + + canResize: function(e){ + if(!e.cellNode || e.cellNode.colSpan > 1){ + return false; + } + var cell = this.grid.getCell(e.cellIndex); + return !cell.noresize && !cell.isFlex(); + }, + + overLeftResizeArea: function(e){ + if(dojo._isBodyLtr()){ + return (e.cellIndex>0) && (e.cellX < this.overResizeWidth) && this.prepareResize(e, -1); + } + return t = e.cellNode && (e.cellX < this.overResizeWidth); + }, + + overRightResizeArea: function(e){ + if(dojo._isBodyLtr()){ + return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth); + } + return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1); + }, + + domousemove: function(e){ + //console.log(e.cellIndex, e.cellX, e.cellNode.offsetWidth); + var c = (this.overRightResizeArea(e) ? 'e-resize' : (this.overLeftResizeArea(e) ? 'w-resize' : '')); + if(c && !this.canResize(e)){ + c = 'not-allowed'; + } + e.sourceView.headerNode.style.cursor = c || ''; //'default'; + if (c) + dojo.stopEvent(e); + }, + + domousedown: function(e){ + if(!dojox.grid.drag.dragging){ + if((this.overRightResizeArea(e) || this.overLeftResizeArea(e)) && this.canResize(e)){ + this.beginColumnResize(e); + }else{ + this.grid.onMouseDown(e); + this.grid.onMouseOverRow(e); + } + //else{ + // this.beginMoveColumn(e); + //} + } + }, + + doclick: function(e) { + if (new Date().getTime() < this.bogusClickTime) { + dojo.stopEvent(e); + return true; + } + }, + + // column resizing + beginColumnResize: function(e){ + dojo.stopEvent(e); + var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode); + for(var i=0, cell; (cell=nodes[i]); i++){ + spanners.push({ node: cell, index: this.getCellNodeIndex(cell), width: cell.offsetWidth }); + //console.log("spanner: " + this.getCellNodeIndex(cell)); + } + var drag = { + scrollLeft: e.sourceView.headerNode.scrollLeft, + view: e.sourceView, + node: e.cellNode, + index: e.cellIndex, + w: e.cellNode.clientWidth, + spanners: spanners + }; + //console.log(drag.index, drag.w); + dojox.grid.drag.start(e.cellNode, dojo.hitch(this, 'doResizeColumn', drag), dojo.hitch(this, 'endResizeColumn', drag), e); + }, + + doResizeColumn: function(inDrag, inEvent){ + var isLtr = dojo._isBodyLtr(); + if(isLtr){ + var w = inDrag.w + inEvent.deltaX; + }else{ + var w = inDrag.w - inEvent.deltaX; + } + if(w >= this.minColWidth){ + for(var i=0, s, sw; (s=inDrag.spanners[i]); i++){ + if(isLtr){ + sw = s.width + inEvent.deltaX; + }else{ + sw = s.width - inEvent.deltaX; + } + s.node.style.width = sw + 'px'; + inDrag.view.setColWidth(s.index, sw); + //console.log('setColWidth', '#' + s.index, sw + 'px'); + } + inDrag.node.style.width = w + 'px'; + inDrag.view.setColWidth(inDrag.index, w); + if(!isLtr){ + inDrag.view.headerNode.scrollLeft = (inDrag.scrollLeft - inEvent.deltaX); + } + } + if(inDrag.view.flexCells && !inDrag.view.testFlexCells()){ + var t = dojox.grid.findTable(inDrag.node); + t && (t.style.width = ''); + } + }, + + endResizeColumn: function(inDrag){ + this.bogusClickTime = new Date().getTime() + 30; + setTimeout(dojo.hitch(inDrag.view, "update"), 50); + } + +}); + +dojo.declare("dojox.grid.tableMap", + null, + { + // summary: + // Maps an html table into a structure parsable for information about cell row and col spanning. + // Used by headerBuilder + constructor: function(inRows){ + this.mapRows(inRows); + }, + + map: null, + + mapRows: function(inRows){ + // summary: Map table topography + + //console.log('mapRows'); + // # of rows + var rowCount = inRows.length; + if(!rowCount){ + return; + } + // map which columns and rows fill which cells + this.map = [ ]; + for(var j=0, row; (row=inRows[j]); j++){ + this.map[j] = []; + } + for(var j=0, row; (row=inRows[j]); j++){ + for(var i=0, x=0, cell, colSpan, rowSpan; (cell=row[i]); i++){ + while (this.map[j][x]){x++}; + this.map[j][x] = { c: i, r: j }; + rowSpan = cell.rowSpan || 1; + colSpan = cell.colSpan || 1; + for(var y=0; y<rowSpan; y++){ + for(var s=0; s<colSpan; s++){ + this.map[j+y][x+s] = this.map[j][x]; + } + } + x += colSpan; + } + } + //this.dumMap(); + }, + + dumpMap: function(){ + for(var j=0, row, h=''; (row=this.map[j]); j++,h=''){ + for(var i=0, cell; (cell=row[i]); i++){ + h += cell.r + ',' + cell.c + ' '; + } + console.log(h); + } + }, + + getMapCoords: function(inRow, inCol){ + // summary: Find node's map coords by it's structure coords + for(var j=0, row; (row=this.map[j]); j++){ + for(var i=0, cell; (cell=row[i]); i++){ + if(cell.c==inCol && cell.r == inRow){ + return { j: j, i: i }; + } + //else{console.log(inRow, inCol, ' : ', i, j, " : ", cell.r, cell.c); }; + } + } + return { j: -1, i: -1 }; + }, + + getNode: function(inTable, inRow, inCol){ + // summary: Find a node in inNode's table with the given structure coords + var row = inTable && inTable.rows[inRow]; + return row && row.cells[inCol]; + }, + + _findOverlappingNodes: function(inTable, inRow, inCol){ + var nodes = []; + var m = this.getMapCoords(inRow, inCol); + //console.log("node j: %d, i: %d", m.j, m.i); + var row = this.map[m.j]; + for(var j=0, row; (row=this.map[j]); j++){ + if(j == m.j){ continue; } + with(row[m.i]){ + //console.log("overlaps: r: %d, c: %d", r, c); + var n = this.getNode(inTable, r, c); + if(n){ nodes.push(n); } + } + } + //console.log(nodes); + return nodes; + }, + + findOverlappingNodes: function(inNode){ + return this._findOverlappingNodes(dojox.grid.findTable(inNode), dojox.grid.getTrIndex(inNode.parentNode), dojox.grid.getTdIndex(inNode)); + } + +}); + +dojox.grid.rowIndexTag = "gridRowIndex"; +dojox.grid.gridViewTag = "gridView"; + +} diff --git a/includes/js/dojox/grid/_grid/cell.js b/includes/js/dojox/grid/_grid/cell.js new file mode 100644 index 0000000..52f92e8 --- /dev/null +++ b/includes/js/dojox/grid/_grid/cell.js @@ -0,0 +1,66 @@ +if(!dojo._hasResource["dojox.grid._grid.cell"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.cell"] = true; +dojo.provide("dojox.grid._grid.cell"); + +dojo.declare("dojox.grid.cell", null, { + // summary: + // Respresents a grid cell and contains information about column options and methods + // for retrieving cell related information. + // Each column in a grid layout has a cell object and most events and many methods + // provide access to these objects. + styles: '', + constructor: function(inProps){ + dojo.mixin(this, inProps); + if(this.editor){this.editor = new this.editor(this);} + }, + // data source + format: function(inRowIndex){ + // summary: + // provides the html for a given grid cell. + // inRowIndex: int + // grid row index + // returns: html for a given grid cell + var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex) : this.value; + if(this.editor && (this.editor.alwaysOn || (i.rowIndex==inRowIndex && i.cell==this))){ + return this.editor.format(d, inRowIndex); + }else{ + return (f = this.formatter) ? f.call(this, d, inRowIndex) : d; + } + }, + // utility + getNode: function(inRowIndex){ + // summary: + // gets the dom node for a given grid cell. + // inRowIndex: int + // grid row index + // returns: dom node for a given grid cell + return this.view.getCellNode(inRowIndex, this.index); + }, + isFlex: function(){ + var uw = this.unitWidth; + return uw && (uw=='auto' || uw.slice(-1)=='%'); + }, + // edit support + applyEdit: function(inValue, inRowIndex){ + this.grid.edit.applyCellEdit(inValue, this, inRowIndex); + }, + cancelEdit: function(inRowIndex){ + this.grid.doCancelEdit(inRowIndex); + }, + _onEditBlur: function(inRowIndex){ + if(this.grid.edit.isEditCell(inRowIndex, this.index)){ + //console.log('editor onblur', e); + this.grid.edit.apply(); + } + }, + registerOnBlur: function(inNode, inRowIndex){ + if(this.commitOnBlur){ + dojo.connect(inNode, "onblur", function(e){ + // hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid + setTimeout(dojo.hitch(this, "_onEditBlur", inRowIndex), 250); + }); + } + } +}); + +} diff --git a/includes/js/dojox/grid/_grid/drag.js b/includes/js/dojox/grid/_grid/drag.js new file mode 100644 index 0000000..df086f9 --- /dev/null +++ b/includes/js/dojox/grid/_grid/drag.js @@ -0,0 +1,113 @@ +if(!dojo._hasResource["dojox.grid._grid.drag"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.drag"] = true; +dojo.provide("dojox.grid._grid.drag"); + +// summary: +// utility functions for dragging as used in grid. +// begin closure +(function(){ + +var dgdrag = dojox.grid.drag = {}; + +dgdrag.dragging = false; +dgdrag.hysteresis = 2; + +dgdrag.capture = function(inElement) { + //console.debug('dojox.grid.drag.capture'); + if (inElement.setCapture) + inElement.setCapture(); + else { + document.addEventListener("mousemove", inElement.onmousemove, true); + document.addEventListener("mouseup", inElement.onmouseup, true); + document.addEventListener("click", inElement.onclick, true); + } +} + +dgdrag.release = function(inElement) { + //console.debug('dojox.grid.drag.release'); + if(inElement.releaseCapture){ + inElement.releaseCapture(); + }else{ + document.removeEventListener("click", inElement.onclick, true); + document.removeEventListener("mouseup", inElement.onmouseup, true); + document.removeEventListener("mousemove", inElement.onmousemove, true); + } +} + +dgdrag.start = function(inElement, inOnDrag, inOnEnd, inEvent, inOnStart){ + if(/*dgdrag.elt ||*/ !inElement || dgdrag.dragging){ + console.debug('failed to start drag: bad input node or already dragging'); + return; + } + dgdrag.dragging = true; + dgdrag.elt = inElement; + dgdrag.events = { + drag: inOnDrag || dojox.grid.nop, + end: inOnEnd || dojox.grid.nop, + start: inOnStart || dojox.grid.nop, + oldmove: inElement.onmousemove, + oldup: inElement.onmouseup, + oldclick: inElement.onclick + }; + dgdrag.positionX = (inEvent && ('screenX' in inEvent) ? inEvent.screenX : false); + dgdrag.positionY = (inEvent && ('screenY' in inEvent) ? inEvent.screenY : false); + dgdrag.started = (dgdrag.position === false); + inElement.onmousemove = dgdrag.mousemove; + inElement.onmouseup = dgdrag.mouseup; + inElement.onclick = dgdrag.click; + dgdrag.capture(dgdrag.elt); +} + +dgdrag.end = function(){ + //console.debug("dojox.grid.drag.end"); + dgdrag.release(dgdrag.elt); + dgdrag.elt.onmousemove = dgdrag.events.oldmove; + dgdrag.elt.onmouseup = dgdrag.events.oldup; + dgdrag.elt.onclick = dgdrag.events.oldclick; + dgdrag.elt = null; + try{ + if(dgdrag.started){ + dgdrag.events.end(); + } + }finally{ + dgdrag.dragging = false; + } +} + +dgdrag.calcDelta = function(inEvent){ + inEvent.deltaX = inEvent.screenX - dgdrag.positionX; + inEvent.deltaY = inEvent.screenY - dgdrag.positionY; +} + +dgdrag.hasMoved = function(inEvent){ + return Math.abs(inEvent.deltaX) + Math.abs(inEvent.deltaY) > dgdrag.hysteresis; +} + +dgdrag.mousemove = function(inEvent){ + inEvent = dojo.fixEvent(inEvent); + dojo.stopEvent(inEvent); + dgdrag.calcDelta(inEvent); + if((!dgdrag.started)&&(dgdrag.hasMoved(inEvent))){ + dgdrag.events.start(inEvent); + dgdrag.started = true; + } + if(dgdrag.started){ + dgdrag.events.drag(inEvent); + } +} + +dgdrag.mouseup = function(inEvent){ + //console.debug("dojox.grid.drag.mouseup"); + dojo.stopEvent(dojo.fixEvent(inEvent)); + dgdrag.end(); +} + +dgdrag.click = function(inEvent){ + dojo.stopEvent(dojo.fixEvent(inEvent)); + //dgdrag.end(); +} + +})(); +// end closure + +} diff --git a/includes/js/dojox/grid/_grid/edit.js b/includes/js/dojox/grid/_grid/edit.js new file mode 100644 index 0000000..d918423 --- /dev/null +++ b/includes/js/dojox/grid/_grid/edit.js @@ -0,0 +1,238 @@ +if(!dojo._hasResource["dojox.grid._grid.edit"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.edit"] = true; +dojo.provide("dojox.grid._grid.edit"); + +dojo.declare("dojox.grid.edit", null, { + // summary: + // Controls grid cell editing process. Owned by grid and used internally for editing. + constructor: function(inGrid){ + // inGrid: dojox.Grid + // The dojox.Grid this editor should be attached to + this.grid = inGrid; + this.connections = []; + if(dojo.isIE){ + this.connections.push(dojo.connect(document.body, "onfocus", dojo.hitch(this, "_boomerangFocus"))); + } + }, + + info: {}, + + destroy: function(){ + dojo.forEach(this.connections,dojo.disconnect); + }, + + cellFocus: function(inCell, inRowIndex){ + // summary: + // Invoke editing when cell is focused + // inCell: cell object + // Grid cell object + // inRowIndex: Integer + // Grid row index + if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){ + // if same row or quick editing, edit + this.setEditCell(inCell, inRowIndex); + }else{ + // otherwise, apply any pending row edits + this.apply(); + } + // if dynamic or static editing... + if(this.isEditing() || (inCell && (inCell.editor||0).alwaysOn)){ + // let the editor focus itself as needed + this._focusEditor(inCell, inRowIndex); + } + }, + + rowClick: function(e){ + if(this.isEditing() && !this.isEditRow(e.rowIndex)){ + this.apply(); + } + }, + + styleRow: function(inRow){ + if(inRow.index == this.info.rowIndex){ + inRow.customClasses += ' dojoxGrid-row-editing'; + } + }, + + dispatchEvent: function(e){ + var c = e.cell, ed = c && c.editor; + return ed && ed.dispatchEvent(e.dispatch, e); + }, + + // Editing + isEditing: function(){ + // summary: + // Indicates editing state of the grid. + // returns: Boolean + // True if grid is actively editing + return this.info.rowIndex !== undefined; + }, + + isEditCell: function(inRowIndex, inCellIndex){ + // summary: + // Indicates if the given cell is being edited. + // inRowIndex: Integer + // Grid row index + // inCellIndex: Integer + // Grid cell index + // returns: Boolean + // True if given cell is being edited + return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex); + }, + + isEditRow: function(inRowIndex){ + // summary: + // Indicates if the given row is being edited. + // inRowIndex: Integer + // Grid row index + // returns: Boolean + // True if given row is being edited + return this.info.rowIndex === inRowIndex; + }, + + setEditCell: function(inCell, inRowIndex){ + // summary: + // Set the given cell to be edited + // inRowIndex: Integer + // Grid row index + // inCell: Object + // Grid cell object + if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit(inCell, inRowIndex)){ + this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editor); + } + }, + + _focusEditor: function(inCell, inRowIndex){ + dojox.grid.fire(inCell.editor, "focus", [inRowIndex]); + }, + + focusEditor: function(){ + if(this.isEditing()){ + this._focusEditor(this.info.cell, this.info.rowIndex); + } + }, + + // implement fix for focus boomerang effect on IE + _boomerangWindow: 500, + _shouldCatchBoomerang: function(){ + return this._catchBoomerang > new Date().getTime(); + }, + _boomerangFocus: function(){ + //console.log("_boomerangFocus"); + if(this._shouldCatchBoomerang()){ + // make sure we don't utterly lose focus + this.grid.focus.focusGrid(); + // let the editor focus itself as needed + this.focusEditor(); + // only catch once + this._catchBoomerang = 0; + } + }, + _doCatchBoomerang: function(){ + // give ourselves a few ms to boomerang IE focus effects + if(dojo.isIE){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;} + }, + // end boomerang fix API + + start: function(inCell, inRowIndex, inEditing){ + this.grid.beginUpdate(); + this.editorApply(); + if(this.isEditing() && !this.isEditRow(inRowIndex)){ + this.applyRowEdit(); + this.grid.updateRow(inRowIndex); + } + if(inEditing){ + this.info = { cell: inCell, rowIndex: inRowIndex }; + this.grid.doStartEdit(inCell, inRowIndex); + this.grid.updateRow(inRowIndex); + }else{ + this.info = {}; + } + this.grid.endUpdate(); + // make sure we don't utterly lose focus + this.grid.focus.focusGrid(); + // let the editor focus itself as needed + this._focusEditor(inCell, inRowIndex); + // give ourselves a few ms to boomerang IE focus effects + this._doCatchBoomerang(); + }, + + _editorDo: function(inMethod){ + var c = this.info.cell + //c && c.editor && c.editor[inMethod](c, this.info.rowIndex); + c && c.editor && c.editor[inMethod](this.info.rowIndex); + }, + + editorApply: function(){ + this._editorDo("apply"); + }, + + editorCancel: function(){ + this._editorDo("cancel"); + }, + + applyCellEdit: function(inValue, inCell, inRowIndex){ + if(this.grid.canEdit(inCell, inRowIndex)){ + this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.fieldIndex); + } + }, + + applyRowEdit: function(){ + this.grid.doApplyEdit(this.info.rowIndex); + }, + + apply: function(){ + // summary: + // Apply a grid edit + if(this.isEditing()){ + this.grid.beginUpdate(); + this.editorApply(); + this.applyRowEdit(); + this.info = {}; + this.grid.endUpdate(); + this.grid.focus.focusGrid(); + this._doCatchBoomerang(); + } + }, + + cancel: function(){ + // summary: + // Cancel a grid edit + if(this.isEditing()){ + this.grid.beginUpdate(); + this.editorCancel(); + this.info = {}; + this.grid.endUpdate(); + this.grid.focus.focusGrid(); + this._doCatchBoomerang(); + } + }, + + save: function(inRowIndex, inView){ + // summary: + // Save the grid editing state + // inRowIndex: Integer + // Grid row index + // inView: Object + // Grid view + var c = this.info.cell; + if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editor){ + c.editor.save(c, this.info.rowIndex); + } + }, + + restore: function(inView, inRowIndex){ + // summary: + // Restores the grid editing state + // inRowIndex: Integer + // Grid row index + // inView: Object + // Grid view + var c = this.info.cell; + if(this.isEditRow(inRowIndex) && c.view == inView && c.editor){ + c.editor.restore(c, this.info.rowIndex); + } + } +}); + +} diff --git a/includes/js/dojox/grid/_grid/focus.js b/includes/js/dojox/grid/_grid/focus.js new file mode 100644 index 0000000..8761042 --- /dev/null +++ b/includes/js/dojox/grid/_grid/focus.js @@ -0,0 +1,207 @@ +if(!dojo._hasResource["dojox.grid._grid.focus"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.focus"] = true; +dojo.provide("dojox.grid._grid.focus"); + +// focus management +dojo.declare("dojox.grid.focus", null, { + // summary: + // Controls grid cell focus. Owned by grid and used internally for focusing. + // Note: grid cell actually receives keyboard input only when cell is being edited. + constructor: function(inGrid){ + this.grid = inGrid; + this.cell = null; + this.rowIndex = -1; + dojo.connect(this.grid.domNode, "onfocus", this, "doFocus"); + }, + tabbingOut: false, + focusClass: "dojoxGrid-cell-focus", + focusView: null, + initFocusView: function(){ + this.focusView = this.grid.views.getFirstScrollingView(); + }, + isFocusCell: function(inCell, inRowIndex){ + // summary: + // states if the given cell is focused + // inCell: object + // grid cell object + // inRowIndex: int + // grid row index + // returns: + // true of the given grid cell is focused + return (this.cell == inCell) && (this.rowIndex == inRowIndex); + }, + isLastFocusCell: function(){ + return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1); + }, + isFirstFocusCell: function(){ + return (this.rowIndex == 0) && (this.cell.index == 0); + }, + isNoFocusCell: function(){ + return (this.rowIndex < 0) || !this.cell; + }, + _focusifyCellNode: function(inBork){ + var n = this.cell && this.cell.getNode(this.rowIndex); + if(n){ + dojo.toggleClass(n, this.focusClass, inBork); + if (inBork){ + this.scrollIntoView(); + try{ + if(!this.grid.edit.isEditing()) + dojox.grid.fire(n, "focus"); + }catch(e){} + } + } + }, + scrollIntoView: function() { + if(!this.cell){ + return; + } + var + c = this.cell, + s = c.view.scrollboxNode, + sr = { + w: s.clientWidth, + l: s.scrollLeft, + t: s.scrollTop, + h: s.clientHeight + }, + n = c.getNode(this.rowIndex), + r = c.view.getRowNode(this.rowIndex), + rt = this.grid.scroller.findScrollTop(this.rowIndex); + // place cell within horizontal view + if(n.offsetLeft + n.offsetWidth > sr.l + sr.w){ + s.scrollLeft = n.offsetLeft + n.offsetWidth - sr.w; + }else if(n.offsetLeft < sr.l){ + s.scrollLeft = n.offsetLeft; + } + // place cell within vertical view + if(rt + r.offsetHeight > sr.t + sr.h){ + this.grid.setScrollTop(rt + r.offsetHeight - sr.h); + }else if(rt < sr.t){ + this.grid.setScrollTop(rt); + } + }, + styleRow: function(inRow){ + return; + }, + setFocusIndex: function(inRowIndex, inCellIndex){ + // summary: + // focuses the given grid cell + // inRowIndex: int + // grid row index + // inCellIndex: int + // grid cell index + this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex); + }, + setFocusCell: function(inCell, inRowIndex){ + // summary: + // focuses the given grid cell + // inCell: object + // grid cell object + // inRowIndex: int + // grid row index + if(inCell && !this.isFocusCell(inCell, inRowIndex)){ + this.tabbingOut = false; + this.focusGridView(); + this._focusifyCellNode(false); + this.cell = inCell; + this.rowIndex = inRowIndex; + this._focusifyCellNode(true); + } + // even if this cell isFocusCell, the document focus may need to be rejiggered + // call opera on delay to prevent keypress from altering focus + if(dojo.isOpera){ + setTimeout(dojo.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1); + }else{ + this.grid.onCellFocus(this.cell, this.rowIndex); + } + }, + next: function(){ + // summary: + // focus next grid cell + var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1; + if(col > cc){ + col = 0; + row++; + } + if(row > rc){ + col = cc; + row = rc; + } + this.setFocusIndex(row, col); + }, + previous: function(){ + // summary: + // focus previous grid cell + var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1; + if(col < 0){ + col = this.grid.layout.cellCount-1; + row--; + } + if(row < 0){ + row = 0; + col = 0; + } + this.setFocusIndex(row, col); + }, + move: function(inRowDelta, inColDelta) { + // summary: + // focus grid cell based on position relative to current focus + // inRowDelta: int + // vertical distance from current focus + // inColDelta: int + // horizontal distance from current focus + var + rc = this.grid.rowCount-1, + cc = this.grid.layout.cellCount-1, + r = this.rowIndex, + i = this.cell.index, + row = Math.min(rc, Math.max(0, r+inRowDelta)), + col = Math.min(cc, Math.max(0, i+inColDelta)); + this.setFocusIndex(row, col); + if(inRowDelta){ + this.grid.updateRow(r); + } + }, + previousKey: function(e){ + if(this.isFirstFocusCell()){ + this.tabOut(this.grid.domNode); + }else{ + dojo.stopEvent(e); + this.previous(); + } + }, + nextKey: function(e) { + if(this.isLastFocusCell()){ + this.tabOut(this.grid.lastFocusNode); + }else{ + dojo.stopEvent(e); + this.next(); + } + }, + tabOut: function(inFocusNode){ + this.tabbingOut = true; + inFocusNode.focus(); + }, + focusGridView: function(){ + dojox.grid.fire(this.focusView, "focus"); + }, + focusGrid: function(inSkipFocusCell){ + this.focusGridView(); + this._focusifyCellNode(true); + }, + doFocus: function(e){ + // trap focus only for grid dom node + if(e && e.target != e.currentTarget){ + return; + } + // do not focus for scrolling if grid is about to blur + if(!this.tabbingOut && this.isNoFocusCell()){ + // establish our virtual-focus, if necessary + this.setFocusIndex(0, 0); + } + this.tabbingOut = false; + } +}); + +} diff --git a/includes/js/dojox/grid/_grid/images/grid_dx_gradient.gif b/includes/js/dojox/grid/_grid/images/grid_dx_gradient.gif Binary files differnew file mode 100644 index 0000000..57f67ba --- /dev/null +++ b/includes/js/dojox/grid/_grid/images/grid_dx_gradient.gif diff --git a/includes/js/dojox/grid/_grid/images/grid_sort_down.gif b/includes/js/dojox/grid/_grid/images/grid_sort_down.gif Binary files differnew file mode 100644 index 0000000..7a73f82 --- /dev/null +++ b/includes/js/dojox/grid/_grid/images/grid_sort_down.gif diff --git a/includes/js/dojox/grid/_grid/images/grid_sort_up.gif b/includes/js/dojox/grid/_grid/images/grid_sort_up.gif Binary files differnew file mode 100644 index 0000000..9452da0 --- /dev/null +++ b/includes/js/dojox/grid/_grid/images/grid_sort_up.gif diff --git a/includes/js/dojox/grid/_grid/images/tabEnabled_rotated.png b/includes/js/dojox/grid/_grid/images/tabEnabled_rotated.png Binary files differnew file mode 100644 index 0000000..e326abd --- /dev/null +++ b/includes/js/dojox/grid/_grid/images/tabEnabled_rotated.png diff --git a/includes/js/dojox/grid/_grid/images/tabHover_rotated.png b/includes/js/dojox/grid/_grid/images/tabHover_rotated.png Binary files differnew file mode 100644 index 0000000..1a30e10 --- /dev/null +++ b/includes/js/dojox/grid/_grid/images/tabHover_rotated.png diff --git a/includes/js/dojox/grid/_grid/layout.js b/includes/js/dojox/grid/_grid/layout.js new file mode 100644 index 0000000..128f486 --- /dev/null +++ b/includes/js/dojox/grid/_grid/layout.js @@ -0,0 +1,75 @@ +if(!dojo._hasResource["dojox.grid._grid.layout"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.layout"] = true; +dojo.provide("dojox.grid._grid.layout"); +dojo.require("dojox.grid._grid.cell"); + +dojo.declare("dojox.grid.layout", null, { + // summary: + // Controls grid cell layout. Owned by grid and used internally. + constructor: function(inGrid){ + this.grid = inGrid; + }, + // flat array of grid cells + cells: [], + // structured array of grid cells + structure: null, + // default cell width + defaultWidth: '6em', + // methods + setStructure: function(inStructure){ + this.fieldIndex = 0; + this.cells = []; + var s = this.structure = []; + for(var i=0, viewDef, rows; (viewDef=inStructure[i]); i++){ + s.push(this.addViewDef(viewDef)); + } + this.cellCount = this.cells.length; + }, + addViewDef: function(inDef){ + this._defaultCellProps = inDef.defaultCell || {}; + return dojo.mixin({}, inDef, {rows: this.addRowsDef(inDef.rows || inDef.cells)}); + }, + addRowsDef: function(inDef){ + var result = []; + for(var i=0, row; inDef && (row=inDef[i]); i++){ + result.push(this.addRowDef(i, row)); + } + return result; + }, + addRowDef: function(inRowIndex, inDef){ + var result = []; + for(var i=0, def, cell; (def=inDef[i]); i++){ + cell = this.addCellDef(inRowIndex, i, def); + result.push(cell); + this.cells.push(cell); + } + return result; + }, + addCellDef: function(inRowIndex, inCellIndex, inDef){ + var w = 0; + if(inDef.colSpan > 1){ + w = 0; + }else if(!isNaN(inDef.width)){ + w = inDef.width + "em"; + }else{ + w = inDef.width || this.defaultWidth; + } + // fieldIndex progresses linearly from the last indexed field + // FIXME: support generating fieldIndex based a text field name (probably in Grid) + var fieldIndex = inDef.field != undefined ? inDef.field : (inDef.get ? -1 : this.fieldIndex); + if((inDef.field != undefined) || !inDef.get){ + this.fieldIndex = (inDef.field > -1 ? inDef.field : this.fieldIndex) + 1; + } + return new dojox.grid.cell( + dojo.mixin({}, this._defaultCellProps, inDef, { + grid: this.grid, + subrow: inRowIndex, + layoutIndex: inCellIndex, + index: this.cells.length, + fieldIndex: fieldIndex, + unitWidth: w + })); + } +}); + +} diff --git a/includes/js/dojox/grid/_grid/lib.js b/includes/js/dojox/grid/_grid/lib.js new file mode 100644 index 0000000..3644dbc --- /dev/null +++ b/includes/js/dojox/grid/_grid/lib.js @@ -0,0 +1,254 @@ +if(!dojo._hasResource["dojox.grid._grid.lib"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.lib"] = true; +dojo.provide("dojox.grid._grid.lib"); +// summary: grid utility library +dojo.mixin(dojox.grid,{ + + na: '...', + + nop: function(){ + // summary: a null function? + }, + + getTdIndex: function(td){ + return td.cellIndex >=0 ? td.cellIndex : dojo.indexOf(td.parentNode.cells, td); + }, + + getTrIndex: function(tr){ + return tr.rowIndex >=0 ? tr.rowIndex : dojo.indexOf(tr.parentNode.childNodes, tr); + }, + + getTr: function(rowOwner, index){ + return rowOwner && ((rowOwner.rows||0)[index] || rowOwner.childNodes[index]); + }, + + getTd: function(rowOwner, rowIndex, cellIndex){ + return (dojox.grid.getTr(inTable, rowIndex)||0)[cellIndex]; + }, + + findTable: function(node){ + for (var n=node; n && n.tagName!='TABLE'; n=n.parentNode); + return n; + }, + + ascendDom: function(inNode, inWhile){ + for (var n=inNode; n && inWhile(n); n=n.parentNode); + return n; + }, + + makeNotTagName: function(inTagName){ + var name = inTagName.toUpperCase(); + return function(node){ return node.tagName != name; }; + }, + + fire: function(ob, ev, args){ + var fn = ob && ev && ob[ev]; + return fn && (args ? fn.apply(ob, args) : ob[ev]()); + }, + + // from lib.js + setStyleText: function(inNode, inStyleText){ + if(inNode.style.cssText == undefined){ + inNode.setAttribute("style", inStyleText); + }else{ + inNode.style.cssText = inStyleText; + } + }, + + getStyleText: function(inNode, inStyleText){ + return (inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText); + }, + + setStyle: function(inElement, inStyle, inValue){ + if(inElement && inElement.style[inStyle] != inValue){ + inElement.style[inStyle] = inValue; + } + }, + + setStyleHeightPx: function(inElement, inHeight){ + if(inHeight >= 0){ + dojox.grid.setStyle(inElement, 'height', inHeight + 'px'); + } + }, + + mouseEvents: [ 'mouseover', 'mouseout', /*'mousemove',*/ 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu' ], + + keyEvents: [ 'keyup', 'keydown', 'keypress' ], + + funnelEvents: function(inNode, inObject, inMethod, inEvents){ + var evts = (inEvents ? inEvents : dojox.grid.mouseEvents.concat(dojox.grid.keyEvents)); + for (var i=0, l=evts.length; i<l; i++){ + dojo.connect(inNode, 'on' + evts[i], inObject, inMethod); + } + }, + + removeNode: function(inNode){ + inNode = dojo.byId(inNode); + inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode); + return inNode; + }, + + getScrollbarWidth: function(){ + if(this._scrollBarWidth){ + return this._scrollBarWidth; + } + this._scrollBarWidth = 18; + try{ + var e = document.createElement("div"); + e.style.cssText = "top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;"; + document.body.appendChild(e); + this._scrollBarWidth = e.offsetWidth - e.clientWidth; + document.body.removeChild(e); + delete e; + }catch (ex){} + return this._scrollBarWidth; + }, + + // needed? dojo has _getProp + getRef: function(name, create, context){ + var obj=context||dojo.global, parts=name.split("."), prop=parts.pop(); + for(var i=0, p; obj&&(p=parts[i]); i++){ + obj = (p in obj ? obj[p] : (create ? obj[p]={} : undefined)); + } + return { obj: obj, prop: prop }; + }, + + getProp: function(name, create, context){ + with(dojox.grid.getRef(name, create, context)){ + return (obj)&&(prop)&&(prop in obj ? obj[prop] : (create ? obj[prop]={} : undefined)); + } + }, + + indexInParent: function(inNode){ + var i=0, n, p=inNode.parentNode; + while((n = p.childNodes[i++])){ + if(n == inNode){ + return i - 1; + } + } + return -1; + }, + + cleanNode: function(inNode){ + if(!inNode){ + return; + } + var filter = function(inW){ + return inW.domNode && dojo.isDescendant(inW.domNode, inNode, true); + } + var ws = dijit.registry.filter(filter); + for(var i=0, w; (w=ws[i]); i++){ + w.destroy(); + } + delete ws; + }, + + getTagName: function(inNodeOrId){ + var node = dojo.byId(inNodeOrId); + return (node && node.tagName ? node.tagName.toLowerCase() : ''); + }, + + nodeKids: function(inNode, inTag){ + var result = []; + var i=0, n; + while((n = inNode.childNodes[i++])){ + if(dojox.grid.getTagName(n) == inTag){ + result.push(n); + } + } + return result; + }, + + divkids: function(inNode){ + return dojox.grid.nodeKids(inNode, 'div'); + }, + + focusSelectNode: function(inNode){ + try{ + dojox.grid.fire(inNode, "focus"); + dojox.grid.fire(inNode, "select"); + }catch(e){// IE sux bad + } + }, + + whenIdle: function(/*inContext, inMethod, args ...*/){ + setTimeout(dojo.hitch.apply(dojo, arguments), 0); + }, + + arrayCompare: function(inA, inB){ + for(var i=0,l=inA.length; i<l; i++){ + if(inA[i] != inB[i]){return false;} + } + return (inA.length == inB.length); + }, + + arrayInsert: function(inArray, inIndex, inValue){ + if(inArray.length <= inIndex){ + inArray[inIndex] = inValue; + }else{ + inArray.splice(inIndex, 0, inValue); + } + }, + + arrayRemove: function(inArray, inIndex){ + inArray.splice(inIndex, 1); + }, + + arraySwap: function(inArray, inI, inJ){ + var cache = inArray[inI]; + inArray[inI] = inArray[inJ]; + inArray[inJ] = cache; + }, + + initTextSizePoll: function(inInterval) { + var f = document.createElement("div"); + with (f.style) { + top = "0px"; + left = "0px"; + position = "absolute"; + visibility = "hidden"; + } + f.innerHTML = "TheQuickBrownFoxJumpedOverTheLazyDog"; + document.body.appendChild(f); + var fw = f.offsetWidth; + var job = function() { + if (f.offsetWidth != fw) { + fw = f.offsetWidth; + dojox.grid.textSizeChanged(); + } + } + window.setInterval(job, inInterval||200); + dojox.grid.initTextSizePoll = dojox.grid.nop; + }, + + textSizeChanged: function() { + + } +}); + +dojox.grid.jobs = { + + cancel: function(inHandle){ + if(inHandle){ + window.clearTimeout(inHandle); + } + }, + + jobs: [], + + job: function(inName, inDelay, inJob){ + dojox.grid.jobs.cancelJob(inName); + var job = function(){ + delete dojox.grid.jobs.jobs[inName]; + inJob(); + } + dojox.grid.jobs.jobs[inName] = setTimeout(job, inDelay); + }, + + cancelJob: function(inName){ + dojox.grid.jobs.cancel(dojox.grid.jobs.jobs[inName]); + } + +} + +} diff --git a/includes/js/dojox/grid/_grid/nihiloGrid.css b/includes/js/dojox/grid/_grid/nihiloGrid.css new file mode 100644 index 0000000..ba9f39d --- /dev/null +++ b/includes/js/dojox/grid/_grid/nihiloGrid.css @@ -0,0 +1,211 @@ +.nihilo .dojoxGrid { + position: relative; + background-color: #e9e9e9; + font-size: 0.85em; + -moz-outline-style: none; + outline: none; + overflow: hidden; + height: 0; +} +.nihilo .dojoxGrid table { + padding: 0; +} +.nihilo .dojoxGrid td { + -moz-outline: none; +} +.nihilo .dojoxGrid-master-header { + position: relative; +} +.nihilo .dojoxGrid-master-view { + position: relative; +} +.nihilo .dojoxGrid-view { + position: absolute; + overflow: hidden; +} +.nihilo .dojoxGrid-header { + position: absolute; + overflow: hidden; +} +.nihilo .dojoxGrid-header { + background-color: #e9e9e9; +} +.nihilo .dojoxGrid-header table { + text-align: center; +} +.nihilo .dojoxGrid-header .dojoxGrid-cell-content { + text-align: center; +} +.nihilo .dojoxGrid-header .dojoxGrid-cell { + border: 1px solid transparent; + + border-color: white #ACA899 #919191 white; + background: url(../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-x top; + padding-bottom: 2px; + color: #000 !important; +} +.nihilo .dojoxGrid-header .dojoxGrid-cell-over { + background: url(../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-x top; +} +.nihilo .dojoxGrid-sort-down { + background: url(images/grid_sort_down.gif) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} +.nihilo .dojoxGrid-sort-up { + background: url(images/grid_sort_up.gif) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} +.nihilo .gridArrowButtonChar { + display:none !important; +} +.dijit_a11y .gridArrowButtonChar { + display:inline !important; +} +.nihilo .dojoxGrid-scrollbox { + position: relative; + overflow: scroll; + background-color: #fefefe; + width: 100%; +} +.nihilo .dojoxGrid-content { + position: relative; + overflow: hidden; + -moz-outline-style: none; + outline: none; +} +.nihilo .dojoxGrid-rowbar { + border: none; + + background: url(images/titleBar.png) #e9e9e9 repeat-y right; + border-right: 1px solid #cccccc; + padding: 0px; +} +.nihilo .dojoxGrid-rowbar-inner { + border: none; + border-bottom: 1px solid #cccccc; +} +.nihilo .dojoxGrid-rowbar-over { + background: url(images/titleBarActive.png) #e9e9e9 repeat-y right; +} +.nihilo .dojoxGrid-rowbar-selected { + background-color: #D9E8F9; + background-image: none; + background: url(../../../dijit/themes/nihilo/images/titleBar.png) #dddddd repeat-x top; + border-right: 1px solid #cccccc; + background-position: center; + background-repeat: no-repeat; +} +.nihilo .dojoxGrid-row { + position: relative; + width: 9000em; +} +.nihilo .dojoxGrid-row { + border: none; + border-left: none; + border-right: none; + background-color: white; + border-top: none; +} +.nihilo .dojoxGrid-row-over { + border-top-color: #cccccc; + border-bottom-color: #cccccc; +} +.nihilo .dojoxGrid-row-over .dojoxGrid-cell { + background-color: #ffe284; +} +.nihilo .dojoxGrid-row-odd { + background-color: #f2f5f9; + +} +.nihilo .dojoxGrid-row-selected { + background-color: #aec7e3; +} +.nihilo .dojoxGrid-row-table { + table-layout: fixed; + width: 0; + border-collapse: collapse; +} +.nihilo .dojoxGrid-invisible { + visibility: hidden; +} +.nihilo .Xdojo-ie .dojoxGrid-invisible { + display: none; +} +.nihilo .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td { + border-top-width: 0; + border-bottom-width: 0; + padding-top: 0; + padding-bottom: 0; + height: 0; + overflow: hidden; +} +.nihilo .dojoxGrid-cell { + border: 1px dotted #D5CDB5; + padding: 3px 3px 3px 3px; + text-align: left; + overflow: hidden; +} +.dj_ie6 .nihilo .dojoxGrid-cell { + border: 1px solid white; + border-right: 1px solid #D5CDB5; +} +.nihilo .dojoxGrid-cell-focus { + border: 1px dotted #a6a6a6; +} +.nihilo .dojoxGrid-cell-over { + border: 1px dotted #a6a6a6; +} +.nihilo .dojoxGrid-cell-focus.dojoxGrid-cell-over { + border: 1px dotted #595959; +} +.nihilo .dojoxGrid-cell-clip { + width: 100%; + overflow: hidden; + white-space:nowrap; + text-overflow: ellipsis; +} +.nihilo .dojoxGrid-row-editing td { + + background-color: #ffe284; + +} +.nihilo .dojoxGrid-row-inserting td { + background-color: #F4FFF4; +} +.nihilo .dojoxGrid-row-inflight td { + background-color: #F2F7B7; +} +.nihilo .dojoxGrid-row-error td { + background-color: #F8B8B6; +} +.nihilo .dojoxGrid-input, +.nihilo .dojoxGrid-select, +.nihilo .dojoxGrid-textarea { + margin: 0; + padding: 0px; + border-style: none; + width: 100%; + font-size: 100%; + font-family: inherit; +} +.dojoxGrid-hidden-focus { + position: absolute; + left: -1000px; + top: -1000px; + height: 0px, width: 0px; +} +.dijit_a11y .dojoxGrid-rowbar-selected { + border-top: 1px solid white; + border-bottom: 1px dashed black; + border-top: 0; + background: none; +} +.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner { + border: 0; + border-top: 1px solid white; +} +.dijit_a11y .dojoxGrid-row-selected { + border-bottom: 1px dashed black; +} diff --git a/includes/js/dojox/grid/_grid/nihiloGrid.css.commented.css b/includes/js/dojox/grid/_grid/nihiloGrid.css.commented.css new file mode 100644 index 0000000..e50697d --- /dev/null +++ b/includes/js/dojox/grid/_grid/nihiloGrid.css.commented.css @@ -0,0 +1,275 @@ +.nihilo .dojoxGrid { + position: relative; + background-color: #e9e9e9; + font-size: 0.85em; /* inherit font-family from dojo.css */ + -moz-outline-style: none; + outline: none; + overflow: hidden; + height: 0; +} + +.nihilo .dojoxGrid table { + padding: 0; +} + +.nihilo .dojoxGrid td { + -moz-outline: none; +} + +/* master header */ + +.nihilo .dojoxGrid-master-header { + position: relative; +} + +/* master view */ + +.nihilo .dojoxGrid-master-view { + position: relative; +} + +/* views */ + +.nihilo .dojoxGrid-view { + position: absolute; + overflow: hidden; +} + +/* header */ + +.nihilo .dojoxGrid-header { + position: absolute; + overflow: hidden; +} + +.nihilo .dojoxGrid-header { + background-color: #e9e9e9; +} + +.nihilo .dojoxGrid-header table { + text-align: center; +} + +.nihilo .dojoxGrid-header .dojoxGrid-cell-content { + text-align: center; +} + +.nihilo .dojoxGrid-header .dojoxGrid-cell { + border: 1px solid transparent; + /* border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; */ + border-color: white #ACA899 #919191 white; + background: url(../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-x top; + padding-bottom: 2px; + color: #000 !important; +} + +.nihilo .dojoxGrid-header .dojoxGrid-cell-over { + background: url(../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-x top; +} + +.nihilo .dojoxGrid-sort-down { + background: url(images/grid_sort_down.gif) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} + +.nihilo .dojoxGrid-sort-up { + background: url(images/grid_sort_up.gif) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} + +.nihilo .gridArrowButtonChar { + display:none !important; +} +.dijit_a11y .gridArrowButtonChar { + display:inline !important; +} + +/* content */ + +.nihilo .dojoxGrid-scrollbox { + position: relative; + overflow: scroll; + background-color: #fefefe; + width: 100%; +} + +.nihilo .dojoxGrid-content { + position: relative; + overflow: hidden; + -moz-outline-style: none; + outline: none; +} + +/* rowbar */ + +.nihilo .dojoxGrid-rowbar { + border: none; + /* + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + */ + background: url(images/titleBar.png) #e9e9e9 repeat-y right; + border-right: 1px solid #cccccc; + padding: 0px; +} + +.nihilo .dojoxGrid-rowbar-inner { + border: none; + border-bottom: 1px solid #cccccc; +} + +.nihilo .dojoxGrid-rowbar-over { + background: url(images/titleBarActive.png) #e9e9e9 repeat-y right; +} + +.nihilo .dojoxGrid-rowbar-selected { + background-color: #D9E8F9; + background-image: none; + background: url(../../../dijit/themes/nihilo/images/titleBar.png) #dddddd repeat-x top; + border-right: 1px solid #cccccc; + background-position: center; + background-repeat: no-repeat; +} + +/* rows */ + +.nihilo .dojoxGrid-row { + position: relative; + width: 9000em; +} + +.nihilo .dojoxGrid-row { + border: none; + border-left: none; + border-right: none; + background-color: white; + border-top: none; +} + +.nihilo .dojoxGrid-row-over { + border-top-color: #cccccc; + border-bottom-color: #cccccc; +} + +.nihilo .dojoxGrid-row-over .dojoxGrid-cell { + background-color: #ffe284; +} + +.nihilo .dojoxGrid-row-odd { + background-color: #f2f5f9; + /*background-color: #F9F7E8;*/ +} + +.nihilo .dojoxGrid-row-selected { + background-color: #aec7e3; +} + +.nihilo .dojoxGrid-row-table { + table-layout: fixed; + width: 0; + border-collapse: collapse; +} + +.nihilo .dojoxGrid-invisible { + visibility: hidden; +} + +.nihilo .Xdojo-ie .dojoxGrid-invisible { + display: none; +} + +.nihilo .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td { + border-top-width: 0; + border-bottom-width: 0; + padding-top: 0; + padding-bottom: 0; + height: 0; + overflow: hidden; +} + +/* cells */ + +.nihilo .dojoxGrid-cell { + border: 1px dotted #D5CDB5; + padding: 3px 3px 3px 3px; + text-align: left; + overflow: hidden; +} + +.dj_ie6 .nihilo .dojoxGrid-cell { + border: 1px solid white; + border-right: 1px solid #D5CDB5; +} + +.nihilo .dojoxGrid-cell-focus { + border: 1px dotted #a6a6a6; +} + +.nihilo .dojoxGrid-cell-over { + border: 1px dotted #a6a6a6; +} + +.nihilo .dojoxGrid-cell-focus.dojoxGrid-cell-over { + border: 1px dotted #595959; +} + +.nihilo .dojoxGrid-cell-clip { + width: 100%; + overflow: hidden; + white-space:nowrap; + text-overflow: ellipsis; +} + +/* editing */ + +/* FIXME: these colors are off! */ +.nihilo .dojoxGrid-row-editing td { + /* background-color: #F4FFF4; */ + background-color: #ffe284; + /* padding: 0px 3px 0px 3px; */ +} + +.nihilo .dojoxGrid-row-inserting td { + background-color: #F4FFF4; +} +.nihilo .dojoxGrid-row-inflight td { + background-color: #F2F7B7; +} +.nihilo .dojoxGrid-row-error td { + background-color: #F8B8B6; +} + +.nihilo .dojoxGrid-input, +.nihilo .dojoxGrid-select, +.nihilo .dojoxGrid-textarea { + margin: 0; + padding: 0px; + border-style: none; + width: 100%; + font-size: 100%; + font-family: inherit; +} + +.dojoxGrid-hidden-focus { + position: absolute; + left: -1000px; + top: -1000px; + height: 0px, width: 0px; +} + +.dijit_a11y .dojoxGrid-rowbar-selected { + border-top: 1px solid white; + border-bottom: 1px dashed black; + border-top: 0; + background: none; +} + +.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner { + border: 0; + border-top: 1px solid white; +} + +.dijit_a11y .dojoxGrid-row-selected { + border-bottom: 1px dashed black; +} diff --git a/includes/js/dojox/grid/_grid/publicEvents.js b/includes/js/dojox/grid/_grid/publicEvents.js new file mode 100644 index 0000000..4abb038 --- /dev/null +++ b/includes/js/dojox/grid/_grid/publicEvents.js @@ -0,0 +1,451 @@ +if(!dojo._hasResource["dojox.grid._grid.publicEvents"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.publicEvents"] = true; +dojo.provide("dojox.grid._grid.publicEvents"); + +dojox.grid.publicEvents = { + // summary: + // VirtualGrid mixin that provides default implementations for grid events. + // description: + // Default ynthetic events dispatched for VirtualGrid. dojo.connect to events to + // retain default implementation or override them for custom handling. + + // cellOverClass: String + // css class to apply to grid cells over which the cursor is placed. + cellOverClass: "dojoxGrid-cell-over", + + onKeyEvent: function(e){ + // summary: top level handler for Key Events + this.dispatchKeyEvent(e); + }, + + onContentEvent: function(e){ + // summary: Top level handler for Content events + this.dispatchContentEvent(e); + }, + + onHeaderEvent: function(e){ + // summary: Top level handler for header events + this.dispatchHeaderEvent(e); + }, + + onStyleRow: function(inRow){ + // summary: + // Perform row styling on a given row. Called whenever row styling is updated. + // + // inRow: Object + // Object containing row state information: selected, true if the row is selcted; over: + // true of the mouse is over the row; odd: true if the row is odd. Use customClasses and + // customStyles to control row css classes and styles; both properties are strings. + // + // example: onStyleRow({ selected: true, over:true, odd:false }) + with(inRow){ + customClasses += (odd?" dojoxGrid-row-odd":"") + (selected?" dojoxGrid-row-selected":"") + (over?" dojoxGrid-row-over":""); + } + this.focus.styleRow(inRow); + this.edit.styleRow(inRow); + }, + + onKeyDown: function(e){ + // summary: + // Grid key event handler. By default enter begins editing and applies edits, escape cancels and edit, + // tab, shift-tab, and arrow keys move grid cell focus. + if(e.altKey || e.ctrlKey || e.metaKey){ + return; + } + var dk = dojo.keys; + switch(e.keyCode){ + case dk.ESCAPE: + this.edit.cancel(); + break; + case dk.ENTER: + if(!e.shiftKey){ + var isEditing = this.edit.isEditing(); + this.edit.apply(); + if(!isEditing){ + this.edit.setEditCell(this.focus.cell, this.focus.rowIndex); + } + } + break; + case dk.TAB: + this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e); + break; + case dk.LEFT_ARROW: + case dk.RIGHT_ARROW: + if(!this.edit.isEditing()){ + dojo.stopEvent(e); + var offset = (e.keyCode == dk.LEFT_ARROW) ? 1 : -1; + if(dojo._isBodyLtr()){ offset *= -1; } + this.focus.move(0, offset); + } + break; + case dk.UP_ARROW: + if(!this.edit.isEditing() && this.focus.rowIndex != 0){ + dojo.stopEvent(e); + this.focus.move(-1, 0); + } + break; + case dk.DOWN_ARROW: + if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.model.count){ + dojo.stopEvent(e); + this.focus.move(1, 0); + } + break; + case dk.PAGE_UP: + if(!this.edit.isEditing() && this.focus.rowIndex != 0){ + dojo.stopEvent(e); + if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){ + this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0); + }else{ + this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1)); + this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1, 0); + } + } + break; + case dk.PAGE_DOWN: + if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.model.count){ + dojo.stopEvent(e); + if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){ + this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0); + }else{ + this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1)); + this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1, 0); + } + } + break; + } + }, + + onMouseOver: function(e){ + // summary: + // Event fired when mouse is over the grid. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + e.rowIndex == -1 ? this.onHeaderCellMouseOver(e) : this.onCellMouseOver(e); + }, + + onMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of the grid. + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + e.rowIndex == -1 ? this.onHeaderCellMouseOut(e) : this.onCellMouseOut(e); + }, + + onMouseDown: function(e){ + // summary: + // Event fired when mouse is down inside grid. + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + e.rowIndex == -1 ? this.onHeaderCellMouseDown(e) : this.onCellMouseDown(e); + }, + + onMouseOverRow: function(e){ + // summary: + // Event fired when mouse is over any row (data or header). + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + if(!this.rows.isOver(e.rowIndex)){ + this.rows.setOverRow(e.rowIndex); + e.rowIndex == -1 ? this.onHeaderMouseOver(e) : this.onRowMouseOver(e); + } + }, + onMouseOutRow: function(e){ + // summary: + // Event fired when mouse moves out of any row (data or header). + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + if(this.rows.isOver(-1)){ + this.onHeaderMouseOut(e); + }else if(!this.rows.isOver(-2)){ + this.rows.setOverRow(-2); + this.onRowMouseOut(e); + } + }, + + onMouseDownRow: function(e){ + // summary: + // Event fired when mouse is down inside grid row + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + if(e.rowIndex != -1) + this.onRowMouseDown(e); + }, + + // cell events + onCellMouseOver: function(e){ + // summary: + // Event fired when mouse is over a cell. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + dojo.addClass(e.cellNode, this.cellOverClass); + }, + + onCellMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of a cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + dojo.removeClass(e.cellNode, this.cellOverClass); + }, + + onCellMouseDown: function(e){ + // summary: + // Event fired when mouse is down in a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onCellClick: function(e){ + // summary: + // Event fired when a cell is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this._click[0] = this._click[1]; + this._click[1] = e; + if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){ + this.focus.setFocusCell(e.cell, e.rowIndex); + } + this.onRowClick(e); + }, + + onCellDblClick: function(e){ + // summary: + // Event fired when a cell is double-clicked. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + if(dojo.isIE){ + this.edit.setEditCell(this._click[1].cell, this._click[1].rowIndex); + }else if(this._click[0].rowIndex != this._click[1].rowIndex){ + this.edit.setEditCell(this._click[0].cell, this._click[0].rowIndex); + }else{ + this.edit.setEditCell(e.cell, e.rowIndex); + } + this.onRowDblClick(e); + }, + + onCellContextMenu: function(e){ + // summary: + // Event fired when a cell context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.onRowContextMenu(e); + }, + + onCellFocus: function(inCell, inRowIndex){ + // summary: + // Event fired when a cell receives focus. + // inCell: Object + // Cell object containing properties of the grid column. + // inRowIndex: Integer + // Index of the grid row + this.edit.cellFocus(inCell, inRowIndex); + }, + + // row events + onRowClick: function(e){ + // summary: + // Event fired when a row is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.edit.rowClick(e); + this.selection.clickSelectEvent(e); + }, + + onRowDblClick: function(e){ + // summary: + // Event fired when a row is double clicked. + // e: Event + // decorated event object which contains reference to grid, cell, and rowIndex + }, + + onRowMouseOver: function(e){ + // summary: + // Event fired when mouse moves over a data row. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onRowMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of a data row. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + }, + + onRowMouseDown: function(e){ + // summary: + // Event fired when mouse is down in a row. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onRowContextMenu: function(e){ + // summary: + // Event fired when a row context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + dojo.stopEvent(e); + }, + + // header events + onHeaderMouseOver: function(e){ + // summary: + // Event fired when mouse moves over the grid header. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + }, + + onHeaderMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of the grid header. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderCellMouseOver: function(e){ + // summary: + // Event fired when mouse moves over a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + dojo.addClass(e.cellNode, this.cellOverClass); + }, + + onHeaderCellMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + dojo.removeClass(e.cellNode, this.cellOverClass); + }, + + onHeaderCellMouseDown: function(e) { + // summary: + // Event fired when mouse is down in a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderClick: function(e){ + // summary: + // Event fired when the grid header is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderCellClick: function(e){ + // summary: + // Event fired when a header cell is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.setSortIndex(e.cell.index); + this.onHeaderClick(e); + }, + + onHeaderDblClick: function(e){ + // summary: + // Event fired when the grid header is double clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderCellDblClick: function(e){ + // summary: + // Event fired when a header cell is double clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.onHeaderDblClick(e); + }, + + onHeaderCellContextMenu: function(e){ + // summary: + // Event fired when a header cell context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.onHeaderContextMenu(e); + }, + + onHeaderContextMenu: function(e){ + // summary: + // Event fired when the grid header context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + dojo.stopEvent(e); + }, + + // editing + onStartEdit: function(inCell, inRowIndex){ + // summary: + // Event fired when editing is started for a given grid cell + // inCell: Object + // Cell object containing properties of the grid column. + // inRowIndex: Integer + // Index of the grid row + }, + + onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){ + // summary: + // Event fired when editing is applied for a given grid cell + // inValue: String + // Value from cell editor + // inRowIndex: Integer + // Index of the grid row + // inFieldIndex: Integer + // Index in the grid's data model + }, + + onCancelEdit: function(inRowIndex){ + // summary: + // Event fired when editing is cancelled for a given grid cell + // inRowIndex: Integer + // Index of the grid row + }, + + onApplyEdit: function(inRowIndex){ + // summary: + // Event fired when editing is applied for a given grid row + // inRowIndex: Integer + // Index of the grid row + }, + + onCanSelect: function(inRowIndex){ + // summary: + // Event to determine if a grid row may be selected + // inRowIndex: Integer + // Index of the grid row + // returns: Boolean + // true if the row can be selected + return true; + }, + + onCanDeselect: function(inRowIndex){ + // summary: + // Event to determine if a grid row may be deselected + // inRowIndex: Integer + // Index of the grid row + // returns: Boolean + // true if the row can be deselected + return true; + }, + + onSelected: function(inRowIndex){ + // summary: + // Event fired when a grid row is selected + // inRowIndex: Integer + // Index of the grid row + this.updateRowStyles(inRowIndex); + }, + + onDeselected: function(inRowIndex){ + // summary: + // Event fired when a grid row is deselected + // inRowIndex: Integer + // Index of the grid row + this.updateRowStyles(inRowIndex); + }, + + onSelectionChanged: function(){ + } + +} + +} diff --git a/includes/js/dojox/grid/_grid/rowbar.js b/includes/js/dojox/grid/_grid/rowbar.js new file mode 100644 index 0000000..d5e34c0 --- /dev/null +++ b/includes/js/dojox/grid/_grid/rowbar.js @@ -0,0 +1,53 @@ +if(!dojo._hasResource["dojox.grid._grid.rowbar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.rowbar"] = true; +dojo.provide("dojox.grid._grid.rowbar"); +dojo.require("dojox.grid._grid.view"); + +dojo.declare('dojox.GridRowView', dojox.GridView, { + // summary: + // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows. + defaultWidth: "3em", + noscroll: true, + padBorderWidth: 2, + buildRendering: function(){ + this.inherited('buildRendering', arguments); + this.scrollboxNode.style.overflow = "hidden"; + this.headerNode.style.visibility = "hidden"; + }, + getWidth: function(){ + return this.viewWidth || this.defaultWidth; + }, + buildRowContent: function(inRowIndex, inRowNode){ + var w = this.contentNode.offsetWidth - this.padBorderWidth + inRowNode.innerHTML = '<table style="width:' + w + 'px;" role="wairole:presentation"><tr><td class="dojoxGrid-rowbar-inner"></td></tr></table>'; + }, + renderHeader: function(){ + }, + resize: function(){ + this.adaptHeight(); + }, + adaptWidth: function(){ + }, + // styling + doStyleRowNode: function(inRowIndex, inRowNode){ + var n = [ "dojoxGrid-rowbar" ]; + if(this.grid.rows.isOver(inRowIndex)){ + n.push("dojoxGrid-rowbar-over"); + } + if(this.grid.selection.isSelected(inRowIndex)){ + n.push("dojoxGrid-rowbar-selected"); + } + inRowNode.className = n.join(" "); + }, + // event handlers + domouseover: function(e){ + this.grid.onMouseOverRow(e); + }, + domouseout: function(e){ + if(!this.isIntraRowEvent(e)){ + this.grid.onMouseOutRow(e); + } + } +}); + +} diff --git a/includes/js/dojox/grid/_grid/rows.js b/includes/js/dojox/grid/_grid/rows.js new file mode 100644 index 0000000..37ecbcb --- /dev/null +++ b/includes/js/dojox/grid/_grid/rows.js @@ -0,0 +1,66 @@ +if(!dojo._hasResource["dojox.grid._grid.rows"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.rows"] = true; +dojo.provide("dojox.grid._grid.rows"); + +dojo.declare("dojox.grid.rows", null, { + // Stores information about grid rows. Owned by grid and used internally. + constructor: function(inGrid){ + this.grid = inGrid; + }, + linesToEms: 2, + defaultRowHeight: 1, // lines + overRow: -2, + // metrics + getHeight: function(inRowIndex){ + return ''; + }, + getDefaultHeightPx: function(){ + // summmary: + // retrieves the default row height + // returns: int, default row height + return 32; + //return Math.round(this.defaultRowHeight * this.linesToEms * this.grid.contentPixelToEmRatio); + }, + // styles + prepareStylingRow: function(inRowIndex, inRowNode){ + return { + index: inRowIndex, + node: inRowNode, + odd: Boolean(inRowIndex&1), + selected: this.grid.selection.isSelected(inRowIndex), + over: this.isOver(inRowIndex), + customStyles: "", + customClasses: "dojoxGrid-row" + } + }, + styleRowNode: function(inRowIndex, inRowNode){ + var row = this.prepareStylingRow(inRowIndex, inRowNode); + this.grid.onStyleRow(row); + this.applyStyles(row); + }, + applyStyles: function(inRow){ + with(inRow){ + node.className = customClasses; + var h = node.style.height; + dojox.grid.setStyleText(node, customStyles + ';' + (node._style||'')); + node.style.height = h; + } + }, + updateStyles: function(inRowIndex){ + this.grid.updateRowStyles(inRowIndex); + }, + // states and events + setOverRow: function(inRowIndex){ + var last = this.overRow; + this.overRow = inRowIndex; + if((last!=this.overRow)&&(last >=0)){ + this.updateStyles(last); + } + this.updateStyles(this.overRow); + }, + isOver: function(inRowIndex){ + return (this.overRow == inRowIndex); + } +}); + +} diff --git a/includes/js/dojox/grid/_grid/scroller.js b/includes/js/dojox/grid/_grid/scroller.js new file mode 100644 index 0000000..d331367 --- /dev/null +++ b/includes/js/dojox/grid/_grid/scroller.js @@ -0,0 +1,489 @@ +if(!dojo._hasResource['dojox.grid._grid.scroller']){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource['dojox.grid._grid.scroller'] = true; +dojo.provide('dojox.grid._grid.scroller'); + +dojo.declare('dojox.grid.scroller.base', null, { + // summary: + // virtual scrollbox, abstract class + // Content must in /rows/ + // Rows are managed in contiguous sets called /pages/ + // There are a fixed # of rows per page + // The minimum rendered unit is a page + constructor: function(){ + this.pageHeights = []; + this.stack = []; + }, + // specified + rowCount: 0, // total number of rows to manage + defaultRowHeight: 10, // default height of a row + keepRows: 100, // maximum number of rows that should exist at one time + contentNode: null, // node to contain pages + scrollboxNode: null, // node that controls scrolling + // calculated + defaultPageHeight: 0, // default height of a page + keepPages: 10, // maximum number of pages that should exists at one time + pageCount: 0, + windowHeight: 0, + firstVisibleRow: 0, + lastVisibleRow: 0, + // private + page: 0, + pageTop: 0, + // init + init: function(inRowCount, inKeepRows, inRowsPerPage){ + switch(arguments.length){ + case 3: this.rowsPerPage = inRowsPerPage; + case 2: this.keepRows = inKeepRows; + case 1: this.rowCount = inRowCount; + } + this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage; + //this.defaultPageHeight = this.defaultRowHeight * Math.min(this.rowsPerPage, this.rowCount); + this.pageCount = Math.ceil(this.rowCount / this.rowsPerPage); + this.setKeepInfo(this.keepRows); + this.invalidate(); + if(this.scrollboxNode){ + this.scrollboxNode.scrollTop = 0; + this.scroll(0); + this.scrollboxNode.onscroll = dojo.hitch(this, 'onscroll'); + } + }, + setKeepInfo: function(inKeepRows){ + this.keepRows = inKeepRows; + this.keepPages = !this.keepRows ? this.keepRows : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2); + }, + // updating + invalidate: function(){ + this.invalidateNodes(); + this.pageHeights = []; + this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0); + this.resize(); + }, + updateRowCount: function(inRowCount){ + this.invalidateNodes(); + this.rowCount = inRowCount; + // update page count, adjust document height + oldPageCount = this.pageCount; + this.pageCount = Math.ceil(this.rowCount / this.rowsPerPage); + if(this.pageCount < oldPageCount){ + for(var i=oldPageCount-1; i>=this.pageCount; i--){ + this.height -= this.getPageHeight(i); + delete this.pageHeights[i] + } + }else if(this.pageCount > oldPageCount){ + this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight(); + } + this.resize(); + }, + // abstract interface + pageExists: function(inPageIndex){ + }, + measurePage: function(inPageIndex){ + }, + positionPage: function(inPageIndex, inPos){ + }, + repositionPages: function(inPageIndex){ + }, + installPage: function(inPageIndex){ + }, + preparePage: function(inPageIndex, inPos, inReuseNode){ + }, + renderPage: function(inPageIndex){ + }, + removePage: function(inPageIndex){ + }, + pacify: function(inShouldPacify){ + }, + // pacification + pacifying: false, + pacifyTicks: 200, + setPacifying: function(inPacifying){ + if(this.pacifying != inPacifying){ + this.pacifying = inPacifying; + this.pacify(this.pacifying); + } + }, + startPacify: function(){ + this.startPacifyTicks = new Date().getTime(); + }, + doPacify: function(){ + var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks; + this.setPacifying(true); + this.startPacify(); + return result; + }, + endPacify: function(){ + this.setPacifying(false); + }, + // default sizing implementation + resize: function(){ + if(this.scrollboxNode){ + this.windowHeight = this.scrollboxNode.clientHeight; + } + dojox.grid.setStyleHeightPx(this.contentNode, this.height); + }, + calcLastPageHeight: function(){ + if(!this.pageCount){ + return 0; + } + var lastPage = this.pageCount - 1; + var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight; + this.pageHeights[lastPage] = lastPageHeight; + return lastPageHeight; + }, + updateContentHeight: function(inDh){ + this.height += inDh; + this.resize(); + }, + updatePageHeight: function(inPageIndex){ + if(this.pageExists(inPageIndex)){ + var oh = this.getPageHeight(inPageIndex); + var h = (this.measurePage(inPageIndex))||(oh); + this.pageHeights[inPageIndex] = h; + if((h)&&(oh != h)){ + this.updateContentHeight(h - oh) + this.repositionPages(inPageIndex); + } + } + }, + rowHeightChanged: function(inRowIndex){ + this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage)); + }, + // scroller core + invalidateNodes: function(){ + while(this.stack.length){ + this.destroyPage(this.popPage()); + } + }, + createPageNode: function(){ + var p = document.createElement('div'); + p.style.position = 'absolute'; + //p.style.width = '100%'; + p.style[dojo._isBodyLtr() ? "left" : "right"] = '0'; + return p; + }, + getPageHeight: function(inPageIndex){ + var ph = this.pageHeights[inPageIndex]; + return (ph !== undefined ? ph : this.defaultPageHeight); + }, + // FIXME: this is not a stack, it's a FIFO list + pushPage: function(inPageIndex){ + return this.stack.push(inPageIndex); + }, + popPage: function(){ + return this.stack.shift(); + }, + findPage: function(inTop){ + var i = 0, h = 0; + for(var ph = 0; i<this.pageCount; i++, h += ph){ + ph = this.getPageHeight(i); + if(h + ph >= inTop){ + break; + } + } + this.page = i; + this.pageTop = h; + }, + buildPage: function(inPageIndex, inReuseNode, inPos){ + this.preparePage(inPageIndex, inReuseNode); + this.positionPage(inPageIndex, inPos); + // order of operations is key below + this.installPage(inPageIndex); + this.renderPage(inPageIndex); + // order of operations is key above + this.pushPage(inPageIndex); + }, + needPage: function(inPageIndex, inPos){ + var h = this.getPageHeight(inPageIndex), oh = h; + if(!this.pageExists(inPageIndex)){ + this.buildPage(inPageIndex, this.keepPages&&(this.stack.length >= this.keepPages), inPos); + h = this.measurePage(inPageIndex) || h; + this.pageHeights[inPageIndex] = h; + if(h && (oh != h)){ + this.updateContentHeight(h - oh) + } + }else{ + this.positionPage(inPageIndex, inPos); + } + return h; + }, + onscroll: function(){ + this.scroll(this.scrollboxNode.scrollTop); + }, + scroll: function(inTop){ + this.startPacify(); + this.findPage(inTop); + var h = this.height; + var b = this.getScrollBottom(inTop); + for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){ + y += this.needPage(p, y); + } + this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop); + this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b); + // indicates some page size has been updated + if(h != this.height){ + this.repositionPages(p-1); + } + this.endPacify(); + }, + getScrollBottom: function(inTop){ + return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1); + }, + // events + processNodeEvent: function(e, inNode){ + var t = e.target; + while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){ + t = t.parentNode; + } + if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){ + return false; + } + var page = t.parentNode; + e.topRowIndex = page.pageIndex * this.rowsPerPage; + e.rowIndex = e.topRowIndex + dojox.grid.indexInParent(t); + e.rowTarget = t; + return true; + }, + processEvent: function(e){ + return this.processNodeEvent(e, this.contentNode); + }, + dummy: 0 +}); + +dojo.declare('dojox.grid.scroller', dojox.grid.scroller.base, { + // summary: + // virtual scroller class, makes no assumption about shape of items being scrolled + constructor: function(){ + this.pageNodes = []; + }, + // virtual rendering interface + renderRow: function(inRowIndex, inPageNode){ + }, + removeRow: function(inRowIndex){ + }, + // page node operations + getDefaultNodes: function(){ + return this.pageNodes; + }, + getDefaultPageNode: function(inPageIndex){ + return this.getDefaultNodes()[inPageIndex]; + }, + positionPageNode: function(inNode, inPos){ + inNode.style.top = inPos + 'px'; + }, + getPageNodePosition: function(inNode){ + return inNode.offsetTop; + }, + repositionPageNodes: function(inPageIndex, inNodes){ + var last = 0; + for(var i=0; i<this.stack.length; i++){ + last = Math.max(this.stack[i], last); + } + // + var n = inNodes[inPageIndex]; + var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0); + //console.log('detected height change, repositioning from #%d (%d) @ %d ', inPageIndex + 1, last, y, this.pageHeights[0]); + // + for(var p=inPageIndex+1; p<=last; p++){ + n = inNodes[p]; + if(n){ + //console.log('#%d @ %d', inPageIndex, y, this.getPageNodePosition(n)); + if(this.getPageNodePosition(n) == y){ + return; + } + //console.log('placing page %d at %d', p, y); + this.positionPage(p, y); + } + y += this.getPageHeight(p); + } + }, + invalidatePageNode: function(inPageIndex, inNodes){ + var p = inNodes[inPageIndex]; + if(p){ + delete inNodes[inPageIndex]; + this.removePage(inPageIndex, p); + dojox.grid.cleanNode(p); + p.innerHTML = ''; + } + return p; + }, + preparePageNode: function(inPageIndex, inReusePageIndex, inNodes){ + var p = (inReusePageIndex === null ? this.createPageNode() : this.invalidatePageNode(inReusePageIndex, inNodes)); + p.pageIndex = inPageIndex; + p.id = (this._pageIdPrefix || "") + 'page-' + inPageIndex; + inNodes[inPageIndex] = p; + }, + // implementation for page manager + pageExists: function(inPageIndex){ + return Boolean(this.getDefaultPageNode(inPageIndex)); + }, + measurePage: function(inPageIndex){ + return this.getDefaultPageNode(inPageIndex).offsetHeight; + }, + positionPage: function(inPageIndex, inPos){ + this.positionPageNode(this.getDefaultPageNode(inPageIndex), inPos); + }, + repositionPages: function(inPageIndex){ + this.repositionPageNodes(inPageIndex, this.getDefaultNodes()); + }, + preparePage: function(inPageIndex, inReuseNode){ + this.preparePageNode(inPageIndex, (inReuseNode ? this.popPage() : null), this.getDefaultNodes()); + }, + installPage: function(inPageIndex){ + this.contentNode.appendChild(this.getDefaultPageNode(inPageIndex)); + }, + destroyPage: function(inPageIndex){ + var p = this.invalidatePageNode(inPageIndex, this.getDefaultNodes()); + dojox.grid.removeNode(p); + }, + // rendering implementation + renderPage: function(inPageIndex){ + var node = this.pageNodes[inPageIndex]; + for(var i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){ + this.renderRow(j, node); + } + }, + removePage: function(inPageIndex){ + for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){ + this.removeRow(j); + } + }, + // scroll control + getPageRow: function(inPage){ + return inPage * this.rowsPerPage; + }, + getLastPageRow: function(inPage){ + return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1; + }, + getFirstVisibleRowNodes: function(inPage, inPageTop, inScrollTop, inNodes){ + var row = this.getPageRow(inPage); + var rows = dojox.grid.divkids(inNodes[inPage]); + for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){ + inPageTop += rows[i].offsetHeight; + } + return (row ? row - 1 : row); + }, + getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){ + if(!this.pageExists(inPage)){ + return 0; + } + return this.getFirstVisibleRowNodes(inPage, inPageTop, inScrollTop, this.getDefaultNodes()); + }, + getLastVisibleRowNodes: function(inPage, inBottom, inScrollBottom, inNodes){ + var row = this.getLastPageRow(inPage); + var rows = dojox.grid.divkids(inNodes[inPage]); + for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){ + inBottom -= rows[i].offsetHeight; + } + return row + 1; + }, + getLastVisibleRow: function(inPage, inBottom, inScrollBottom){ + if(!this.pageExists(inPage)){ + return 0; + } + return this.getLastVisibleRowNodes(inPage, inBottom, inScrollBottom, this.getDefaultNodes()); + }, + findTopRowForNodes: function(inScrollTop, inNodes){ + var rows = dojox.grid.divkids(inNodes[this.page]); + for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){ + h = rows[i].offsetHeight; + t += h; + if(t >= inScrollTop){ + this.offset = h - (t - inScrollTop); + return i + this.page * this.rowsPerPage; + } + } + return -1; + }, + findScrollTopForNodes: function(inRow, inNodes){ + var rowPage = Math.floor(inRow / this.rowsPerPage); + var t = 0; + for(var i=0; i<rowPage; i++){ + t += this.getPageHeight(i); + } + this.pageTop = t; + this.needPage(rowPage, this.pageTop); + var rows = dojox.grid.divkids(inNodes[rowPage]); + var r = inRow - this.rowsPerPage * rowPage; + for(var i=0,l=rows.length; i<l && i<r; i++){ + t += rows[i].offsetHeight; + } + return t; + }, + findTopRow: function(inScrollTop){ + return this.findTopRowForNodes(inScrollTop, this.getDefaultNodes()); + }, + findScrollTop: function(inRow){ + return this.findScrollTopForNodes(inRow, this.getDefaultNodes()); + }, + dummy: 0 +}); + +dojo.declare('dojox.grid.scroller.columns', dojox.grid.scroller, { + // summary: + // Virtual scroller class that scrolls list of columns. Owned by grid and used internally + // for virtual scrolling. + constructor: function(inContentNodes){ + this.setContentNodes(inContentNodes); + }, + // nodes + setContentNodes: function(inNodes){ + this.contentNodes = inNodes; + this.colCount = (this.contentNodes ? this.contentNodes.length : 0); + this.pageNodes = []; + for(var i=0; i<this.colCount; i++){ + this.pageNodes[i] = []; + } + }, + getDefaultNodes: function(){ + return this.pageNodes[0] || []; + }, + scroll: function(inTop) { + if(this.colCount){ + dojox.grid.scroller.prototype.scroll.call(this, inTop); + } + }, + // resize + resize: function(){ + if(this.scrollboxNode){ + this.windowHeight = this.scrollboxNode.clientHeight; + } + for(var i=0; i<this.colCount; i++){ + dojox.grid.setStyleHeightPx(this.contentNodes[i], this.height); + } + }, + // implementation for page manager + positionPage: function(inPageIndex, inPos){ + for(var i=0; i<this.colCount; i++){ + this.positionPageNode(this.pageNodes[i][inPageIndex], inPos); + } + }, + preparePage: function(inPageIndex, inReuseNode){ + var p = (inReuseNode ? this.popPage() : null); + for(var i=0; i<this.colCount; i++){ + this.preparePageNode(inPageIndex, p, this.pageNodes[i]); + } + }, + installPage: function(inPageIndex){ + for(var i=0; i<this.colCount; i++){ + this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]); + } + }, + destroyPage: function(inPageIndex){ + for(var i=0; i<this.colCount; i++){ + dojox.grid.removeNode(this.invalidatePageNode(inPageIndex, this.pageNodes[i])); + } + }, + // rendering implementation + renderPage: function(inPageIndex){ + var nodes = []; + for(var i=0; i<this.colCount; i++){ + nodes[i] = this.pageNodes[i][inPageIndex]; + } + //this.renderRows(inPageIndex*this.rowsPerPage, this.rowsPerPage, nodes); + for(var i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){ + this.renderRow(j, nodes); + } + } +}); + +} diff --git a/includes/js/dojox/grid/_grid/selection.js b/includes/js/dojox/grid/_grid/selection.js new file mode 100644 index 0000000..75229c0 --- /dev/null +++ b/includes/js/dojox/grid/_grid/selection.js @@ -0,0 +1,215 @@ +if(!dojo._hasResource['dojox.grid._grid.selection']){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource['dojox.grid._grid.selection'] = true; +dojo.provide('dojox.grid._grid.selection'); + +dojo.declare("dojox.grid.selection", + null, + { + // summary: + // Manages row selection for grid. Owned by grid and used internally + // for selection. Override to implement custom selection. + + constructor: function(inGrid){ + this.grid = inGrid; + this.selected = []; + }, + + multiSelect: true, + selected: null, + updating: 0, + selectedIndex: -1, + + onCanSelect: function(inIndex){ + return this.grid.onCanSelect(inIndex); + }, + + onCanDeselect: function(inIndex){ + return this.grid.onCanDeselect(inIndex); + }, + + onSelected: function(inIndex){ + return this.grid.onSelected(inIndex); + }, + + onDeselected: function(inIndex){ + return this.grid.onDeselected(inIndex); + }, + + //onSetSelected: function(inIndex, inSelect) { }; + onChanging: function(){ + }, + + onChanged: function(){ + return this.grid.onSelectionChanged(); + }, + + isSelected: function(inIndex){ + return this.selected[inIndex]; + }, + + getFirstSelected: function(){ + for(var i=0, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + return i; + } + } + return -1; + }, + + getNextSelected: function(inPrev){ + for(var i=inPrev+1, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + return i; + } + } + return -1; + }, + + getSelected: function(){ + var result = []; + for(var i=0, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + result.push(i); + } + } + return result; + }, + + getSelectedCount: function(){ + var c = 0; + for(var i=0; i<this.selected.length; i++){ + if(this.selected[i]){ + c++; + } + } + return c; + }, + + beginUpdate: function(){ + if(this.updating == 0){ + this.onChanging(); + } + this.updating++; + }, + + endUpdate: function(){ + this.updating--; + if(this.updating == 0){ + this.onChanged(); + } + }, + + select: function(inIndex){ + this.unselectAll(inIndex); + this.addToSelection(inIndex); + }, + + addToSelection: function(inIndex){ + inIndex = Number(inIndex); + if(this.selected[inIndex]){ + this.selectedIndex = inIndex; + }else{ + if(this.onCanSelect(inIndex) !== false){ + this.selectedIndex = inIndex; + this.beginUpdate(); + this.selected[inIndex] = true; + this.grid.onSelected(inIndex); + //this.onSelected(inIndex); + //this.onSetSelected(inIndex, true); + this.endUpdate(); + } + } + }, + + deselect: function(inIndex){ + inIndex = Number(inIndex); + if(this.selectedIndex == inIndex){ + this.selectedIndex = -1; + } + if(this.selected[inIndex]){ + if(this.onCanDeselect(inIndex) === false){ + return; + } + this.beginUpdate(); + delete this.selected[inIndex]; + this.grid.onDeselected(inIndex); + //this.onDeselected(inIndex); + //this.onSetSelected(inIndex, false); + this.endUpdate(); + } + }, + + setSelected: function(inIndex, inSelect){ + this[(inSelect ? 'addToSelection' : 'deselect')](inIndex); + }, + + toggleSelect: function(inIndex){ + this.setSelected(inIndex, !this.selected[inIndex]) + }, + + insert: function(inIndex){ + this.selected.splice(inIndex, 0, false); + if(this.selectedIndex >= inIndex){ + this.selectedIndex++; + } + }, + + remove: function(inIndex){ + this.selected.splice(inIndex, 1); + if(this.selectedIndex >= inIndex){ + this.selectedIndex--; + } + }, + + unselectAll: function(inExcept){ + for(var i in this.selected){ + if((i!=inExcept)&&(this.selected[i]===true)){ + this.deselect(i); + } + } + }, + + shiftSelect: function(inFrom, inTo){ + var s = (inFrom >= 0 ? inFrom : inTo), e = inTo; + if(s > e){ + e = s; + s = inTo; + } + for(var i=s; i<=e; i++){ + this.addToSelection(i); + } + }, + + clickSelect: function(inIndex, inCtrlKey, inShiftKey){ + this.beginUpdate(); + if(!this.multiSelect){ + this.select(inIndex); + }else{ + var lastSelected = this.selectedIndex; + if(!inCtrlKey){ + this.unselectAll(inIndex); + } + if(inShiftKey){ + this.shiftSelect(lastSelected, inIndex); + }else if(inCtrlKey){ + this.toggleSelect(inIndex); + }else{ + this.addToSelection(inIndex) + } + } + this.endUpdate(); + }, + + clickSelectEvent: function(e){ + this.clickSelect(e.rowIndex, e.ctrlKey, e.shiftKey); + }, + + clear: function(){ + this.beginUpdate(); + this.unselectAll(); + this.endUpdate(); + } + +}); + +} diff --git a/includes/js/dojox/grid/_grid/soriaGrid.css b/includes/js/dojox/grid/_grid/soriaGrid.css new file mode 100644 index 0000000..f244030 --- /dev/null +++ b/includes/js/dojox/grid/_grid/soriaGrid.css @@ -0,0 +1,212 @@ +.soria .dojoxGrid { + position: relative; + background-color: #e9e9e9; + font-size: 0.85em; + -moz-outline-style: none; + outline: none; + overflow: hidden; + height: 0; +} +.soria .dojoxGrid table { + padding: 0; +} +.soria .dojoxGrid td { + -moz-outline: none; +} +.soria .dojoxGrid-master-header { + position: relative; +} +.soria .dojoxGrid-master-view { + position: relative; +} +.soria .dojoxGrid-view { + position: absolute; + overflow: hidden; +} +.soria .dojoxGrid-header { + position: absolute; + overflow: hidden; +} +.soria .dojoxGrid-header { + background-color: #e9e9e9; +} +.soria .dojoxGrid-header table { + text-align: center; +} +.soria .dojoxGrid-header .dojoxGrid-cell-content { + text-align: center; +} +.soria .dojoxGrid-header .dojoxGrid-cell { + border: 1px solid transparent; + + border-color: white #ACA899 #919191 white; + background: url(../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-x top; + padding-bottom: 2px; + color: #000 !important; +} +.soria .dojoxGrid-header .dojoxGrid-cell-over { + background: url(../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-x top; +} +.soria .dojoxGrid-sort-down { + background: url(images/grid_sort_down.gif) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} +.soria .dojoxGrid-sort-up { + background: url(images/grid_sort_up.gif) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} +.soria .gridArrowButtonChar { + display:none !important; +} +.dijit_a11y .gridArrowButtonChar { + display:inline !important; +} +.soria .dojoxGrid-scrollbox { + position: relative; + overflow: scroll; + background-color: #fefefe; + width: 100%; +} +.soria .dojoxGrid-content { + position: relative; + overflow: hidden; + -moz-outline-style: none; + outline: none; +} +.soria .dojoxGrid-rowbar { + border: none; + + background: url(images/titleBar.png) #e9e9e9 repeat-y right; + border-right: 1px solid #cccccc; + padding: 0px; +} +.soria .dojoxGrid-rowbar-inner { + border: none; + border-bottom: 1px solid #cccccc; +} +.soria .dojoxGrid-rowbar-over { + background: url(images/titleBarActive.png) #e9e9e9 repeat-y right; +} +.soria .dojoxGrid-rowbar-selected { + background-color: #D9E8F9; + background-image: none; + background: url(../../../dijit/themes/soria/images/titleBar.png) #dddddd repeat-x top; + border-right: 1px solid #cccccc; + background-position: center; + background-repeat: no-repeat; +} +.soria .dojoxGrid-row { + position: relative; + width: 9000em; +} +.soria .dojoxGrid-row { + border: none; + border-left: none; + border-right: none; + background-color: white; + border-top: none; +} +.soria .dojoxGrid-row-over { + border-top-color: #cccccc; + border-bottom-color: #cccccc; +} +.soria .dojoxGrid-row-over .dojoxGrid-cell { + background-color: #60a1ea; + color:#fff; +} +.soria .dojoxGrid-row-odd { + background-color: #f2f5f9; + +} +.soria .dojoxGrid-row-selected { + background-color: #aec7e3; +} +.soria .dojoxGrid-row-table { + table-layout: fixed; + width: 0; + border-collapse: collapse; +} +.soria .dojoxGrid-invisible { + visibility: hidden; +} +.soria .Xdojo-ie .dojoxGrid-invisible { + display: none; +} +.soria .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td { + border-top-width: 0; + border-bottom-width: 0; + padding-top: 0; + padding-bottom: 0; + height: 0; + overflow: hidden; +} +.soria .dojoxGrid-cell { + border: 1px dotted #D5CDB5; + padding: 3px 3px 3px 3px; + text-align: left; + overflow: hidden; +} +.dj_ie6 .soria .dojoxGrid-cell { + border: 1px solid white; + border-right: 1px solid #D5CDB5; +} +.soria .dojoxGrid-cell-focus { + border: 1px dotted #a6a6a6; +} +.soria .dojoxGrid-cell-over { + border: 1px dotted #a6a6a6; +} +.soria .dojoxGrid-cell-focus.dojoxGrid-cell-over { + border: 1px dotted #595959; +} +.soria .dojoxGrid-cell-clip { + width: 100%; + overflow: hidden; + white-space:nowrap; + text-overflow: ellipsis; +} +.soria .dojoxGrid-row-editing td { + + background-color: #60a1ea; + +} +.soria .dojoxGrid-row-inserting td { + background-color: #F4FFF4; +} +.soria .dojoxGrid-row-inflight td { + background-color: #F2F7B7; +} +.soria .dojoxGrid-row-error td { + background-color: #F8B8B6; +} +.soria .dojoxGrid-input, +.soria .dojoxGrid-select, +.soria .dojoxGrid-textarea { + margin: 0; + padding: 0px; + border-style: none; + width: 100%; + font-size: 100%; + font-family: inherit; +} +.dojoxGrid-hidden-focus { + position: absolute; + left: -1000px; + top: -1000px; + height: 0px, width: 0px; +} +.dijit_a11y .dojoxGrid-rowbar-selected { + border-top: 1px solid white; + border-bottom: 1px dashed black; + border-top: 0; + background: none; +} +.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner { + border: 0; + border-top: 1px solid white; +} +.dijit_a11y .dojoxGrid-row-selected { + border-bottom: 1px dashed black; +} diff --git a/includes/js/dojox/grid/_grid/soriaGrid.css.commented.css b/includes/js/dojox/grid/_grid/soriaGrid.css.commented.css new file mode 100644 index 0000000..06263ad --- /dev/null +++ b/includes/js/dojox/grid/_grid/soriaGrid.css.commented.css @@ -0,0 +1,276 @@ +.soria .dojoxGrid { + position: relative; + background-color: #e9e9e9; + font-size: 0.85em; /* inherit font-family from dojo.css */ + -moz-outline-style: none; + outline: none; + overflow: hidden; + height: 0; +} + +.soria .dojoxGrid table { + padding: 0; +} + +.soria .dojoxGrid td { + -moz-outline: none; +} + +/* master header */ + +.soria .dojoxGrid-master-header { + position: relative; +} + +/* master view */ + +.soria .dojoxGrid-master-view { + position: relative; +} + +/* views */ + +.soria .dojoxGrid-view { + position: absolute; + overflow: hidden; +} + +/* header */ + +.soria .dojoxGrid-header { + position: absolute; + overflow: hidden; +} + +.soria .dojoxGrid-header { + background-color: #e9e9e9; +} + +.soria .dojoxGrid-header table { + text-align: center; +} + +.soria .dojoxGrid-header .dojoxGrid-cell-content { + text-align: center; +} + +.soria .dojoxGrid-header .dojoxGrid-cell { + border: 1px solid transparent; + /* border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; */ + border-color: white #ACA899 #919191 white; + background: url(../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-x top; + padding-bottom: 2px; + color: #000 !important; +} + +.soria .dojoxGrid-header .dojoxGrid-cell-over { + background: url(../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-x top; +} + +.soria .dojoxGrid-sort-down { + background: url(images/grid_sort_down.gif) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} + +.soria .dojoxGrid-sort-up { + background: url(images/grid_sort_up.gif) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} + +.soria .gridArrowButtonChar { + display:none !important; +} +.dijit_a11y .gridArrowButtonChar { + display:inline !important; +} + +/* content */ + +.soria .dojoxGrid-scrollbox { + position: relative; + overflow: scroll; + background-color: #fefefe; + width: 100%; +} + +.soria .dojoxGrid-content { + position: relative; + overflow: hidden; + -moz-outline-style: none; + outline: none; +} + +/* rowbar */ + +.soria .dojoxGrid-rowbar { + border: none; + /* + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + */ + background: url(images/titleBar.png) #e9e9e9 repeat-y right; + border-right: 1px solid #cccccc; + padding: 0px; +} + +.soria .dojoxGrid-rowbar-inner { + border: none; + border-bottom: 1px solid #cccccc; +} + +.soria .dojoxGrid-rowbar-over { + background: url(images/titleBarActive.png) #e9e9e9 repeat-y right; +} + +.soria .dojoxGrid-rowbar-selected { + background-color: #D9E8F9; + background-image: none; + background: url(../../../dijit/themes/soria/images/titleBar.png) #dddddd repeat-x top; + border-right: 1px solid #cccccc; + background-position: center; + background-repeat: no-repeat; +} + +/* rows */ + +.soria .dojoxGrid-row { + position: relative; + width: 9000em; +} + +.soria .dojoxGrid-row { + border: none; + border-left: none; + border-right: none; + background-color: white; + border-top: none; +} + +.soria .dojoxGrid-row-over { + border-top-color: #cccccc; + border-bottom-color: #cccccc; +} + +.soria .dojoxGrid-row-over .dojoxGrid-cell { + background-color: #60a1ea; + color:#fff; +} + +.soria .dojoxGrid-row-odd { + background-color: #f2f5f9; + /*background-color: #F9F7E8;*/ +} + +.soria .dojoxGrid-row-selected { + background-color: #aec7e3; +} + +.soria .dojoxGrid-row-table { + table-layout: fixed; + width: 0; + border-collapse: collapse; +} + +.soria .dojoxGrid-invisible { + visibility: hidden; +} + +.soria .Xdojo-ie .dojoxGrid-invisible { + display: none; +} + +.soria .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td { + border-top-width: 0; + border-bottom-width: 0; + padding-top: 0; + padding-bottom: 0; + height: 0; + overflow: hidden; +} + +/* cells */ + +.soria .dojoxGrid-cell { + border: 1px dotted #D5CDB5; + padding: 3px 3px 3px 3px; + text-align: left; + overflow: hidden; +} + +.dj_ie6 .soria .dojoxGrid-cell { + border: 1px solid white; + border-right: 1px solid #D5CDB5; +} + +.soria .dojoxGrid-cell-focus { + border: 1px dotted #a6a6a6; +} + +.soria .dojoxGrid-cell-over { + border: 1px dotted #a6a6a6; +} + +.soria .dojoxGrid-cell-focus.dojoxGrid-cell-over { + border: 1px dotted #595959; +} + +.soria .dojoxGrid-cell-clip { + width: 100%; + overflow: hidden; + white-space:nowrap; + text-overflow: ellipsis; +} + +/* editing */ + +/* FIXME: these colors are off! */ +.soria .dojoxGrid-row-editing td { + /* background-color: #F4FFF4; */ + background-color: #60a1ea; + /* padding: 0px 3px 0px 3px; */ +} + +.soria .dojoxGrid-row-inserting td { + background-color: #F4FFF4; +} +.soria .dojoxGrid-row-inflight td { + background-color: #F2F7B7; +} +.soria .dojoxGrid-row-error td { + background-color: #F8B8B6; +} + +.soria .dojoxGrid-input, +.soria .dojoxGrid-select, +.soria .dojoxGrid-textarea { + margin: 0; + padding: 0px; + border-style: none; + width: 100%; + font-size: 100%; + font-family: inherit; +} + +.dojoxGrid-hidden-focus { + position: absolute; + left: -1000px; + top: -1000px; + height: 0px, width: 0px; +} + +.dijit_a11y .dojoxGrid-rowbar-selected { + border-top: 1px solid white; + border-bottom: 1px dashed black; + border-top: 0; + background: none; +} + +.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner { + border: 0; + border-top: 1px solid white; +} + +.dijit_a11y .dojoxGrid-row-selected { + border-bottom: 1px dashed black; +} diff --git a/includes/js/dojox/grid/_grid/tundraGrid.css b/includes/js/dojox/grid/_grid/tundraGrid.css new file mode 100644 index 0000000..d7b7a5f --- /dev/null +++ b/includes/js/dojox/grid/_grid/tundraGrid.css @@ -0,0 +1,215 @@ +.tundra .dojoxGrid { + position: relative; + background-color: #e9e9e9; + font-size: 0.85em; + -moz-outline-style: none; + outline: none; + overflow: hidden; + height: 0; +} +.tundra .dojoxGrid table { + padding: 0; +} +.tundra .dojoxGrid td { + -moz-outline: none; +} +.tundra .dojoxGrid-master-header { + position: relative; +} +.tundra .dojoxGrid-master-view { + position: relative; +} +.tundra .dojoxGrid-view { + position: absolute; + overflow: hidden; +} +.tundra .dojoxGrid-header { + position: absolute; + overflow: hidden; +} +.tundra .dojoxGrid-header { + background-color: #e9e9e9; +} +.tundra .dojoxGrid-header table { + text-align: center; +} +.tundra .dojoxGrid-header .dojoxGrid-cell-content { + text-align: center; +} +.tundra .dojoxGrid-header .dojoxGrid-cell { + border: 1px solid transparent; + + border-color: white #ACA899 #919191 white; + background: url(../../../dijit/themes/tundra/images/tabEnabled.png) #e9e9e9 repeat-x top; + padding-bottom: 2px; + color: #000 !important; +} +.tundra .dojoxGrid-header .dojoxGrid-cell-over { + background: url(../../../dijit/themes/tundra/images/tabHover.png) #e9e9e9 repeat-x top; + color: #000 !important; +} +.tundra .dojoxGrid-sort-down { + background: url(../../../dijit/themes/tundra/images/arrowDown.png) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} +.tundra .dojoxGrid-sort-up { + background: url(../../../dijit/themes/tundra/images/arrowUp.png) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} +.tundra .gridArrowButtonChar { + display:none !important; +} +.dijit_a11y .gridArrowButtonChar { + display:inline !important; +} +.tundra .dojoxGrid-scrollbox { + position: relative; + overflow: scroll; + background-color: #fefefe; + width: 100%; +} +.tundra .dojoxGrid-content { + position: relative; + overflow: hidden; + -moz-outline-style: none; + outline: none; +} +.tundra .dojoxGrid-rowbar { + border: none; + + background: url(images/tabEnabled_rotated.png) #e9e9e9 repeat-y right; + border-right: 1px solid #cccccc; + padding: 0px; +} +.tundra .dojoxGrid-rowbar-inner { + border: none; + border-bottom: 1px solid #cccccc; +} +.tundra .dojoxGrid-rowbar-over { + background: url(images/tabHover_rotated.png) #e9e9e9 repeat-y right; +} +.tundra .dojoxGrid-rowbar-selected { + background-color: #D9E8F9; + background-image: none; + background: url(../../../dijit/themes/tundra/images/tabDisabled.png) #dddddd repeat-x top; + border-right: 1px solid #cccccc; + background-position: center; + background-repeat: no-repeat; +} +.tundra .dojoxGrid-row { + position: relative; + width: 9000em; +} +.tundra .dojoxGrid-row { + border: none; + border-left: none; + border-right: none; + background-color: white; + border-top: none; +} +.tundra .dojoxGrid-row-over { + border-top-color: #cccccc; + border-bottom-color: #cccccc; +} +.tundra .dojoxGrid-row-over .dojoxGrid-cell { + background-color: #60a1ea; + color:#fff; + +} +.tundra .dojoxGrid-row-odd { + background-color: #f2f5f9; + +} +.tundra .dojoxGrid-row-selected { + background-color: #aec7e3; + +} +.tundra .dojoxGrid-row-table { + table-layout: fixed; + width: 0; + border-collapse: collapse; +} +.tundra .dojoxGrid-invisible { + visibility: hidden; +} +.tundra .Xdojo-ie .dojoxGrid-invisible { + display: none; +} +.tundra .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td { + border-top-width: 0; + border-bottom-width: 0; + padding-top: 0; + padding-bottom: 0; + height: 0; + overflow: hidden; +} +.tundra .dojoxGrid-cell { + border: 1px dotted #D5CDB5; + padding: 3px 3px 3px 3px; + text-align: left; + overflow: hidden; +} +.dj_ie6 .tundra .dojoxGrid-cell { + border: 1px solid white; + border-right: 1px solid #D5CDB5; +} +.tundra .dojoxGrid-cell-focus { + border: 1px dotted #a6a6a6; +} +.tundra .dojoxGrid-cell-over { + border: 1px dotted #a6a6a6; +} +.tundra .dojoxGrid-cell-focus.dojoxGrid-cell-over { + border: 1px dotted #595959; +} +.tundra .dojoxGrid-cell-clip { + width: 100%; + overflow: hidden; + white-space:nowrap; + text-overflow: ellipsis; +} +.tundra .dojoxGrid-row-editing td { + + background-color: #60a1ea; + +} +.tundra .dojoxGrid-row-inserting td { + background-color: #F4FFF4; +} +.tundra .dojoxGrid-row-inflight td { + background-color: #F2F7B7; +} +.tundra .dojoxGrid-row-error td { + background-color: #F8B8B6; +} +.tundra .dojoxGrid-input, +.tundra .dojoxGrid-select, +.tundra .dojoxGrid-textarea { + margin: 0; + padding: 0px; + border-style: none; + width: 100%; + font-size: 100%; + font-family: inherit; +} +.dojoxGrid-hidden-focus { + position: absolute; + left: -1000px; + top: -1000px; + height: 0px, width: 0px; +} +.dijit_a11y .dojoxGrid-rowbar-selected { + border-top: 1px solid white; + border-bottom: 1px dashed black; + border-top: 0; + background: none; +} +.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner { + border: 0; + border-top: 1px solid white; +} +.dijit_a11y .dojoxGrid-row-selected { + border-bottom: 1px dashed black; +} diff --git a/includes/js/dojox/grid/_grid/tundraGrid.css.commented.css b/includes/js/dojox/grid/_grid/tundraGrid.css.commented.css new file mode 100644 index 0000000..a282f58 --- /dev/null +++ b/includes/js/dojox/grid/_grid/tundraGrid.css.commented.css @@ -0,0 +1,281 @@ +.tundra .dojoxGrid { + position: relative; + background-color: #e9e9e9; + font-size: 0.85em; /* inherit font-family from dojo.css */ + -moz-outline-style: none; + outline: none; + overflow: hidden; + height: 0; +} + +.tundra .dojoxGrid table { + padding: 0; +} + +.tundra .dojoxGrid td { + -moz-outline: none; +} + +/* master header */ + +.tundra .dojoxGrid-master-header { + position: relative; +} + +/* master view */ + +.tundra .dojoxGrid-master-view { + position: relative; +} + +/* views */ + +.tundra .dojoxGrid-view { + position: absolute; + overflow: hidden; +} + +/* header */ + +.tundra .dojoxGrid-header { + position: absolute; + overflow: hidden; +} + +.tundra .dojoxGrid-header { + background-color: #e9e9e9; +} + +.tundra .dojoxGrid-header table { + text-align: center; +} + +.tundra .dojoxGrid-header .dojoxGrid-cell-content { + text-align: center; +} + +.tundra .dojoxGrid-header .dojoxGrid-cell { + border: 1px solid transparent; + /* border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; */ + border-color: white #ACA899 #919191 white; + background: url(../../../dijit/themes/tundra/images/tabEnabled.png) #e9e9e9 repeat-x top; + padding-bottom: 2px; + color: #000 !important; +} + +.tundra .dojoxGrid-header .dojoxGrid-cell-over { + background: url(../../../dijit/themes/tundra/images/tabHover.png) #e9e9e9 repeat-x top; + color: #000 !important; +} + +.tundra .dojoxGrid-sort-down { + background: url(../../../dijit/themes/tundra/images/arrowDown.png) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} + +.tundra .dojoxGrid-sort-up { + background: url(../../../dijit/themes/tundra/images/arrowUp.png) right no-repeat; + padding-left: 0px; + margin-left: 0px; +} + +.tundra .gridArrowButtonChar { + display:none !important; +} +.dijit_a11y .gridArrowButtonChar { + display:inline !important; +} + +/* content */ + +.tundra .dojoxGrid-scrollbox { + position: relative; + overflow: scroll; + background-color: #fefefe; + width: 100%; +} + +.tundra .dojoxGrid-content { + position: relative; + overflow: hidden; + -moz-outline-style: none; + outline: none; +} + +/* rowbar */ + +.tundra .dojoxGrid-rowbar { + border: none; + /* + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + */ + background: url(images/tabEnabled_rotated.png) #e9e9e9 repeat-y right; + border-right: 1px solid #cccccc; + padding: 0px; +} + +.tundra .dojoxGrid-rowbar-inner { + border: none; + border-bottom: 1px solid #cccccc; +} + +.tundra .dojoxGrid-rowbar-over { + background: url(images/tabHover_rotated.png) #e9e9e9 repeat-y right; +} + +.tundra .dojoxGrid-rowbar-selected { + background-color: #D9E8F9; + background-image: none; + background: url(../../../dijit/themes/tundra/images/tabDisabled.png) #dddddd repeat-x top; + border-right: 1px solid #cccccc; + background-position: center; + background-repeat: no-repeat; +} + +/* rows */ + +.tundra .dojoxGrid-row { + position: relative; + width: 9000em; +} + +.tundra .dojoxGrid-row { + border: none; + border-left: none; + border-right: none; + background-color: white; + border-top: none; +} + +.tundra .dojoxGrid-row-over { + border-top-color: #cccccc; + border-bottom-color: #cccccc; +} + +.tundra .dojoxGrid-row-over .dojoxGrid-cell { + background-color: #60a1ea; + color:#fff; + /*background: url(../../../dijit/themes/tundra/images/tabEnabled.png) #e9e9e9 repeat-x top;*/ +} + +.tundra .dojoxGrid-row-odd { + background-color: #f2f5f9; + /*background-color: #F9F7E8;*/ +} + +.tundra .dojoxGrid-row-selected { + background-color: #aec7e3; + /* + background: url(../../../dijit/themes/tundra/images/tabDisabled.png) #dddddd repeat-x top; + */ +} + +.tundra .dojoxGrid-row-table { + table-layout: fixed; + width: 0; + border-collapse: collapse; +} + +.tundra .dojoxGrid-invisible { + visibility: hidden; +} + +.tundra .Xdojo-ie .dojoxGrid-invisible { + display: none; +} + +.tundra .dojoxGrid-invisible td, .dojoxGrid-header .dojoxGrid-invisible td { + border-top-width: 0; + border-bottom-width: 0; + padding-top: 0; + padding-bottom: 0; + height: 0; + overflow: hidden; +} + +/* cells */ + +.tundra .dojoxGrid-cell { + border: 1px dotted #D5CDB5; + padding: 3px 3px 3px 3px; + text-align: left; + overflow: hidden; +} + +.dj_ie6 .tundra .dojoxGrid-cell { + border: 1px solid white; + border-right: 1px solid #D5CDB5; +} + +.tundra .dojoxGrid-cell-focus { + border: 1px dotted #a6a6a6; +} + +.tundra .dojoxGrid-cell-over { + border: 1px dotted #a6a6a6; +} + +.tundra .dojoxGrid-cell-focus.dojoxGrid-cell-over { + border: 1px dotted #595959; +} + +.tundra .dojoxGrid-cell-clip { + width: 100%; + overflow: hidden; + white-space:nowrap; + text-overflow: ellipsis; +} + +/* editing */ + +/* FIXME: these colors are off! */ +.tundra .dojoxGrid-row-editing td { + /* background-color: #F4FFF4; */ + background-color: #60a1ea; + /* padding: 0px 3px 0px 3px; */ +} + +.tundra .dojoxGrid-row-inserting td { + background-color: #F4FFF4; +} +.tundra .dojoxGrid-row-inflight td { + background-color: #F2F7B7; +} +.tundra .dojoxGrid-row-error td { + background-color: #F8B8B6; +} + +.tundra .dojoxGrid-input, +.tundra .dojoxGrid-select, +.tundra .dojoxGrid-textarea { + margin: 0; + padding: 0px; + border-style: none; + width: 100%; + font-size: 100%; + font-family: inherit; +} + +.dojoxGrid-hidden-focus { + position: absolute; + left: -1000px; + top: -1000px; + height: 0px, width: 0px; +} + +.dijit_a11y .dojoxGrid-rowbar-selected { + border-top: 1px solid white; + border-bottom: 1px dashed black; + border-top: 0; + background: none; +} + +.dijit_a11y .dojoxGrid-rowbar-selected .dojoxGrid-rowbar-inner { + border: 0; + border-top: 1px solid white; +} + +.dijit_a11y .dojoxGrid-row-selected { + border-bottom: 1px dashed black; +} diff --git a/includes/js/dojox/grid/_grid/view.js b/includes/js/dojox/grid/_grid/view.js new file mode 100644 index 0000000..7f669cd --- /dev/null +++ b/includes/js/dojox/grid/_grid/view.js @@ -0,0 +1,336 @@ +if(!dojo._hasResource["dojox.grid._grid.view"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.view"] = true; +dojo.provide("dojox.grid._grid.view"); + +dojo.require("dijit._Widget"); +dojo.require("dijit._Templated"); +dojo.require("dojox.grid._grid.builder"); + +dojo.declare('dojox.GridView', + [dijit._Widget, dijit._Templated], + { + // summary: + // A collection of grid columns. A grid is comprised of a set of views that stack horizontally. + // Grid creates views automatically based on grid's layout structure. + // Users should typically not need to access individual views directly. + // + // defaultWidth: String + // Default widget of the view + defaultWidth: "18em", + + // viewWidth: String + // Width for the view, in valid css unit + viewWidth: "", + + templateString:"<div class=\"dojoxGrid-view\">\n\t<div class=\"dojoxGrid-header\" dojoAttachPoint=\"headerNode\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGrid-hidden-focus\" dojoAttachPoint=\"hiddenFocusNode\" />\n\t<input type=\"checkbox\" class=\"dojoxGrid-hidden-focus\" />\n\t<div class=\"dojoxGrid-scrollbox\" dojoAttachPoint=\"scrollboxNode\">\n\t\t<div class=\"dojoxGrid-content\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\"></div>\n\t</div>\n</div>\n", + + themeable: false, + classTag: 'dojoxGrid', + marginBottom: 0, + rowPad: 2, + + postMixInProperties: function(){ + this.rowNodes = []; + }, + + postCreate: function(){ + this.connect(this.scrollboxNode,"onscroll","doscroll"); + dojox.grid.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]); + dojox.grid.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]); + this.content = new dojox.grid.contentBuilder(this); + this.header = new dojox.grid.headerBuilder(this); + //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node + if(!dojo._isBodyLtr()){ + this.headerNodeContainer.style.width = ""; + } + }, + + destroy: function(){ + dojox.grid.removeNode(this.headerNode); + this.inherited("destroy", arguments); + }, + + // focus + focus: function(){ + if(dojo.isSafari || dojo.isOpera){ + this.hiddenFocusNode.focus(); + }else{ + this.scrollboxNode.focus(); + } + }, + + setStructure: function(inStructure){ + var vs = this.structure = inStructure; + // FIXME: similar logic is duplicated in layout + if(vs.width && !isNaN(vs.width)){ + this.viewWidth = vs.width + 'em'; + }else{ + this.viewWidth = vs.width || this.viewWidth; //|| this.defaultWidth; + } + this.onBeforeRow = vs.onBeforeRow; + this.noscroll = vs.noscroll; + if(this.noscroll){ + this.scrollboxNode.style.overflow = "hidden"; + } + // bookkeeping + this.testFlexCells(); + // accomodate new structure + this.updateStructure(); + }, + + testFlexCells: function(){ + // FIXME: cheater, this function does double duty as initializer and tester + this.flexCells = false; + for(var j=0, row; (row=this.structure.rows[j]); j++){ + for(var i=0, cell; (cell=row[i]); i++){ + cell.view = this; + this.flexCells = this.flexCells || cell.isFlex(); + } + } + return this.flexCells; + }, + + updateStructure: function(){ + // header builder needs to update table map + this.header.update(); + // content builder needs to update markup cache + this.content.update(); + }, + + getScrollbarWidth: function(){ + return (this.noscroll ? 0 : dojox.grid.getScrollbarWidth()); // Integer + }, + + getColumnsWidth: function(){ + return this.headerContentNode.firstChild.offsetWidth; // Integer + }, + + getWidth: function(){ + return this.viewWidth || (this.getColumnsWidth()+this.getScrollbarWidth()) +'px'; // String + }, + + getContentWidth: function(){ + return Math.max(0, dojo._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String + }, + + render: function(){ + this.scrollboxNode.style.height = ''; + this.renderHeader(); + }, + + renderHeader: function(){ + this.headerContentNode.innerHTML = this.header.generateHtml(this._getHeaderContent); + }, + + // note: not called in 'view' context + _getHeaderContent: function(inCell){ + var n = inCell.name || inCell.grid.getCellName(inCell); + if(inCell.index != inCell.grid.getSortIndex()){ + return n; + } + return [ '<div class="', inCell.grid.sortInfo > 0 ? 'dojoxGrid-sort-down' : 'dojoxGrid-sort-up', '"><div class="gridArrowButtonChar">', inCell.grid.sortInfo > 0 ? '▼' : '▲', '</div>', n, '</div>' ].join(''); + }, + + resize: function(){ + this.adaptHeight(); + this.adaptWidth(); + }, + + hasScrollbar: function(){ + return (this.scrollboxNode.clientHeight != this.scrollboxNode.offsetHeight); // Boolean + }, + + adaptHeight: function(){ + if(!this.grid.autoHeight){ + var h = this.domNode.clientHeight; + if(!this.hasScrollbar()){ // no scrollbar is rendered + h -= dojox.grid.getScrollbarWidth(); + } + dojox.grid.setStyleHeightPx(this.scrollboxNode, h); + } + }, + + adaptWidth: function(){ + if(this.flexCells){ + // the view content width + this.contentWidth = this.getContentWidth(); + this.headerContentNode.firstChild.style.width = this.contentWidth; + } + // FIXME: it should be easier to get w from this.scrollboxNode.clientWidth, + // but clientWidth seemingly does not include scrollbar width in some cases + var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth(); + w = Math.max(w, this.getColumnsWidth()) + 'px'; + with(this.contentNode){ + style.width = ''; + offsetWidth; + style.width = w; + } + }, + + setSize: function(w, h){ + with(this.domNode.style){ + if(w){ + width = w; + } + height = (h >= 0 ? h + 'px' : ''); + } + with(this.headerNode.style){ + if(w){ + width = w; + } + } + }, + + renderRow: function(inRowIndex, inHeightPx){ + var rowNode = this.createRowNode(inRowIndex); + this.buildRow(inRowIndex, rowNode, inHeightPx); + this.grid.edit.restore(this, inRowIndex); + return rowNode; + }, + + createRowNode: function(inRowIndex){ + var node = document.createElement("div"); + node.className = this.classTag + '-row'; + node[dojox.grid.gridViewTag] = this.id; + node[dojox.grid.rowIndexTag] = inRowIndex; + this.rowNodes[inRowIndex] = node; + return node; + }, + + buildRow: function(inRowIndex, inRowNode){ + this.buildRowContent(inRowIndex, inRowNode); + this.styleRow(inRowIndex, inRowNode); + }, + + buildRowContent: function(inRowIndex, inRowNode){ + inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex); + if(this.flexCells){ + // FIXME: accessing firstChild here breaks encapsulation + inRowNode.firstChild.style.width = this.contentWidth; + } + }, + + rowRemoved:function(inRowIndex){ + this.grid.edit.save(this, inRowIndex); + delete this.rowNodes[inRowIndex]; + }, + + getRowNode: function(inRowIndex){ + return this.rowNodes[inRowIndex]; + }, + + getCellNode: function(inRowIndex, inCellIndex){ + var row = this.getRowNode(inRowIndex); + if(row){ + return this.content.getCellNode(row, inCellIndex); + } + }, + + // styling + styleRow: function(inRowIndex, inRowNode){ + inRowNode._style = dojox.grid.getStyleText(inRowNode); + this.styleRowNode(inRowIndex, inRowNode); + }, + + styleRowNode: function(inRowIndex, inRowNode){ + if(inRowNode){ + this.doStyleRowNode(inRowIndex, inRowNode); + } + }, + + doStyleRowNode: function(inRowIndex, inRowNode){ + this.grid.styleRowNode(inRowIndex, inRowNode); + }, + + // updating + updateRow: function(inRowIndex, inHeightPx, inPageNode){ + var rowNode = this.getRowNode(inRowIndex); + if(rowNode){ + rowNode.style.height = ''; + this.buildRow(inRowIndex, rowNode); + } + return rowNode; + }, + + updateRowStyles: function(inRowIndex){ + this.styleRowNode(inRowIndex, this.getRowNode(inRowIndex)); + }, + + // scrolling + lastTop: 0, + firstScroll:0, + + doscroll: function(inEvent){ + //var s = dojo.marginBox(this.headerContentNode.firstChild); + var isLtr = dojo._isBodyLtr(); + if(this.firstScroll < 2){ + if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll == 0)){ + var s = dojo.marginBox(this.headerNodeContainer); + if(dojo.isIE){ + this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px'; + }else if(dojo.isMoz){ + //TODO currently only for FF, not sure for safari and opera + this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px'; + //this.headerNodeContainer.style.width = s.w + 'px'; + //set scroll to right in FF + if(isLtr){ + this.scrollboxNode.scrollLeft = this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth; + }else{ + this.scrollboxNode.scrollLeft = this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth; + } + } + } + this.firstScroll++; + } + this.headerNode.scrollLeft = this.scrollboxNode.scrollLeft; + // 'lastTop' is a semaphore to prevent feedback-loop with setScrollTop below + var top = this.scrollboxNode.scrollTop; + if(top != this.lastTop){ + this.grid.scrollTo(top); + } + }, + + setScrollTop: function(inTop){ + // 'lastTop' is a semaphore to prevent feedback-loop with doScroll above + this.lastTop = inTop; + this.scrollboxNode.scrollTop = inTop; + return this.scrollboxNode.scrollTop; + }, + + // event handlers (direct from DOM) + doContentEvent: function(e){ + if(this.content.decorateEvent(e)){ + this.grid.onContentEvent(e); + } + }, + + doHeaderEvent: function(e){ + if(this.header.decorateEvent(e)){ + this.grid.onHeaderEvent(e); + } + }, + + // event dispatch(from Grid) + dispatchContentEvent: function(e){ + return this.content.dispatchEvent(e); + }, + + dispatchHeaderEvent: function(e){ + return this.header.dispatchEvent(e); + }, + + // column resizing + setColWidth: function(inIndex, inWidth){ + this.grid.setCellWidth(inIndex, inWidth + 'px'); + }, + + update: function(){ + var left = this.scrollboxNode.scrollLeft; + this.content.update(); + this.grid.update(); + this.scrollboxNode.scrollLeft = left; + this.headerNode.scrollLeft = left; + } +}); + +} diff --git a/includes/js/dojox/grid/_grid/views.js b/includes/js/dojox/grid/_grid/views.js new file mode 100644 index 0000000..d13bbb7 --- /dev/null +++ b/includes/js/dojox/grid/_grid/views.js @@ -0,0 +1,277 @@ +if(!dojo._hasResource["dojox.grid._grid.views"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.grid._grid.views"] = true; +dojo.provide("dojox.grid._grid.views"); + +dojo.declare('dojox.grid.views', null, { + // summary: + // A collection of grid views. Owned by grid and used internally for managing grid views. + // description: + // Grid creates views automatically based on grid's layout structure. + // Users should typically not need to access individual views or the views collection directly. + constructor: function(inGrid){ + this.grid = inGrid; + }, + + defaultWidth: 200, + + views: [], + + // operations + resize: function(){ + this.onEach("resize"); + }, + + render: function(){ + this.onEach("render"); + }, + + // views + addView: function(inView){ + inView.idx = this.views.length; + this.views.push(inView); + }, + + destroyViews: function(){ + for (var i=0, v; v=this.views[i]; i++) + v.destroy(); + this.views = []; + }, + + getContentNodes: function(){ + var nodes = []; + for(var i=0, v; v=this.views[i]; i++){ + nodes.push(v.contentNode); + } + return nodes; + }, + + forEach: function(inCallback){ + for(var i=0, v; v=this.views[i]; i++){ + inCallback(v, i); + } + }, + + onEach: function(inMethod, inArgs){ + inArgs = inArgs || []; + for(var i=0, v; v=this.views[i]; i++){ + if(inMethod in v){ + v[inMethod].apply(v, inArgs); + } + } + }, + + // layout + normalizeHeaderNodeHeight: function(){ + var rowNodes = []; + for(var i=0, v; (v=this.views[i]); i++){ + if(v.headerContentNode.firstChild){ + rowNodes.push(v.headerContentNode) + }; + } + this.normalizeRowNodeHeights(rowNodes); + }, + + normalizeRowNodeHeights: function(inRowNodes){ + var h = 0; + for(var i=0, n, o; (n=inRowNodes[i]); i++){ + h = Math.max(h, (n.firstChild.clientHeight)||(n.firstChild.offsetHeight)); + } + h = (h >= 0 ? h : 0); + // + var hpx = h + 'px'; + for(var i=0, n; (n=inRowNodes[i]); i++){ + if(n.firstChild.clientHeight!=h){ + n.firstChild.style.height = hpx; + } + } + // + //console.log('normalizeRowNodeHeights ', h); + // + // querying the height here seems to help scroller measure the page on IE + if(inRowNodes&&inRowNodes[0]){ + inRowNodes[0].parentNode.offsetHeight; + } + }, + + resetHeaderNodeHeight: function(){ + for(var i=0, v, n; (v=this.views[i]); i++){ + n = v.headerContentNode.firstChild; + if(n) + n.style.height = ""; + } + }, + + renormalizeRow: function(inRowIndex){ + var rowNodes = []; + for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){ + n.firstChild.style.height = ''; + rowNodes.push(n); + } + this.normalizeRowNodeHeights(rowNodes); + }, + + getViewWidth: function(inIndex){ + return this.views[inIndex].getWidth() || this.defaultWidth; + }, + + // must be called after view widths are properly set or height can be miscalculated + // if there are flex columns + measureHeader: function(){ + // need to reset view header heights so they are properly measured. + this.resetHeaderNodeHeight(); + this.forEach(function(inView){ + inView.headerContentNode.style.height = ''; + }); + var h = 0; + // calculate maximum view header height + this.forEach(function(inView){ + h = Math.max(inView.headerNode.offsetHeight, h); + }); + return h; + }, + + measureContent: function(){ + var h = 0; + this.forEach(function(inView) { + h = Math.max(inView.domNode.offsetHeight, h); + }); + return h; + }, + + findClient: function(inAutoWidth){ + // try to use user defined client + var c = this.grid.elasticView || -1; + // attempt to find implicit client + if(c < 0){ + for(var i=1, v; (v=this.views[i]); i++){ + if(v.viewWidth){ + for(i=1; (v=this.views[i]); i++){ + if(!v.viewWidth){ + c = i; + break; + } + } + break; + } + } + } + // client is in the middle by default + if(c < 0){ + c = Math.floor(this.views.length / 2); + } + return c; + }, + + arrange: function(l, w){ + var i, v, vw, len = this.views.length; + // find the client + var c = (w <= 0 ? len : this.findClient()); + // layout views + var setPosition = function(v, l){ + with(v.domNode.style){ + if(!dojo._isBodyLtr()){ + right = l + 'px'; + }else{ + left = l + 'px'; + } + top = 0 + 'px'; + } + with(v.headerNode.style){ + if(!dojo._isBodyLtr()){ + right = l + 'px'; + }else{ + left = l + 'px'; + } + top = 0; + } + } + // for views left of the client + //BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with + //leading and tailing concept. + for(i=0; (v=this.views[i])&&(i<c); i++){ + // get width + vw = this.getViewWidth(i); + // process boxes + v.setSize(vw, 0); + setPosition(v, l); + vw = v.domNode.offsetWidth; + // update position + l += vw; + } + // next view (is the client, i++ == c) + i++; + // start from the right edge + var r = w; + // for views right of the client (iterated from the right) + for(var j=len-1; (v=this.views[j])&&(i<=j); j--){ + // get width + vw = this.getViewWidth(j); + // set size + v.setSize(vw, 0); + // measure in pixels + vw = v.domNode.offsetWidth; + // update position + r -= vw; + // set position + setPosition(v, r); + } + if(c<len){ + v = this.views[c]; + // position the client box between left and right boxes + vw = Math.max(1, r-l); + // set size + v.setSize(vw + 'px', 0); + setPosition(v, l); + } + return l; + }, + + // rendering + renderRow: function(inRowIndex, inNodes){ + var rowNodes = []; + for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){ + rowNode = v.renderRow(inRowIndex); + n.appendChild(rowNode); + rowNodes.push(rowNode); + } + this.normalizeRowNodeHeights(rowNodes); + }, + + rowRemoved: function(inRowIndex){ + this.onEach("rowRemoved", [ inRowIndex ]); + }, + + // updating + updateRow: function(inRowIndex, inHeight){ + for(var i=0, v; v=this.views[i]; i++){ + v.updateRow(inRowIndex, inHeight); + } + this.renormalizeRow(inRowIndex); + }, + + updateRowStyles: function(inRowIndex){ + this.onEach("updateRowStyles", [ inRowIndex ]); + }, + + // scrolling + setScrollTop: function(inTop){ + var top = inTop; + for(var i=0, v; v=this.views[i]; i++){ + top = v.setScrollTop(inTop); + } + return top; + //this.onEach("setScrollTop", [ inTop ]); + }, + + getFirstScrollingView: function(){ + // summary: Returns the first grid view with a scroll bar + for(var i=0, v; (v=this.views[i]); i++){ + if(v.hasScrollbar()){ + return v; + } + } + } + +}); + +} |