313 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			313 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
| Product Name: dhtmlxSuite 
 | |
| Version: 4.0.3 
 | |
| Edition: Professional 
 | |
| License: content of this file is covered by DHTMLX Commercial or Enterprise license. Usage without proper license is prohibited. To obtain it contact sales@dhtmlx.com
 | |
| Copyright UAB Dinamenta http://www.dhtmlx.com
 | |
| */
 | |
| 
 | |
| /**
 | |
| *	@desc: cell with support for math formulas
 | |
| *	@param: cell - cell object
 | |
| *	@type:  private
 | |
| *   @edition: Professional
 | |
| */
 | |
| function eXcell_math(cell){
 | |
| 	if (cell){
 | |
| 		this.cell = cell;
 | |
|     	this.grid = this.cell.parentNode.grid;
 | |
| 	}
 | |
| 	this.edit = function(){
 | |
| 		this.grid.editor = new eXcell_ed(this.cell);
 | |
| 		this.grid.editor.fix_self=true;
 | |
| 		this.grid.editor.getValue=this.cell.original?(function(){ return this.cell.original}):this.getValue;
 | |
| 		this.grid.editor.setValue=this.setValue;
 | |
| 		this.grid.editor.edit();
 | |
| 	}
 | |
| 	this.isDisabled = function(){ return !this.grid._mathEdit; }
 | |
| 	this.setValue = function(val){
 | |
| 				val=this.grid._compileSCL(val,this.cell,this.fix_self);
 | |
|                 if (this.grid._strangeParams[this.cell._cellIndex])
 | |
|     				this.grid.cells5(this.cell,this.grid._strangeParams[this.cell._cellIndex]).setValue(val);
 | |
|                 else{
 | |
|                     this.setCValue(val);
 | |
|     	            this.cell._clearCell=false;
 | |
| 	            }
 | |
|     }
 | |
|     this.getValue = function(){
 | |
|         if (this.grid._strangeParams[this.cell._cellIndex])
 | |
| 			return this.grid.cells5(this.cell,this.grid._strangeParams[this.cell._cellIndex]).getValue();
 | |
|         
 | |
|         return this.cell.innerHTML;
 | |
|     }
 | |
| }
 | |
| eXcell_math.prototype = new eXcell;
 | |
| 
 | |
| dhtmlXGridObject.prototype._init_point_bm=dhtmlXGridObject.prototype._init_point;
 | |
| dhtmlXGridObject.prototype._init_point = function(){
 | |
| 	this._mat_links={};
 | |
| 	this._aggregators=[];
 | |
| 	this.attachEvent("onClearAll",function(){
 | |
| 		this._mat_links={};
 | |
| 		this._aggregators=[];
 | |
| 	})
 | |
| 	this.attachEvent("onCellChanged",function(id,ind){
 | |
| 		if (this._mat_links[id]){ 
 | |
| 			var cell=this._mat_links[id][ind];
 | |
| 			if (cell){ 
 | |
| 				for (var i=0; i<cell.length; i++)
 | |
|           if (cell[i].parentNode)
 | |
|             this.cells5(cell[i]).setValue(this._calcSCL(cell[i]));
 | |
| 			}
 | |
| 		}
 | |
| 		if (!this._parsing && this._aggregators[ind]){
 | |
| 			var pid=this._h2.get[id].parent.id;
 | |
| 			if (pid!=0){
 | |
| 				var ed=this.cells(pid,ind);
 | |
| 				ed.setValue(this._calcSCL(ed.cell));
 | |
| 			}
 | |
| 		}
 | |
| 	})
 | |
| 	this.attachEvent("onAfterRowDeleted",function(id,pid){ //will be called for each delete operation, may be optimized
 | |
| 		if (pid!=0)
 | |
| 			if (!this._parsing && this._aggregators.length){
 | |
| 				for (var ind=0; ind < this._aggregators.length; ind++) {
 | |
| 					if (this._aggregators[ind]){
 | |
| 							var ed=this.cells(pid,ind);
 | |
| 							ed.setValue(this._calcSCL(ed.cell));
 | |
| 					}
 | |
| 				};
 | |
| 			}
 | |
| 		return true;
 | |
| 	})
 | |
| 	this.attachEvent("onXLE",function(){
 | |
| 		for (var i=0; i < this._aggregators.length; i++) {
 | |
| 			if (this._aggregators[i])
 | |
| 				this._h2.forEachChild(0,function(el){
 | |
| 					if (el.childs.length!=0){
 | |
| 						var ed=this.cells(el.id,i);
 | |
| 						ed.setValue(this._calcSCL(ed.cell));
 | |
| 					}
 | |
| 				},this);
 | |
| 		};
 | |
| 	})
 | |
| 	this._init_point=this._init_point_bm;
 | |
| 	if (this._init_point) this._init_point();
 | |
| }
 | |
| 
 | |
| /**
 | |
| *	@desc: enable/disable serialization of math formulas
 | |
| *	@param: status - true/false
 | |
| *	@type:  public
 | |
| *   @edition: Professional
 | |
| */
 | |
| dhtmlXGridObject.prototype.enableMathSerialization=function(status){
 | |
|     this._mathSerialization=convertStringToBoolean(status);
 | |
| }
 | |
| /**
 | |
| *	@desc: enable/disable rounding while math calculations
 | |
| *	@param: digits - set hom many digits must be rounded, set 0 for disabling
 | |
| *	@type:  public
 | |
| *   @edition: Professional
 | |
| */
 | |
| dhtmlXGridObject.prototype.setMathRound=function(digits){
 | |
| 	this._roundDl=digits;
 | |
|     this._roundD=Math.pow(10,digits);
 | |
| }
 | |
| /**
 | |
| *	@desc: enable/disable editing of math cells
 | |
| *	@param: status - true/false
 | |
| *	@type:  public
 | |
| *   @edition: Professional
 | |
| */
 | |
| dhtmlXGridObject.prototype.enableMathEditing=function(status){
 | |
|     this._mathEdit=convertStringToBoolean(status);
 | |
| }
 | |
| 
 | |
| /**
 | |
| *	@desc: calculate value of math cell
 | |
| *	@param: cell - math cell
 | |
| *	@returns: cell value
 | |
| *	@type:  private
 | |
| *   @edition: Professional
 | |
| */
 | |
| dhtmlXGridObject.prototype._calcSCL=function(cell){ 
 | |
|     if (!cell._code) return this.cells5(cell).getValue();
 | |
|     try{
 | |
|     	dhtmlx.agrid=this;
 | |
|     	var z=eval(cell._code);
 | |
|     } catch(e){ return ("#SCL"); }
 | |
|     if (this._roundD)
 | |
|         { 
 | |
|         	var pre=Math.abs(z)<1?"0":"";
 | |
|          	if (z<0) pre="-"+pre;
 | |
|             z=Math.round(Math.abs(z)*this._roundD).toString();
 | |
|             if (z==0) return 0;
 | |
|             if (this._roundDl>0){
 | |
|             	var n=z.length-this._roundDl;
 | |
|             	if (n<0) {
 | |
|             		z=("000000000"+z).substring(9+n);
 | |
|             		n=0;
 | |
|             	}
 | |
|             	return (pre+z.substring(0,n)+"."+z.substring(n,z.length));
 | |
|             }
 | |
|           return pre+z;
 | |
|       }
 | |
|     return z;      
 | |
| }
 | |
| 
 | |
| dhtmlXGridObject.prototype._countTotal=function(row,cell){ 
 | |
| 	var b=0;
 | |
| 	var z=this._h2.get[row];
 | |
| 	for (var i=0; i<z.childs.length; i++){
 | |
| 		if (!z.childs[i].buff) return b;	// dnd of item with childs, item inserted in hierarchy but not fully processed
 | |
| 		if (z.childs[i].buff._parser){
 | |
| 			this._h2.forEachChild(row,function(el){
 | |
| 				if (el.childs.length==0){
 | |
|           var value = parseFloat(this._get_cell_value(el.buff,cell),10);
 | |
|           if (value)
 | |
| 					 b += value;
 | |
|         }
 | |
| 			},this)
 | |
| 			return b;
 | |
| 		}
 | |
|     var value = parseFloat(this._get_cell_value(z.childs[i].buff,cell),10);
 | |
|     if (value)
 | |
| 		  b += value;
 | |
| 	}
 | |
| 	return b;
 | |
| }
 | |
| 
 | |
| /**
 | |
| *	@desc: compile pseudo code to correct javascript
 | |
| *	@param: code - pseudo code
 | |
| *	@param: cell - math cell
 | |
| *	@returns: valid js code
 | |
| *	@type:  private
 | |
| *   @edition: Professional
 | |
| */
 | |
| dhtmlXGridObject.prototype._compileSCL=function(code,cell,fix){ 
 | |
| 		if (code === null || code === window.undefined) return code;
 | |
|         code=code.toString();
 | |
|         if (code.indexOf("=")!=0 || !cell.parentNode) {
 | |
|         	this._reLink([],cell);
 | |
|         	if (fix) cell._code = cell.original = null;
 | |
|             return code;
 | |
|         }
 | |
|         cell.original=code;
 | |
|         
 | |
|         var linked=null;
 | |
|         code=code.replace("=","");
 | |
|         if (code.indexOf("sum")!=-1){ 
 | |
|             code=code.replace("sum","(dhtmlx.agrid._countTotal('"+cell.parentNode.idd+"',"+cell._cellIndex+"))");
 | |
|             if (!this._aggregators) this._aggregators=[];
 | |
|             this._aggregators[cell._cellIndex]="sum";
 | |
|             cell._code=code;
 | |
|         	return  this._parsing?"":this._calcSCL(cell);
 | |
|         }
 | |
|         if (code.indexOf("[[")!=-1){
 | |
|           var test = /(\[\[([^\,]*)\,([^\]]*)]\])/g;
 | |
|           dhtmlx.agrid=this;
 | |
|           linked=linked||(new Array());
 | |
|           code=code.replace(test,
 | |
|               function ($0,$1,$2,$3){
 | |
|                   if ($2=="-")
 | |
|                       $2=cell.parentNode.idd;
 | |
|                   if ($2.indexOf("#")==0)
 | |
|                       $2=dhtmlx.agrid.getRowId($2.replace("#",""));
 | |
|                       linked[linked.length]=[$2,$3];
 | |
|                   return "(parseFloat(dhtmlx.agrid.cells(\""+$2+"\","+$3+").getValue(),10))";
 | |
|               }
 | |
|           );
 | |
|         }
 | |
|         
 | |
|         if (code.indexOf(":")!=-1){ 
 | |
|           var test = /:(\w+)/g;
 | |
|           dhtmlx.agrid=this;
 | |
|           var id=cell.parentNode.idd;
 | |
|           linked=linked||(new Array());
 | |
|           code=code.replace(test,
 | |
|               function ($0,$1,$2,$3){
 | |
|                   linked[linked.length]=[id,dhtmlx.agrid.getColIndexById($1)];
 | |
|                   return '(parseFloat(dhtmlx.agrid.cells("'+id+'",dhtmlx.agrid.getColIndexById("'+$1+'")).getValue(),10))';
 | |
|               }
 | |
|           );
 | |
|         }
 | |
|         else{
 | |
|           var test = /c([0-9]+)/g;
 | |
|           dhtmlx.agrid=this;
 | |
|           var id=cell.parentNode.idd;
 | |
|           linked=linked||(new Array());
 | |
|           code=code.replace(test,
 | |
|               function ($0,$1,$2,$3){
 | |
|                   linked[linked.length]=[id,$1];
 | |
|                   return "(parseFloat(dhtmlx.agrid.cells(\""+id+"\","+$1+").getValue(),10))";
 | |
|               }
 | |
|           );
 | |
|         }
 | |
|         
 | |
|         this._reLink(linked,cell);
 | |
|         cell._code=code;
 | |
|         return this._calcSCL(cell);
 | |
|     }
 | |
| 
 | |
| /**
 | |
| *	@desc: link math cells to it source cells
 | |
| *	@param: ar - array of nodes for linking
 | |
| *	@param: cell - math cell
 | |
| *	@type:  private
 | |
| *   @edition: Professional
 | |
| */
 | |
| dhtmlXGridObject.prototype._reLink=function(ar,cell){
 | |
| 		if (!ar.length) return; // basically it would be good to clear unused math links, but it will require a symetric structure 
 | |
| 		for (var i=0; i<ar.length; i++){ 
 | |
| 			if (!this._mat_links[ar[i][0]]) this._mat_links[ar[i][0]]={};
 | |
| 			var t=this._mat_links[ar[i][0]];
 | |
| 			if (!t[ar[i][1]]) t[ar[i][1]]=[];
 | |
| 			t[ar[i][1]].push(cell);
 | |
| 		}
 | |
| }
 | |
| 
 | |
| if (_isKHTML){
 | |
| // replace callback support for safari.
 | |
|  (function(){
 | |
|    var default_replace = String.prototype.replace;
 | |
|    String.prototype.replace = function(search,replace){
 | |
|  // replace is not function
 | |
|  if(typeof replace != "function"){
 | |
|  return default_replace.apply(this,arguments)
 | |
|  }
 | |
|  var str = "" + this;
 | |
|  var callback = replace;
 | |
|  // search string is not RegExp
 | |
|  if(!(search instanceof RegExp)){
 | |
|  var idx = str.indexOf(search);
 | |
|  return (
 | |
|  idx == -1 ? str :
 | |
|  default_replace.apply(str,[search,callback(search, idx, str)])
 | |
|  )
 | |
|  }
 | |
|  var reg = search;
 | |
|  var result = [];
 | |
|  var lastidx = reg.lastIndex;
 | |
|  var re;
 | |
|  while((re = reg.exec(str)) != null){
 | |
|  var idx  = re.index;
 | |
|  var args = re.concat(idx, str);
 | |
|  result.push(
 | |
|  str.slice(lastidx,idx),
 | |
|  callback.apply(null,args).toString()
 | |
|  );
 | |
|  if(!reg.global){
 | |
|  lastidx += RegExp.lastMatch.length;
 | |
|  break
 | |
|  }else{
 | |
|  lastidx = reg.lastIndex;
 | |
|  }
 | |
|  }
 | |
|  result.push(str.slice(lastidx));
 | |
|  return result.join("")
 | |
|    }
 | |
|  })();
 | |
|  }
 | |
| //(c)dhtmlx ltd. www.dhtmlx.com
 |