@syncfusion/ej2-spreadsheet
Version:
Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel
142 lines (111 loc) • 8.6 kB
Markdown
# Edit Module data flow
## What It Does
Provides in-cell and formula-bar editing support across the Spreadsheet UI and Workbook core, including:
- Inline cell editing, multi-line entry (Alt+Enter), and formula editing with autocomplete.
- Coordination between Spreadsheet UI (`src/spreadsheet/`) and Workbook core (`src/workbook/`) for model updates, formula computation, and formatting.
- Validation (data validation rules, read-only/protected sheets), formula error handling, and undo/redo integration.
- Special handling for dynamic functions (e.g., UNIQUE spill ranges, #SPILL!), date/number formatting inference, hyperlinks, and manual-calculation scenarios.
## Entry Points
**UI Layer — `Edit` (Spreadsheet)**
- `constructor(parent: Spreadsheet)` — initializes editor state, DOM/editor element, and event listeners.
- `addEventListener()` / `removeEventListener()` — wire UI events and spreadsheet notifications (mouse/keyboard, editOperation, editValue, addressHandler, initiateCur, etc.).
- `startEdit(address?, value?)` — prepare `editCellData`, render editor, position editor, enable edit mode.
- `renderEditor()` / `refreshEditor()` — create or update the contentEditable editor element and sync formula bar.
- `endEdit(refreshFormulaBar?)` / `cancelEdit()` — commit or abort edits, trigger validation, reset edit state.
- `updateEditedValue()` / `updateCell()` — orchestrate validations, formula detection, and delegate commit to core via events.
- `triggerEvent(eventName, ...)` — central method that prepares `beforeCellSave` / `cellSave` style payloads for event listeners and callers.
- `checkUniqueRange()` / `reApplyFormula()` — handle UNIQUE function reapply and spilled-range bookkeeping in the UI.
- Helpers: `getEditElement()`, `positionEditor()`, `setCursorPosition()`, `getCurPosition()`.
**Core Layer — `WorkbookEdit` (Workbook)**
- `constructor(workbook: Workbook)` — set up listener for workbook-level edit operations.
- `addEventListener()` / `removeEventListener()` — listen for `workbookEditOperation` events from UI layer.
- `performEditOperation(args)` — route edit actions; primary action: `updateCellValue`.
- `updateCellValue(address, value, sheetIdx?, isValueOnly?, ...)` — apply value/formula to `SheetModel` cells, perform format inference, date/number checks, unique/spill handling, notify `workbookFormulaOperation` for recalculation, and update charts/used-range.
**Cross-layer Notifications / Events (selected)**
- `workbookEditOperation` — UI → Core to request cell updates.
- `workbookFormulaOperation` — Core/Calc engine notifications to compute or refresh formulas.
- `checkDateFormat`, `getFormattedCellObject`, `checkNumberFormat` — formatting/locale conversion hooks invoked by core during value application.
- `checkUniqueRange` — request to evaluate UNIQUE spill interactions.
- `refreshChart` — notify chart layer when values change.
- `setLinkModel` — auto-convert detected URLs to hyperlinks.
## Core Logic Flow
```
User Action (double-click / F2 / formula bar / paste / programmatic update)
↓
UI.startEdit() -> create editor DOM and populate with cell value
↓
User types / formula autocomplete / ref selection
↓
UI.endEdit() -> UI.updateEditedValue() (validation & formula checks)
↓
If valid and needs model update -> UI triggers workbookEditOperation (updateCellValue)
↓
Workbook.updateCellValue():
- Determine if value is formula or literal
- Normalize value (parseIntValue, date/number inference)
- Update cell.value / cell.formula / cell.format as needed
- Invoke format helpers: checkDateFormat, getFormattedCellObject, checkNumberFormat
- If formula -> notify workbookFormulaOperation (computeExpression / refreshCalculate)
- Handle UNIQUE/spill logic and checkUniqueRange
- Update used range, charts via refreshChart
↓
Async formula compute may update dependent cells and charts
↓
UI receives final updates (via notifications) -> re-render cell(s)/formula bar
```
## Operations Handled
1. Editor lifecycle
- Render inline editor and sync with formula bar; support multi-line and selection cursor positioning.
- Positioning for merged/hidden cells and template-protected cells.
2. Value & Formula Commit
- Detect formulas (`=`), compute if needed, and store `cell.formula` and `cell.value` appropriately.
- Respect `Text` format which disables formula interpretation.
- Handle special tokens: `#SPILL!`, UNIQUE(...) results and spilled ranges.
3. Formatting & Locale
- Infer number, currency, percentage, and date formats using locale numeric settings.
- Route format conversion through `getFormattedCellObject`, `checkDateFormat`, `checkNumberFormat`.
4. Validation & Alerts
- Run data-validation rules before commit; show validation dialogs when blocked.
- Detect formula parsing errors and show formula-alert dialogs with localized messages.
5. Undo/Redo and Action Data
- Prepare before/after action payloads for undo/redo (`setActionData`, `cellInformation`), including cut/copy interactions.
6. Hyperlink & Link Model
- Auto-detect URL-like values and call `setLinkModel` to create hyperlinks when committing text values.
7. Manual Calculation & Deferred Evaluation
- In Manual calc mode, optionally skip recalculation and persist formula text; support redo/undo flows restoring displayText.
8. Dependent Updates
- Trigger recalculation of dependent formulas and refresh charts when values change.
9. Edge cases
- Edits on protected/read-only sheets, template cells, merged-hidden cells, and edits while another modal or edit session is active.
## Validation & Safety
- Prevent committing edits while `parent.isEdit` is inconsistent, or when modal dialogs or overlays are present.
- Block edits on protected sheets or locked cells and show `readonlyAlert` where applicable.
- Sanity checks for merged/hidden cells and template-protected ranges; avoid corrupting merged state.
- Reject or surface formula parsing errors via `showFormulaAlertDlg` and `formulaErrorStrings`.
- Avoid unbounded recalculation loops by coordinating `isDependentUpdate`, manual calc flags, and `isRandomFormula` markers.
- Preserve undo/redo integrity by capturing `beforeCellSave` and `cellSave` payloads and including `cellInformation` for redo flows.
## Desired Outputs
User-Facing:
- Seamless inline editing experience like a spreadsheet: F2/double-click, formula bar sync, multi-line entry, formula autocomplete and reference selection.
- Immediate formatting feedback when applicable (dates, numbers, currency), and informative formula error dialogs.
- Correct spill behavior for dynamic array functions (UNIQUE, FILTER) and visible indicators for spilled ranges.
System-Level:
- `editCellData` state object (row/col/addr/value/oldValue/element) maintained by UI.
- `workbookEditOperation` events sent from UI; `updateCellValue` applied in Workbook core.
- Notifications chain: `workbookFormulaOperation`, `checkDateFormat`, `getFormattedCellObject`, `checkUniqueRange`, `refreshChart`, `setLinkModel`.
- Updated `SheetModel` cells with `value`, `formula`, `format`, and `formattedText` where appropriate.
- Consistent undo/redo action entries and integration points (`setActionData`, `BeforeActionData` payloads).
## UX Considerations & Integration Notes
- Formula bar and inline editor must remain synchronized: edits in one reflect in the other and share cursor/selection state.
- Avoid triggering full recalculation on minor edits when in Manual mode; expose appropriate UX for "Calculate Now" actions.
- Ensure editor DOM is cleaned up on `destroy()` and that listeners are removed via `removeEventListener()`.
- Handle mobile/safari/iOS quirks (editor focus, selection handling) as special-cased in UI listeners.
## Minimal Test Scenarios
- Edit a plain text cell, commit, and verify `cell.value` and UI update.
- Enter `=1+1` in a cell, commit, and verify `cell.formula` and computed `cell.value`.
- Type a date string and verify `checkDateFormat` converts it to locale date value and format.
- Enter a URL text and verify `setLinkModel` creates a hyperlink.
- Edit a UNIQUE formula produce spill; verify `checkUniqueRange` and reapply flows handle spilled region.
- Perform edits with sheet protection/read-only cells and confirm alerts/prevention.
---
Generated from UI (`src/spreadsheet/actions/edit.ts`) and Core (`src/workbook/actions/edit.ts`) implementations, capturing events and helpers used across both layers.