aboutsummaryrefslogtreecommitdiff
path: root/includes/js/dojox/grid/_grid
diff options
context:
space:
mode:
authormensonge <mensonge@b3834d28-1941-0410-a4f8-b48e95affb8f>2008-11-13 09:49:11 +0000
committermensonge <mensonge@b3834d28-1941-0410-a4f8-b48e95affb8f>2008-11-13 09:49:11 +0000
commite44a7e37b6c7b5961adaffc62b9042b8d442938e (patch)
tree95b67c356e93163467db2451f2b8cce84ed5d582 /includes/js/dojox/grid/_grid
parenta62b9742ee5e28bcec6872d88f50f25b820914f6 (diff)
downloadsemanticscuttle-e44a7e37b6c7b5961adaffc62b9042b8d442938e.tar.gz
semanticscuttle-e44a7e37b6c7b5961adaffc62b9042b8d442938e.tar.bz2
New feature: basic Ajax suggestion for tags and implementation of Dojo toolkit
git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@151 b3834d28-1941-0410-a4f8-b48e95affb8f
Diffstat (limited to 'includes/js/dojox/grid/_grid')
-rw-r--r--includes/js/dojox/grid/_grid/Grid.css201
-rw-r--r--includes/js/dojox/grid/_grid/Grid.css.commented.css258
-rw-r--r--includes/js/dojox/grid/_grid/Grid_rtl.css8
-rw-r--r--includes/js/dojox/grid/_grid/Grid_rtl.css.commented.css10
-rw-r--r--includes/js/dojox/grid/_grid/builder.js522
-rw-r--r--includes/js/dojox/grid/_grid/cell.js66
-rw-r--r--includes/js/dojox/grid/_grid/drag.js113
-rw-r--r--includes/js/dojox/grid/_grid/edit.js238
-rw-r--r--includes/js/dojox/grid/_grid/focus.js207
-rw-r--r--includes/js/dojox/grid/_grid/images/grid_dx_gradient.gifbin0 -> 267 bytes
-rw-r--r--includes/js/dojox/grid/_grid/images/grid_sort_down.gifbin0 -> 49 bytes
-rw-r--r--includes/js/dojox/grid/_grid/images/grid_sort_up.gifbin0 -> 48 bytes
-rw-r--r--includes/js/dojox/grid/_grid/images/tabEnabled_rotated.pngbin0 -> 94 bytes
-rw-r--r--includes/js/dojox/grid/_grid/images/tabHover_rotated.pngbin0 -> 106 bytes
-rw-r--r--includes/js/dojox/grid/_grid/layout.js75
-rw-r--r--includes/js/dojox/grid/_grid/lib.js254
-rw-r--r--includes/js/dojox/grid/_grid/nihiloGrid.css211
-rw-r--r--includes/js/dojox/grid/_grid/nihiloGrid.css.commented.css275
-rw-r--r--includes/js/dojox/grid/_grid/publicEvents.js451
-rw-r--r--includes/js/dojox/grid/_grid/rowbar.js53
-rw-r--r--includes/js/dojox/grid/_grid/rows.js66
-rw-r--r--includes/js/dojox/grid/_grid/scroller.js489
-rw-r--r--includes/js/dojox/grid/_grid/selection.js215
-rw-r--r--includes/js/dojox/grid/_grid/soriaGrid.css212
-rw-r--r--includes/js/dojox/grid/_grid/soriaGrid.css.commented.css276
-rw-r--r--includes/js/dojox/grid/_grid/tundraGrid.css215
-rw-r--r--includes/js/dojox/grid/_grid/tundraGrid.css.commented.css281
-rw-r--r--includes/js/dojox/grid/_grid/view.js336
-rw-r--r--includes/js/dojox/grid/_grid/views.js277
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
new file mode 100644
index 0000000..57f67ba
--- /dev/null
+++ b/includes/js/dojox/grid/_grid/images/grid_dx_gradient.gif
Binary files differ
diff --git a/includes/js/dojox/grid/_grid/images/grid_sort_down.gif b/includes/js/dojox/grid/_grid/images/grid_sort_down.gif
new file mode 100644
index 0000000..7a73f82
--- /dev/null
+++ b/includes/js/dojox/grid/_grid/images/grid_sort_down.gif
Binary files differ
diff --git a/includes/js/dojox/grid/_grid/images/grid_sort_up.gif b/includes/js/dojox/grid/_grid/images/grid_sort_up.gif
new file mode 100644
index 0000000..9452da0
--- /dev/null
+++ b/includes/js/dojox/grid/_grid/images/grid_sort_up.gif
Binary files differ
diff --git a/includes/js/dojox/grid/_grid/images/tabEnabled_rotated.png b/includes/js/dojox/grid/_grid/images/tabEnabled_rotated.png
new file mode 100644
index 0000000..e326abd
--- /dev/null
+++ b/includes/js/dojox/grid/_grid/images/tabEnabled_rotated.png
Binary files differ
diff --git a/includes/js/dojox/grid/_grid/images/tabHover_rotated.png b/includes/js/dojox/grid/_grid/images/tabHover_rotated.png
new file mode 100644
index 0000000..1a30e10
--- /dev/null
+++ b/includes/js/dojox/grid/_grid/images/tabHover_rotated.png
Binary files differ
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 ? '&#9660;' : '&#9650;', '</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;
+ }
+ }
+ }
+
+});
+
+}