该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-10-20
,又不想花钱,就自己扩展了一下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下载 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-10-20
很不错的组件,可以用在以后的财务模块。
|
|
返回顶楼 | |
发表时间:2006-10-23
pro 版的还可以在xml里定义table的header,现在的还不可以,等我有时间了,搞一搞
|
|
返回顶楼 | |
发表时间:2006-10-25
居然不支持中文
|
|
返回顶楼 | |
发表时间:2006-10-27
测试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有什么用 |
|
返回顶楼 | |
发表时间:2006-10-27
这个问题我跟作者交流了好几次,他说是ie在处理http://和file://文件不一样,如果用firefox就没事
|
|
返回顶楼 | |
发表时间:2006-10-30
没有试过firefox,ie下即使采用http也必须注释那句
|
|
返回顶楼 | |
发表时间:2006-10-30
我也出现过这个问题,但是在1.0版本中,不论是ie 还是ff, reload都能正常工作
|
|
返回顶楼 | |
发表时间:2006-11-03
今天不太忙,我把从xml里配置header的js搞出来了,这也是它的pro版才提供的功能哦
在dhtmXGrid.js里加上这个方法, dhtmlXGridObject.prototype._parseHeader = function(headCols) { var arLab = new Array(0); var arWdth = new Array(0); var arTyp = new Array(0); var arAlg = new Array(0); var arSrt = new Array(0); for (var i=0; i < headCols.length; i++) { arLab[arLab.length] = headCols[i].firstChild?headCols[i].firstChild.data:"col"+(i+1); arWdth[arWdth.length] = headCols[i].getAttribute("width"); arTyp[arTyp.length] = headCols[i].getAttribute("type"); arAlg[arAlg.length] = headCols[i].getAttribute("align"); arSrt[arSrt.length] = headCols[i].getAttribute("sort"); } this.setHeader(arLab.join(',')); this.setInitWidths(arWdth.join(',')); this.setColTypes(arTyp.join(',')); this.setColAlign(arAlg.join(',')); this.setColSorting(arSrt.join(',')); this.init(); } 然后在parseXML方法里 var ar = new Array(); var idAr = new Array(); 的上一行加上这几句 // add by ivan li 2006-11-03 begin for config header in xml begin var headCol = this.xmlLoader.doXPath("//rows/head/column", xmlDoc); if(headCol.length > 0) {// have config the rowheader in the xml this._parseHeader(headCol); } // add by ivan li 2006-11-03 begin for config header in xml end 就搞定了 现在的xml里可以这样配置了 <?xml version="1.0" encoding="utf-8"?> <rows> <head> <column width="50" type="ro" align="right" sort="str">a</column> <column width="50" type="ro" align="right" sort="str">b</column> <column width="50" type="ro" align="right" sort="str">c</column> <column width="50" type="ro" align="right" sort="str">d</column> <column width="50" type="ro" align="right" sort="str">e</column> <column width="50" type="ro" align="right" sort="str">f</column> <column width="50" type="ro" align="right" sort="str">g</column> <column width="50" type="ro" align="right" sort="str">h</column> </head> <row id="1"> <cell>-1500</cell> <cell>A Time to Kill</cell> <cell><![CDATA[gavin king]]></cell> <cell>=2^3,3^3</cell> <cell>1</cell> <cell>24</cell> <cell>=1^4,1^3,2^4</cell> <cell>05/01/1998</cell> </row> <row id="2"> <cell>1000</cell> <cell>Blood and Smoke</cell> <cell><![CDATA[<font color="red">Ste</font>phen King]]></cell> <cell>0</cell> <cell>1</cell> <cell>24</cell> <cell>=2^4,2^3</cell> <cell>01/01/2000</cell> </row> </rows> 在页面里只需要 mygrid = new dhtmlXGridObject('gridbox'); mygrid.setImagePath("../imgs/"); mygrid.init(); mygrid.loadXML("formulas.xml"); 就可以了,这个功能的实现对于要生成动态列的用户来说提供了很大的方便,在我们系统里就要求表格的列是动态的,原来必须把动态的列用taglib打到页面上去,例如 mygrid.setHeader('<bean:write name="myform" property="headerData"/>'); 感觉很丑陋,现在好了,只要在后台构建好xml就搞定了 |
|
返回顶楼 | |
发表时间:2006-11-27
老大能把dhtmlxGrid1.1 pro版里面的setSerializationLevel(userData,fullXML,config,changedAttr,onlyChanged)函数提取出来吗?
非常感激! |
|
返回顶楼 | |