DownloadMigration Guide: v2.x → v3.0
This guide helps you migrate from the legacy jQuery-based Calx.js (v2.x) to the new TypeScript-based version (v3.0).
Breaking Changes
1. Top-Level API Change
v2.x (jQuery/Sheet-based) // Sheet was the main entry point
var sheet = new calx.Sheet('#myTable');
sheet.set('A1', 100);
sheet.calculate();
v3.0 (Workbook-based) // Workbook is now the main entry point
import { Calx } from '@xsanisty/calxjs';
const workbook = Calx.createWorkbook();
const sheet = workbook.createSheet('MySheet');
sheet.createCell('A1', { value: 100 });
workbook.build();
workbook.calculate();
2. Cell Creation
v2.x // Simple setter
sheet.set('A1', 100);
sheet.set('A2', '=A1*2');
v3.0 import { DataType } from '@xsanisty/calxjs/Cell/DataType';
// Explicit cell creation with metadata
sheet.createCell('A1', {
value: 100,
type: DataType.NUMBER
});
sheet.createCell('A2', {
formula: '=A1*2',
type: DataType.NUMBER
});
3. Getting Cell Values
v2.x var value = sheet.get('A1');
var computedValue = sheet.getCell('A2').value;
v3.0 const value = sheet.getCellValue('A1');
// or
const value = sheet.getCell('A1').value;
4. Calculation
v2.x // Calculate entire sheet
sheet.calculate();
// Calculate specific cell
sheet.calculateCell('A1');
v3.0 // Build dependencies first
workbook.build();
// Calculate entire workbook
workbook.calculate();
// Or calculate specific sheet
sheet.calculate();
// Or request calculation for specific cell
sheet.requestCalculate('A1');
5. Cross-Sheet References
v2.x // Use sheet registry (buggy)
calx.sheetRegistry['sheet1'] = sheet1;
calx.sheetRegistry['sheet2'] = sheet2;
// In formula
sheet2.set('A1', '=#sheet1!B1');
v3.0 // All sheets managed by workbook
const workbook = Calx.createWorkbook();
const sheet1 = workbook.createSheet('Sheet1');
const sheet2 = workbook.createSheet('Sheet2');
// Cross-sheet reference (syntax remains similar)
sheet2.createCell('A1', {
formula: '=#Sheet1!B1'
});
workbook.build();
workbook.calculate();
6. Events
v2.x // jQuery events
$(sheet.element).on('calculated', function() {
console.log('Calculated');
});
// Custom callbacks
sheet.onCalculate = function() {
console.log('Done');
};
v3.0 import { SheetEvent } from '@xsanisty/calxjs/Sheet/SheetEvent';
import { CellEvent } from '@xsanisty/calxjs/Cell/CellEvent';
// Unified event system
sheet.dispatcher.listen(SheetEvent.CALCULATION_COMPLETE, (event) => {
console.log('Calculated');
});
sheet.dispatcher.listen(CellEvent.VALUE_CHANGED, (event) => {
console.log(`Cell ${event.cell} changed to ${event.value}`);
});
7. Custom Functions
v2.x // Extend sheet.fx
sheet.fx.CUSTOM = function(a, b) {
return a + b;
};
v3.0 // Use static Calx API
Calx.setFormula('CUSTOM', (a: number, b: number) => {
return a + b;
});
// Or set multiple at once
Calx.setFormulae({
CUSTOM1: (a, b) => a + b,
CUSTOM2: (a, b) => a * b
});
Step-by-Step Migration
Step 1: Install v3.0
npm install @xsanisty/calxjs@3.0.0
Step 2: Update Imports
Before <script src="jquery.js"></script>
<script src="jquery-calx-2.2.8.js"></script>
After import { Calx } from '@xsanisty/calxjs';
import { DataType } from '@xsanisty/calxjs/Cell/DataType';
Step 3: Update Initialization
Before $(document).ready(function() {
var sheet = new calx.Sheet('#myTable');
sheet.set('A1', 100);
sheet.set('A2', 200);
sheet.set('A3', '=A1+A2');
sheet.calculate();
});
After // Create workbook
const workbook = Calx.createWorkbook();
// Create sheet
const sheet = workbook.createSheet('MySheet');
// Add cells
sheet.createCell('A1', { value: 100, type: DataType.NUMBER });
sheet.createCell('A2', { value: 200, type: DataType.NUMBER });
sheet.createCell('A3', { formula: '=A1+A2', type: DataType.NUMBER });
// Build and calculate
workbook.build();
workbook.calculate();
// Get result
console.log(sheet.getCell('A3').value); // 300
Step 4: Update Multiple Sheets
Before var sheet1 = new calx.Sheet('#table1');
var sheet2 = new calx.Sheet('#table2');
// Register for cross-sheet
calx.sheetRegistry['sheet1'] = sheet1;
calx.sheetRegistry['sheet2'] = sheet2;
sheet1.set('A1', 100);
sheet2.set('A1', '=#sheet1!A1 * 2');
sheet1.calculate();
sheet2.calculate();
After const workbook = Calx.createWorkbook();
const sheet1 = workbook.createSheet('Sheet1');
const sheet2 = workbook.createSheet('Sheet2');
sheet1.createCell('A1', { value: 100 });
sheet2.createCell('A1', { formula: '=#Sheet1!A1 * 2' });
workbook.build();
workbook.calculate();
console.log(sheet2.getCell('A1').value); // 200
Step 5: Update Event Handlers
Before $(sheet.element).on('calculated', function() {
$('#result').text('Calculation complete!');
});
sheet.onCellChange = function(address, value) {
console.log('Cell', address, 'changed to', value);
};
After import { SheetEvent } from '@xsanisty/calxjs/Sheet/SheetEvent';
import { CellEvent } from '@xsanisty/calxjs/Cell/CellEvent';
sheet.dispatcher.listen(SheetEvent.CALCULATION_COMPLETE, () => {
document.getElementById('result')!.textContent = 'Calculation complete!';
});
sheet.dispatcher.listen(CellEvent.VALUE_CHANGED, (event: any) => {
console.log('Cell', event.cell, 'changed to', event.value);
});
Common Migration Patterns
Pattern 1: Simple Calculation
Before var sheet = new calx.Sheet();
sheet.set('A1', 10);
sheet.set('A2', 20);
sheet.set('A3', '=A1+A2');
sheet.calculate();
var result = sheet.get('A3');
After const workbook = Calx.createWorkbook();
const sheet = workbook.createSheet('Sheet1');
sheet.createCell('A1', { value: 10 });
sheet.createCell('A2', { value: 20 });
sheet.createCell('A3', { formula: '=A1+A2' });
workbook.build();
workbook.calculate();
const result = sheet.getCellValue('A3');
Pattern 2: Data-Driven Initialization
Before var data = {
'A1': 100,
'A2': 200,
'A3': '=A1+A2'
};
var sheet = new calx.Sheet();
for (var addr in data) {
sheet.set(addr, data[addr]);
}
sheet.calculate();
After const data = {
'A1': { value: 100 },
'A2': { value: 200 },
'A3': { formula: '=A1+A2' }
};
const workbook = Calx.createWorkbook();
const sheet = workbook.createSheet('Sheet1');
for (const addr in data) {
sheet.createCell(addr, data[addr]);
}
workbook.build();
workbook.calculate();
Or use the data API:
const workbook = Calx.createWorkbookFromData({
sheets: {
'Sheet1': {
cells: {
'A1': { value: 100 },
'A2': { value: 200 },
'A3': { formula: '=A1+A2' }
},
variables: {}
}
}
});
workbook.build();
workbook.calculate();
Pattern 3: Dynamic Updates
Before var sheet = new calx.Sheet();
sheet.set('A1', 10);
sheet.set('A2', '=A1*2');
sheet.calculate();
console.log(sheet.get('A2')); // 20
// Update A1
sheet.set('A1', 15);
sheet.calculate();
console.log(sheet.get('A2')); // 30
After const workbook = Calx.createWorkbook();
const sheet = workbook.createSheet('Sheet1');
sheet.createCell('A1', { value: 10 });
sheet.createCell('A2', { formula: '=A1*2' });
workbook.build();
workbook.calculate();
console.log(sheet.getCellValue('A2')); // 20
// Update A1
sheet.getCell('A1').value = 15;
sheet.requestCalculate('A1');
sheet.calculate();
console.log(sheet.getCellValue('A2')); // 30
Pattern 4: HTML Table Binding
Before // Bind to HTML table
var sheet = new calx.Sheet('#myTable');
// Cells automatically map to table cells
sheet.calculate();
After // Create workbook with element binding
const table = document.getElementById('myTable') as HTMLElement;
const workbook = Calx.createWorkbookFromElement(table);
// Manual cell-to-element mapping (or use a binding utility)
const sheet = workbook.createSheet('Sheet1', table);
// ... create cells and calculate
workbook.build();
workbook.calculate();
// TODO: v3.0 needs DOM binding utilities (coming soon)
Feature Comparison
| Feature | v2.x | v3.0 | Notes |
|---------|------|------|-------|
| Basic formulas | ✅ | ✅ | Same syntax |
| Cell references | ✅ | ✅ | Same syntax |
| Cross-sheet refs | ⚠️ | ✅ | Fixed bugs |
| Cell ranges | ✅ | 🚧 | Coming soon |
| Array formulas | ❌ | 🚧 | Coming soon |
| Custom functions | ✅ | ✅ | Better API |
| Events | ⚠️ | ✅ | Unified system |
| HTML binding | ✅ | 🚧 | Coming soon |
| TypeScript | ❌ | ✅ | Full support |
| Circular deps | ❌ | ✅ | Detected |
| Dependency tree | ⚠️ | ✅ | Proper impl |
Legend:
- ✅ Fully supported
- ⚠️ Partially supported or buggy
- 🚧 In development
- ❌ Not supported
Troubleshooting
Issue: "Cannot find module '@xsanisty/calxjs'"
Solution: Make sure you've installed the package: npm install @xsanisty/calxjs
Issue: TypeScript errors with cell data
Solution: Import and use the DataType enum: import { DataType } from '@xsanisty/calxjs/Cell/DataType';
sheet.createCell('A1', {
value: 100,
type: DataType.NUMBER
});
Issue: Formulas not calculating
Solution: Make sure to call build() before calculate(): workbook.build(); // Build dependency tree
workbook.calculate(); // Then calculate
Issue: Cross-sheet references not working
Solution: Make sure both sheets are in the same workbook: const workbook = Calx.createWorkbook();
const sheet1 = workbook.createSheet('Sheet1');
const sheet2 = workbook.createSheet('Sheet2');
// Now cross-sheet references work
sheet2.createCell('A1', { formula: '=#Sheet1!A1' });
Issue: Custom functions not found
Solution: Register functions before creating workbook: Calx.setFormula('CUSTOM', (a, b) => a + b);
const workbook = Calx.createWorkbook();
// Now CUSTOM() is available in formulas
Need Help?
Gradual Migration Strategy
You can migrate gradually:
-
Phase 1: Install v3.0 alongside v2.x
-
Phase 2: Migrate one sheet/feature at a time
-
Phase 3: Test thoroughly
-
Phase 4: Remove v2.x dependency
Example of running both versions:
// Legacy code (still works)
var legacySheet = new calx.Sheet('#oldTable');
legacySheet.calculate();
// New code
import { Calx } from '@xsanisty/calxjs';
const workbook = Calx.createWorkbook();
const newSheet = workbook.createSheet('NewSheet');
workbook.calculate();
This allows you to migrate at your own pace without breaking existing functionality.
|