dhtmlxgrid 1.4功能自助增补(二)--键盘事件和文本类型单元格

3. 在表格中添加需要的键盘事件;目前版本的dhtmlxgrid只支持部分键盘事件,所以你可以根据自己的需要添加。
键盘事件大多是在dhtmlXGrid.js文件this.doKey方法中定义的,当然你也可以在页面中通过setOnKeyPressed()方法自己添加;
以下是我自己修改后的源码,注释掉的部分是自带源码:
[code]
this.doKey = function (ev) {
if (!ev) {
return true;
}
if ((ev.target || ev.srcElement).value !== window.undefined) {
var zx = (ev.target || ev.srcElement);
if ((!zx.parentNode) || (zx.parentNode.className.indexOf("editable") == -1)) {
return true;
}
}
if ((globalActiveDHTMLGridObject) && (this != globalActiveDHTMLGridObject)) {
return globalActiveDHTMLGridObject.doKey(ev);
}
if (this.isActive == false) {
return true;
}
if (this._htkebl) {
return true;
}
if (!this.callEvent("onKeyPress", [ev.keyCode, ev.ctrlKey, ev.shiftKey])) {
return false;
}
try {
//daoger_start
//define flag for judgment the editing state of selected cell
var editeabled = null;
if (this.editor) {
editeabled = true;
}
//var type = this.cellType[this.cell._cellIndex];
//daoger_end
//if (ev.keyCode == 13 && (ev.ctrlKey || ev.shiftKey)) {
// var rowInd = this.rowsCol._dhx_find(this.row);
// if (window.event.ctrlKey && rowInd != this.rowsCol.length - 1) {
// if (this.row.rowIndex == this.obj._rowslength() - 1 && this.dynScroll && this.dynScroll != "false") {
// this.doDynScroll("dn");
// }
// this.selectCell(this.rowsCol[rowInd + 1], this.cell._cellIndex, true);
// } else {
// if (ev.shiftKey && rowInd != 0) {
// if (this.row.rowIndex == 0 && this.dynScroll && this.dynScroll != "false") {
// this.doDynScroll("up");
// }
// this.selectCell(this.rowsCol[rowInd - 1], this.cell._cellIndex, true);
// }
// }
// _isIE ? ev.returnValue = false : ev.preventDefault();
//}
if (ev.keyCode == 13 && !ev.ctrlKey && !ev.shiftKey) {
this.editStop();
//daoger_start
//modify action of enter key
//修改回车键事件,使得敲回车后选择状态或焦点下移
var rowInd = this.row.rowIndex;
if (rowInd != this.rowsCol.length && rowInd != this.obj.rows.length - 1) {
var nrow = this.obj._rows(rowInd);
if (nrow._sRow || nrow._rLoad) {
return false;
}
this.selectCell(nrow, this.cell._cellIndex, true);
if (editeabled) {
this.editCell();
}
} else {
if (this.pagingOn && (this.row != this.rowsCol[this.rowsCol.length - 1] || this.rowsBuffer[0].length > 0 || !this.recordsNoMore)) {
this.changePage(this.currentPage + 1);
this.selectCell(this.obj._rows(0), this.cell._cellIndex, true);
if (editeabled) {
this.editCell();
}
}
}
//this.callEvent("onEnter", [this.row.idd, this.cell._cellIndex]);
//daoger_end
_isIE ? ev.returnValue = false : ev.preventDefault();
}
if (ev.keyCode == 9) {
this.editStop();
if (ev.shiftKey) {
var z = this._getPrevCell();
} else {
var z = this._getNextCell();
}
if (!z) {
return true;
}
this.selectCell(z.parentNode, z._cellIndex, (this.row != z.parentNode));
this.editCell();
_isIE ? ev.returnValue = false : ev.preventDefault();
}
//daoger_start
//add action of del key
//选择一个单元格或多个单元格后,用del键清楚单元格内容
if (ev.keyCode == 46) {
if (this._selectionArea) {
this.clearSelection();
var startRow = this._selectionArea.LeftTopRow;
var startCol = this._selectionArea.LeftTopCol;
var endRow = this._selectionArea.RightBottomRow;
var endCol = this._selectionArea.RightBottomCol;
for (var i = startRow; i < endRow + 1; i++) {
for (var j = startCol; j < endCol + 1; j++) {
if (!(this.cellType[j] == "linenumber")) {
this.cells(this.getRowId(i), j).setValue();
}
}
}
startRow = null;
startCol = null;
endRow = null;
endCol = null;
} else {
if (!(this.cellType[this.cell._cellIndex] == "linenumber") && !this.editor) {
this.cells(this.getSelectedId(), this.cell._cellIndex).setValue();
}
}
return true;
}
//daoger_end
//根据上一个单元格的编辑状态判断通过方向键移动后下一个单元格的状态是处于选择还是编辑状态
if (ev.keyCode == 40 || ev.keyCode == 38) {
if (this.editor && this.editor.combo) {
if (ev.keyCode == 40) {
this.editor.shiftNext();
}
if (ev.keyCode == 38) {
this.editor.shiftPrev();
}
return false;
} else {
var rowInd = this.row.rowIndex;
if (ev.keyCode == 38 && rowInd != 1) {
var nrow = this.obj._rows(rowInd - 2);
if (nrow._sRow || nrow._rLoad) {
return false;
}
this.selectCell(this.obj._rows(rowInd - 2), this.cell._cellIndex, true);
//daoger_start
//set state of this cell according to last
if (editeabled) {
this.editCell();
}
//daoger_end
} else {
if (this.pagingOn && ev.keyCode == 38 && rowInd == 1 && this.currentPage != 1) {
this.changePage(this.currentPage - 1);
this.selectCell(this.obj.rows[this.obj.rows.length - 1], this.cell._cellIndex, true);
//daoger_start
//set state of this cell according to last
if (editeabled) {
this.editCell();
}
//daoger_end
} else {
if (ev.keyCode == 40 && rowInd != this.rowsCol.length && rowInd != this.obj.rows.length - 1) {
var nrow = this.obj._rows(rowInd);
if (nrow._sRow || nrow._rLoad) {
return false;
}
this.selectCell(nrow, this.cell._cellIndex, true);
//daoger_start
//set state of this cell according to last
if (editeabled) {
this.editCell();
}
//daoger_end
} else {
if (this.pagingOn && ev.keyCode == 40 && (this.row != this.rowsCol[this.rowsCol.length - 1] || this.rowsBuffer[0].length > 0 || !this.recordsNoMore)) {
this.changePage(this.currentPage + 1);
this.selectCell(this.obj._rows(0), this.cell._cellIndex, true);
//daoger_start
//set state of this cell according to last
if (editeabled) {
this.editCell();
}
//daoger_end
}
}
}
}
}
_isIE ? ev.returnValue = false : ev.preventDefault();
}
//daoger_start
//add action of left and right key
//添加左右方向键事件
if (ev.keyCode == 37 || ev.keyCode == 39) {
this.editStop();
if (ev.keyCode == 37) {
var z = this._getPrevCell();
} else {
if (ev.keyCode == 39) {
var z = this._getNextCell();
}
}
if (!z) {
return true;
}
this.selectCell(z.parentNode, z._cellIndex, (this.row != z.parentNode));
if (editeabled) {
this.editCell();
}
_isIE ? ev.returnValue = false : ev.preventDefault();
}
//daoger_end
if ((ev.keyCode == 113) && (this._f2kE)) {
this.editCell();
return false;
}
if (ev.keyCode == 32) {
var c = this.cell;
var ed = this.cells4(c);
if (ed.changeState() != false) {
_isIE ? ev.returnValue = false : ev.preventDefault();
}
}
if (ev.keyCode == 27 && this.oe != false) {
this.editStop();
_isIE ? ev.returnValue = false : ev.preventDefault();
}
if (ev.keyCode == 33 || ev.keyCode == 34) {
if (this.pagingOn) {
if (ev.keyCode == 33) {
this.changePage(this.currentPage - 1);
} else {
this.changePage(this.currentPage + 1);
}
}
var new_ind = Math.floor((this.getRowIndex(this.row.idd) || 0) + (ev.keyCode != 33 ? 1 : -1) * this.objBox.offsetHeight / (this._srdh || 20));
if (new_ind < 0) {
new_ind = 0;
}
if (this._dload && (!this.rowsCol[new_ind])) {
this._askRealRows(new_ind, function () {
try {
self.selectCell(new_ind, this.cell._cellIndex, true);
}
catch (e) {
}
});
} else {
if (new_ind >= this.rowsCol.length) {
new_ind = this.rowsCol.length - 1;
}
this.selectCell(new_ind, this.cell._cellIndex, true);
}
if (_isIE) {
ev.returnValue = false;
} else {
ev.preventDefault();
}
}
if (!this.editor) {
if (ev.keyCode == 37 && this.cellType._dhx_find("tree") != -1) {
this.collapseKids(this.row);
_isIE ? ev.returnValue = false : ev.preventDefault();
}
if (ev.keyCode == 39 && this.cellType._dhx_find("tree") != -1) {
this.expandKids(this.row);
_isIE ? ev.returnValue = false : ev.preventDefault();
}
}
return true;
}
catch (er) {
return true;
}
};
[/code]
4 文本类型单元格
它可以进行大篇幅文档的存储,但是dhtmlxgrid自带的功能和样式不怎么样,我们可以自己修改。

(1)修改单元格编辑状态下的样式,使得单元格在编辑状态下边框突出。
这是我修改dhtmlXGrid.css后的代码:
[code]
div.gridbox table.obj tr.rowselected td.cellselected,div.gridbox table.obj td.cellselected{
background-color: #EDF5FE;
border: 2px solid #009ACD;
}
[/code]
(2) 修改txt类型的其他属性,这些都是在dhtmlXGrid.js文件中定义的
[code]
function eXcell_txt(cell) {
if (cell) {
this.cell = cell;
this.grid = this.cell.parentNode.grid;
}
this.edit = function () {
this.val = this.getValue();
this.obj = document.createElement("TEXTAREA");
this.obj.className = "dhx_textarea";
this.obj.onclick = function (e) {
(e || event).cancelBubble = true;
};
var arPos = this.grid.getPosition(this.cell);
if (!this.cell._clearCell) {
this.obj.value = this.val;
}
this.obj.style.display = "";
//daoger_start
//modify textarea align
this.obj.style.textAlign = "left";//文字对齐方式
//this.obj.style.textAlign = this.cell.align;
//daoger_end
if (_isFF) {
var z_ff = document.createElement("DIV");
z_ff.appendChild(this.obj);
z_ff.style.overflow = "auto";
z_ff.className = "dhx_textarea";
this.obj.style.margin = "0px 0px 0px 0px";
this.obj.style.border = "0px";
this.obj = z_ff;
}
document.body.appendChild(this.obj);
this.obj.onkeydown = function (e) {
var ev = (e || event);
if (ev.keyCode == 9) {
globalActiveDHTMLGridObject.entBox.focus();
globalActiveDHTMLGridObject.doKey({keyCode:ev.keyCode, shiftKey:ev.shiftKey, srcElement:"0"});
return false;
}
};
this.obj.style.left = arPos[0] + "px";
//daoger_start
//让单元格编辑状态下自适应文本长度
//this.obj.style.top = arPos[1] + this.cell.offsetHeight + "px";
this.obj.style.top = (arPos[1] + 1) + "px";
//adjust width of textarea under text cell
//if (this.cell.scrollWidth < 200) {
// var pw = 200;
//} else {
// var pw = this.cell.scrollWidth;
//}
if (this.cell.scrollWidth < 100) {
var pw = 100;
} else {
if (this.cell.scrollWidth > 200) {
var pw = 200;
} else {
var pw = this.cell.scrollWidth;
}
}
this.obj.style.width = (pw + (_isFF ? 6 : 4)) + "px";
//this.obj.style.width = (pw + (_isFF ? 18 : 16)) + "px";
//在键盘输入状态下,文本编辑区域随着文本的增加高度也增加
this.obj.style.height = "0px";
//this.obj.onPropertyChange = new Function("this.setTxtHeight(this.obj);");
//daoger_end
if (_isFF) {
this.obj.firstChild.style.width = parseInt(this.obj.style.width) + "px";
this.obj.firstChild.style.height = this.obj.offsetHeight - 3 + "px";
}
this.obj.focus();
if (_isFF) {
this.obj.firstChild.focus();
} else {
this.obj.focus();
}
};
[/code]
来看看效果图:
[img]http://daoger.iteye.com/upload/picture/pic/5874/cf23aab0-d128-4ea4-bf30-57e89f011069.jpg[/img]

说明:这只是针对1.4专业版的修改,有些功能在普通版中可能没有。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
dhtmlXTree进行一个小的扩展 需求1: 动态生成树形菜单,每个节点都有各自的URL地址,单击不同的节点框架页的右侧跳转到该节点所对应的URL。(框架页说明:左边是树形菜单;右边是显示页面相应信息的页面) 分析: dhtmlXTree提供了很好的添加,删除节点的方法,故选择dhtmlXTree。 但是dhtmlXTree不能满足"每个节点都有各自的URL地址,单击不同的节点框架页的右侧跳转到该节点所对应的URL"这点需求,因次想到了对dhtmlXTree进行一个小的扩展,即在其节点对象原有属性的基础上,再添加两个扩展属性。具体操作如下: 1、找到定义节点对象的那个函数(或方法) function dhtmlXTreeItemObject(itemId,itemText,parentObject,treeObject,actionHandler,mode) 修改为 function dhtmlXTreeItemObject(itemId,itemText,parentObject,treeObject,actionHandler,mode,url,target) 并在方法体中添加赋值语句:this.itemURL=url;this.itemTarget=target; 2、然后修改所有与dhtmlXTreeItemObject有关(直接或者间接相关)的方法: _attachChildNode,insertNewItem,insertNewChild,insertNewNext,_recreateBranch,_parseXMLTree 注:_parseXMLTree方法是与loadXML,loadXMLString相关的。 在这些方法中生成节点的语句中添加相应的参数和语句,以支持新添加的属性itemURL,itemTarget。 需求2: 为dhtmlXTree树上的每一个节点添加右键菜单。附:在树上的节点上点右键时才会生成菜单,空白区域单击时不会生成菜单。 分析: 1、用 dhtmlXTree + dhtmlxmenu 实现。 2、 用dhtmlxmenu生成菜单的部分代码: var menu = new dhtmlXMenuObject(); menu.setImagePath("imgs/"); menu.setIconsPath("images/"); menu.renderAsContextMenu(); menu.loadXML("dhtmlxmenu.xml?e="+new Date().getTime()); menu.addContextZone("treeboxbox_tree"); menu.addContextZone方法是为了把菜单添加到指定区域。 3、dhtmlXTreeObject.prototype._createItem方法是构造树形菜单上元素的具体实现方法。看这个方法的具体操作,可以发现它为每一个节点构建了一个table,节点的内容(即名字)放置在一个span中。 4、考虑到dhtmlxmenu实在指定的区域构建菜单,所以可以为dhtmlXTree树上的每一个节点添加右键事件,在这个右键事件里获得该节点对象所对应的区域,然后在这个区域内构建Menu菜单。 难点和解决方案: 1、怎样获得dhtmlXTree树上的每一个节点对象所对应的区域?(dhtmlXTreeObject.prototype._createItem方法没有为这个节点的span设置id) 解决方法: 在dhtmlXTreeObject.prototype._createItem方法中添加一个为span设置id的语句: 即: 在itemObject.span=document.createElement('span'); itemObject.span.className="standartTreeRow"; 后,新添加一句 itemObject.span.id="treeNode_"+itemObject.id;//为这个span新增一个Id属性 2、为dhtmlXTree树上的每一个节点添加右键事件,在这个右键事件里获得该节点对象所对应的区域,然后在这个区域内构建Menu菜单。 解决方法: a、为dhtmlXTree树上的每一个节点添加右键事件: tree.setOnRightClickHandler(treeOnRegihtClick);//右键事件 b、构建Menu菜单: var menu = new dhtmlXMenuObject(); function treeOnRegihtClick(id){ alert("右键 "+" span.id:"+tree.getItem(id).span.id); menu.setImagePath("imgs/"); menu.setIconsPath("images/"); menu.renderAsContextMenu(); menu.loadXML("dhtmlxmenu.xml?e="+new Date().getTime()); menu.addContextZone(tree.getItem(id).span.id);alert("width:"+tree.getItem(id).span.clientWidth); //var X=tree.getItem(id).span.getBoundingClientRect().left; //var Y=tree.getItem(id).span.getBoundingClientRect().top; var X=document.getElementById('mouseXPosition').value;//获得鼠标的横坐标位置 var Y=document.getElementById('mouseYPosition').value;//获得鼠标的纵坐标位置 menu.showContextMenu(X,Y);//调用showContextMenu方法显示菜单 说明:如果这儿不加上这条语句的话,第一次点击右键时只能生成菜单,但是显示不出菜单,下次点击右键Menu菜单才能弹出。 //menu._showContextMenu(X,Y,tree.getItem(id).span.id); } c、用 javascript 获取当页面上鼠标(光标)位置 <script type="text/javascript"> // 说明:获取鼠标位置 function mousePosition(ev){ if(ev.pageX || ev.pageY){ return {x:ev.pageX, y:ev.pageY}; } return { x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, y:ev.clientY + document.body.scrollTop - document.body.clientTop }; } document.onmousemove = mouseMove; function mouseMove(ev){ ev = ev || window.event; var mousePos = mousePosition(ev); document.getElementById('mouseXPosition').value = mousePos.x; document.getElementById('mouseYPosition').value = mousePos.y; } </script> 页面上放置两个隐藏域存放鼠标的位置:<input type="hidden" id=mouseXPosition><input type="hidden" id=mouseYPosition>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值