Files
aportil/themes/sources/dhtmlxGrid/codebase/ext/dhtmlxgrid_math.js

330 lines
9.6 KiB
JavaScript

/*
Product Name: dhtmlxSuite
Version: 5.2.0
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;
dhx4.attachEvent("onGridCreated", function(grid){
grid._reset_math();
if (grid._was_created_math) return;
grid._was_created_math = true;
grid.attachEvent("onClearAll", grid._reset_math);
grid.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));
}
}
})
grid.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;
})
grid.attachEvent("onXLE", grid._refresh_math);
});
dhtmlXGridObject.prototype._reset_math=function(){
this._mat_links = {};
this._aggregators = [];
};
dhtmlXGridObject.prototype._refresh_math=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);
};
};
dhtmlXGridObject.prototype.refreshMath=function(status){
this._mat_links = {};
for (var i=0; i<this.getColumnsNum(); i++){
if (this.getColType(i) == "math"){
this.forEachRow(function(id){
var cell = this.cells(id, i);
cell.setValue(cell.cell.original || cell.getValue());
});
}
}
};
/**
* @desc: enable/disable serialization of math formulas
* @param: status - true/false
* @type: public
* @edition: Professional
*/
dhtmlXGridObject.prototype.enableMathSerialization=function(status){
this._mathSerialization=dhx4.s2b(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=dhx4.s2b(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){
b = 0;
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