`
IvanLi
  • 浏览: 599719 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

扩展dhtmlGrid,使其支持自定义公式和动态列,表头合并

阅读更多
dhtmlGrid是一个功能比较齐全的html Grid控件,在其profesonal版中生成支持公式编辑到cell级别,我只想动态求任意列的和
,又不想花钱,就自己扩展了一下dhtmlgrid,使其支持在任意cell上添加求和公式,同时如果没个cell的值发生了改变,那么关联的
公式项会自动变化,跟excell有点像了,当然他的功能远不及excell强大。
1:扩展eXcell
eXcell是dhmtlGrid所有的cell的基类,所有的cell都是扩展自eXcell,dhtml中自带的类型有readOnly(eXcell_ro),editable(eXcell_ed)
图片,link,等等可以自己看它的doc有介绍,我扩展的类就叫eXcell_formulas
2:扩展eXcell步骤:
function eXcell_formulas(cell){
		try{
			this.cell = cell;
			this.grid = this.cell.parentNode.grid;
		}catch(er){}
		/**
		*	@desc: method called by grid to start editing
		*/
		this.edit = function(){
					
			}
		/**
		*	@desc: get real value of the cell
		*/
		this.getValue = function(){
				return "";
			}
		/**
		*	@desc: set formated value to the cell
		*/
		this.setValue = function(val){
				if(val.toString().trim()=="")
					val = " ";
				this.cell.innerHTML = val;
			}
		/**
		*	@desc: this method called by grid to close editor
		*/
		this.detach = function(){
				this.setValue(this.obj.value);
				return this.val!=this.getValue();
			}
}
eXcell_formulas.prototype = new eXcell;

这是扩展的骨架,要实现setValue,getValue,edit,detach四个方法,也可以继承已有的类
看看我的代码吧
/*==== add by ivan li math begin====*/
function eXcell_formulas(cell)
{
 	try
	{
		this.cell = cell;
		//指向grid控件
		this.grid = this.cell.parentNode.grid;
		
	}catch(er){}
}
//再这里我扩展自eXcell_ed
eXcell_formulas.prototype = new eXcell_ed;
//这个方法接受外界传来的cell的值,在这里是公式的值,
//当让,在这里cell是可以编辑的,如果输入的是公式那么要以=号开头
eXcell_formulas.prototype.setValue = function(val)
{
	if((typeof(val)!="number")&& val.toString()._dhx_trim()=="")
	{
 		val=" "
 		this.cell._clearCell=true;
	}
	
	if(val.toString()._dhx_trim().indexOf('=') != -1)
	{
		//以=号开头,说明是公式,那么存下来公式
		this.cell._val = val.toString()._dhx_trim();
		this.cell.innerHTML="formulas";
		
	}
	else
	{
		//如果不是以=号开头那么仍然保留原来的公式
		this.cell.innerHTML=val.toString()._dhx_trim();
	}
	//add cell observer
	//prototype.addCellObserver()
	//计划在此处把用obserer模式存下targetCell ->this,但是现在没成功,
        //主要式在callBack时不能调用存下的this.calcVale方法
}
//就算公式的值并显示
eXcell_formulas.prototype.calcValue = function()
{
	var innerFormulas;
	//如果没有存公式那么就不用计算了
	if(!this.cell._val)
	{
		return;
	}
	else
	{
		innerFormulas = this.cell._val.substr(1);
	}
	var cellAr = innerFormulas.split(',');
	
	var formulasResult = 0;
	for(icell=0; icell<cellAr.length;icell++)
	{
		
		cellChild = cellAr[icell].split('^');
		//得到targetCell对象
		var ex = this.grid.cells(cellChild[0],cellChild[1]);
		//目前只实现了加法,对于公式的解析还有待实现
		formulasResult= Number(formulasResult)+Number(ex.getValue());
	}
	this.cell.innerHTML = formulasResult;
	//如果有公式,那么把cell的颜色设置成黄色,以做提示
	this.setBgColor("yellow");
}
//此处添加CellObserver
eXcell_formulas.prototype.addCellObserver = function()
{
	var cellAr = this.cell._val.split(',');
	for(i = 0; i< cellAr.length; i++)
	{
		//if already has observer on the cell
		if(this.grid.formulasObserver.hasKey(cellAr[i]))
		{
			formulasCellAr = this.grid.formulasObserver.getValue(cellAr[i]);
			var hasRegistered = false;
			
			for(j = 0; j<formulasCellAr.length;j++)
			{
				if(this._val == formulasCellAr[j]._val)
				{
					hasRegistered = true;
					break;
				}
			}
			//if has not registered then add this formulascell in
			if(!hasRegistered)
			{
				formulasCellAr.push(this);
			}
		}
		//if no observer on the cell then add a new one
		else
		{
			var cellObservers = new Array();
			cellObservers.push(this);
			
			this.grid.formulasObserver.add(cellAr[i], cellObservers);
		}
	}
}

/*====add by ivan li math end====*/

3:修改grid部分
/*add by Ivan Li 2006-10-20 begin*/
	this.calcFormulas = function()
	{
		for(i = 0; i<this.getColumnCount();i++)
		{
			if("formulas" == this.getColType(i))
			{
				this._calcFormulasCol(i)
			}
		}
	};
	this._calcFormulasCol = function(colIdx)
	{
		for(j = 0; j < this.getRowsNum(); j++)
		{
			this.cells2(j, colIdx).calcValue();
		}
	};
	this.notifyCellChange = function(rowId,cellInd)
	{
		
		formulasCells = this.formulasObserver.getValue(rowId+"^"+cellInd);
		
		for(i = 0; i<formulasCells.length; i++)
		{
			
			//formulasCells[i] is eXcell_formulas type
			formulasCells[i].calcValue();
		}
	};
	/*add by Ivan Li 2006-10-20 end*/

有关dhtmlGrid可以自己到http://www.scbr.com/docs/products/dhtmlxGrid/index.shtml下载
分享到:
评论
29 楼 清风车影 2007-06-29  
非常好,找了好久才看到这么精典的。最喜欢的就是dhtmlxGrid1.2里面的动态过滤。
28 楼 zhenjia 2007-06-24  
个人感觉
mygrid.setHeader()
比xml里进行构造好得多,我的客户常常想改页面列表的title,如果进行XML里的构造我如果有要改的 不是改库就是改代码,或者有可能有人会那种读取properties文件,但是我觉得如果在JS上能进行设置就好了mygrid.setHeader('<bean:write name="myform" property="headerData"/>'); 这也不是很丑陋啊 标准标签 而不是<%%>
27 楼 IvanLi 2007-01-25  
walterjar 写道
能支持服务器端分页的dhtmlxGrid 什么地方有啊?Ivan Li
改了没有?

1.2 pro版里有!要花钱
26 楼 walterjar 2007-01-25  
能支持服务器端分页的dhtmlxGrid 什么地方有啊?Ivan Li
改了没有?
25 楼 IvanLi 2007-01-18  
今天新发现
在使用dhtml grid中的enableAutoHeigth方法要注意:
1:enableAutoHeigth的好处是可以根据grid的行的高度和行数来自动调整grid的高度,比如动态增加或者删除一行时,这个功能很有用。
2:但是在享受enableAutoHeigth带来的好处的同时我们牺牲了sroll bar,也就不能够smart rendering,而且如果在初始化grid时如果没有设定buffer的大小,那么dhtmlGrid的默认buffer是40,在grid行数>40的情况下,如果使用enableAutoHeigth(true),那么40行以上的数据将不会被显示,由于没有sroll bar,这些数据永远也不会被显示了!
24 楼 daoger 2007-01-17  
Ivan Li 写道
写分页比较有难度,值得一试


在客户端实现分页,将不属于该页的数据暂时放入缓存是困难一些!

在服务器端实现分页则比较好控制,只需要构造要显示的数据即可!
23 楼 IvanLi 2007-01-17  
写分页比较有难度,值得一试
22 楼 daoger 2007-01-17  
我现在做的几个页面感觉速度还是很快的,以后我准备添加显示的分页功能,提高操作速度!

每次只有保存后才更新页面上的数据显示!我用的是免费版,有些工作是自己扩展的!

21 楼 IvanLi 2007-01-17  
berlo 写道
你是服务器端处理的呀,还有个问题,你的数据是从服务器端取的数吧,服务器端是什么?jsp、php、asp?
我用的是jsp,直接loadXML(http://地址),服务器端返回xml格式的数据,现在能够正常的显示出数据来,但是我客户端取数据的请求发送了两遍,如果插入或修改操作岂不重复了,数据多对服务器端的压力也很大。这个问题你有吗?苦恼,跟踪代码也找不出来,嗨

1:js只认服务器返回的XML数据,至于服务器端使用什么技术,dhtmlgrid并不关心。
2:发送两次请求应该是你jsp写的有问题,你可以把代码贴上来看看
3:对于grid的crud操作,应该使用gridAPI+ajax来控制,而不是每次都重新load grid
20 楼 IvanLi 2007-01-17  
berlo 写道
刚才对dhtmlGrid进行500条数据的测试,什么呀,在一个数据窗口显示500条数据,反应极其缓慢,简直让人不能接受!!!!!!!!!!!!!

500条,每行多少列?
dhtml有4种方式来提高相应速度
1:Dynamical Loading
2:Buffering
3:Distributed Parsing
4:Split the Content of Grid into Pages
其中3,4是pro版才支持的功能。
4比较繁琐,3的话如果你好好看看std版中parseXML的部分可以自己写出来

dhtmlgrid大概每秒中能够渲染300-500个cell
这个跟客户机的配置有关,还有如果cell里如果包含了复杂的公式计算,那么渲染速度会慢些
19 楼 berlo 2007-01-17  
大家还知道有什么别的数据窗口比较好吗,功能倒不用太多,能增、删、改、动态添加数据就行呀
18 楼 berlo 2007-01-17  
刚才对dhtmlGrid进行500条数据的测试,什么呀,在一个数据窗口显示500条数据,反应极其缓慢,简直让人不能接受!!!!!!!!!!!!!
17 楼 berlo 2007-01-16  
你是服务器端处理的呀,还有个问题,你的数据是从服务器端取的数吧,服务器端是什么?jsp、php、asp?
我用的是jsp,直接loadXML(http://地址),服务器端返回xml格式的数据,现在能够正常的显示出数据来,但是我客户端取数据的请求发送了两遍,如果插入或修改操作岂不重复了,数据多对服务器端的压力也很大。这个问题你有吗?苦恼,跟踪代码也找不出来,嗨
16 楼 daoger 2007-01-16  
berlo 写道
解决了,楼上的这样做:
这行:if((_isIE)&&(!this._retry)){
变成:if(_isIE){
就ok了
呵呵


我是服务器端处理的问题,现在已经解决了!
15 楼 berlo 2007-01-16  
解决了,楼上的这样做:
这行:if((_isIE)&&(!this._retry)){
变成:if(_isIE){
就ok了
呵呵
14 楼 berlo 2007-01-16  
lz,我的问题和上面的一样,注释掉那一句也还是不行,reload时仍报错呀,急死我了,呀
13 楼 daoger 2007-01-12  
poiuyt373 写道
测试reloaddata,发现同样的xml也报错,"LoadXML Incorrect XML",跟踪了一下发现
dhtmlXCommon.js中
dtmlXMLLoaderObject.prototype.getXMLTopNode=function(tagName){
if(this.xmlDoc.responseXML){
var temp=this.xmlDoc.responseXML.getElementsByTagName(tagName);
var z=temp[0];
}else
var z=this.xmlDoc.documentElement;
if(z)
return z;

if((_isIE)&&(!this._retry)){

var xmlString=this.xmlDoc.responseText;
this._retry=true;
this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
this.xmlDoc.async=false;
this.xmlDoc.loadXML(xmlString);
return this.getXMLTopNode(tagName);
}

dhtmlxError.throwError("LoadXML","Incorrect XML",[this.xmlDoc])
return document.createElement("DIV");
};


必须把this._retry=true;这句注释掉才行,不清楚_retry有什么用




LZ 我在用dhtmlXGrid的时候也出现了这种问题,按照这位同学的方法仍没解决,不知你是怎么解决的?

请看一下我的问题吧!谢谢

http://www.iteye.com/topic/46367
12 楼 泡泡 2007-01-11  
lipengch 写道
你好,非常感谢你的关注.  我用的是1.0pro了, 里面没有setSerializationLevel(userData,fullXML,config,changedAttr,onlyChanged)这个功能. 不知道怎么实现.
非常好
11 楼 lipengch 2006-12-20  
你好,非常感谢你的关注.  我用的是1.0pro了, 里面没有setSerializationLevel(userData,fullXML,config,changedAttr,onlyChanged)这个功能. 不知道怎么实现.
10 楼 IvanLi 2006-12-20  
1.2版中支持表头合并,但是比较恶心的是在statnd版中支持生成表格后在调用js来合并表头,要想从xml配置,对不起,掏钱。搞得我很是郁闷,怎么办,搞它。其实也很简单,加了几句js搞定,对于生手说困难在于先要理清内部方法,我仅仅在我原来H它的_parseHeader方法中做一下手脚就搞定了。
我把我扩展的代码都传上来了,想要的自取。各位老大有什么好的扩展也通知一声,谢谢!
我改过的代码在extend_ivan文件夹下
1:支持自定义公式到任意cell(目前只是求和)
2:支持从XML里配置表头
3:支持从XML里配置表头合并。
其实我很想建议公司买一个正版的150$而已,真的算不上什么,公司给QA MM们买的什么IBM基层测试工具要20多万$,那群MM们还不是那它
做这Selenium做的事,唉,谁叫咱们是小弟呢!

相关推荐

Global site tag (gtag.js) - Google Analytics