`
lgx2351
  • 浏览: 171383 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

grid里用右键来实现功能菜单

阅读更多

在自定义grid中,如果一个grid的列很多,窗口无法显示这么长的内容,且我们一般把grid每一行按操作按钮(如编辑删除按钮)放在每一行的最后一列。这时候用户要要操作某一行的数据,如要做“删除”操作时,就要用鼠标拉动水平滚动条,拉动到能看到最后一列的时候再进行点击操作。这就显得比较麻烦了。这时候,右键某一行,把这行最后的按钮内容构造成右键的显示内容,就可以方便地进行操作了。

整体的思路:create一个div,把grid行最后的按钮内容构造成右键的内容,执行最后一行的按钮的onclick事件即可。

主要的代码如下:

/**
 * 构造grid的右键菜单 
 * author:liugx
 */
//orgCellColor存放点击行的原始颜色值
ConRightMenu.orgCellColor = "";
ConRightMenu.clickRow = "";
function ConRightMenu(){
}
ConRightMenu.prototype ={
	cancelRight:function(){
		event.returnValue=false;   
	  	event.cancelBubble=true; 
	},
	getEventElement:function(clickObject){
		var evt = Event.getEvent();
		return (evt)?(event.target || event.srcElement):clickObject;	
	},
	getTrObj:function(){
		var oCh = "";
		try {
			if(DOMModel.type()==1){
				oCh = conRightMenu.getEventElement().parentElement;
			}else if(DOMModel.type()==2){
				oCh = Event.findElement(evt,"tr");
			}
		}catch(e){
			_alert(e.message);
			return "";
		}
		return oCh;
	},
	changeClassForTD:function(trObj){
		//先清空其它的td底色
		if(trObj.parentElement){
			var allTDObj = trObj.parentElement.getElementsByTagName("TD");
			for(var j=0;j<allTDObj.length;j++){
				if(allTDObj[j].style.backgroundColor.toUpperCase()=='#DCDCDC'.toUpperCase()){
					allTDObj[j].style.backgroundColor = ConRightMenu.orgCellColor;
				}
			}
		}
		var trChildNodes =  trObj.childNodes;
		//设置tr的底色
		for(var i=0;i<trChildNodes.length;i++){
			if(i==0){
				ConRightMenu.orgCellColor = trChildNodes[i].style.backgroundColor;
			}
			trChildNodes[i].style.backgroundColor = '#DCDCDC';
		}
	},
	buttonClickFun:function(itemId){
		var trObj = $(ConRightMenu.clickRow);
		if(trObj){
			var childNodes =  trObj.lastChild.childNodes;
			for(var i=0;i<childNodes.length;i++){
				if(childNodes[i].id == itemId){
					childNodes[i].fireEvent("onclick");
				}
			}
		}
	},
	consButtonHtml:function(trObj){
	  	var result = "";
	  	result += "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">";
	  	var childNodes = trObj.lastChild.childNodes;
	  	var childNodesLen = childNodes.length;
	  	for(var i=0;i<childNodesLen;i++){
	  		var outerHtml = childNodes[i].outerHTML;
	  		var onclickHtml = outerHtml.substring(outerHtml.indexOf("onclick"),outerHtml.length-1);
	  		var itemId = childNodes[i].id;
	  		result += "<tr onmouseover='this.className=\"mouseOverGrid\";' onmouseout='this.className=\"mouseOutGrid\";'";
	  		result += " onclick='conRightMenu.buttonClickFun(\""+itemId+"\");";
	  		result += "$(\"right_reslut_div\").style.display=\"none\"'><td>";
	  		var tdImg = document.createElement('img');
	  		var tdImgUrl = childNodes(i).currentStyle.backgroundImage.replace("url(\"","");
	  		tdImgUrl = tdImgUrl.replace("\")","");
	  		tdImg.src = tdImgUrl;
	  		result += tdImg.outerHTML;
	  		result += "</td><td>"+childNodes[i].title+"</td></tr>";
	  		if(i<childNodesLen-1){
		  		result += "<tr><td colspan='2'><div class='rowSplit'></div></td></tr>";
	  		}
		}
		result += "</table>";
		return result;
	},
	buildRightMenu:function(){
		conRightMenu.cancelRight();
		var trObj = conRightMenu.getTrObj();
		if(trObj){
			ConRightMenu.clickRow = trObj.id;
	        var buttonHtml = conRightMenu.consButtonHtml(trObj);
			if(!$("right_reslut_div")){
				var right_res_div = document.createElement('div');
				right_res_div.id = "right_reslut_div";
			}else{
				right_res_div = $("right_reslut_div");
			}	
			right_res_div.innerHTML = buttonHtml;
			right_res_div.style.background = '#DCDCDC';
			right_res_div.style.padding = "1 1 1 1";
			right_res_div.style.border  = "solid #C0C0C0 1px";
			right_res_div.style.position = 'absolute';
			right_res_div.style.left = event.clientX  + geometry.getHorizontalScroll() + 'px';
			right_res_div.style.top = event.clientY + geometry.getVerticalScroll() + 'px';
			right_res_div.style.width = 100 +'px';
			right_res_div.style.height = trObj.lastChild.childNodes.length*18 +'px';
			if(!$("right_reslut_div")){
				document.body.appendChild(right_res_div);
			}
			right_res_div.style.display = '';
			
			conRightMenu.changeClassForTD(trObj);
		}
	},
	display_right_div:function(){
		if($("right_reslut_div")){
			if($("right_reslut_div").style.display==''){
				$("right_reslut_div").innerHTML = '';
				$("right_reslut_div").style.display = 'none';
			}
		}
	}
}
var conRightMenu = new ConRightMenu();

 分析以上代码如下:

1、

//orgCellColor存放点击行的原始颜色值
ConRightMenu.orgCellColor = "";
ConRightMenu.clickRow = "";

orgCellColor和clickRow分别存储的是点击行的原始背景颜色值和点击行的id,前者的作用是右键点击某一行设置了这行的背景值后再右键点击另一行时,把之前的那行的原始背景值再赋值给它;后者是得到点击某行的id值,这在设置右键按钮的事件中有很重要的作用。因为右键后显示的div的按钮与grid的按钮是不一样的,如果前者的onclick事件也和后者一样执行一个函数的话,那么是不行的。因为grid的按钮执行的函数里用到的event.srcElement等有关event事件的元素都与右键div的按钮的event事件的元素不一样,如果右键div的按钮执行grid的按钮的函数,就会出错。所以,我们解决方法是执行grid按钮的fireEvent("onclick")方法。这就要求能够取得到右键点击grid那行的按钮元素。通过clickRow得到tr的id,就可以定位到点击grid的那行的每个按钮元素了。可能有些抽象,大家认真看下代码就会明白了。

2、getTrObj()函数得到点击事件的那行tr这个obj。得到它后就可以定位到我们关心的任何东西了。注意这里的:Event.findElement(evt,"tr");和getEventElement()都很好重用。

3、changeClassForTD()用于设置右键某行后的背景颜色,因为右键的行要与其它行区分开来,所以用上背景颜色会比较直观。这里要注意的,右键某行时要把之前右键某行的保存的原始背景色赋值上去,这在前面的第一点的orgCellColor也讨论过了。这里通过trObj.parentElement.得到tr外面的table元素,再通过table元素的getElementsByTagName("TD")得到所有的td元素,如果td的背景色是#DCDCDC时则说明它是之前右键的那行,把它赋值为原始的值。这里要注意用了比较的两方都用了toUpperCase来得到颜色值,还要注意用backgroundColor,而不是background。

4、buttonClickFun()方法指定了右键按钮点击时执行的事件函数。写这个实现时发了挺多时间,走了弯路。本来想通过grid的每个按钮的id来得到每个按钮,但构造每个grid按钮的id名发了好多时间。后来想到,用如之前第一点说的用clickRow得到右键的那行,保存下来后。就可以得到这行下面的每个grid按钮了。

5、consButtonHtml()主要是通过自定义grid的按钮解析它们的html来得到右键内容。为什么要那样解析,其中前台jsp的自定义的写法如下:

<self:tag_grid tag_name='VOU_RECORD_GRID'
			is_right_menu = "true" 
 			custom_button="
			<button title='编辑' class='gridBtnEdit' id='grid_custom_button_edit' onclick='vouRecordJsMgr.preEditVouRec();'>
			<button title='删除' class='gridBtnDel' id='grid_custom_button_del' onclick='vouRecordJsMgr.delVouRec(1);'> 
			"></self:tag_grid>

 上面的custom_button=""的内容就是我们要解析和构造的。

同时,用到的css如下:

.mouseOverGrid{
	background-color:#C0C0C0;
}
.mouseOutGrid{
	background-color:#DCDCDC;
}
.rowSplit {
	height: 3px;
	background: url(Image/m_splitLine.gif) repeat-x;
	font-size: 0px;
	margin: 0 2px;
}
 

6、buildRightMenu()是构建右键菜单的主要生成代码。它主要做了三件事:一是取得右键的行的id即ConRightMenu.clickRow;第二件事是通过consButtonHtml()取得构造右键div的html,并设置这个div的属性,如style属性等;第三件事是设置右键行的背景色。其中设置style属性是为了美观和正确的定位。要注意的是left和top值要加上滚动条的值,因为鼠标的位置取的是文档坐标。代码如下:

function Geometry(){}
Geometry.prototype = {
	getHorizontalScroll:function(){
		var result = 0;
		// All browsers but IE
		if (window.innerWidth) {
			result = window.pageXOffset;
		}
		// for IE 6 when there is a DOCTYPE
		if (document.documentElement && document.documentElement.clientWidth) { 
			result = document.documentElement.scrollLeft;
		}
		// for IE4, IE5, and IE6 without a DOCTYPE
		if (document.body.clientWidth) { 
			result = document.body.scrollLeft;
		}
		return result;
	},
	getVerticalScroll:function(){
		var result = 0;
		// All browsers but IE
		if (window.innerWidth) {
			result = window.pageYOffset;
		}
		// for IE 6 when there is a DOCTYPE
		if (document.documentElement && document.documentElement.clientWidth) {
			result = document.documentElement.scrollTop;
		}
		// for IE4, IE5, and IE6 without a DOCTYPE
		if (document.body.clientWidth) { 
			result = document.body.scrollTop;
		}
		return result;
	}
}
var geometry = new Geometry();

 

7、display_right_div()方法是当右键点击body时把右键隐藏掉。

 

以上大致介绍了自定义grid里用右键来实现功能菜单的操作过程,总体的过程就是那样了,希望对大家会有帮助。

最终的效果如下:

 

  • 大小: 18.1 KB
0
0
分享到:
评论

相关推荐

    WPF分页DataGrid(二)列右键菜单实现

    在"WPF分页DataGrid"中介绍了如何实现分页功能,本文中介绍如果实现右键菜单。点击菜单项Age,将Age列隐藏,再点击则显示;并实现移动列后,同步显示。 详见:...

    Ext.grid.GridPanel右键菜单

    右键菜单的资料,代码已经详细描写。请仿照文件中所描述即可使用,不限于EXT4.0以上版本使用。

    基于FineUI Grid控件添加右键菜单

    大家对于FineUI Grid控件会添加右键菜单吗,下面小编就给大家详细介绍基于FineUI Grid控件添加右键菜单,需要的朋友可以参考下

    Jquery EasyUI Datagrid右键菜单实现方法

    最近在学Jquery EasyUI,现在来说一说EasyUI的DataGrid,一般当我们在实现前端界面的时候,经常在DataGrid的上面或者后面加一些按钮,方便用户进行一些添加,删除,编辑等功能 用户在每次使用的时候,都需要去先...

    CxGrid右键增强功能源代码

    //右键菜单 CopyCell:TMenuItem;//复制单元格内容 CopyList:TMenuItem;//复制选中列内容 CopyLine:TMenuItem;//复制选中行内容 PastLine:TMenuItem;//粘贴#9分隔符数据 DerFiles:TMenuItem;//导出文件 ...

    ExtJs grid行 右键菜单的两种方法

    ExtJs grid行 右键菜单的两种方法,需要用extjs制作右键菜单的朋友可以参考下。

    dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法

    在以前的一个公司内部管理系统(InnerOA)中,对于目录树的构造我采用的是dTree,实现无限级目录显示及右键菜单功能(右键菜单中包括:新建、修改、共享、删除、刷新等功能,如下图所示) 关于公司内部管理系统...

    jQuery右键菜单contextMenu使用实例

    在下面我们将设计一个场景,表格grid需要在每行实现鼠标右键,增加,删除,保存操作。grid我就用gridview了,随便用微软提供的样式,测试用例不用搞的多好看嘛,我也不是做美工了,哈哈,偷偷懒。 先上效果图,是...

    jQuery LigerUI V1.1.0

    [增加]ligerTab增加右键菜单功能,包括 关闭其他/关闭全部等。 [增加]ligerTab增加获取Items Count,删除项等常见方法 [增加]ligerLayout增加初始化控制左边/右边隐藏、是否折叠、是否调整大小等方法。 ...

    Datagridview使用技巧(9)Datagridview的右键菜单

    可以通过设置ContextMenuStrip对象来控制DataGridView的右键菜单的显示。 DataGridViewColumn的ContextMenuStrip属性设定除了列头以外的单元格的右键菜单。 DataGridViewRow的ContextMenuStrip属性设定除了行头以外...

    基于VFP基类Grid开发的用于程序开发的工具类

    4、粘贴、拷贝功能的实现 使用方法,按住Shift键不放,在Grid格中依次点击两个单元格, 选择一个区域,在所选区域上点击鼠标右键,在弹出菜单上选择复制, 在Excel或Word中粘贴即可。 联系人:张春雷 Email :...

    Ext grid 添加右击菜单

    // 右键菜单代码关键部分 //Menu 建立 var rightClick = new Ext . menu . Menu ({ id : ‘rightClickCont’ , // 在 HTML 文件中必须有个 rightClickCont 的 DIV 元素 items : [{ id : ‘rMenu1’ , handler : ...

    Javascript Grid控件

    javascript数据列表控件。包括分页,排序,右键选中弹出菜单。

    Delphi自定义Grid控件

    自定义查询GRID内数据 点击标题自动排序 打印内容 添加、修改、更新内容 右键菜单、 适用于DELPHI7.0

    金傑MIS開發--GRID欄位編輯+智能過濾

    在表格上按右键,即可出现功能菜单,点击进入!程序应该适用于各版本的DELPHI,但由于条件有限未做测试!希望大家多多交流,能得到大家的各种有用的源代码!本程序的全部代码您都可以任意使用,但源代码的最前面几行的注释不...

    MIS開發Grid欄位編輯器+智能過濾

    在表格上按右键,即可出现功能菜单,点击进入!程序应该适用于各版本的DELPHI,但由于条件有限未做测试!希望大家多多交流,能得到大家的各种有用的源代码!本程序的全部代码您都可以任意使用,但源代码的最前面几行的注释不...

    react-datasheet-grid

    完全支持键盘导航和快捷方式支持右键单击和自定义上下文菜单支持自定义小部件快速燃烧,针对速度进行了优化流畅的动画虚拟化,支持数十万行广泛可定制,可控制的行为安装npm install --save react-datasheet-grid...

Global site tag (gtag.js) - Google Analytics