-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathformula.js
106 lines (90 loc) · 3.7 KB
/
formula.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
let cell = document.querySelector(`.cell[rid="${i}"][cid="${j}"]`);
cell.addEventListener("blur", (e) => {
let address = addressBar.value;
let [activeCell, cellProp] = getCellAndCellProp(address);
let enteredData = activeCell.innerText;
if (enteredData === cellProp.value)
return;
cellProp.value = enteredData;
// If data modifies remove P-C relation, make formula empty,
// update children with new hardcoded (modified) value
removeChildFromParent(cellProp.formula);
cellProp.formula = "";
updateChildrenCells(address);
})
}
}
let formulaBar = document.querySelector(".formula-bar");
formulaBar.addEventListener("keydown", (e) => {
let inputFormula = formulaBar.value;
if (e.key === "Enter" && inputFormula) {
// If change in formula, break old P-c relation
//evalute new formula, add new P-C relation
let address = addressBar.value;
let [cell, cellProp] = getCellAndCellProp(address);
if (inputFormula !== cellProp.formula)
removeChildFromParent(cellProp.formula);
let evaluatedValue = evaluateFormula(inputFormula);
// To update UI & cellProp in DB
setCellUIAndCellProp(evaluatedValue, inputFormula, address);
addChildToParent(inputFormula);
updateChildrenCells(address);
}
})
function updateChildrenCells(parentAddress) {
let [parentCell, parentCellProp] = getCellAndCellProp(parentAddress);
let children = parentCellProp.children;
for (let i = 0; i < children.length; i++) {
let childAddress = children[i];
let [childCell, childCellProp] = getCellAndCellProp(childAddress);
let childFormula = childCellProp.formula;
let evaluatedValue = evaluateFormula(childFormula);
setCellUIAndCellProp(evaluatedValue, childFormula, childAddress);
updateChildrenCells(childAddress);
}
}
function addChildToParent(formula) {
let childAddress = addressBar.value;
let encodedFormula = formula.split(" ");
for (let i = 0; i < encodedFormula.length; i++) {
let asciiValue = encodedFormula[i].charCodeAt(0);
if (asciiValue >= 65 && asciiValue <= 90) {
let [parentCell, parentCellProp] = getCellAndCellProp(encodedFormula[i]);
parentCellProp.children.push(childAddress);
}
}
}
function removeChildFromParent(formula) {
let childAddress = addressBar.value;
let encodedFormula = formula.split(" ");
for (let i = 0; i < encodedFormula.length; i++) {
let asciiValue = encodedFormula[i].charCodeAt(0);
if (asciiValue >= 65 && asciiValue <= 90) {
let [parentCell, parentCellProp] = getCellAndCellProp(encodedFormula[i]);
let idx = parentCellProp.children.indexOf(childAddress);
parentCellProp.children.splice(idx, 1);
}
}
}
function evaluateFormula(formula) {
let encodedFormula = formula.split(" ");
for (let i = 0; i < encodedFormula.length; i++) {
let asciiValue = encodedFormula[i].charCodeAt(0);
if (asciiValue >= 65 && asciiValue <= 90) {
let [cell, cellProp] = getCellAndCellProp(encodedFormula[i]);
encodedFormula[i] = cellProp.value;
}
}
let decodedFormula = encodedFormula.join(" ");
return eval(decodedFormula);
}
function setCellUIAndCellProp(evaluatedValue, formula, address) {
let [cell, cellProp] = getCellAndCellProp(address);
// UI change
cell.innerText = evaluatedValue;
// DB update
cellProp.value = evaluatedValue;
cellProp.formula = formula;
}