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下载