');
}else{
ret = ret.concat([ ' ',
inCell.grid.sortInfo > 0 ? 'dojoxGridSortUp' : 'dojoxGridSortDown',
'">
',
inCell.grid.sortInfo > 0 ? '▲' : '▼',
'
',
'
']);
}
ret = ret.concat([n, '
']);
return ret.join('');
},
resize: function(){
this.adaptHeight();
this.adaptWidth();
},
hasHScrollbar: function(reset){
var hadScroll = this._hasHScroll||false;
if(this._hasHScroll == undefined || reset){
if(this.noscroll){
this._hasHScroll = false;
}else{
var style = html.style(this.scrollboxNode, "overflow");
if(style == "hidden"){
this._hasHScroll = false;
}else if(style == "scroll"){
this._hasHScroll = true;
}else{
this._hasHScroll = (this.scrollboxNode.offsetWidth - this.getScrollbarWidth() < this.contentNode.offsetWidth );
}
}
}
if(hadScroll !== this._hasHScroll){
this.grid.update();
}
return this._hasHScroll; // Boolean
},
hasVScrollbar: function(reset){
var hadScroll = this._hasVScroll||false;
if(this._hasVScroll == undefined || reset){
if(this.noscroll){
this._hasVScroll = false;
}else{
var style = html.style(this.scrollboxNode, "overflow");
if(style == "hidden"){
this._hasVScroll = false;
}else if(style == "scroll"){
this._hasVScroll = true;
}else{
this._hasVScroll = (this.scrollboxNode.scrollHeight > this.scrollboxNode.clientHeight);
}
}
}
if(hadScroll !== this._hasVScroll){
this.grid.update();
}
return this._hasVScroll; // Boolean
},
convertColPctToFixed: function(){
// Fix any percentage widths to be pixel values
var hasPct = false;
this.grid.initialWidth = "";
var cellNodes = query("th", this.headerContentNode);
var fixedWidths = array.map(cellNodes, function(c, vIdx){
var w = c.style.width;
html.attr(c, "vIdx", vIdx);
if(w && w.slice(-1) == "%"){
hasPct = true;
}else if(w && w.slice(-2) == "px"){
return window.parseInt(w, 10);
}
return html.contentBox(c).w;
});
if(hasPct){
array.forEach(this.grid.layout.cells, function(cell, idx){
if(cell.view == this){
var cellNode = cell.view.getHeaderCellNode(cell.index);
if(cellNode && html.hasAttr(cellNode, "vIdx")){
var vIdx = window.parseInt(html.attr(cellNode, "vIdx"));
this.setColWidth(idx, fixedWidths[vIdx]);
html.removeAttr(cellNode, "vIdx");
}
}
}, this);
return true;
}
return false;
},
adaptHeight: function(minusScroll){
if(!this.grid._autoHeight){
var h = (this.domNode.style.height && parseInt(this.domNode.style.height.replace(/px/,''), 10)) || this.domNode.clientHeight;
var self = this;
var checkOtherViewScrollers = function(){
var v;
for(var i in self.grid.views.views){
v = self.grid.views.views[i];
if(v !== self && v.hasHScrollbar()){
return true;
}
}
return false;
};
if(minusScroll || (this.noscroll && checkOtherViewScrollers())){
h -= metrics.getScrollbar().h;
}
util.setStyleHeightPx(this.scrollboxNode, h);
}
this.hasVScrollbar(true);
},
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();
if(!this._removingColumn){
w = Math.max(w, this.getColumnsWidth()) + 'px';
}else{
w = Math.min(w, this.getColumnsWidth()) + 'px';
this._removingColumn = false;
}
var cn = this.contentNode;
cn.style.width = w;
this.hasHScrollbar(true);
},
setSize: function(w, h){
var ds = this.domNode.style;
var hs = this.headerNode.style;
if(w){
ds.width = w;
hs.width = w;
}
ds.height = (h >= 0 ? h + 'px' : '');
},
renderRow: function(inRowIndex){
var rowNode = this.createRowNode(inRowIndex);
this.buildRow(inRowIndex, rowNode);
//this.grid.edit.restore(this, inRowIndex);
return rowNode;
},
createRowNode: function(inRowIndex){
var node = document.createElement("div");
node.className = this.classTag + 'Row';
if (this instanceof dojox.grid._RowSelector){
html.attr(node,"role","presentation");
}else{
html.attr(node,"role","row");
if (this.grid.selectionMode != "none") {
node.setAttribute("aria-selected", "false"); //rows can be selected so add aria-selected prop
}
}
node[util.gridViewTag] = this.id;
node[util.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 && this.contentWidth){
// FIXME: accessing firstChild here breaks encapsulation
inRowNode.firstChild.style.width = this.contentWidth;
}
util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]);
},
rowRemoved:function(inRowIndex){
if(inRowIndex >= 0){
this._cleanupRowWidgets(this.getRowNode(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);
}
},
getHeaderCellNode: function(inCellIndex){
if(this.headerContentNode){
return this.header.getCellNode(this.headerContentNode, inCellIndex);
}
},
// styling
styleRow: function(inRowIndex, inRowNode){
inRowNode._style = 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){
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,
_nativeScroll: false,
doscroll: function(inEvent){
if(has('ff') >= 13){
this._nativeScroll = true;
}
//var s = dojo.marginBox(this.headerContentNode.firstChild);
var isLtr = this.grid.isLeftToRight();
if(this.firstScroll < 2){
if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll === 0)){
var s = html.marginBox(this.headerNodeContainer);
if(has('ie')){
this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px';
}else if(has('mozilla')){
//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
this.scrollboxNode.scrollLeft = isLtr ?
this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth :
this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth;
}
}
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);
}
this._nativeScroll = false;
},
setScrollTop: function(inTop){
// 'lastTop' is a semaphore to prevent feedback-loop with doScroll above
this.lastTop = inTop;
if(!this._nativeScroll){
//fix #15487
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(){
if(!this.domNode){
return;
}
this.content.update();
this.grid.update();
//get scroll after update or scroll left setting goes wrong on IE.
//See trac: #8040
var left = this.scrollboxNode.scrollLeft;
this.scrollboxNode.scrollLeft = left;
this.headerNode.scrollLeft = left;
}
});
var _GridAvatar = declare("dojox.grid._GridAvatar", Avatar, {
construct: function(){
var dd = win.doc;
var a = dd.createElement("table");
a.cellPadding = a.cellSpacing = "0";
a.className = "dojoxGridDndAvatar";
a.style.position = "absolute";
a.style.zIndex = 1999;
a.style.margin = "0px"; // to avoid dojo.marginBox() problems with table's margins
var b = dd.createElement("tbody");
var tr = dd.createElement("tr");
var td = dd.createElement("td");
var img = dd.createElement("td");
tr.className = "dojoxGridDndAvatarItem";
img.className = "dojoxGridDndAvatarItemImage";
img.style.width = "16px";
var source = this.manager.source, node;
if(source.creator){
// create an avatar representation of the node
node = source._normalizedCreator(source.getItem(this.manager.nodes[0].id).data, "avatar").node;
}else{
// or just clone the node and hope it works
node = this.manager.nodes[0].cloneNode(true);
var table, tbody;
if(node.tagName.toLowerCase() == "tr"){
// insert extra table nodes
table = dd.createElement("table");
tbody = dd.createElement("tbody");
tbody.appendChild(node);
table.appendChild(tbody);
node = table;
}else if(node.tagName.toLowerCase() == "th"){
// insert extra table nodes
table = dd.createElement("table");
tbody = dd.createElement("tbody");
var r = dd.createElement("tr");
table.cellPadding = table.cellSpacing = "0";
r.appendChild(node);
tbody.appendChild(r);
table.appendChild(tbody);
node = table;
}
}
node.id = "";
td.appendChild(node);
tr.appendChild(img);
tr.appendChild(td);
html.style(tr, "opacity", 0.9);
b.appendChild(tr);
a.appendChild(b);
this.node = a;
var m = Manager.manager();
this.oldOffsetY = m.OFFSET_Y;
m.OFFSET_Y = 1;
},
destroy: function(){
Manager.manager().OFFSET_Y = this.oldOffsetY;
this.inherited(arguments);
}
});
var oldMakeAvatar = Manager.manager().makeAvatar;
Manager.manager().makeAvatar = function(){
var src = this.source;
if(src.viewIndex !== undefined && !html.hasClass(win.body(),"dijit_a11y")){
return new _GridAvatar(this);
}
return oldMakeAvatar.call(Manager.manager());
};
return _View;
});