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; } } } }); }