File size: 6,932 Bytes
1f1bb3e
 
 
 
e945b07
 
 
 
 
 
 
 
 
 
 
 
 
 
1f1bb3e
e945b07
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1f1bb3e
e945b07
 
1f1bb3e
e945b07
 
 
 
1f1bb3e
e945b07
 
 
1f1bb3e
e945b07
 
 
 
 
 
 
 
 
 
 
 
 
 
1f1bb3e
e945b07
 
 
1f1bb3e
e945b07
 
 
 
 
1f1bb3e
e945b07
 
 
 
 
1f1bb3e
e945b07
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1f1bb3e
e945b07
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1f1bb3e
e945b07
 
 
 
 
 
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// ECMAScript Module format for FormulaJS playground

// Check which FormulaJS API is available when page loads
document.addEventListener("DOMContentLoaded", function() {
  console.log("FormulaJS API Check:");
  if (window.formulajs) {
    console.log("Using window.formulajs API");
  } else if (window.Formula) {
    console.log("Using window.Formula API");
  } else {
    console.warn("FormulaJS library not detected. Some functions may not work.");
  }

  const formulaSelect = document.getElementById("formula-select");
  const paramsContainer = document.getElementById("params-container");
  const calculateBtn = document.getElementById("calculate-btn");
  const resultDiv = document.getElementById("result");
  const formulaCodeDiv = document.getElementById("formula-code");
  
  // Define parameters for each formula
  const formulaParams = {
    SUM: [
      { name: "number1", type: "number", default: 1 },
      { name: "number2", type: "number", default: 2 },
      { name: "number3", type: "number", default: 3 }
    ],
    AVERAGE: [
      { name: "number1", type: "number", default: 1 },
      { name: "number2", type: "number", default: 2 },
      { name: "number3", type: "number", default: 3 }
    ],
    MAX: [
      { name: "number1", type: "number", default: 1 },
      { name: "number2", type: "number", default: 2 },
      { name: "number3", type: "number", default: 3 }
    ],
    MIN: [
      { name: "number1", type: "number", default: 1 },
      { name: "number2", type: "number", default: 2 },
      { name: "number3", type: "number", default: 3 }
    ],
    PMT: [
      { name: "rate", type: "number", default: 0.05 },
      { name: "nper", type: "number", default: 36 },
      { name: "pv", type: "number", default: 10000 }
    ],
    FV: [
      { name: "rate", type: "number", default: 0.05 },
      { name: "nper", type: "number", default: 10 },
      { name: "pmt", type: "number", default: -100 },
      { name: "pv", type: "number", default: -1000 }
    ],
    NPV: [
      { name: "rate", type: "number", default: 0.1 },
      { name: "value1", type: "number", default: -10000 },
      { name: "value2", type: "number", default: 3000 },
      { name: "value3", type: "number", default: 4200 },
      { name: "value4", type: "number", default: 6800 }
    ],
    IRR: [
      { name: "values", type: "array", default: "[-100, 39, 59, 55, 20]" }
    ],
    VLOOKUP: [
      { name: "lookup_value", type: "number", default: 40 },
      { name: "table_array", type: "array", default: "[[10, 'A'], [20, 'B'], [30, 'C'], [40, 'D'], [50, 'E']]" },
      { name: "col_index_num", type: "number", default: 2 },
      { name: "range_lookup", type: "boolean", default: false }
    ],
    REGEXEXTRACT: [
      { name: "text", type: "string", default: "Extract 42 from this text" },
      { name: "regular_expression", type: "string", default: "\\d+" }
    ],
    REGEXMATCH: [
      { name: "text", type: "string", default: "Does this text contain numbers like 123?" },
      { name: "regular_expression", type: "string", default: "\\d+" }
    ],
    REGEXREPLACE: [
      { name: "text", type: "string", default: "Replace all numbers like 42 and 123 in this text" },
      { name: "regular_expression", type: "string", default: "\\d+" },
      { name: "replacement", type: "string", default: "[number]" }
    ]
  };
  
  // Update parameters when formula changes
  formulaSelect.addEventListener("change", updateParams);
  
  // Initial parameter setup
  updateParams();
  
  // Calculate result when button is clicked
  calculateBtn.addEventListener("click", calculateResult);
  
  function updateParams() {
    const selectedFormula = formulaSelect.value;
    const params = formulaParams[selectedFormula];
    
    // Clear existing parameters
    paramsContainer.innerHTML = "";
    
    // Add parameter inputs
    params.forEach(param => {
      const paramContainer = document.createElement("div");
      paramContainer.className = "param-container";
      
      const label = document.createElement("label");
      label.className = "param-label";
      label.textContent = param.name;
      
      const input = document.createElement("input");
      input.type = "text";
      input.id = `param-${param.name}`;
      input.value = param.default;
      
      paramContainer.appendChild(label);
      paramContainer.appendChild(input);
      paramsContainer.appendChild(paramContainer);
    });
  }
  
  function calculateResult() {
    const selectedFormula = formulaSelect.value;
    const params = formulaParams[selectedFormula];
    
    // Get parameter values
    const paramValues = params.map(param => {
      const value = document.getElementById(`param-${param.name}`).value;
      
      if (param.type === "array") {
        try {
          return JSON.parse(value);
        } catch (e) {
          return value;
        }
      } else if (param.type === "number") {
        return parseFloat(value);
      } else if (param.type === "boolean") {
        return value.toLowerCase() === "true";
      }
      
      return value;
    });
    
    try {
      let result;
      
      // FormulaJS has changed its export structure in newer versions
      // First try window.formulajs (older versions)
      if (window.formulajs && typeof window.formulajs[selectedFormula] === 'function') {
        result = window.formulajs[selectedFormula](...paramValues);
      } 
      // Then try window.Formula (newer versions)
      else if (window.Formula && typeof window.Formula[selectedFormula] === 'function') {
        result = window.Formula[selectedFormula](...paramValues);
      }
      // Custom implementation for regex functions if not available
      else if (selectedFormula === 'REGEXEXTRACT') {
        const [text, pattern] = paramValues;
        const regex = new RegExp(pattern);
        const match = text.match(regex);
        result = match ? match[0] : null;
      }
      else if (selectedFormula === 'REGEXMATCH') {
        const [text, pattern] = paramValues;
        const regex = new RegExp(pattern);
        result = regex.test(text);
      }
      else {
        throw new Error(`Function ${selectedFormula} not found in FormulaJS`);
      }
      
      // Display result
      resultDiv.textContent = result !== undefined ? result : "undefined";
      
      // Show the code
      const formulaNamespace = window.formulajs ? "formulajs" : "Formula";
      formulaCodeDiv.textContent = `${formulaNamespace}.${selectedFormula}(${paramValues.map(v => 
        typeof v === 'object' ? JSON.stringify(v) : 
        typeof v === 'string' ? `"${v}"` : v
      ).join(", ")}) = ${result}`;
    } catch (error) {
      resultDiv.textContent = "Error";
      formulaCodeDiv.textContent = error.message;
    }
  }
});

// Export any functions you want to make available to other modules
// This is optional and not needed for this playground
export const version = "1.0.0";