最近因为一个机会研究了一下dhtmlxgrid的1.4专业版,以下是自己的总结,有差漏或错误请各位网友积极指正! (由于版权的问题,附件中只有我自己添加的js和css文件) 1. 添加自己的自定义右键菜单 在1.4的专业版中已经添加了自定义右键菜单并且也有示例,但是当在grid上可以选择多个单元格进行操作时,在所选区域上右击却不能显示右键菜单, 原因是grid在有区域被选择后没有修改自己的oncontextmenu属性;我用它自己的右键菜单尝试修改,没有成功。所以自己修改了一个右键菜单添加到了其 中; 以下是我自己修改后的一个右键菜单的js源码,其中添加了不少专业版中的功能;
代码
-
- // contruct main menu object
- function contextMenu() {
- this.items = new Array();
- this.addItem = function (item) {
- this.items[this.items.length] = item;
- };
- this.show = function (oDoc) {
- var strShow = "";
- var i;
- strShow = "<div id=/"rightmenu/" class=/"menudiv/">";
- strShow += "<table border=/"0/" height=/"";
- strShow += this.items.length * 20;
- strShow += "/" cellpadding=/"0/" cellspacing=/"0/">";
- strShow += "<tr height=/"3/"><td width=/"2/"></td><td>";
- strShow += "<table border=/"0/" width=/"100%/" height=/"100%/" cellpadding=0 cellspacing=0 >";
- strShow += "<tr><td width=/"23/"></td><td><img src=/" /" height=/"1/" border=/"0/"></td></tr></table>";
- strShow += "</td><td width=/"2/"></td></tr>";
- strShow += "<tr><td></td><td>";
- strShow += "<table border=/"0/" width=/"100%/" height=/"100%/" cellpadding=3 cellspacing=0 >";
- oDoc.write(strShow);
- for (i = 0; i < this.items.length; i++) {
- this.items[i].show(oDoc);
- }
- strShow = "</table></td><td></td></tr>";
- strShow += "<tr height=/"3/"><td></td><td>";
- strShow += "<table border=/"0/" width=/"100%/" height=/"100%/" cellpadding=0 cellspacing=0>";
- strShow += "<tr><td width=/"23/"></td><td><img src=/" /" height=/"1/" border=/"0/"></td></tr></table>";
- strShow += "</td><td></td></tr>";
- strShow += "</table></div>/n";
- oDoc.write(strShow);
- };
- }
-
- // contruct menu Item object
- function contextItem(text, icon, id, type) {
- this.text = text ? text : "";
- this.icon = icon ? icon : "";
- this.id = id ? id : "";
- this.type = type ? type : "menu";
- this.show = function (oDoc) {
- var strShow = "";
- if (this.type == "menu") {
- strShow += "<tr id='" + this.id + "' ";
- strShow += "onmouseover=/"changeStyle(this, 'on');/" ";
- strShow += "onmouseout=/"changeStyle(this, 'out');/" ";
- //strShow += "onclick="";
- //strShow += this.cmd;
- strShow += ">";
- strShow += "<td class=/"ltdexit/" width=/"16/">";
- if (this.icon == "") {
- strShow += " ";
- } else {
- strShow += "<img border=/"0/" src=/"";
- strShow += this.icon;
- strShow += "/" width=/"16/" height=/"16/" style=/"POSITION: relative/"></img>";
- }
- strShow += "</td><td class=/"mtdexit/">";
- strShow += this.text;
- strShow += "</td><td class=/"rtdexit/" width=/"5/"> </td></tr>";
- } else {
- if (this.type == "separator") {
- //strShow += "<tr><td class="ltdexit"> </td>";
- strShow += "<td class=/"mtdexit/" style='height:10px;' colspan=/"3/"><hr class='hrLine' color=/"#7EC0EE/" size=/"1/"></td></tr>";
- }
- }
- oDoc.write(strShow);
- };
- }
- // change style of every menu item when mouse over
- function changeStyle(obj, cmd) {
- if (obj) {
- try {
- var imgObj = obj.children(0).children(0);
- if (cmd == "on") {
- obj.children(0).className = "ltdfocus";
- obj.children(1).className = "mtdfocus";
- obj.children(2).className = "rtdfocus";
- if (imgObj) {
- if (imgObj.tagName.toUpperCase() == "IMG") {
- imgObj.style.left = "-1px";
- imgObj.style.top = "-1px";
- }
- }
- } else {
- if (cmd == "out") {
- obj.children(0).className = "ltdexit";
- obj.children(1).className = "mtdexit";
- obj.children(2).className = "rtdexit";
- if (imgObj) {
- if (imgObj.tagName.toUpperCase() == "IMG") {
- imgObj.style.left = "0px";
- imgObj.style.top = "0px";
- }
- }
- }
- }
- }
- catch (e) {
- }
- }
- }
- //show right menu on page
- function showMenu() {
- var x, y, w, h, ox, oy;
- x = event.clientX;
- y = event.clientY;
- var obj = document.getElementById("rightmenu");
- if (obj == null) {
- return true;
- }
- ox = document.body.clientWidth;
- oy = document.body.clientHeight;
- if (x > ox || y > oy) {
- return false;
- }
- w = obj.offsetWidth;
- h = obj.offsetHeight;
- if ((x + w) > ox) {
- xx = x - w;
- }
- if ((y + h) > oy) {
- yy = y - h;
- }
- obj.style.posLeft = x + document.body.scrollLeft;
- obj.style.posTop = y + document.body.scrollTop;
- obj.style.visibility = "visible";
- return false;
- }
- //hide right menu
- function hideMenu() {
- if (event.button == 0) {
- var obj = document.getElementById("rightmenu");
- if (obj == null) {
- return true;
- }
- obj.style.visibility = "hidden";
- obj.style.posLeft = 0;
- obj.style.posTop = 0;
- }
- }
- //the mothed of contruct right menu
- dhtmlXGridObject.prototype.makeMenu = function () {
- var self = this;
- var myMenu, item;
- myMenu = new contextMenu();
- item = new contextItem("copy", "", "cellCopy", "menu");
- myMenu.addItem(item);
- item = new contextItem("cut", "", "cellCut", "menu");
- myMenu.addItem(item);
- item = new contextItem("paste", "", "cellPaste", "menu");
- myMenu.addItem(item);
- item = new contextItem("add row", "", "rowAdd", "menu");
- myMenu.addItem(item);
- item = new contextItem("", "", "", "separator");
- myMenu.addItem(item);
- item = new contextItem("delete cell(s)", "", "cellDelete", "menu");
- myMenu.addItem(item);
- item = new contextItem("delete row", "", "rowDelete", "menu");
- myMenu.addItem(item);
- myMenu.show(document);
- delete item;
- delete myMenu;
- if (this.objName) {
- this.objName = "mygrid";
- }
- //add action to every menu item
- document.getElementById("cellCopy").onclick = new Function(new String(this.objName + ".doRightMenuCopy();"));
- document.getElementById("cellCut").onclick = new Function(new String(this.objName + ".doRightMenuCut()"));
- document.getElementById("cellPaste").onclick = new Function(new String(this.objName + ".doRightMenuPaste()"));
- document.getElementById("rowAdd").onclick = new Function(new String(this.objName + ".doRightMenuAddRow()"));
- document.getElementById("cellDelete").onclick = new Function(new String(this.objName + ".doRightMenuDelete();"));
- document.getElementById("rowDelete").onclick = new Function(new String(this.objName + ".deleteSelectedItem();"));
- };
- function toggleMenu(isEnable) {
- if (isEnable) {
- document.oncontextmenu = showMenu;
- } else {
- document.oncontextmenu = new function () {
- return true;
- };
- }
- }
- //the mothed of show right menu in dhtmlXGridObject
- dhtmlXGridObject.prototype.showRightMenu = function () {
- document.attachEvent("onclick", hideMenu);
- showMenu();
- document.attachEvent("oncontextmenu", new Function("return false"));
- };
- //set the name of grid object(it's necessary if you want to response the menu item click)
- dhtmlXGridObject.prototype.setRightMenuObject = function (para) {
- this.objName = para;
- };
- //response to click copy item
- dhtmlXGridObject.prototype.doRightMenuCopy = function () {
- //alert("doCopy");
- if (this._selectionArea) {
- this.setCSVDelimiter("/t");
- this.copyBlockToClipboard();
- } else {
- if (this.cell) {
- if (!(this.cellType[this.cell._cellIndex] == "linenumber") && !this.editor) {
- window.clipboardData.setData("text", this.cells(this.getSelectedId(), this.cell._cellIndex).getValue());
- }
- }
- }
- };
- //response to click cut item
- dhtmlXGridObject.prototype.doRightMenuCut = function () {
- //alert("doCut");
- if (this._selectionArea) {
- this.setCSVDelimiter("/t");
- this.copyBlockToClipboard();
- } else {
- if (this.cell) {
- if (!(this.cellType[this.cell._cellIndex] == "linenumber") && !this.editor) {
- window.clipboardData.setData("text", this.cells(this.getSelectedId(), this.cell._cellIndex).getValue());
- }
- }
- }
- this.doRightMenuDelete();
- };
- //response to click paste item
- dhtmlXGridObject.prototype.doRightMenuPaste = function () {
- //alert("doPaste");
- this.pasteBlockFromClipboard();
- };
- //add new row
- dhtmlXGridObject.prototype.doRightMenuAddRow = function () {
- var cc = this.getColumnCount();
- var newnewrow = new Array(cc + 1);
- this.addRow((new Date()).valueOf(), newrow, this.getRowIndex(this.getSelectedId()));
- cc = null;
- newrow = null;
- };
- //response to click delete item
- dhtmlXGridObject.prototype.doRightMenuDelete = function () {
- //alert("doDelete");
- 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.cell) {
- if (!(this.cellType[this.cell._cellIndex] == "linenumber") && !this.editor) {
- this.cells(this.getSelectedId(), this.cell._cellIndex).setValue();
- }
- }
- }
- };
-
<script type="text/javascript">render_code();</script> 下面是右键菜单的样式表:
代码
- TABLE {
- font-family: /"Tahoma/", /"Verdana/", /"/u5b8b/u4f53/";
- font-size: 9pt
- }
-
- .mtdfocus {
- background-color: #EDF5FE;
- border-bottom: #B0E2FF 1px solid;
- border-top: #B0E2FF 1px solid;
- cursor: hand
- }
-
- .mtdexit {
- background-color: whitesmoke;
- border-bottom: #ffffff 1px solid;
- border-top: #ffffff 1px solid;
- }
-
- .ltdfocus {
- background-color: #EDF5FE;
- border-bottom: #B0E2FF 1px solid;
- border-top: #B0E2FF 1px solid;
- border-left: whitesmoke 1px solid;
- cursor: hand
- }
-
- .ltdexit {
- background-color: whitesmoke;
- border-bottom: #ffffff 1px solid;
- border-top: #ffffff 1px solid;
- border-left: whitesmoke 1px solid
- }
-
- .rtdfocus {
- background-color: #EDF5FE;
- border-bottom: #B0E2FF 1px solid;
- border-top: #B0E2FF 1px solid;
- border-right: whitesmoke 1px solid;
- cursor: hand
- }
-
- .rtdexit {
- background-color: whitesmoke;
- border-bottom: #ffffff 1px solid;
- border-top: #ffffff 1px solid;
- border-right: whitesmoke 1px solid
- }
-
- .menudiv {
- background-color: whitesmoke;
- border: #00B2EE 1px solid;
- left: 0px;
- position: absolute;
- top: 0px;
- visibility: hidden;
- z-index: 10;
- }
-
- .hrLine {
- position: absolute;
- bottom: 52px;
- }
-
<script type="text/javascript">render_code();</script> 然后将右键菜单添加到grid中: (1) 修改dhtmlXGridObject对象中的this.init 方法,这个方法在dhtmlXGrid.js文件中。 示例代码如下,注释之间的代码是新增代码:
代码
- this.init = function (fl) {
- if ((this.isTreeGrid()) && (!this._h2)) {
- this._aEx = new _dhtmlxArray();
- this._h2 = new dhtmlxHierarchy();
- if ((this._fake) && (!this._realfake)) {
- this._fake._h2 = this._h2;
- }
- this._tgc = {imgURL:null};
- }
- if (!this._hstyles) {
- return;
- }
-
-
- this.makeMenu();
-
- this.setOnRightClick(this.showRightMenu);
-
- this.editStop();
- this.lastClicked = null;
- this.resized = null;
- this.fldSorted = this.r_fldSorted = null;
- this.gridWidth = 0;
- this.gridHeight = 0;
- this.cellWidthPX = new Array(0);
- this.cellWidthPC = new Array(0);
- if (this.hdr.rows.length > 0) {
- this.clearAll(true);
- }
- ......
<script type="text/javascript">render_code();</script> (2) 将右键菜单隐藏操作添加到grid的单击事件中,即修改this.obj.onclick 属性方法,也是在dhtmlXGrid.js文件中; 将原方法中添加hideMenu()方法;修改后的代码如下:
代码
- ......
- this.obj.onmousemove = this._drawTooltip;
-
-
-
- this.obj.onclick = new Function("e", "hideMenu();this.grid._doClick(e||window.event);if (this.grid._sclE)this.grid.editCell(e||window.event);(e||event).cancelBubble=true;");
-
- if (_isMacOS) {
- this.entBox.oncontextmenu = new Function("e", "return this.grid._doContClick(e||window.event);");
- }
- ......
<script type="text/javascript">render_code();</script>
(3) 修改dhtmlXGridObject对象中的_OnSelectionStop 方法,使得在单元格选择区域(选择区域的实现其实就是添加了一个div区域)上,也可以有 自定义的右键菜单,使得当单击区域时区域消失,右击区域显示菜单;这个方法在dhtmlXGrid_selection.js文件中,代码如下:
代码
- dhtmlXGridObject.prototype._OnSelectionStop = function (event) {
- var self = this;
- if (this._blsTimer) {
- window.clearTimeout(this._blsTimer);
- }
- this.obj.onmousedown = function (e) {
- e = e || event;
-
-
-
- if (e.button == 1) {
- self._OnSelectionStart(e, this);
- } else {
- if (e.button == 2) {
- self.showRightMenu();
- }
- }
-
- return true;
- };
- this.obj.onmousemove = this.obj.onmmold || null;
- document.body.onmouseup = this._oldDMP || null;
- if (parseInt(this._selectionObj.style.width) < 2 && parseInt(this._selectionObj.style.height) < 2) {
- this._HideSelection();
- } else {
- var src = this.getFirstParentOfType(event.srcElement || event.target, "TD");
- if ((!src) || (!src.parentNode.idd)) {
- src = this._endSelectionCell;
- }
- while (src.tagName.toLowerCase() != "td") {
- src = src.parentNode;
- }
- this._stopSelectionCell = src;
- this._selectionArea = this._RedrawSelectionPos(this._startSelectionCell, this._stopSelectionCell);
- this.callEvent("onBlockSelected", []);
- }
- };
<script type="text/javascript">render_code();</script> (4) 为了实现右键菜单的功能,还需要在表格初始化方法init()前添加mygrid.setRightMenuObject("mygrid"),其中参数就是声明的grid对象名称。 2. 表格左侧添加行号 行号其实就是在原有的grid上添加一个列,放置每一行的indexid就可以了;专业版中已经给出了添加列的属性方法。 (1) 声明两个变量:
代码
- var lineflag = false;
- var itemsid = new Array(0);
<script type="text/javascript">render_code();</script> (2) 添加一个linenumber列类型,它不接受编辑,只可以选择;要修改的文件是dhtmlXGridCell.js; 在该文件中添加以下代码:
代码
-
-
- function eXcell_linenumber(cell) {
- this.base = eXcell_ed;
- this.base(cell);
- this.editable = false;
- this.edit = function () {
- };
- this.isDisabled = function () {
- return true;
- };
- }
-
- eXcell_linenumber.prototype = new eXcell_ed;
-
<script type="text/javascript">render_code();</script> (3) 在dhtmlXGrid.js中添加设定标志位和添加行号的方法:
代码
-
-
- dhtmlXGridObject.prototype.addLineNumber = function () {
- var linecell = null;
- itemsid = this.getAllItemIds().split(",");
- if (itemsid.length > 1) {
- for (var i = 0; i < itemsid.length; i++) {
- linecell = this.cells(itemsid[i], 0);
- linecell.setValue(this.getRowIndex(itemsid[i]) + 1);
- }
- }
- };
- dhtmlXGridObject.prototype.setLineFlag = function (para) {
- if (para) {
- lineflag = true;
- }
- if (lineflag) {
-
- this.insertColumn(0, " ", "linenumber", 30);
-
- this.addLineNumber();
- }
- };
-
-
-
<script type="text/javascript">render_code();</script> (4) 因为在初始化构建表格时,dhtmlxgrid本身默认采用的是异步模式,这时候是取不到每一行的id的;在直接浏览html页面时可以成功添加行号, 但是在服务器中不行;并且采用异步模式还有很多隐患,所以修改dhtmlxgrid的数据加载模式:
代码
-
- this.xmlLoader = new dtmlXMLLoaderObject(this.doLoadDetails, window, false, this.no_cashe);
-
-
<script type="text/javascript">render_code();</script> (5) 在能够引起行号变化的地方,添加重新设置行号的方法:
代码
- this._onHeaderClick = function (e) {
- var that = this.grid;
- var el = that.getFirstParentOfType(_isIE ? event.srcElement : e.target, "TD");
- if (!(this.grid.callEvent("onHeaderClick", [el._cellIndexS, (e || event)]))) {
- return false;
- }
- if (this.grid.resized == null) {
- that.sortField(el._cellIndexS, false, el);
- }
-
-
- if (lineflag) {
- that.addLineNumber();
- }
-
- };
- dhtmlXGridObject.prototype.addRow = function (new_id, text, ind) {
- var r = this._addRow(new_id, text, ind);
- if (!this.dragContext) {
- this.callEvent("onRowAdded", [new_id]);
- }
- this.callEvent("onRowCreated", [r.idd, r, null]);
- if (this.pagingOn) {
- this.changePage(this.currentPage);
- }
- this.setSizes();
- r._added = true;
- this.callEvent("onGridReconstructed", []);
-
-
- if (lineflag) {
- this.addLineNumber();
- }
-
- return r;
- };
- dhtmlXGridObject.prototype.deleteRow = function (row_id, node) {
- if (!node) {
- node = this.getRowById(row_id);
- }
- if (!node) {
- return;
- }
- this.editStop();
- if (this.callEvent("onBeforeRowDeleted", [row_id]) == false) {
- return false;
- }
- if (this.cellType._dhx_find("tree") != -1) {
- this._removeTrGrRow(node);
- } else {
- if (node.parentNode) {
- node.parentNode.removeChild(node);
- }
- var ind = this.rowsCol._dhx_find(node);
- if (ind != -1) {
- this.rowsCol._dhx_removeAt(ind);
- } else {
- ind = this.rowsBuffer[0]._dhx_find(row_id);
- if (ind >= 0) {
- this.rowsBuffer[0]._dhx_removeAt(ind);
- this.rowsBuffer[1]._dhx_removeAt(ind);
- }
- }
- this.rowsAr[row_id] = null;
- }
- for (var i = 0; i < this.selectedRows.length; i++) {
- if (this.selectedRows[i].idd == row_id) {
- this.selectedRows._dhx_removeAt(i);
- }
- }
- this.callEvent("onGridReconstructed", []);
- if (this.pagingOn) {
- this.changePage();
- }
- this.setSizes();
-
-
- if (lineflag) {
- this.addLineNumber();
- }
-
- return true;
- };
<script type="text/javascript">render_code();</script> (6) 在页面中的init()方法后设置是否添加行号标志;
代码
- mygrid.setLineFlag(true);
<script type="text/javascript">render_code();</script> 还有需要说明的一点是,添加行号后可能会影响到dhtmlxgrid自己的数据存储方法,这个我还没有修改它自带的数据存储方法,以后修改了再把代码贴上来,数据显示肯定没有问题! 这样右键菜单添加完成,看看示例的截图吧:  |