UNPKG

@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
# 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.