UNPKG

@syncfusion/ej2-spreadsheet

Version:

Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel

121 lines (99 loc) 8.91 kB
# Find & Replace Module data flow ## What It Does Provides find and replace/search functionality across the Spreadsheet and Workbook layers, including: - Single-sheet and workbook-wide searches (next/previous), and Find All. - Case-sensitive / case-insensitive search, exact-match and partial-match modes. - Search by row or by column, with start-position control and wrap-around behavior. - Replace single occurrences and Replace All with optional action events and UI confirmation. - UI tool (Find dialog, Find toolbar) integration with Ribbon/Dialogs and lightweight inline find widget. - Counting matches and producing an address collection for Find All or Replace All flows. ## Entry Points **Spreadsheet UI Class (`FindAndReplace`)** - `constructor(parent: Spreadsheet)` — initializes UI state, controls and event listeners. - `addEventListener()` / `removeEventListener()` — wire up UI notifications and native events. - `findToolDlg(args)` — lightweight find toolbar that sits over the sheet panel (quick-find input and prev/next controls). - `renderFindDlg(args?)` — full Find & Replace dialog rendering (Find/Replace/Goto views, options, buttons). - `findandreplaceContent()` / `GotoContent()` — dialog content builders for Find/Replace and Goto. - `findHandler()` / `replaceHandler(action)` — collect UI options and forward find/replace requests to Core via `parent.notify`. - `replaceAllDialog(options)` / `showFindAlert()` — render results/alerts after bulk operations. - `destroy()` / `getModuleName()` — lifecycle helpers. **Workbook Core Class (`WorkbookFindAndReplace`)** - `constructor(parent: Workbook)` — registers core event listeners and holds search state. - `addEventListener()` / `removeEventListener()` — subscribe to core events: `find`, `replace`, `replaceAll`, `count`, `findAllValues`. - `find(args: FindOptionsArgs)` — orchestrates search parameters (sheet/workbook mode), computes start positions, and delegates to `findNext` or `findPrevious`. - `findNext(args, findArgs)` / `findPrevious(args, findArgs)` — top-level traversal across sheets honoring workbook mode and wrapping. - `findNextOnSheet(...)` / `findPrevOnSheet(...)` — scan a single sheet row- or column-wise, skipping hidden rows/columns and honoring activeCell. - `checkMatch(...)` — determine a per-cell match using display text, formatting and locale considerations. - `replace(args)` / `replaceAll(args)` — perform single replacement and Replace All flows, including event triggers, validation, and actual `updateCell`/`updateCellDetails` calls. - `totalCount(args)` — computes counts and the "n of m" display used by the UI. - `findAllValues(findAllArguments)` — gather addresses and values for a Find All operation. - `getDisplayText(cell, rowIdx, colIdx, localeObj)` / `getCellVal(cell, localeObj)` — helpers to obtain formatted display text and canonical searchable values. - `getModuleName()` — module identifier. ## Core Logic Flow ``` User Action (UI quick-find or Find dialog -> Next/Previous/Replace/Replace All) ↓ UI collects options (Find value, Case/Exact, Search within Sheet/Workbook, By Row/Column) ↓ UI -> `parent.notify('find'|'replace'|'replaceAll'| 'count' | 'findAllValues', args)` ↓ WorkbookFindAndReplace.find(args): normalize start, compute `findArgs` + sheets list ↓ Delegates to `findNext` / `findPrevious`: - iterate sheets (if Workbook mode) - call `findNextOnSheet` / `findPrevOnSheet` for per-sheet scan - call `checkMatch` per cell and respect hidden/locked/protected state ↓ Match found -> `parent.notify('goto', { address })` (UI navigates) OR no-match -> `parent.notify('showFindAlert')` ↓ Replace flows: - `replace`: validate protection/read-only, trigger `beginAction` events, call `updateCell` - `replaceAll`: build `addressCollection`, compute `replaceCount`, optionally show replace-confirm dialog, call `updateCellDetails` or `updateCell` (using `requestAnimationFrame` for UI pacing) ↓ UI updates: highlight selection, update count text, show alerts/dialogs ``` ## Operations Handled 1. Initialization & Event Wiring - UI wiring: attaches Find/Goto dialog requests, toolbar find widget, keyboard handlers (`findKeyUp`) and refresh on `activeSheetChanged`. - Core wiring: listens for `find`, `replace`, `replaceAll`, `count`, and `findAllValues` notifications. 2. Search State & Parameters - UI collects: `value`, `mode` (`Sheet|Workbook`), `isCSen` (case), `isEMatch` (exact), `searchBy` (`By Row|By Column`), `findOpt` (`next|previous`), `sheetIndex`. - Core normalizes: `startRow`, `startCol`, `findVal` (lowercased when not case-sensitive), `sheets` array, and `sheetIdx` for current sheet. 3. Scanning & Matching - Per-sheet scanning performed by `findNextOnSheet` / `findPrevOnSheet` using either row-major or column-major order. - Skip hidden rows/columns (`isHiddenRow` / `isHiddenCol`) and protect/locked cells checks (`isLocked`, `isReadOnly`). - `checkMatch` compares either the display text (`getDisplayText`) or raw cell value (`getCellVal`) depending on formatting and `isCSen`/`isEMatch` options. - Handle wrapped searches across sheet boundaries when workbook mode provided. 4. Replace & Replace All - Single `replace` validates protection and readonly state, optionally fires `beginAction` and `actionComplete` notifications, and calls `updateCell` to persist the replacement. - `replaceAll` builds an `addressCollection`, matches each target (using regex/contains rules consistent with case/exact options), and applies changes asynchronously for large sets using `requestAnimationFrame` where available. - `replaceAll` informs UI via `replaceAllDialog` with replacement counts and optionally triggers `actionBegin` with `beforeReplaceAll`. 5. Counting & Find All - `totalCount` iterates sheet rows/cells and computes `count` and `totalCount` using the same matching heuristics as search. - `findAllValues` returns a collection of matching cell addresses and values for UI consumption (Find All list). 6. UI Presentation & Interaction - Full Find dialog: options, Replace, Replace All buttons, Goto tab, and result messages (`showFindAlert`, `replaceAllDialog`). - Lightweight Find toolbar (`findToolDlg`): inline input, previous/next buttons, quick-count updates. - Dialog lifecycle: beforeOpen/beforeClose/close hooks to maintain focus and selection. ## Validation & Safety - Prevent operations on protected sheets: check `sheet.isProtected` and `protectSettings`; show `workBookeditAlert` or `workbookReadonlyAlert` as applicable. - Respect read-only cells and locked columns/rows; abort or skip replacements when `isReadOnly` or `isLocked` prevents changes. - Skip hidden rows/columns during scans to mimic visible search behavior. - Handle formatted cells and localized numbers/dates: use `getFormattedCellObject` / `getNumericObject` and `getCellVal` to compare canonical values (decimal separators, date formatting). - Avoid replacing while the workbook is in edit mode; UI prevents searching while in-cell edit state. - Replace All uses batched updates and optional async pacing to avoid blocking the UI and to keep animation/visual updates responsive. ## Desired Outputs User-Facing: - Keyboard + dialog driven Find/Replace that mirrors typical spreadsheet apps (next/previous, match-case, whole-cell match). - Clear Replace All confirmation with counts and final summary messages. - Inline quick-find toolbar for fast navigation and a full dialog for advanced options. System-Level: - `FindAndReplace` (UI) and `WorkbookFindAndReplace` (Core) as distinct responsibilities: UI gathers options and renders dialogs; Core executes searches and mutations. - Notifications used: `find`, `replace`, `replaceAll`, `count`, `findAllValues`, `goto`, `showFindAlert`, `replaceAllDialog`, `beginAction`/`actionComplete`. - `addressCollection` (array of cell addresses) produced for Replace All / Find All flows. - Match helpers: `getDisplayText`, `getCellVal` and `checkMatch` used consistently across count, find, and replace operations. - Async-safe replace flow using `requestAnimationFrame` and `updateCellDetails`/`updateCell`. ## Implementation Notes / Integration Points - UI components referenced: `Dialog`, `Toolbar`, `TextBox`, `DropDownList`, `CheckBox`, and a `FindDialog` wrapper class. - Core helpers and utilities: `getCell`, `getCellAddress`, `getRangeIndexes`, `getCellIndexes`, `isHiddenRow`, `isHiddenCol`, `isLocked`, `isReadOnly`, `updateCell`, `updateCellDetails`, `getFormattedCellObject`, `getNumericObject`. - Events the rest of the system may listen to: navigation (`goto`), replacement lifecycle (`beginAction` with `beforeReplace`/`beforeReplaceAll`, `actionComplete`), and UI alerts.