精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-10-30
(由于版权的问题,附件中只有我自己添加的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) { x = x - w; } if ((y + h) > oy) { y = 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 newrow = 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(); } } } }; 下面是右键菜单的样式表: 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; } 然后将右键菜单添加到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; } //daoger_start //constructe components of right menu this.makeMenu(); //add rightclick action this.setOnRightClick(this.showRightMenu); //daoger_end 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); } ...... //方法的以后部分省略 (2) 将右键菜单隐藏操作添加到grid的单击事件中,即修改this.obj.onclick 属性方法,也是在dhtmlXGrid.js文件中; 将原方法中添加hideMenu()方法;修改后的代码如下: ...... this.obj.onmousemove = this._drawTooltip; //daoger_start //this.obj.onclick = new Function("e", "this.grid._doClick(e||window.event);if (this.grid._sclE)this.grid.editCell(e||window.event);(e||event).cancelBubble=true;"); //hide right menu when left click 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;"); //daoger_end if (_isMacOS) { this.entBox.oncontextmenu = new Function("e", "return this.grid._doContClick(e||window.event);"); } ...... (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; //daoger_start //self._OnSelectionStart(e, this); //define the different operations of right click and left click if (e.button == 1) { self._OnSelectionStart(e, this);//do select } else { if (e.button == 2) { self.showRightMenu();//show right menu } } //daoger_end 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", []); } }; (4) 为了实现右键菜单的功能,还需要在表格初始化方法init()前添加mygrid.setRightMenuObject("mygrid"),其中参数就是声明的grid对象名称。 2. 表格左侧添加行号 行号其实就是在原有的grid上添加一个列,放置每一行的indexid就可以了;专业版中已经给出了添加列的属性方法。 (1) 声明两个变量: var lineflag = false;//是否添加行号判定标志 var itemsid = new Array(0);//所有行的id数组 (2) 添加一个linenumber列类型,它不接受编辑,只可以选择;要修改的文件是dhtmlXGridCell.js; 在该文件中添加以下代码: //daoger_start //create linenumber type of column function eXcell_linenumber(cell) { this.base = eXcell_ed; this.base(cell); this.editable = false; this.edit = function () { }; this.isDisabled = function () { return true; }; } //take on all mothed of ed type eXcell_linenumber.prototype = new eXcell_ed; //daoger_end (3) 在dhtmlXGrid.js中添加设定标志位和添加行号的方法: //daoger_start_addLineNumber //the mothed of add line number on the first column 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) { //add line number column at the first index this.insertColumn(0, " ", "linenumber", 30); //add line number on this column this.addLineNumber(); } }; //daoger_end (4) 因为在初始化构建表格时,dhtmlxgrid本身默认采用的是异步模式,这时候是取不到每一行的id的;在直接浏览html页面时可以成功添加行号, 但是在服务器中不行;并且采用异步模式还有很多隐患,所以修改dhtmlxgrid的数据加载模式: //daoger_start this.xmlLoader = new dtmlXMLLoaderObject(this.doLoadDetails, window, false, this.no_cashe); //this.xmlLoader = new dtmlXMLLoaderObject(this.doLoadDetails, window, true, this.no_cashe); //daoger_end (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); } //daoger_start //reset line number of the first column after sorting if (lineflag) { that.addLineNumber(); } //daoger_end }; 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", []); //daoger_start //reset line number of the first column after add a new row if (lineflag) { this.addLineNumber(); } //daoger_end 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(); //daoger_start //reset line number of the first column after deleting a row if (lineflag) { this.addLineNumber(); } //daoger_end return true; }; (6) 在页面中的init()方法后设置是否添加行号标志; mygrid.setLineFlag(true); 还有需要说明的一点是,添加行号后可能会影响到dhtmlxgrid自己的数据存储方法,这个我还没有修改它自带的数据存储方法,以后修改了再把代码贴上来,数据显示肯定没有问题! 这样右键菜单添加完成,看看示例的截图吧: 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-11-05
通过loadXML()可以方便的加载xml文件到grid中,但是如果现在代码中是xml string,除了分节点解析外,有没有直接读取xml string的方法呢?
--重新查看了文档,这是专业版中的方法,我用的是试用版,看来必须得逐步解析了。 loadXML String() //load content from specified string |
|
返回顶楼 | |
发表时间:2007-11-06
xml 写道 通过loadXML()可以方便的加载xml文件到grid中,但是如果现在代码中是xml string,除了分节点解析外,有没有直接读取xml string的方法呢?
--重新查看了文档,这是专业版中的方法,我用的是试用版,看来必须得逐步解析了。 loadXML String() //load content from specified string 为什么要加载一个字符串呢? 如果你想实现grid普通版和后端数据交互的话,可以参考我的另一个帖子:http://www.iteye.com/topic/53104 |
|
返回顶楼 | |
发表时间:2007-11-06
我的测试代码基于ASP.Net,曾经这样写过:
mygrid.loadXML("QInfo.aspx"); //但是返回错误 最后是将客户端获得的xml串解析后用mygrid.addRow来构建每一组row,稍微麻烦了一点。 |
|
返回顶楼 | |
发表时间:2007-11-07
xml 写道 我的测试代码基于ASP.Net,曾经这样写过:
mygrid.loadXML("QInfo.aspx"); //但是返回错误 最后是将客户端获得的xml串解析后用mygrid.addRow来构建每一组row,稍微麻烦了一点。 ASP.net我不懂,我原来用java代码测试的,struts MVC、spring MVC和jsp页面处理的都没有问题;你再查看一下后端代码。返回的xml文件流要通过response写回,并且不要进行页面跳转! 顺便,如果有网友对修改的部分有问题可以联系我,留下email,我可以把专业版的相关部分代码发给你! |
|
返回顶楼 | |
发表时间:2007-11-07
daoger 写道 ASP.net我不懂,我原来用java代码测试的,struts MVC、spring MVC和jsp页面处理的都没有问题;你再查看一下后端代码。返回的xml文件流要通过response写回,并且不要进行页面跳转! ASP.Net返回的字符串是在.aspx.cs中进行response: protected void Page_Load(object sender, EventArgs e) { Response.Charset = "utf-8"; Response.ContentType = "text/xml"; Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8"); string strXml; //程序后面对strXml进行赋值 …………………… Response.Write(strXml); Response.End(); } 然后在js中处理服务器端返回的数据流,不知道是不是对ASP.Net支持不好。现在问题通过其他方式解决了,但是还有很多不懂的地方,需要慢慢挖掘:) 右键功能的实现我会参考你的方法,感谢你的帮助! 另外,你有尝试过dhtmlxGrid和mootools结合使用吗?我还没有深入研究两者的源代码就先这样做了,暂时没有发现兼容性的问题。 |
|
返回顶楼 | |
发表时间:2007-11-07
不知道各位有沒有這樣的經驗
我希望把dhtmlxgrid配合prototype.js的Ajax.request使用,但 dhtmlxgrid 用 loadXML(data.php); ajax.request用 ajaxObj = new Ajax.Request( 'data.php', { method: 'post', postBody: pars, asynchronous: true, onCreate:function(result){ effectStart(); }, onSuccess:function(result){ result(result); }, onComplete:function(result){ effectEnd(); } } ); 我希望使用ajax.request,因為可以自行控制我需要的effect,但dhtmlxgrid非用loadXML不可.. 請問有解釋方法嗎??? |
|
返回顶楼 | |
发表时间:2007-11-07
xml 写道 另外,你有尝试过dhtmlxGrid和mootools结合使用吗?
我见有网友实现过和prototype的结合使用,想必和mootools的结合也应该没有问题! |
|
返回顶楼 | |
发表时间:2007-11-07
vtsuper 写道 不知道各位有沒有這樣的經驗
我希望把dhtmlxgrid配合prototype.js的Ajax.request使用,但 dhtmlxgrid 用 loadXML(data.php); ajax.request用 ajaxObj = new Ajax.Request( 'data.php', { method: 'post', postBody: pars, asynchronous: true, onCreate:function(result){ effectStart(); }, onSuccess:function(result){ result(result); }, onComplete:function(result){ effectEnd(); } } ); 我希望使用ajax.request,因為可以自行控制我需要的effect,但dhtmlxgrid非用loadXML不可.. 請問有解釋方法嗎??? dhtmlxgrid与后台的数据交互也是基于ajax实现的,专业版中都已经有很完善的方法来实现数据加载和保存,包括一个单元格修改后失去焦点就进行的保存;普通版中没有这些功能,你可以自己实现数据的保存,但是加载你可以用dhtmlxgrid自己的加载方式,毕竟他自己的处理已经很完善了;当然你也可以自己修改dhtmlxgrid的数据交互方面的代码(dhtmlXCommon.js)。 |
|
返回顶楼 | |
发表时间:2007-11-07
"数据的保存"是指什麼呢???
我已看過這編內容 http://www.iteye.com/topic/53104 但應該不太合用... |
|
返回顶楼 | |