diff --git a/CHANGELOG.md b/CHANGELOG.md index 74dbb6c82..d31e0414d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.2.0](https://github.com/6pac/SlickGrid/compare/5.1.0...5.2.0) (2023-10-21) + +### Bug Fixes + +* add `containerCssClass` to RowMove to fix cell styling issue with icons ([#865](https://github.com/6pac/SlickGrid/issues/865)) ([5abad6d](https://github.com/6pac/SlickGrid/commit/5abad6d65fdb36e68e0186e69b1fdbe542fc1bfa)) +* argument of `getViewportNode()` should all be optional ([#860](https://github.com/6pac/SlickGrid/issues/860)) ([09e7617](https://github.com/6pac/SlickGrid/commit/09e7617fb978b6a9cc8f71bcc9ed4ec056c875db)) +* CellSelectionModel calculate page row count only once ([#858](https://github.com/6pac/SlickGrid/issues/858)) ([65c2382](https://github.com/6pac/SlickGrid/commit/65c2382386f45e6bae20995323515b1533b4d227)) +* should use strict ESLint & TypeScript code ([#863](https://github.com/6pac/SlickGrid/issues/863)) ([f1abfd8](https://github.com/6pac/SlickGrid/commit/f1abfd8e723a2c4f60c52700cfc290db6ad32d32)) + +### Features + +* add sub-menu(s) to CellMenu & ContextMenu plugins ([#867](https://github.com/6pac/SlickGrid/issues/867)) ([0309ec4](https://github.com/6pac/SlickGrid/commit/0309ec47470ba61b47eb22bf82f253d0c733171f)) +* add sub-menu(s) to GridMenu control ([#868](https://github.com/6pac/SlickGrid/issues/868)) ([24f30f6](https://github.com/6pac/SlickGrid/commit/24f30f6220b627c3e9c1b2d5d684ed9c04b67d10)) +* add sub-menu(s) to HeaderMenu plugin ([#869](https://github.com/6pac/SlickGrid/issues/869)) ([6eaee7a](https://github.com/6pac/SlickGrid/commit/6eaee7aaeba975152fcb3bfd64f09b1896443189)) + # [5.1.0](https://github.com/6pac/SlickGrid/compare/5.0.1...5.1.0) (2023-10-03) ### Bug Fixes diff --git a/dist/browser/controls/slick.columnmenu.js b/dist/browser/controls/slick.columnmenu.js index 74af03d5e..0f854e2b4 100644 --- a/dist/browser/controls/slick.columnmenu.js +++ b/dist/browser/controls/slick.columnmenu.js @@ -60,7 +60,7 @@ let liElm = document.createElement("li"); liElm.className = excludeCssClass, liElm.ariaLabel = ((_a = this.columns[i]) == null ? void 0 : _a.name) || ""; let checkboxElm = document.createElement("input"); - checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this._columnCheckboxes.push(checkboxElm), this.grid.getColumnIndex(columnId) != null && !this.columns[i].hidden && (checkboxElm.checked = !0), (_c = (_b = this._options) == null ? void 0 : _b.columnPicker) != null && _c.headerColumnValueExtractor ? columnLabel = this._options.columnPicker.headerColumnValueExtractor(this.columns[i], this._options) : columnLabel = this._defaults.headerColumnValueExtractor(this.columns[i], this._options); + checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this._columnCheckboxes.push(checkboxElm), Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden && (checkboxElm.checked = !0), (_c = (_b = this._options) == null ? void 0 : _b.columnPicker) != null && _c.headerColumnValueExtractor ? columnLabel = this._options.columnPicker.headerColumnValueExtractor(this.columns[i], this._options) : columnLabel = this._defaults.headerColumnValueExtractor(this.columns[i], this._options); let labelElm = document.createElement("label"); labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`, labelElm.innerHTML = columnLabel, liElm.appendChild(labelElm), this._listElm.appendChild(liElm); } diff --git a/dist/browser/controls/slick.columnmenu.js.map b/dist/browser/controls/slick.columnmenu.js.map index 5147d0b57..007923f11 100644 --- a/dist/browser/controls/slick.columnmenu.js.map +++ b/dist/browser/controls/slick.columnmenu.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/controls/slick.columnmenu.ts"], - "sourcesContent": ["import { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { Column, ColumnPickerOption, DOMMouseOrTouchEvent, GridOption, OnColumnsChangedArgs } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * A control to add a Column Picker (right+click on any column header to reveal the column picker)\n * NOTE: this a simplified and updated version of slick.columnpicker.js\n *\n * USAGE:\n *\n * Add the slick.columnpicker.(js|css) files and register it with the grid.\n *\n * Available options, by defining a columnPicker object:\n *\n * let options = {\n * enableCellNavigation: true,\n * columnPicker: {\n * columnTitle: \"Columns\", // default to empty string\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\" (default:false)\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\" (default:false)\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * headerColumnValueExtractor: \"Extract the column label\" // default to column.name\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n * }\n * };\n */\n\nexport class SlickColumnMenu {\n // --\n // public API\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _gridUid: string;\n protected _columnTitleElm!: HTMLElement;\n protected _listElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _bindingEventService = new BindingEventService();\n protected _options: GridOption;\n protected _defaults: ColumnPickerOption = {\n fadeSpeed: 250,\n\n // the last 2 checkboxes titles\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n syncResizeTitle: 'Synchronous resize',\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name || ''\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, options: GridOption) {\n this._gridUid = grid.getUID();\n this._options = Utils.extend({}, this._defaults, options);\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n grid.onHeaderContextMenu.subscribe(this.handleHeaderContextMenu.bind(this));\n grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-columnpicker ${this._gridUid}`;\n this._menuElm.style.display = 'none';\n document.body.appendChild(this._menuElm);\n\n const buttonElm = document.createElement('button');\n buttonElm.type = 'button';\n buttonElm.className = 'close';\n buttonElm.dataset.dismiss = 'slick-columnpicker';\n buttonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.innerHTML = '×';\n buttonElm.appendChild(spanCloseElm);\n this._menuElm.appendChild(buttonElm);\n\n // user could pass a title on top of the columns list\n if (this._options.columnPickerTitle || (this._options.columnPicker?.columnTitle)) {\n const columnTitle = this._options.columnPickerTitle || this._options.columnPicker?.columnTitle;\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'slick-gridmenu-custom';\n this._columnTitleElm.textContent = columnTitle || '';\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-columnpicker-list';\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n destroy() {\n this.grid.onHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this));\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this._bindingEventService.unbindAll();\n this._listElm?.remove();\n this._menuElm?.remove();\n }\n\n handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n if ((this._menuElm !== e.target && !(this._menuElm && this._menuElm.contains(e.target))) || e.target.className === 'close') {\n this._menuElm.setAttribute('aria-expanded', 'false');\n this._menuElm.style.display = 'none';\n }\n }\n\n handleHeaderContextMenu(e: DOMMouseOrTouchEvent) {\n e.preventDefault();\n Utils.emptyElement(this._listElm);\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n excludeCssClass = this.columns[i].excludeFromColumnPicker ? \"hidden\" : \"\";\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = this.columns[i]?.name || '';\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n this._columnCheckboxes.push(checkboxElm);\n\n if (this.grid.getColumnIndex(columnId) != null && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n if (this._options?.columnPicker?.headerColumnValueExtractor) {\n columnLabel = this._options.columnPicker.headerColumnValueExtractor(this.columns[i], this._options);\n } else {\n columnLabel = this._defaults.headerColumnValueExtractor!(this.columns[i], this._options);\n }\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`;\n labelElm.innerHTML = columnLabel;\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._options.columnPicker && (!this._options.columnPicker.hideForceFitButton || !this._options.columnPicker.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!this._options.columnPicker?.hideForceFitButton) {\n const forceFitTitle = this._options.columnPicker?.forceFitTitle || this._options.forceFitTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle || '';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`;\n labelElm.textContent = forceFitTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!this._options.columnPicker?.hideSyncResizeButton) {\n const syncResizeTitle = this._options.columnPicker?.syncResizeTitle || this._options.syncResizeTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle || '';\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n this.repositionMenu(e);\n }\n\n repositionMenu(event: DOMMouseOrTouchEvent) {\n const targetEvent = event?.touches?.[0] || event;\n this._menuElm.style.top = `${targetEvent.pageY - 10}px`;\n this._menuElm.style.left = `${targetEvent.pageX - 10}px`;\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY}px`;\n this._menuElm.style.display = 'block';\n this._menuElm.setAttribute('aria-expanded', 'true');\n this._menuElm.appendChild(this._listElm);\n }\n\n updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n /** Update the Titles of each sections (command, customTitle, ...) */\n updateAllTitles(pickerOptions: { columnTitle: string; }) {\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = pickerOptions.columnTitle;\n }\n }\n\n updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked = e.target.checked;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n if (e.target.checked) {\n this.grid.setOptions({ syncColumnCellResize: true });\n } else {\n this.grid.setOptions({ syncColumnCellResize: false });\n }\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (this.columns[idx].hidden !== undefined) { this.columns[idx].hidden = !columnCheckbox.checked; }\n if (columnCheckbox.checked) {\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId: columnId, showing: isChecked, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n }\n\n setColumnVisibiliy(idxOrId: number | string, show: boolean) {\n const idx = typeof idxOrId === 'number' ? idxOrId : this.getColumnIndexbyId(idxOrId);\n let visibleColumns: Column[] = this.getVisibleColumns();\n const col = this.columns[idx];\n if (show) {\n col.hidden = false;\n visibleColumns.splice(idx, 0, col);\n } else {\n const newVisibleColumns: Column[] = [];\n for (let i = 0; i < visibleColumns.length; i++) {\n if (visibleColumns[i].id !== col.id) { newVisibleColumns.push(visibleColumns[i]); }\n }\n visibleColumns = newVisibleColumns;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId: col.id, showing: show, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n getColumnbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return this.columns[i]; }\n }\n return null;\n }\n\n getColumnIndexbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return i; }\n }\n return -1;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.ColumnPicker = SlickColumnMenu;\n}\n"], - "mappings": "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", + "sourcesContent": ["import { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { Column, ColumnPickerOption, DOMMouseOrTouchEvent, GridOption, OnColumnsChangedArgs } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * A control to add a Column Picker (right+click on any column header to reveal the column picker)\n * NOTE: this a simplified and updated version of slick.columnpicker.js\n *\n * USAGE:\n *\n * Add the slick.columnpicker.(js|css) files and register it with the grid.\n *\n * Available options, by defining a columnPicker object:\n *\n * let options = {\n * enableCellNavigation: true,\n * columnPicker: {\n * columnTitle: \"Columns\", // default to empty string\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\" (default:false)\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\" (default:false)\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * headerColumnValueExtractor: \"Extract the column label\" // default to column.name\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n * }\n * };\n */\n\nexport class SlickColumnMenu {\n // --\n // public API\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _gridUid: string;\n protected _columnTitleElm!: HTMLElement;\n protected _listElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _bindingEventService = new BindingEventService();\n protected _options: GridOption;\n protected _defaults: ColumnPickerOption = {\n fadeSpeed: 250,\n\n // the last 2 checkboxes titles\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n syncResizeTitle: 'Synchronous resize',\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name || ''\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, options: GridOption) {\n this._gridUid = grid.getUID();\n this._options = Utils.extend({}, this._defaults, options);\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n grid.onHeaderContextMenu.subscribe(this.handleHeaderContextMenu.bind(this));\n grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-columnpicker ${this._gridUid}`;\n this._menuElm.style.display = 'none';\n document.body.appendChild(this._menuElm);\n\n const buttonElm = document.createElement('button');\n buttonElm.type = 'button';\n buttonElm.className = 'close';\n buttonElm.dataset.dismiss = 'slick-columnpicker';\n buttonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.innerHTML = '×';\n buttonElm.appendChild(spanCloseElm);\n this._menuElm.appendChild(buttonElm);\n\n // user could pass a title on top of the columns list\n if (this._options.columnPickerTitle || (this._options.columnPicker?.columnTitle)) {\n const columnTitle = this._options.columnPickerTitle || this._options.columnPicker?.columnTitle;\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'slick-gridmenu-custom';\n this._columnTitleElm.textContent = columnTitle || '';\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-columnpicker-list';\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n destroy() {\n this.grid.onHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this));\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this._bindingEventService.unbindAll();\n this._listElm?.remove();\n this._menuElm?.remove();\n }\n\n handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n if ((this._menuElm !== e.target && !(this._menuElm && this._menuElm.contains(e.target))) || e.target.className === 'close') {\n this._menuElm.setAttribute('aria-expanded', 'false');\n this._menuElm.style.display = 'none';\n }\n }\n\n handleHeaderContextMenu(e: DOMMouseOrTouchEvent) {\n e.preventDefault();\n Utils.emptyElement(this._listElm);\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n excludeCssClass = this.columns[i].excludeFromColumnPicker ? \"hidden\" : \"\";\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = this.columns[i]?.name || '';\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n this._columnCheckboxes.push(checkboxElm);\n\n if (Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n if (this._options?.columnPicker?.headerColumnValueExtractor) {\n columnLabel = this._options.columnPicker.headerColumnValueExtractor(this.columns[i], this._options);\n } else {\n columnLabel = this._defaults.headerColumnValueExtractor!(this.columns[i], this._options);\n }\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`;\n labelElm.innerHTML = columnLabel;\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._options.columnPicker && (!this._options.columnPicker.hideForceFitButton || !this._options.columnPicker.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!this._options.columnPicker?.hideForceFitButton) {\n const forceFitTitle = this._options.columnPicker?.forceFitTitle || this._options.forceFitTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle || '';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`;\n labelElm.textContent = forceFitTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!this._options.columnPicker?.hideSyncResizeButton) {\n const syncResizeTitle = this._options.columnPicker?.syncResizeTitle || this._options.syncResizeTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle || '';\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n this.repositionMenu(e);\n }\n\n repositionMenu(event: DOMMouseOrTouchEvent) {\n const targetEvent = event?.touches?.[0] || event;\n this._menuElm.style.top = `${targetEvent.pageY - 10}px`;\n this._menuElm.style.left = `${targetEvent.pageX - 10}px`;\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY}px`;\n this._menuElm.style.display = 'block';\n this._menuElm.setAttribute('aria-expanded', 'true');\n this._menuElm.appendChild(this._listElm);\n }\n\n updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n /** Update the Titles of each sections (command, customTitle, ...) */\n updateAllTitles(pickerOptions: { columnTitle: string; }) {\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = pickerOptions.columnTitle;\n }\n }\n\n updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked = e.target.checked;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n if (e.target.checked) {\n this.grid.setOptions({ syncColumnCellResize: true });\n } else {\n this.grid.setOptions({ syncColumnCellResize: false });\n }\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (this.columns[idx].hidden !== undefined) { this.columns[idx].hidden = !columnCheckbox.checked; }\n if (columnCheckbox.checked) {\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId, showing: isChecked, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n }\n\n setColumnVisibiliy(idxOrId: number | string, show: boolean) {\n const idx = typeof idxOrId === 'number' ? idxOrId : this.getColumnIndexbyId(idxOrId);\n let visibleColumns: Column[] = this.getVisibleColumns();\n const col = this.columns[idx];\n if (show) {\n col.hidden = false;\n visibleColumns.splice(idx, 0, col);\n } else {\n const newVisibleColumns: Column[] = [];\n for (let i = 0; i < visibleColumns.length; i++) {\n if (visibleColumns[i].id !== col.id) { newVisibleColumns.push(visibleColumns[i]); }\n }\n visibleColumns = newVisibleColumns;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId: col.id, showing: show, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n getColumnbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return this.columns[i]; }\n }\n return null;\n }\n\n getColumnIndexbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return i; }\n }\n return -1;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.ColumnPicker = SlickColumnMenu;\n}\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/controls/slick.columnpicker.js b/dist/browser/controls/slick.columnpicker.js index 32e475470..33f18c506 100644 --- a/dist/browser/controls/slick.columnpicker.js +++ b/dist/browser/controls/slick.columnpicker.js @@ -61,7 +61,7 @@ let liElm = document.createElement("li"); liElm.className = excludeCssClass, liElm.ariaLabel = ((_a = this.columns[i]) == null ? void 0 : _a.name) || ""; let checkboxElm = document.createElement("input"); - checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this._columnCheckboxes.push(checkboxElm), this.grid.getColumnIndex(columnId) != null && !this.columns[i].hidden && (checkboxElm.checked = !0), (_c = (_b = this._gridOptions) == null ? void 0 : _b.columnPicker) != null && _c.headerColumnValueExtractor ? columnLabel = this._gridOptions.columnPicker.headerColumnValueExtractor(this.columns[i], this._gridOptions) : columnLabel = this._defaults.headerColumnValueExtractor(this.columns[i], this._gridOptions); + checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this._columnCheckboxes.push(checkboxElm), Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden && (checkboxElm.checked = !0), (_c = (_b = this._gridOptions) == null ? void 0 : _b.columnPicker) != null && _c.headerColumnValueExtractor ? columnLabel = this._gridOptions.columnPicker.headerColumnValueExtractor(this.columns[i], this._gridOptions) : columnLabel = this._defaults.headerColumnValueExtractor(this.columns[i], this._gridOptions); let labelElm = document.createElement("label"); labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`, labelElm.innerHTML = columnLabel, liElm.appendChild(labelElm), this._listElm.appendChild(liElm); } diff --git a/dist/browser/controls/slick.columnpicker.js.map b/dist/browser/controls/slick.columnpicker.js.map index 8f18806c9..861132a00 100644 --- a/dist/browser/controls/slick.columnpicker.js.map +++ b/dist/browser/controls/slick.columnpicker.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/controls/slick.columnpicker.ts"], - "sourcesContent": ["import { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { Column, ColumnPickerOption, DOMMouseOrTouchEvent, GridOption, OnColumnsChangedArgs } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * A control to add a Column Picker (right+click on any column header to reveal the column picker)\n * NOTE: this is the old 'complex' column pciker that hides columns by removing them from the grid\n * for a more modern version that uses the column.hidden property and is a lot simpler, use slick.columnmenu.js\n *\n * USAGE:\n *\n * Add the slick.columnpicker.(js|css) files and register it with the grid.\n *\n * Available options, by defining a columnPicker object:\n *\n * let options = {\n * enableCellNavigation: true,\n * columnPicker: {\n * columnTitle: \"Columns\", // default to empty string\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\" (default:false)\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\" (default:false)\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * headerColumnValueExtractor: \"Extract the column label\" // default to column.name\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n * }\n * };\n */\n\nexport class SlickColumnPicker {\n // --\n // public API\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _gridUid: string;\n protected _columnTitleElm!: HTMLElement;\n protected _listElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _bindingEventService = new BindingEventService();\n protected _gridOptions: GridOption;\n protected _defaults: ColumnPickerOption = {\n fadeSpeed: 250,\n\n // the last 2 checkboxes titles\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n syncResizeTitle: 'Synchronous resize',\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name || ''\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, gridOptions: GridOption) {\n this._gridUid = grid.getUID();\n this._gridOptions = Utils.extend({}, this._defaults, gridOptions);\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n grid.onHeaderContextMenu.subscribe(this.handleHeaderContextMenu.bind(this));\n grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-columnpicker ${this._gridUid}`;\n this._menuElm.style.display = 'none';\n document.body.appendChild(this._menuElm);\n\n const buttonElm = document.createElement('button');\n buttonElm.type = 'button';\n buttonElm.className = 'close';\n buttonElm.dataset.dismiss = 'slick-columnpicker';\n buttonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.innerHTML = '×';\n buttonElm.appendChild(spanCloseElm);\n this._menuElm.appendChild(buttonElm);\n\n // user could pass a title on top of the columns list\n if (this._gridOptions.columnPickerTitle || (this._gridOptions.columnPicker?.columnTitle)) {\n const columnTitle = this._gridOptions.columnPickerTitle || this._gridOptions.columnPicker?.columnTitle;\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'slick-gridmenu-custom';\n this._columnTitleElm.textContent = columnTitle || '';\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-columnpicker-list';\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n destroy() {\n this.grid.onHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this));\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this._bindingEventService.unbindAll();\n this._listElm?.remove();\n this._menuElm?.remove();\n }\n\n protected handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n if ((this._menuElm !== e.target && !this._menuElm?.contains(e.target)) || e.target.className === 'close') {\n this._menuElm.setAttribute('aria-expanded', 'false');\n this._menuElm.style.display = 'none';\n }\n }\n\n protected handleHeaderContextMenu(e: DOMMouseOrTouchEvent) {\n e.preventDefault();\n Utils.emptyElement(this._listElm);\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n excludeCssClass = this.columns[i].excludeFromColumnPicker ? 'hidden' : '';\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = this.columns[i]?.name || '';\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n this._columnCheckboxes.push(checkboxElm);\n\n if (this.grid.getColumnIndex(columnId) != null && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n if (this._gridOptions?.columnPicker?.headerColumnValueExtractor) {\n columnLabel = this._gridOptions.columnPicker.headerColumnValueExtractor(this.columns[i], this._gridOptions);\n } else {\n columnLabel = this._defaults.headerColumnValueExtractor!(this.columns[i], this._gridOptions);\n }\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`;\n labelElm.innerHTML = columnLabel;\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._gridOptions.columnPicker && (!this._gridOptions.columnPicker.hideForceFitButton || !this._gridOptions.columnPicker.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!(this._gridOptions.columnPicker?.hideForceFitButton)) {\n const forceFitTitle = this._gridOptions.columnPicker?.forceFitTitle || this._gridOptions.forceFitTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle || '';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`;\n labelElm.textContent = forceFitTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!(this._gridOptions.columnPicker?.hideSyncResizeButton)) {\n const syncResizeTitle = (this._gridOptions.columnPicker?.syncResizeTitle) || this._gridOptions.syncResizeTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle || '';\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n this.repositionMenu(e);\n }\n\n protected repositionMenu(event: DOMMouseOrTouchEvent) {\n const targetEvent: MouseEvent | Touch = (event as TouchEvent)?.touches?.[0] ?? event;\n this._menuElm.style.top = `${targetEvent.pageY - 10}px`;\n this._menuElm.style.left = `${targetEvent.pageX - 10}px`;\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY}px`;\n this._menuElm.style.display = 'block';\n this._menuElm.setAttribute('aria-expanded', 'true');\n this._menuElm.appendChild(this._listElm);\n }\n\n protected updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n /** Update the Titles of each sections (command, customTitle, ...) */\n updateAllTitles(pickerOptions: { columnTitle: string; }) {\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = pickerOptions.columnTitle;\n }\n }\n\n protected updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked: boolean = e.target.checked || false;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n if (e.target.checked) {\n this.grid.setOptions({ syncColumnCellResize: true });\n } else {\n this.grid.setOptions({ syncColumnCellResize: false });\n }\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (this.columns[idx].hidden !== undefined) { this.columns[idx].hidden = !columnCheckbox.checked; }\n if (columnCheckbox.checked) {\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId: columnId, showing: isChecked, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n }\n\n setColumnVisibiliy(idxOrId: number | string, show: boolean) {\n const idx = typeof idxOrId === 'number' ? idxOrId : this.getColumnIndexbyId(idxOrId);\n let visibleColumns = this.getVisibleColumns();\n const col = this.columns[idx];\n if (show) {\n col.hidden = false;\n visibleColumns.splice(idx, 0, col);\n } else {\n const newVisibleColumns: Column[] = [];\n for (let i = 0; i < visibleColumns.length; i++) {\n if (visibleColumns[i].id !== col.id) { newVisibleColumns.push(visibleColumns[i]); }\n }\n visibleColumns = newVisibleColumns;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId: col.id, showing: show, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n getColumnbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return this.columns[i]; }\n }\n return null;\n }\n\n getColumnIndexbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return i; }\n }\n return -1;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.ColumnPicker = SlickColumnPicker;\n}\n"], - "mappings": ";;;;;;;AAKA,MAAM,sBAAkC,MAAM,qBACxC,aAAyB,MAAM,OAC/B,QAAoB,MAAM,OA4BnB,oBAAN,MAAwB;AAAA,IAyB7B,YAAsB,SAAsC,MAAiB,aAAyB;AAAhF;AAAsC;AAtB5D;AAAA;AAAA,8CAAmB,IAAI,WAAiC;AAIxD;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU,qBAAwC,CAAC;AACnD,0BAAU,wBAAuB,IAAI,oBAAoB;AACzD,0BAAU;AACV,0BAAU,aAAgC;AAAA,QACxC,WAAW;AAAA;AAAA,QAGX,oBAAoB;AAAA,QACpB,sBAAsB;AAAA,QACtB,eAAe;AAAA,QACf,iBAAiB;AAAA,QACjB,4BAA4B,CAAC,cAAsB,UAAU,QAAQ;AAAA,MACvE;AAGE,WAAK,WAAW,KAAK,OAAO,GAC5B,KAAK,eAAe,MAAM,OAAO,CAAC,GAAG,KAAK,WAAW,WAAW,GAChE,KAAK,KAAK,KAAK,IAAI;AAAA,IACrB;AAAA,IAEA,KAAK,MAAiB;AAlExB;AAmEI,WAAK,oBAAoB,UAAU,KAAK,wBAAwB,KAAK,IAAI,CAAC,GAC1E,KAAK,mBAAmB,UAAU,KAAK,kBAAkB,KAAK,IAAI,CAAC,GAEnE,KAAK,WAAW,SAAS,cAAc,KAAK,GAC5C,KAAK,SAAS,YAAY,sBAAsB,KAAK,QAAQ,IAC7D,KAAK,SAAS,MAAM,UAAU,QAC9B,SAAS,KAAK,YAAY,KAAK,QAAQ;AAEvC,UAAM,YAAY,SAAS,cAAc,QAAQ;AACjD,gBAAU,OAAO,UACjB,UAAU,YAAY,SACtB,UAAU,QAAQ,UAAU,sBAC5B,UAAU,YAAY;AAEtB,UAAM,eAAe,SAAS,cAAc,MAAM;AAQlD,UAPA,aAAa,YAAY,SACzB,aAAa,aAAa,QAC1B,aAAa,YAAY,WACzB,UAAU,YAAY,YAAY,GAClC,KAAK,SAAS,YAAY,SAAS,GAG/B,KAAK,aAAa,sBAAsB,UAAK,aAAa,iBAAlB,WAAgC,aAAc;AACxF,YAAM,cAAc,KAAK,aAAa,uBAAqB,UAAK,aAAa,iBAAlB,mBAAgC;AAC3F,aAAK,kBAAkB,SAAS,cAAc,KAAK,GACnD,KAAK,gBAAgB,YAAY,yBACjC,KAAK,gBAAgB,cAAc,eAAe,IAClD,KAAK,SAAS,YAAY,KAAK,eAAe;AAAA,MAChD;AAEA,WAAK,qBAAqB,KAAK,KAAK,UAAU,SAAS,KAAK,aAAa,KAAK,IAAI,CAAkB,GAEpG,KAAK,WAAW,SAAS,cAAc,MAAM,GAC7C,KAAK,SAAS,YAAY,2BAG1B,KAAK,qBAAqB,KAAK,SAAS,MAAM,aAAa,KAAK,oBAAoB,KAAK,IAAI,CAAkB,GAG/G,KAAK,qBAAqB,KAAK,SAAS,MAAM,gBAAgB,KAAK,QAAQ,KAAK,IAAI,CAAC;AAAA,IACvF;AAAA,IAEA,UAAU;AA7GZ;AA8GI,WAAK,KAAK,oBAAoB,YAAY,KAAK,wBAAwB,KAAK,IAAI,CAAC,GACjF,KAAK,KAAK,mBAAmB,YAAY,KAAK,kBAAkB,KAAK,IAAI,CAAC,GAC1E,KAAK,qBAAqB,UAAU,IACpC,UAAK,aAAL,WAAe,WACf,UAAK,aAAL,WAAe;AAAA,IACjB;AAAA,IAEU,oBAAoB,GAAsC;AArHtE;AAsHI,OAAK,KAAK,aAAa,EAAE,UAAU,GAAC,UAAK,aAAL,WAAe,SAAS,EAAE,YAAY,EAAE,OAAO,cAAc,aAC/F,KAAK,SAAS,aAAa,iBAAiB,OAAO,GACnD,KAAK,SAAS,MAAM,UAAU;AAAA,IAElC;AAAA,IAEU,wBAAwB,GAAyC;AA5H7E;AA6HI,QAAE,eAAe,GACjB,MAAM,aAAa,KAAK,QAAQ,GAChC,KAAK,kBAAkB,GACvB,KAAK,oBAAoB,CAAC;AAE1B,UAAI,UAAU,aAAa;AAC3B,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;AAC5C,mBAAW,KAAK,QAAQ,CAAC,EAAE,IAC3B,kBAAkB,KAAK,QAAQ,CAAC,EAAE,0BAA0B,WAAW;AAEvE,YAAM,QAAQ,SAAS,cAAc,IAAI;AACzC,cAAM,YAAY,iBAClB,MAAM,cAAY,UAAK,QAAQ,CAAC,MAAd,mBAAiB,SAAQ;AAE3C,YAAM,cAAc,SAAS,cAAc,OAAO;AAClD,oBAAY,OAAO,YACnB,YAAY,KAAK,GAAG,KAAK,QAAQ,aAAa,QAAQ,IACtD,YAAY,QAAQ,WAAW,OAAO,KAAK,QAAQ,CAAC,EAAE,EAAE,GACxD,MAAM,YAAY,WAAW,GAE7B,KAAK,kBAAkB,KAAK,WAAW,GAEnC,KAAK,KAAK,eAAe,QAAQ,KAAK,QAAQ,CAAC,KAAK,QAAQ,CAAC,EAAE,WACjE,YAAY,UAAU,MAGpB,gBAAK,iBAAL,mBAAmB,iBAAnB,WAAiC,6BACnC,cAAc,KAAK,aAAa,aAAa,2BAA2B,KAAK,QAAQ,CAAC,GAAG,KAAK,YAAY,IAE1G,cAAc,KAAK,UAAU,2BAA4B,KAAK,QAAQ,CAAC,GAAG,KAAK,YAAY;AAG7F,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,iBAAS,UAAU,GAAG,KAAK,QAAQ,aAAa,QAAQ,IACxD,SAAS,YAAY,aACrB,MAAM,YAAY,QAAQ,GAC1B,KAAK,SAAS,YAAY,KAAK;AAAA,MACjC;AAMA,UAJI,KAAK,aAAa,iBAAiB,CAAC,KAAK,aAAa,aAAa,sBAAsB,CAAC,KAAK,aAAa,aAAa,yBAC3H,KAAK,SAAS,YAAY,SAAS,cAAc,IAAI,CAAC,GAGpD,GAAE,UAAK,aAAa,iBAAlB,WAAgC,qBAAqB;AACzD,YAAM,kBAAgB,UAAK,aAAa,iBAAlB,mBAAgC,kBAAiB,KAAK,aAAa,eAEnF,QAAQ,SAAS,cAAc,IAAI;AACzC,cAAM,YAAY,iBAAiB,IACnC,KAAK,SAAS,YAAY,KAAK;AAE/B,YAAM,sBAAsB,SAAS,cAAc,OAAO;AAC1D,4BAAoB,OAAO,YAC3B,oBAAoB,KAAK,GAAG,KAAK,QAAQ,sBACzC,oBAAoB,QAAQ,SAAS,cACrC,MAAM,YAAY,mBAAmB;AAErC,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,iBAAS,UAAU,GAAG,KAAK,QAAQ,sBACnC,SAAS,cAAc,iBAAiB,IACxC,MAAM,YAAY,QAAQ,GAEtB,KAAK,KAAK,WAAW,EAAE,oBACzB,oBAAoB,UAAU;AAAA,MAElC;AAEA,UAAI,GAAE,UAAK,aAAa,iBAAlB,WAAgC,uBAAuB;AAC3D,YAAM,oBAAmB,UAAK,aAAa,iBAAlB,mBAAgC,oBAAoB,KAAK,aAAa,iBAEzF,QAAQ,SAAS,cAAc,IAAI;AACzC,cAAM,YAAY,mBAAmB,IACrC,KAAK,SAAS,YAAY,KAAK;AAE/B,YAAM,wBAAwB,SAAS,cAAc,OAAO;AAC5D,8BAAsB,OAAO,YAC7B,sBAAsB,KAAK,GAAG,KAAK,QAAQ,wBAC3C,sBAAsB,QAAQ,SAAS,cACvC,MAAM,YAAY,qBAAqB;AAEvC,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,iBAAS,UAAU,GAAG,KAAK,QAAQ,wBACnC,SAAS,cAAc,mBAAmB,IAC1C,MAAM,YAAY,QAAQ,GAEtB,KAAK,KAAK,WAAW,EAAE,yBACzB,sBAAsB,UAAU;AAAA,MAEpC;AAEA,WAAK,eAAe,CAAC;AAAA,IACvB;AAAA,IAEU,eAAe,OAA6C;AAzNxE;AA0NI,UAAM,eAAmC,0CAAsB,YAAtB,mBAAgC,OAAhC,YAAsC;AAC/E,WAAK,SAAS,MAAM,MAAM,GAAG,YAAY,QAAQ,EAAE,MACnD,KAAK,SAAS,MAAM,OAAO,GAAG,YAAY,QAAQ,EAAE,MACpD,KAAK,SAAS,MAAM,YAAY,GAAG,OAAO,cAAc,YAAY,OAAO,MAC3E,KAAK,SAAS,MAAM,UAAU,SAC9B,KAAK,SAAS,aAAa,iBAAiB,MAAM,GAClD,KAAK,SAAS,YAAY,KAAK,QAAQ;AAAA,IACzC;AAAA,IAEU,oBAAoB;AAO5B,UAAM,UAAU,KAAK,KAAK,WAAW,EAAE,MAAM,CAAC,GACxC,UAAU,IAAI,MAAM,KAAK,QAAQ,MAAM;AAC7C,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ;AAClC,QAAI,KAAK,KAAK,eAAe,KAAK,QAAQ,CAAC,EAAE,EAAE,MAAM,SAGnD,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAG3B,QAAQ,CAAC,IAAI,QAAQ,MAAM;AAG/B,WAAK,UAAU;AAAA,IACjB;AAAA;AAAA,IAGA,gBAAgB,eAAyC;AA1P3D;AA2PI,OAAI,UAAK,oBAAL,WAAsB,cACxB,KAAK,gBAAgB,YAAY,cAAc;AAAA,IAEnD;AAAA,IAEU,aAAa,GAA2C;AAChE,UAAI,EAAE,OAAO,QAAQ,WAAW,cAAc;AAG5C,YAAM,yBAAyB,KAAK,kBAAkB,GAChD,YAAqB,EAAE,OAAO,WAAW;AAC/C,aAAK,KAAK,WAAW,EAAE,iBAAiB,UAAU,CAAC,GACnD,KAAK,KAAK,WAAW,sBAAsB;AAC3C;AAAA,MACF;AAEA,UAAI,EAAE,OAAO,QAAQ,WAAW,cAAc;AAC5C,QAAI,EAAE,OAAO,UACX,KAAK,KAAK,WAAW,EAAE,sBAAsB,GAAK,CAAC,IAEnD,KAAK,KAAK,WAAW,EAAE,sBAAsB,GAAM,CAAC;AAEtD;AAAA,MACF;AAEA,UAAI,EAAE,OAAO,SAAS,YAAY;AAChC,YAAM,YAAY,EAAE,OAAO,SACrB,WAAW,EAAE,OAAO,QAAQ,YAAY,IACxC,iBAA2B,CAAC;AAQlC,YAPA,KAAK,kBAAkB,QAAQ,CAAC,gBAAgB,QAAQ;AACtD,UAAI,KAAK,QAAQ,GAAG,EAAE,WAAW,WAAa,KAAK,QAAQ,GAAG,EAAE,SAAS,CAAC,eAAe,UACrF,eAAe,WACjB,eAAe,KAAK,KAAK,QAAQ,GAAG,CAAC;AAAA,QAEzC,CAAC,GAEG,CAAC,eAAe,QAAQ;AAC1B,YAAE,OAAO,UAAU;AACnB;AAAA,QACF;AAEA,aAAK,KAAK,WAAW,cAAc,GACnC,KAAK,iBAAiB,OAAO,EAAE,UAAoB,SAAS,WAAW,YAAY,KAAK,SAAS,SAAS,KAAK,SAAS,gBAAgB,MAAM,KAAK,KAAK,CAAC;AAAA,MAC3J;AAAA,IACF;AAAA,IAEA,mBAAmB,SAA0B,MAAe;AAC1D,UAAM,MAAM,OAAO,WAAY,WAAW,UAAU,KAAK,mBAAmB,OAAO,GAC/E,iBAAiB,KAAK,kBAAkB,GACtC,MAAM,KAAK,QAAQ,GAAG;AAC5B,UAAI;AACF,YAAI,SAAS,IACb,eAAe,OAAO,KAAK,GAAG,GAAG;AAAA,WAC5B;AACL,YAAM,oBAA8B,CAAC;AACrC,iBAAS,IAAI,GAAG,IAAI,eAAe,QAAQ;AACzC,UAAI,eAAe,CAAC,EAAE,OAAO,IAAI,MAAM,kBAAkB,KAAK,eAAe,CAAC,CAAC;AAEjF,yBAAiB;AAAA,MACnB;AAEA,WAAK,KAAK,WAAW,cAAc,GACnC,KAAK,iBAAiB,OAAO,EAAE,UAAU,IAAI,IAAI,SAAS,MAAM,YAAY,KAAK,SAAS,SAAS,KAAK,SAAS,gBAAgB,MAAM,KAAK,KAAK,CAAC;AAAA,IACpJ;AAAA,IAEA,gBAAgB;AACd,aAAO,KAAK;AAAA,IACd;AAAA,IAEA,cAAc,IAAqB;AACjC,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ;AACvC,YAAI,KAAK,QAAQ,CAAC,EAAE,OAAO;AAAM,iBAAO,KAAK,QAAQ,CAAC;AAExD,aAAO;AAAA,IACT;AAAA,IAEA,mBAAmB,IAAqB;AACtC,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ;AACvC,YAAI,KAAK,QAAQ,CAAC,EAAE,OAAO;AAAM,iBAAO;AAE1C,aAAO;AAAA,IACT;AAAA;AAAA,IAGA,oBAAoB;AAClB,aAAO,KAAK,KAAK,WAAW;AAAA,IAC9B;AAAA,EACF;AAGA,EAAiB,OAAO,UACtB,OAAO,MAAM,WAAW,OAAO,MAAM,YAAY,CAAC,GAClD,OAAO,MAAM,SAAS,eAAe;", + "sourcesContent": ["import { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { Column, ColumnPickerOption, DOMMouseOrTouchEvent, GridOption, OnColumnsChangedArgs } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * A control to add a Column Picker (right+click on any column header to reveal the column picker)\n * NOTE: this is the old 'complex' column pciker that hides columns by removing them from the grid\n * for a more modern version that uses the column.hidden property and is a lot simpler, use slick.columnmenu.js\n *\n * USAGE:\n *\n * Add the slick.columnpicker.(js|css) files and register it with the grid.\n *\n * Available options, by defining a columnPicker object:\n *\n * let options = {\n * enableCellNavigation: true,\n * columnPicker: {\n * columnTitle: \"Columns\", // default to empty string\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\" (default:false)\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\" (default:false)\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * headerColumnValueExtractor: \"Extract the column label\" // default to column.name\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n * }\n * };\n */\n\nexport class SlickColumnPicker {\n // --\n // public API\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _gridUid: string;\n protected _columnTitleElm!: HTMLElement;\n protected _listElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _bindingEventService = new BindingEventService();\n protected _gridOptions: GridOption;\n protected _defaults: ColumnPickerOption = {\n fadeSpeed: 250,\n\n // the last 2 checkboxes titles\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n syncResizeTitle: 'Synchronous resize',\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name || ''\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, gridOptions: GridOption) {\n this._gridUid = grid.getUID();\n this._gridOptions = Utils.extend({}, this._defaults, gridOptions);\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n grid.onHeaderContextMenu.subscribe(this.handleHeaderContextMenu.bind(this));\n grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-columnpicker ${this._gridUid}`;\n this._menuElm.style.display = 'none';\n document.body.appendChild(this._menuElm);\n\n const buttonElm = document.createElement('button');\n buttonElm.type = 'button';\n buttonElm.className = 'close';\n buttonElm.dataset.dismiss = 'slick-columnpicker';\n buttonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.innerHTML = '×';\n buttonElm.appendChild(spanCloseElm);\n this._menuElm.appendChild(buttonElm);\n\n // user could pass a title on top of the columns list\n if (this._gridOptions.columnPickerTitle || (this._gridOptions.columnPicker?.columnTitle)) {\n const columnTitle = this._gridOptions.columnPickerTitle || this._gridOptions.columnPicker?.columnTitle;\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'slick-gridmenu-custom';\n this._columnTitleElm.textContent = columnTitle || '';\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-columnpicker-list';\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n destroy() {\n this.grid.onHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this));\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this._bindingEventService.unbindAll();\n this._listElm?.remove();\n this._menuElm?.remove();\n }\n\n protected handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n if ((this._menuElm !== e.target && !this._menuElm?.contains(e.target)) || e.target.className === 'close') {\n this._menuElm.setAttribute('aria-expanded', 'false');\n this._menuElm.style.display = 'none';\n }\n }\n\n protected handleHeaderContextMenu(e: DOMMouseOrTouchEvent) {\n e.preventDefault();\n Utils.emptyElement(this._listElm);\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n excludeCssClass = this.columns[i].excludeFromColumnPicker ? 'hidden' : '';\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = this.columns[i]?.name || '';\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n this._columnCheckboxes.push(checkboxElm);\n\n if (Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n if (this._gridOptions?.columnPicker?.headerColumnValueExtractor) {\n columnLabel = this._gridOptions.columnPicker.headerColumnValueExtractor(this.columns[i], this._gridOptions);\n } else {\n columnLabel = this._defaults.headerColumnValueExtractor!(this.columns[i], this._gridOptions);\n }\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`;\n labelElm.innerHTML = columnLabel;\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._gridOptions.columnPicker && (!this._gridOptions.columnPicker.hideForceFitButton || !this._gridOptions.columnPicker.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!(this._gridOptions.columnPicker?.hideForceFitButton)) {\n const forceFitTitle = this._gridOptions.columnPicker?.forceFitTitle || this._gridOptions.forceFitTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle || '';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`;\n labelElm.textContent = forceFitTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!(this._gridOptions.columnPicker?.hideSyncResizeButton)) {\n const syncResizeTitle = (this._gridOptions.columnPicker?.syncResizeTitle) || this._gridOptions.syncResizeTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle || '';\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n this.repositionMenu(e);\n }\n\n protected repositionMenu(event: DOMMouseOrTouchEvent) {\n const targetEvent: MouseEvent | Touch = (event as TouchEvent)?.touches?.[0] ?? event;\n this._menuElm.style.top = `${targetEvent.pageY - 10}px`;\n this._menuElm.style.left = `${targetEvent.pageX - 10}px`;\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY}px`;\n this._menuElm.style.display = 'block';\n this._menuElm.setAttribute('aria-expanded', 'true');\n this._menuElm.appendChild(this._listElm);\n }\n\n protected updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n /** Update the Titles of each sections (command, customTitle, ...) */\n updateAllTitles(pickerOptions: { columnTitle: string; }) {\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = pickerOptions.columnTitle;\n }\n }\n\n protected updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked: boolean = e.target.checked || false;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n if (e.target.checked) {\n this.grid.setOptions({ syncColumnCellResize: true });\n } else {\n this.grid.setOptions({ syncColumnCellResize: false });\n }\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (this.columns[idx].hidden !== undefined) { this.columns[idx].hidden = !columnCheckbox.checked; }\n if (columnCheckbox.checked) {\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId, showing: isChecked, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n }\n\n setColumnVisibiliy(idxOrId: number | string, show: boolean) {\n const idx = typeof idxOrId === 'number' ? idxOrId : this.getColumnIndexbyId(idxOrId);\n let visibleColumns = this.getVisibleColumns();\n const col = this.columns[idx];\n if (show) {\n col.hidden = false;\n visibleColumns.splice(idx, 0, col);\n } else {\n const newVisibleColumns: Column[] = [];\n for (let i = 0; i < visibleColumns.length; i++) {\n if (visibleColumns[i].id !== col.id) { newVisibleColumns.push(visibleColumns[i]); }\n }\n visibleColumns = newVisibleColumns;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId: col.id, showing: show, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n getColumnbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return this.columns[i]; }\n }\n return null;\n }\n\n getColumnIndexbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return i; }\n }\n return -1;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.ColumnPicker = SlickColumnPicker;\n}\n"], + "mappings": ";;;;;;;AAKA,MAAM,sBAAkC,MAAM,qBACxC,aAAyB,MAAM,OAC/B,QAAoB,MAAM,OA4BnB,oBAAN,MAAwB;AAAA,IAyB7B,YAAsB,SAAsC,MAAiB,aAAyB;AAAhF;AAAsC;AAtB5D;AAAA;AAAA,8CAAmB,IAAI,WAAiC;AAIxD;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU,qBAAwC,CAAC;AACnD,0BAAU,wBAAuB,IAAI,oBAAoB;AACzD,0BAAU;AACV,0BAAU,aAAgC;AAAA,QACxC,WAAW;AAAA;AAAA,QAGX,oBAAoB;AAAA,QACpB,sBAAsB;AAAA,QACtB,eAAe;AAAA,QACf,iBAAiB;AAAA,QACjB,4BAA4B,CAAC,cAAsB,UAAU,QAAQ;AAAA,MACvE;AAGE,WAAK,WAAW,KAAK,OAAO,GAC5B,KAAK,eAAe,MAAM,OAAO,CAAC,GAAG,KAAK,WAAW,WAAW,GAChE,KAAK,KAAK,KAAK,IAAI;AAAA,IACrB;AAAA,IAEA,KAAK,MAAiB;AAlExB;AAmEI,WAAK,oBAAoB,UAAU,KAAK,wBAAwB,KAAK,IAAI,CAAC,GAC1E,KAAK,mBAAmB,UAAU,KAAK,kBAAkB,KAAK,IAAI,CAAC,GAEnE,KAAK,WAAW,SAAS,cAAc,KAAK,GAC5C,KAAK,SAAS,YAAY,sBAAsB,KAAK,QAAQ,IAC7D,KAAK,SAAS,MAAM,UAAU,QAC9B,SAAS,KAAK,YAAY,KAAK,QAAQ;AAEvC,UAAM,YAAY,SAAS,cAAc,QAAQ;AACjD,gBAAU,OAAO,UACjB,UAAU,YAAY,SACtB,UAAU,QAAQ,UAAU,sBAC5B,UAAU,YAAY;AAEtB,UAAM,eAAe,SAAS,cAAc,MAAM;AAQlD,UAPA,aAAa,YAAY,SACzB,aAAa,aAAa,QAC1B,aAAa,YAAY,WACzB,UAAU,YAAY,YAAY,GAClC,KAAK,SAAS,YAAY,SAAS,GAG/B,KAAK,aAAa,sBAAsB,UAAK,aAAa,iBAAlB,WAAgC,aAAc;AACxF,YAAM,cAAc,KAAK,aAAa,uBAAqB,UAAK,aAAa,iBAAlB,mBAAgC;AAC3F,aAAK,kBAAkB,SAAS,cAAc,KAAK,GACnD,KAAK,gBAAgB,YAAY,yBACjC,KAAK,gBAAgB,cAAc,eAAe,IAClD,KAAK,SAAS,YAAY,KAAK,eAAe;AAAA,MAChD;AAEA,WAAK,qBAAqB,KAAK,KAAK,UAAU,SAAS,KAAK,aAAa,KAAK,IAAI,CAAkB,GAEpG,KAAK,WAAW,SAAS,cAAc,MAAM,GAC7C,KAAK,SAAS,YAAY,2BAG1B,KAAK,qBAAqB,KAAK,SAAS,MAAM,aAAa,KAAK,oBAAoB,KAAK,IAAI,CAAkB,GAG/G,KAAK,qBAAqB,KAAK,SAAS,MAAM,gBAAgB,KAAK,QAAQ,KAAK,IAAI,CAAC;AAAA,IACvF;AAAA,IAEA,UAAU;AA7GZ;AA8GI,WAAK,KAAK,oBAAoB,YAAY,KAAK,wBAAwB,KAAK,IAAI,CAAC,GACjF,KAAK,KAAK,mBAAmB,YAAY,KAAK,kBAAkB,KAAK,IAAI,CAAC,GAC1E,KAAK,qBAAqB,UAAU,IACpC,UAAK,aAAL,WAAe,WACf,UAAK,aAAL,WAAe;AAAA,IACjB;AAAA,IAEU,oBAAoB,GAAsC;AArHtE;AAsHI,OAAK,KAAK,aAAa,EAAE,UAAU,GAAC,UAAK,aAAL,WAAe,SAAS,EAAE,YAAY,EAAE,OAAO,cAAc,aAC/F,KAAK,SAAS,aAAa,iBAAiB,OAAO,GACnD,KAAK,SAAS,MAAM,UAAU;AAAA,IAElC;AAAA,IAEU,wBAAwB,GAAyC;AA5H7E;AA6HI,QAAE,eAAe,GACjB,MAAM,aAAa,KAAK,QAAQ,GAChC,KAAK,kBAAkB,GACvB,KAAK,oBAAoB,CAAC;AAE1B,UAAI,UAAU,aAAa;AAC3B,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;AAC5C,mBAAW,KAAK,QAAQ,CAAC,EAAE,IAC3B,kBAAkB,KAAK,QAAQ,CAAC,EAAE,0BAA0B,WAAW;AAEvE,YAAM,QAAQ,SAAS,cAAc,IAAI;AACzC,cAAM,YAAY,iBAClB,MAAM,cAAY,UAAK,QAAQ,CAAC,MAAd,mBAAiB,SAAQ;AAE3C,YAAM,cAAc,SAAS,cAAc,OAAO;AAClD,oBAAY,OAAO,YACnB,YAAY,KAAK,GAAG,KAAK,QAAQ,aAAa,QAAQ,IACtD,YAAY,QAAQ,WAAW,OAAO,KAAK,QAAQ,CAAC,EAAE,EAAE,GACxD,MAAM,YAAY,WAAW,GAE7B,KAAK,kBAAkB,KAAK,WAAW,GAEnC,MAAM,UAAU,KAAK,KAAK,eAAe,QAAQ,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,EAAE,WAC1E,YAAY,UAAU,MAGpB,gBAAK,iBAAL,mBAAmB,iBAAnB,WAAiC,6BACnC,cAAc,KAAK,aAAa,aAAa,2BAA2B,KAAK,QAAQ,CAAC,GAAG,KAAK,YAAY,IAE1G,cAAc,KAAK,UAAU,2BAA4B,KAAK,QAAQ,CAAC,GAAG,KAAK,YAAY;AAG7F,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,iBAAS,UAAU,GAAG,KAAK,QAAQ,aAAa,QAAQ,IACxD,SAAS,YAAY,aACrB,MAAM,YAAY,QAAQ,GAC1B,KAAK,SAAS,YAAY,KAAK;AAAA,MACjC;AAMA,UAJI,KAAK,aAAa,iBAAiB,CAAC,KAAK,aAAa,aAAa,sBAAsB,CAAC,KAAK,aAAa,aAAa,yBAC3H,KAAK,SAAS,YAAY,SAAS,cAAc,IAAI,CAAC,GAGpD,GAAE,UAAK,aAAa,iBAAlB,WAAgC,qBAAqB;AACzD,YAAM,kBAAgB,UAAK,aAAa,iBAAlB,mBAAgC,kBAAiB,KAAK,aAAa,eAEnF,QAAQ,SAAS,cAAc,IAAI;AACzC,cAAM,YAAY,iBAAiB,IACnC,KAAK,SAAS,YAAY,KAAK;AAE/B,YAAM,sBAAsB,SAAS,cAAc,OAAO;AAC1D,4BAAoB,OAAO,YAC3B,oBAAoB,KAAK,GAAG,KAAK,QAAQ,sBACzC,oBAAoB,QAAQ,SAAS,cACrC,MAAM,YAAY,mBAAmB;AAErC,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,iBAAS,UAAU,GAAG,KAAK,QAAQ,sBACnC,SAAS,cAAc,iBAAiB,IACxC,MAAM,YAAY,QAAQ,GAEtB,KAAK,KAAK,WAAW,EAAE,oBACzB,oBAAoB,UAAU;AAAA,MAElC;AAEA,UAAI,GAAE,UAAK,aAAa,iBAAlB,WAAgC,uBAAuB;AAC3D,YAAM,oBAAmB,UAAK,aAAa,iBAAlB,mBAAgC,oBAAoB,KAAK,aAAa,iBAEzF,QAAQ,SAAS,cAAc,IAAI;AACzC,cAAM,YAAY,mBAAmB,IACrC,KAAK,SAAS,YAAY,KAAK;AAE/B,YAAM,wBAAwB,SAAS,cAAc,OAAO;AAC5D,8BAAsB,OAAO,YAC7B,sBAAsB,KAAK,GAAG,KAAK,QAAQ,wBAC3C,sBAAsB,QAAQ,SAAS,cACvC,MAAM,YAAY,qBAAqB;AAEvC,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,iBAAS,UAAU,GAAG,KAAK,QAAQ,wBACnC,SAAS,cAAc,mBAAmB,IAC1C,MAAM,YAAY,QAAQ,GAEtB,KAAK,KAAK,WAAW,EAAE,yBACzB,sBAAsB,UAAU;AAAA,MAEpC;AAEA,WAAK,eAAe,CAAC;AAAA,IACvB;AAAA,IAEU,eAAe,OAA6C;AAzNxE;AA0NI,UAAM,eAAmC,0CAAsB,YAAtB,mBAAgC,OAAhC,YAAsC;AAC/E,WAAK,SAAS,MAAM,MAAM,GAAG,YAAY,QAAQ,EAAE,MACnD,KAAK,SAAS,MAAM,OAAO,GAAG,YAAY,QAAQ,EAAE,MACpD,KAAK,SAAS,MAAM,YAAY,GAAG,OAAO,cAAc,YAAY,OAAO,MAC3E,KAAK,SAAS,MAAM,UAAU,SAC9B,KAAK,SAAS,aAAa,iBAAiB,MAAM,GAClD,KAAK,SAAS,YAAY,KAAK,QAAQ;AAAA,IACzC;AAAA,IAEU,oBAAoB;AAO5B,UAAM,UAAU,KAAK,KAAK,WAAW,EAAE,MAAM,CAAC,GACxC,UAAU,IAAI,MAAM,KAAK,QAAQ,MAAM;AAC7C,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ;AAClC,QAAI,KAAK,KAAK,eAAe,KAAK,QAAQ,CAAC,EAAE,EAAE,MAAM,SAGnD,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAG3B,QAAQ,CAAC,IAAI,QAAQ,MAAM;AAG/B,WAAK,UAAU;AAAA,IACjB;AAAA;AAAA,IAGA,gBAAgB,eAAyC;AA1P3D;AA2PI,OAAI,UAAK,oBAAL,WAAsB,cACxB,KAAK,gBAAgB,YAAY,cAAc;AAAA,IAEnD;AAAA,IAEU,aAAa,GAA2C;AAChE,UAAI,EAAE,OAAO,QAAQ,WAAW,cAAc;AAG5C,YAAM,yBAAyB,KAAK,kBAAkB,GAChD,YAAqB,EAAE,OAAO,WAAW;AAC/C,aAAK,KAAK,WAAW,EAAE,iBAAiB,UAAU,CAAC,GACnD,KAAK,KAAK,WAAW,sBAAsB;AAC3C;AAAA,MACF;AAEA,UAAI,EAAE,OAAO,QAAQ,WAAW,cAAc;AAC5C,QAAI,EAAE,OAAO,UACX,KAAK,KAAK,WAAW,EAAE,sBAAsB,GAAK,CAAC,IAEnD,KAAK,KAAK,WAAW,EAAE,sBAAsB,GAAM,CAAC;AAEtD;AAAA,MACF;AAEA,UAAI,EAAE,OAAO,SAAS,YAAY;AAChC,YAAM,YAAY,EAAE,OAAO,SACrB,WAAW,EAAE,OAAO,QAAQ,YAAY,IACxC,iBAA2B,CAAC;AAQlC,YAPA,KAAK,kBAAkB,QAAQ,CAAC,gBAAgB,QAAQ;AACtD,UAAI,KAAK,QAAQ,GAAG,EAAE,WAAW,WAAa,KAAK,QAAQ,GAAG,EAAE,SAAS,CAAC,eAAe,UACrF,eAAe,WACjB,eAAe,KAAK,KAAK,QAAQ,GAAG,CAAC;AAAA,QAEzC,CAAC,GAEG,CAAC,eAAe,QAAQ;AAC1B,YAAE,OAAO,UAAU;AACnB;AAAA,QACF;AAEA,aAAK,KAAK,WAAW,cAAc,GACnC,KAAK,iBAAiB,OAAO,EAAE,UAAU,SAAS,WAAW,YAAY,KAAK,SAAS,SAAS,KAAK,SAAS,gBAAgB,MAAM,KAAK,KAAK,CAAC;AAAA,MACjJ;AAAA,IACF;AAAA,IAEA,mBAAmB,SAA0B,MAAe;AAC1D,UAAM,MAAM,OAAO,WAAY,WAAW,UAAU,KAAK,mBAAmB,OAAO,GAC/E,iBAAiB,KAAK,kBAAkB,GACtC,MAAM,KAAK,QAAQ,GAAG;AAC5B,UAAI;AACF,YAAI,SAAS,IACb,eAAe,OAAO,KAAK,GAAG,GAAG;AAAA,WAC5B;AACL,YAAM,oBAA8B,CAAC;AACrC,iBAAS,IAAI,GAAG,IAAI,eAAe,QAAQ;AACzC,UAAI,eAAe,CAAC,EAAE,OAAO,IAAI,MAAM,kBAAkB,KAAK,eAAe,CAAC,CAAC;AAEjF,yBAAiB;AAAA,MACnB;AAEA,WAAK,KAAK,WAAW,cAAc,GACnC,KAAK,iBAAiB,OAAO,EAAE,UAAU,IAAI,IAAI,SAAS,MAAM,YAAY,KAAK,SAAS,SAAS,KAAK,SAAS,gBAAgB,MAAM,KAAK,KAAK,CAAC;AAAA,IACpJ;AAAA,IAEA,gBAAgB;AACd,aAAO,KAAK;AAAA,IACd;AAAA,IAEA,cAAc,IAAqB;AACjC,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ;AACvC,YAAI,KAAK,QAAQ,CAAC,EAAE,OAAO;AAAM,iBAAO,KAAK,QAAQ,CAAC;AAExD,aAAO;AAAA,IACT;AAAA,IAEA,mBAAmB,IAAqB;AACtC,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ;AACvC,YAAI,KAAK,QAAQ,CAAC,EAAE,OAAO;AAAM,iBAAO;AAE1C,aAAO;AAAA,IACT;AAAA;AAAA,IAGA,oBAAoB;AAClB,aAAO,KAAK,KAAK,WAAW;AAAA,IAC9B;AAAA,EACF;AAGA,EAAiB,OAAO,UACtB,OAAO,MAAM,WAAW,OAAO,MAAM,YAAY,CAAC,GAClD,OAAO,MAAM,SAAS,eAAe;", "names": [] } diff --git a/dist/browser/controls/slick.gridmenu.js b/dist/browser/controls/slick.gridmenu.js index d028272f3..f34610a6a 100644 --- a/dist/browser/controls/slick.gridmenu.js +++ b/dist/browser/controls/slick.gridmenu.js @@ -22,7 +22,7 @@ __publicField(this, "_gridOptions"); __publicField(this, "_gridUid"); __publicField(this, "_isMenuOpen", !1); - __publicField(this, "_gridMenuOptions", null); + __publicField(this, "_columnCheckboxes", []); __publicField(this, "_columnTitleElm"); __publicField(this, "_customTitleElm"); __publicField(this, "_customMenuElm"); @@ -30,7 +30,8 @@ __publicField(this, "_listElm"); __publicField(this, "_buttonElm"); __publicField(this, "_menuElm"); - __publicField(this, "_columnCheckboxes", []); + __publicField(this, "_subMenuParentId", ""); + __publicField(this, "_gridMenuOptions", null); __publicField(this, "_defaults", { showButton: !0, hideForceFitButton: !1, @@ -60,7 +61,7 @@ createGridMenu() { var _a, _b, _c, _d, _e; let gridMenuWidth = ((_a = this._gridMenuOptions) == null ? void 0 : _a.menuWidth) || this._defaults.menuWidth; - if (this._gridOptions && this._gridOptions.hasOwnProperty("frozenColumn") && this._gridOptions.frozenColumn >= 0 ? this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-right`) : this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-left`), this._headerElm.style.width = `calc(100% - ${gridMenuWidth}px)`, (((_b = this._gridMenuOptions) == null ? void 0 : _b.resizeOnShowHeaderRow) != null ? this._gridMenuOptions.resizeOnShowHeaderRow : this._defaults.resizeOnShowHeaderRow) && this._gridOptions.showHeaderRow) { + if (this._gridOptions && this._gridOptions.hasOwnProperty("frozenColumn") && this._gridOptions.frozenColumn >= 0 ? this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-right`) : this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-left`), this._headerElm.style.width = `calc(100% - ${gridMenuWidth}px)`, (Utils.isDefined((_b = this._gridMenuOptions) == null ? void 0 : _b.resizeOnShowHeaderRow) ? this._gridMenuOptions.resizeOnShowHeaderRow : this._defaults.resizeOnShowHeaderRow) && this._gridOptions.showHeaderRow) { let headerRow = document.querySelector(`.${this._gridUid}.slick-headerrow`); headerRow && (headerRow.style.width = `calc(100% - ${gridMenuWidth}px)`); } @@ -73,11 +74,30 @@ } this._headerElm.parentElement.insertBefore(this._buttonElm, this._headerElm.parentElement.firstChild), this._bindingEventService.bind(this._buttonElm, "click", this.showGridMenu.bind(this)); } - this._menuElm = document.createElement("div"), this._menuElm.className = `slick-gridmenu ${this._gridUid}`, this._menuElm.style.display = "none", document.body.appendChild(this._menuElm); - let buttonElm = document.createElement("button"); - buttonElm.type = "button", buttonElm.className = "close", buttonElm.dataset.dismiss = "slick-gridmenu", buttonElm.ariaLabel = "Close"; - let spanCloseElm = document.createElement("span"); - spanCloseElm.className = "close", spanCloseElm.ariaHidden = "true", spanCloseElm.innerHTML = "×", buttonElm.appendChild(spanCloseElm), this._menuElm.appendChild(buttonElm), this._customMenuElm = document.createElement("div"), this._customMenuElm.className = "slick-gridmenu-custom", this._customMenuElm.role = "menu", this._menuElm.appendChild(this._customMenuElm), this.populateCustomMenus(this._gridMenuOptions || {}, this._customMenuElm), this.populateColumnPicker(), this._bindingEventService.bind(document.body, "mousedown", this.handleBodyMouseDown.bind(this)), this._bindingEventService.bind(document.body, "beforeunload", this.destroy.bind(this)); + this._menuElm = this.createMenu(0), this.populateColumnPicker(), document.body.appendChild(this._menuElm), this._bindingEventService.bind(document.body, "mousedown", this.handleBodyMouseDown.bind(this)), this._bindingEventService.bind(document.body, "beforeunload", this.destroy.bind(this)); + } + /** Create the menu or sub-menu(s) but without the column picker which is a separate single process */ + createMenu(level = 0, item) { + var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k; + let maxHeight = isNaN((_a = this._gridMenuOptions) == null ? void 0 : _a.maxHeight) ? (_b = this._gridMenuOptions) == null ? void 0 : _b.maxHeight : `${(_d = (_c = this._gridMenuOptions) == null ? void 0 : _c.maxHeight) != null ? _d : 0}px`, width = isNaN((_e = this._gridMenuOptions) == null ? void 0 : _e.width) ? (_f = this._gridMenuOptions) == null ? void 0 : _f.width : `${(_h = (_g = this._gridMenuOptions) == null ? void 0 : _g.maxWidth) != null ? _h : 0}px`, subMenuCommand = item == null ? void 0 : item.command, subMenuId = level === 1 && subMenuCommand ? subMenuCommand.replaceAll(" ", "") : ""; + subMenuId && (this._subMenuParentId = subMenuId), level > 1 && (subMenuId = this._subMenuParentId); + let menuClasses = `slick-gridmenu slick-menu-level-${level} ${this._gridUid}`, bodyMenuElm = document.body.querySelector(`.slick-gridmenu.slick-menu-level-${level}${this.getGridUidSelector()}`); + if (bodyMenuElm) { + if (bodyMenuElm.dataset.subMenuParent === subMenuId) + return bodyMenuElm; + this.destroySubMenus(); + } + let menuElm = document.createElement("div"); + menuElm.role = "menu", menuElm.className = menuClasses, level > 0 && (menuElm.classList.add("slick-submenu"), subMenuId && (menuElm.dataset.subMenuParent = subMenuId)), menuElm.ariaLabel = level > 1 ? "SubMenu" : "Grid Menu", width && (menuElm.style.width = width), maxHeight && (menuElm.style.maxHeight = maxHeight), menuElm.style.display = "none"; + let closeButtonElm = null; + if (level === 0) { + closeButtonElm = document.createElement("button"), closeButtonElm.type = "button", closeButtonElm.className = "close", closeButtonElm.dataset.dismiss = "slick-gridmenu", closeButtonElm.ariaLabel = "Close"; + let spanCloseElm = document.createElement("span"); + spanCloseElm.className = "close", spanCloseElm.ariaHidden = "true", spanCloseElm.innerHTML = "×", closeButtonElm.appendChild(spanCloseElm), menuElm.appendChild(closeButtonElm); + } + this._customMenuElm = document.createElement("div"), this._customMenuElm.className = `slick-gridmenu-custom slick-gridmenu-command-list slick-menu-level-${level}`, this._customMenuElm.role = "menu", menuElm.appendChild(this._customMenuElm); + let commandItems = (_k = (_j = item == null ? void 0 : item.customItems) != null ? _j : (_i = this._gridMenuOptions) == null ? void 0 : _i.customItems) != null ? _k : []; + return commandItems.length > 0 && item && level > 0 && this.addSubMenuTitleWhenExists(item, this._customMenuElm), this.populateCustomMenus(commandItems, this._customMenuElm, { grid: this.grid, level }), level++, menuElm; } /** Destroy the plugin by unsubscribing every events & also delete the menu DOM elements */ destroy() { @@ -91,26 +111,34 @@ let gridMenuElm = document.querySelector(`div.slick-gridmenu.${this._gridUid}`); gridMenuElm && (gridMenuElm.style.display = "none"), this._headerElm && (this._headerElm.style.width = "100%"), (_a = this._buttonElm) == null || _a.remove(), (_b = this._menuElm) == null || _b.remove(); } - populateCustomMenus(gridMenuOptions, customMenuElm) { - var _a; - if (!(!gridMenuOptions || !gridMenuOptions.customItems)) { - (_a = this._gridMenuOptions) != null && _a.customTitle && (this._customTitleElm = document.createElement("div"), this._customTitleElm.className = "title", this._customTitleElm.innerHTML = this._gridMenuOptions.customTitle, customMenuElm.appendChild(this._customTitleElm)); - for (let i = 0, ln = gridMenuOptions.customItems.length; i < ln; i++) { - let addClickListener = !0, item = gridMenuOptions.customItems[i], callbackArgs = { - grid: this.grid, - menu: this._menuElm, - columns: this.columns, - visibleColumns: this.getVisibleColumns() - }, isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, callbackArgs), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, callbackArgs); - if (!isItemVisible) - continue; - Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable); - let liElm = document.createElement("div"); - liElm.className = "slick-gridmenu-item", liElm.role = "menuitem", (item.divider || item === "divider") && (liElm.classList.add("slick-gridmenu-item-divider"), addClickListener = !1), item.disabled && liElm.classList.add("slick-gridmenu-item-disabled"), item.hidden && liElm.classList.add("slick-gridmenu-item-hidden"), item.cssClass && liElm.classList.add(...item.cssClass.split(" ")), item.tooltip && (liElm.title = item.tooltip || ""); - let iconElm = document.createElement("div"); - iconElm.className = "slick-gridmenu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...item.iconCssClass.split(" ")), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`); - let textElm = document.createElement("span"); - textElm.className = "slick-gridmenu-content", textElm.innerHTML = item.title || "", liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), customMenuElm.appendChild(liElm), addClickListener && this._bindingEventService.bind(liElm, "click", this.handleMenuItemClick.bind(this, item)); + /** Close and destroy all previously opened sub-menus */ + destroySubMenus() { + document.querySelectorAll(`.slick-gridmenu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => subElm.remove()); + } + /** Construct the custom command menu items. */ + populateCustomMenus(customItems, customMenuElm, args) { + var _a, _b; + let isSubMenu = args.level > 0; + (_a = this._gridMenuOptions) != null && _a.customTitle && !isSubMenu && (this._customTitleElm = document.createElement("div"), this._customTitleElm.className = "title", this._customTitleElm.innerHTML = this._gridMenuOptions.customTitle, customMenuElm.appendChild(this._customTitleElm)); + for (let i = 0, ln = customItems.length; i < ln; i++) { + let addClickListener = !0, item = customItems[i], callbackArgs = { + grid: this.grid, + menu: this._menuElm, + columns: this.columns, + visibleColumns: this.getVisibleColumns() + }, isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, callbackArgs), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, callbackArgs); + if (!isItemVisible) + continue; + Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable); + let liElm = document.createElement("div"); + liElm.className = "slick-gridmenu-item", liElm.role = "menuitem", (item.divider || item === "divider") && (liElm.classList.add("slick-gridmenu-item-divider"), addClickListener = !1), item.disabled && liElm.classList.add("slick-gridmenu-item-disabled"), item.hidden && liElm.classList.add("slick-gridmenu-item-hidden"), item.cssClass && liElm.classList.add(...item.cssClass.split(" ")), item.tooltip && (liElm.title = item.tooltip || ""); + let iconElm = document.createElement("div"); + iconElm.className = "slick-gridmenu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...item.iconCssClass.split(" ")), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`); + let textElm = document.createElement("span"); + if (textElm.className = "slick-gridmenu-content", textElm.innerHTML = item.title || "", liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), customMenuElm.appendChild(liElm), addClickListener && this._bindingEventService.bind(liElm, "click", this.handleMenuItemClick.bind(this, item, args.level)), item.customItems) { + let chevronElm = document.createElement("span"); + chevronElm.className = "sub-item-chevron", (_b = this._gridMenuOptions) != null && _b.subItemChevronClass ? chevronElm.classList.add(...this._gridMenuOptions.subItemChevronClass.split(" ")) : chevronElm.textContent = "\u2B9E", liElm.classList.add("slick-submenu-item"), liElm.appendChild(chevronElm); + continue; } } } @@ -126,35 +154,37 @@ showGridMenu(e) { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j; let targetEvent = e.touches ? e.touches[0] : e; - e.preventDefault(), Utils.emptyElement(this._listElm), Utils.emptyElement(this._customMenuElm), this.populateCustomMenus(this._gridMenuOptions || {}, this._customMenuElm), this.updateColumnOrder(), this._columnCheckboxes = []; + e.preventDefault(), Utils.emptyElement(this._listElm), Utils.emptyElement(this._customMenuElm); + let commandItems = (_b = (_a = this._gridMenuOptions) == null ? void 0 : _a.customItems) != null ? _b : []; + this.populateCustomMenus(commandItems, this._customMenuElm, { grid: this.grid, level: 0 }), this.updateColumnOrder(), this._columnCheckboxes = []; let callbackArgs = { grid: this.grid, menu: this._menuElm, allColumns: this.columns, visibleColumns: this.getVisibleColumns() }; - if (this._gridMenuOptions && !this.runOverrideFunctionWhenExists(this._gridMenuOptions.menuUsabilityOverride, callbackArgs) || typeof e.stopPropagation == "function" && this.onBeforeMenuShow.notify(callbackArgs, e, this).getReturnValue() == !1) + if (this._gridMenuOptions && !this.runOverrideFunctionWhenExists(this._gridMenuOptions.menuUsabilityOverride, callbackArgs) || typeof e.stopPropagation == "function" && this.onBeforeMenuShow.notify(callbackArgs, e, this).getReturnValue() === !1) return; let columnId, columnLabel, excludeCssClass; for (let i = 0; i < this.columns.length; i++) { columnId = this.columns[i].id, excludeCssClass = this.columns[i].excludeFromGridMenu ? "hidden" : ""; let liElm = document.createElement("li"); - liElm.className = excludeCssClass, liElm.ariaLabel = ((_a = this.columns[i]) == null ? void 0 : _a.name) || ""; + liElm.className = excludeCssClass, liElm.ariaLabel = ((_c = this.columns[i]) == null ? void 0 : _c.name) || ""; let checkboxElm = document.createElement("input"); - checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}-gridmenu-colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this.grid.getColumnIndex(this.columns[i].id) != null && !this.columns[i].hidden && (checkboxElm.checked = !0), this._columnCheckboxes.push(checkboxElm), (_b = this._gridMenuOptions) != null && _b.headerColumnValueExtractor ? columnLabel = this._gridMenuOptions.headerColumnValueExtractor(this.columns[i], this._gridOptions) : columnLabel = this._defaults.headerColumnValueExtractor(this.columns[i]); + checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}-gridmenu-colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), Utils.isDefined(this.grid.getColumnIndex(this.columns[i].id)) && !this.columns[i].hidden && (checkboxElm.checked = !0), this._columnCheckboxes.push(checkboxElm), (_d = this._gridMenuOptions) != null && _d.headerColumnValueExtractor ? columnLabel = this._gridMenuOptions.headerColumnValueExtractor(this.columns[i], this._gridOptions) : columnLabel = this._defaults.headerColumnValueExtractor(this.columns[i]); let labelElm = document.createElement("label"); labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-${columnId}`, labelElm.innerHTML = columnLabel || "", liElm.appendChild(labelElm), this._listElm.appendChild(liElm); } - if (this._gridMenuOptions && (!this._gridMenuOptions.hideForceFitButton || !this._gridMenuOptions.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !((_c = this._gridMenuOptions) != null && _c.hideForceFitButton)) { - let forceFitTitle = ((_d = this._gridMenuOptions) == null ? void 0 : _d.forceFitTitle) || this._defaults.forceFitTitle, liElm = document.createElement("li"); + if (this._gridMenuOptions && (!this._gridMenuOptions.hideForceFitButton || !this._gridMenuOptions.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !((_e = this._gridMenuOptions) != null && _e.hideForceFitButton)) { + let forceFitTitle = ((_f = this._gridMenuOptions) == null ? void 0 : _f.forceFitTitle) || this._defaults.forceFitTitle, liElm = document.createElement("li"); liElm.ariaLabel = forceFitTitle, liElm.role = "menuitem", this._listElm.appendChild(liElm); let forceFitCheckboxElm = document.createElement("input"); forceFitCheckboxElm.type = "checkbox", forceFitCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-forcefit`, forceFitCheckboxElm.dataset.option = "autoresize", liElm.appendChild(forceFitCheckboxElm); let labelElm = document.createElement("label"); labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-forcefit`, labelElm.textContent = forceFitTitle, liElm.appendChild(labelElm), this.grid.getOptions().forceFitColumns && (forceFitCheckboxElm.checked = !0); } - if (!((_e = this._gridMenuOptions) != null && _e.hideSyncResizeButton)) { - let syncResizeTitle = ((_f = this._gridMenuOptions) == null ? void 0 : _f.syncResizeTitle) || this._defaults.syncResizeTitle, liElm = document.createElement("li"); + if (!((_g = this._gridMenuOptions) != null && _g.hideSyncResizeButton)) { + let syncResizeTitle = ((_h = this._gridMenuOptions) == null ? void 0 : _h.syncResizeTitle) || this._defaults.syncResizeTitle, liElm = document.createElement("li"); liElm.ariaLabel = syncResizeTitle, this._listElm.appendChild(liElm); let syncResizeCheckboxElm = document.createElement("input"); syncResizeCheckboxElm.type = "checkbox", syncResizeCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-syncresize`, syncResizeCheckboxElm.dataset.option = "syncresize", liElm.appendChild(syncResizeCheckboxElm); @@ -162,49 +192,88 @@ labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-syncresize`, labelElm.textContent = syncResizeTitle, liElm.appendChild(labelElm), this.grid.getOptions().syncColumnCellResize && (syncResizeCheckboxElm.checked = !0); } let buttonElm = e.target.nodeName === "BUTTON" ? e.target : e.target.querySelector("button"); - buttonElm || (buttonElm = e.target.parentElement), this._menuElm.style.display = "block", this._menuElm.style.opacity = "0"; - let menuIconOffset = Utils.offset(buttonElm), menuWidth = this._menuElm.offsetWidth, useClickToRepositionMenu = ((_g = this._gridMenuOptions) == null ? void 0 : _g.useClickToRepositionMenu) !== void 0 ? this._gridMenuOptions.useClickToRepositionMenu : this._defaults.useClickToRepositionMenu, contentMinWidth = (_h = this._gridMenuOptions) != null && _h.contentMinWidth ? this._gridMenuOptions.contentMinWidth : this._defaults.contentMinWidth, currentMenuWidth = contentMinWidth > menuWidth ? contentMinWidth : menuWidth + 5, nextPositionTop = useClickToRepositionMenu && targetEvent.pageY > 0 ? targetEvent.pageY : menuIconOffset.top + 10, nextPositionLeft = useClickToRepositionMenu && targetEvent.pageX > 0 ? targetEvent.pageX : menuIconOffset.left + 10, menuMarginBottom = ((_i = this._gridMenuOptions) == null ? void 0 : _i.marginBottom) !== void 0 ? this._gridMenuOptions.marginBottom : this._defaults.marginBottom; - this._menuElm.style.top = `${nextPositionTop + 10}px`, this._menuElm.style.left = `${nextPositionLeft - currentMenuWidth + 10}px`, contentMinWidth > 0 && (this._menuElm.style.minWidth = `${contentMinWidth}px`), ((_j = this._gridMenuOptions) == null ? void 0 : _j.height) !== void 0 ? this._menuElm.style.height = `${this._gridMenuOptions.height}px` : this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY - menuMarginBottom}px`, this._menuElm.style.display = "block", this._menuElm.style.opacity = "1", this._menuElm.appendChild(this._listElm), this._isMenuOpen = !0, typeof e.stopPropagation == "function" && this.onAfterMenuShow.notify(callbackArgs, e, this).getReturnValue() == !1; + buttonElm || (buttonElm = e.target.parentElement), this._menuElm.style.display = "block", this._menuElm.style.opacity = "0", this.repositionMenu(e, this._menuElm, buttonElm); + let menuMarginBottom = ((_i = this._gridMenuOptions) == null ? void 0 : _i.marginBottom) !== void 0 ? this._gridMenuOptions.marginBottom : this._defaults.marginBottom; + ((_j = this._gridMenuOptions) == null ? void 0 : _j.height) !== void 0 ? this._menuElm.style.height = `${this._gridMenuOptions.height}px` : this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY - menuMarginBottom}px`, this._menuElm.style.display = "block", this._menuElm.style.opacity = "1", this._menuElm.appendChild(this._listElm), this._isMenuOpen = !0, typeof e.stopPropagation == "function" && this.onAfterMenuShow.notify(callbackArgs, e, this).getReturnValue(); } - handleBodyMouseDown(event) { + getGridUidSelector() { + let gridUid = this.grid.getUID() || ""; + return gridUid ? `.${gridUid}` : ""; + } + handleBodyMouseDown(e) { var _a; - (this._menuElm !== event.target && !((_a = this._menuElm) != null && _a.contains(event.target)) && this._isMenuOpen || event.target.className === "close") && this.hideMenu(event); + let isMenuClicked = !1; + (_a = this._menuElm) != null && _a.contains(e.target) && (isMenuClicked = !0), isMenuClicked || document.querySelectorAll(`.slick-gridmenu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => { + subElm.contains(e.target) && (isMenuClicked = !0); + }), (this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented && this._isMenuOpen || e.target.className === "close") && this.hideMenu(e); } - handleMenuItemClick(item, e) { + handleMenuItemClick(item, level = 0, e) { var _a; - let command = item.command || ""; - if (item.disabled || item.divider || item === "divider") - return; - if (command != null && command != "") { - let callbackArgs = { - grid: this.grid, - command, - item, - allColumns: this.columns, - visibleColumns: this.getVisibleColumns() - }; - this.onCommand.notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs); + if (item !== "divider" && !item.disabled && !item.divider) { + let command = item.command || ""; + if (Utils.isDefined(command) && !item.customItems) { + let callbackArgs = { + grid: this.grid, + command, + item, + allColumns: this.columns, + visibleColumns: this.getVisibleColumns() + }; + this.onCommand.notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs), !!!((_a = this._gridMenuOptions) != null && _a.leaveOpen) && !e.defaultPrevented && this.hideMenu(e), e.preventDefault(), e.stopPropagation(); + } else + item.customItems ? this.repositionSubMenu(item, level, e) : this.destroySubMenus(); } - !!!((_a = this._gridMenuOptions) != null && _a.leaveOpen) && !e.defaultPrevented && this.hideMenu(e), e.preventDefault(), e.stopPropagation(); } hideMenu(e) { if (this._menuElm) { - Utils.hide(this._menuElm), this._isMenuOpen = !1; let callbackArgs = { grid: this.grid, menu: this._menuElm, allColumns: this.columns, visibleColumns: this.getVisibleColumns() }; - if (this.onMenuClose.notify(callbackArgs, e, this).getReturnValue() == !1) + if (this._isMenuOpen && this.onMenuClose.notify(callbackArgs, e, this).getReturnValue() === !1) return; + this._isMenuOpen = !1, Utils.hide(this._menuElm); } + this.destroySubMenus(); } /** Update the Titles of each sections (command, customTitle, ...) */ updateAllTitles(gridMenuOptions) { var _a, _b; (_a = this._customTitleElm) != null && _a.innerHTML && (this._customTitleElm.innerHTML = gridMenuOptions.customTitle || ""), (_b = this._columnTitleElm) != null && _b.innerHTML && (this._columnTitleElm.innerHTML = gridMenuOptions.columnTitle || ""); } + addSubMenuTitleWhenExists(item, commandOrOptionMenu) { + if (item !== "divider" && (item != null && item.subMenuTitle)) { + let subMenuTitleElm = document.createElement("div"); + subMenuTitleElm.className = "slick-menu-title", subMenuTitleElm.textContent = item.subMenuTitle; + let subMenuTitleClass = item.subMenuTitleCssClass; + subMenuTitleClass && subMenuTitleElm.classList.add(...subMenuTitleClass.split(" ")), commandOrOptionMenu.appendChild(subMenuTitleElm); + } + } + repositionSubMenu(item, level, e) { + e.target.classList.contains("slick-cell") && this.destroySubMenus(); + let subMenuElm = this.createMenu(level + 1, item); + subMenuElm.style.display = "block", document.body.appendChild(subMenuElm), this.repositionMenu(e, subMenuElm); + } + /** + * Reposition the menu drop (up/down) and the side (left/right) + * @param {*} event + */ + repositionMenu(e, menuElm, buttonElm) { + var _a, _b, _c, _d; + let targetEvent = e.touches ? e.touches[0] : e, isSubMenu = menuElm.classList.contains("slick-submenu"), parentElm = isSubMenu ? e.target.closest(".slick-gridmenu-item") : targetEvent.target, menuIconOffset = Utils.offset(buttonElm || this._buttonElm), menuWidth = menuElm.offsetWidth, useClickToRepositionMenu = ((_a = this._gridMenuOptions) == null ? void 0 : _a.useClickToRepositionMenu) !== void 0 ? this._gridMenuOptions.useClickToRepositionMenu : this._defaults.useClickToRepositionMenu, contentMinWidth = (_b = this._gridMenuOptions) != null && _b.contentMinWidth ? this._gridMenuOptions.contentMinWidth : this._defaults.contentMinWidth, currentMenuWidth = contentMinWidth > menuWidth ? contentMinWidth : menuWidth + 5, menuOffsetTop = useClickToRepositionMenu && targetEvent.pageY > 0 ? targetEvent.pageY : menuIconOffset.top + 10, menuOffsetLeft = useClickToRepositionMenu && targetEvent.pageX > 0 ? targetEvent.pageX : menuIconOffset.left + 10; + if (isSubMenu && parentElm) { + let parentOffset = Utils.offset(parentElm); + menuOffsetLeft = (_c = parentOffset == null ? void 0 : parentOffset.left) != null ? _c : 0, menuOffsetTop = (_d = parentOffset == null ? void 0 : parentOffset.top) != null ? _d : 0; + let gridPos = this.grid.getGridPosition(), subMenuPosCalc = menuOffsetLeft + Number(menuWidth); + isSubMenu && (subMenuPosCalc += parentElm.clientWidth); + let browserWidth = document.documentElement.clientWidth; + (subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth ? "left" : "right") === "left" ? (menuElm.classList.remove("dropright"), menuElm.classList.add("dropleft"), menuOffsetLeft -= menuWidth) : (menuElm.classList.remove("dropleft"), menuElm.classList.add("dropright"), isSubMenu && (menuOffsetLeft += parentElm.offsetWidth)); + } else + menuOffsetTop += 10, menuOffsetLeft = menuOffsetLeft - currentMenuWidth + 10; + menuElm.style.top = `${menuOffsetTop}px`, menuElm.style.left = `${menuOffsetLeft}px`, contentMinWidth > 0 && (this._menuElm.style.minWidth = `${contentMinWidth}px`); + } updateColumnOrder() { let current = this.grid.getColumns().slice(0), ordered = new Array(this.columns.length); for (let i = 0; i < ordered.length; i++) diff --git a/dist/browser/controls/slick.gridmenu.js.map b/dist/browser/controls/slick.gridmenu.js.map index 55676c6bb..07e2297b4 100644 --- a/dist/browser/controls/slick.gridmenu.js.map +++ b/dist/browser/controls/slick.gridmenu.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/controls/slick.gridmenu.ts"], - "sourcesContent": ["import type { Column, DOMMouseOrTouchEvent, GridMenuCommandItemCallbackArgs, GridMenuEventWithElementCallbackArgs, GridMenuItem, GridMenuOption, GridOption, onGridMenuColumnsChangedCallbackArgs } from '../models/index';\nimport { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A control to add a Grid Menu (hambuger menu on top-right of the grid)\n *\n * USAGE:\n *\n * Add the slick.gridmenu.(js|css) files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n * let gridMenuControl = new Slick.Controls.GridMenu(columns, grid, options);\n *\n * Available grid options, by defining a gridMenu object:\n *\n * let options = {\n * enableCellNavigation: true,\n * gridMenu: {\n * customTitle: \"Custom Menus\", // default to empty string\n * columnTitle: \"Columns\", // default to empty string\n * iconImage: \"some-image.png\", // this is the Grid Menu icon (hamburger icon)\n * iconCssClass: \"fa fa-bars\", // you can provide iconImage OR iconCssClass\n * leaveOpen: false, // do we want to leave the Grid Menu open after a command execution? (false by default)\n * menuWidth: 18, // width (icon) that will be use to resize the column header container (18 by default)\n * contentMinWidth: 0,\t\t\t\t\t\t\t // defaults to 0 (auto), minimum width of grid menu content (command, column list)\n * marginBottom: 15, // defaults to 15, margin to use at the bottom of the grid when using max-height (default)\n * resizeOnShowHeaderRow: false, // false by default\n * showButton: true, // true by default - it allows the user to control if the\n * // default gridMenu button (located on the top right corner by default CSS)\n * // should be created or omitted\n * useClickToRepositionMenu: true, // true by default\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\"\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\"\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n *\n * customItems: [\n * {\n * // custom menu item options\n * },\n * {\n * // custom menu item options\n * }\n * ]\n * }\n * };\n *\n *\n * Available menu options:\n * hideForceFitButton: Hide the \"Force fit columns\" button (defaults to false)\n * hideSyncResizeButton: Hide the \"Synchronous resize\" button (defaults to false)\n * forceFitTitle: Text of the title \"Force fit columns\"\n * contentMinWidth:\t\t\t\t\t\tminimum width of grid menu content (command, column list), defaults to 0 (auto)\n * height: Height of the Grid Menu content, when provided it will be used instead of the max-height (defaults to undefined)\n * menuWidth: Grid menu button width (defaults to 18)\n * resizeOnShowHeaderRow: Do we want to resize on the show header row event\n * syncResizeTitle: Text of the title \"Synchronous resize\"\n * useClickToRepositionMenu: Use the Click offset to reposition the Grid Menu (defaults to true), when set to False it will use the icon offset to reposition the grid menu\n * menuUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling the menu from being usable (must be combined with a custom formatter)\n * marginBottom: Margin to use at the bottom of the grid menu, only in effect when height is undefined (defaults to 15)\n *\n * Available custom menu item options:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * title: Menu item text.\n * divider: Whether the current item is a divider, not an actual command.\n * disabled: Whether the item/command is disabled.\n * hidden: Whether the item/command is hidden.\n * tooltip: Item tooltip.\n * command: A command identifier to be passed to the onCommand event handlers.\n * cssClass: A CSS class to be added to the menu item container.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * iconImage: A url to the icon image.\n * textCssClass: A CSS class to be added to the menu item text.\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n *\n * The plugin exposes the following events:\n *\n * onAfterMenuShow: Fired after the menu is shown. You can customize the menu or dismiss it by returning false.\n * * ONLY works with a JS event (as per slick.core code), so we cannot notify when it's a button event (when grid menu is attached to an external button, not the hamburger menu)\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * * ONLY works with a JS event (as per slick.core code), so we cannot notify when it's a button event (when grid menu is attached to an external button, not the hamburger menu)\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onMenuClose: Fired when the menu is closing.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onCommand: Fired on menu item click for buttons with 'command' specified.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * command: Button command identified.\n * button: Button options. Note that you can change the button options in your\n * event handler, and the column header will be automatically updated to\n * reflect them. This is useful if you want to implement something like a\n * toggle button.\n */\n\nexport class SlickGridMenu {\n // --\n // public API\n onAfterMenuShow = new SlickEvent();\n onBeforeMenuShow = new SlickEvent();\n onMenuClose = new SlickEvent();\n onCommand = new SlickEvent();\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _bindingEventService: BindingEventService_;\n protected _gridOptions: GridOption;\n protected _gridUid: string;\n protected _isMenuOpen = false;\n protected _gridMenuOptions: GridMenuOption | null = null;\n protected _columnTitleElm!: HTMLElement;\n protected _customTitleElm!: HTMLElement;\n protected _customMenuElm!: HTMLElement;\n protected _headerElm: HTMLDivElement | null = null;\n protected _listElm!: HTMLElement;\n protected _buttonElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _defaults = {\n showButton: true,\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n marginBottom: 15,\n menuWidth: 18,\n contentMinWidth: 0,\n resizeOnShowHeaderRow: false,\n syncResizeTitle: 'Synchronous resize',\n useClickToRepositionMenu: true,\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name,\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, gridOptions: GridOption) {\n this._gridUid = grid.getUID();\n this._gridOptions = gridOptions;\n this._gridMenuOptions = Utils.extend({}, gridOptions.gridMenu);\n this._bindingEventService = new BindingEventService();\n\n // when a grid optionally changes from a regular grid to a frozen grid, we need to destroy & recreate the grid menu\n // we do this change because the Grid Menu is on the left container for a regular grid, it is however on the right container for a frozen grid\n grid.onSetOptions.subscribe((_e, args) => {\n if (args && args.optionsBefore && args.optionsAfter) {\n const switchedFromRegularToFrozen = args.optionsBefore.frozenColumn! >= 0 && args.optionsAfter.frozenColumn === -1;\n const switchedFromFrozenToRegular = args.optionsBefore.frozenColumn === -1 && args.optionsAfter.frozenColumn! >= 0;\n if (switchedFromRegularToFrozen || switchedFromFrozenToRegular) {\n this.recreateGridMenu();\n }\n }\n });\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n this._gridOptions = grid.getOptions();\n this.createGridMenu();\n\n // subscribe to the grid, when it's destroyed, we should also destroy the Grid Menu\n grid.onBeforeDestroy.subscribe(this.destroy.bind(this));\n }\n\n setOptions(newOptions: GridMenuOption) {\n this._gridMenuOptions = Utils.extend({}, this._gridMenuOptions, newOptions);\n }\n\n protected createGridMenu() {\n const gridMenuWidth = (this._gridMenuOptions?.menuWidth) || this._defaults.menuWidth;\n if (this._gridOptions && this._gridOptions.hasOwnProperty('frozenColumn') && this._gridOptions.frozenColumn! >= 0) {\n this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-right`);\n } else {\n this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-left`);\n }\n this._headerElm!.style.width = `calc(100% - ${gridMenuWidth}px)`;\n\n // if header row is enabled, we need to resize its width also\n const enableResizeHeaderRow = (this._gridMenuOptions?.resizeOnShowHeaderRow != undefined) ? this._gridMenuOptions.resizeOnShowHeaderRow : this._defaults.resizeOnShowHeaderRow;\n if (enableResizeHeaderRow && this._gridOptions.showHeaderRow) {\n const headerRow = document.querySelector(`.${this._gridUid}.slick-headerrow`);\n if (headerRow) {\n headerRow.style.width = `calc(100% - ${gridMenuWidth}px)`;\n }\n }\n\n const showButton = (this._gridMenuOptions?.showButton !== undefined) ? this._gridMenuOptions.showButton : this._defaults.showButton;\n if (showButton) {\n this._buttonElm = document.createElement('button');\n this._buttonElm.className = 'slick-gridmenu-button';\n this._buttonElm.ariaLabel = 'Grid Menu';\n\n if (this._gridMenuOptions?.iconCssClass) {\n this._buttonElm.classList.add(...this._gridMenuOptions.iconCssClass.split(' '));\n } else {\n const iconImageElm = document.createElement('img');\n iconImageElm.src = (this._gridMenuOptions?.iconImage) ? this._gridMenuOptions.iconImage : '../images/drag-handle.png';\n this._buttonElm.appendChild(iconImageElm);\n }\n\n this._headerElm!.parentElement!.insertBefore(this._buttonElm, this._headerElm!.parentElement!.firstChild);\n\n // add on click handler for the Grid Menu itself\n this._bindingEventService.bind(this._buttonElm, 'click', this.showGridMenu.bind(this) as EventListener);\n }\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-gridmenu ${this._gridUid}`;\n this._menuElm.style.display = 'none';\n document.body.appendChild(this._menuElm);\n\n const buttonElm = document.createElement('button');\n buttonElm.type = 'button';\n buttonElm.className = 'close';\n buttonElm.dataset.dismiss = 'slick-gridmenu';\n buttonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.innerHTML = '×';\n buttonElm.appendChild(spanCloseElm);\n this._menuElm.appendChild(buttonElm);\n\n this._customMenuElm = document.createElement('div');\n this._customMenuElm.className = 'slick-gridmenu-custom';\n this._customMenuElm.role = 'menu';\n\n this._menuElm.appendChild(this._customMenuElm);\n\n this.populateCustomMenus(this._gridMenuOptions || {}, this._customMenuElm);\n this.populateColumnPicker();\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n /** Destroy the plugin by unsubscribing every events & also delete the menu DOM elements */\n destroy() {\n this.onAfterMenuShow.unsubscribe();\n this.onBeforeMenuShow.unsubscribe();\n this.onMenuClose.unsubscribe();\n this.onCommand.unsubscribe();\n this.onColumnsChanged.unsubscribe();\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this.grid.onBeforeDestroy.unsubscribe();\n this.grid.onSetOptions.unsubscribe();\n this._bindingEventService.unbindAll();\n this._menuElm?.remove();\n this.deleteMenu();\n }\n\n /** Delete the menu DOM element but without unsubscribing any events */\n deleteMenu() {\n this._bindingEventService.unbindAll();\n const gridMenuElm = document.querySelector(`div.slick-gridmenu.${this._gridUid}`);\n if (gridMenuElm) {\n gridMenuElm.style.display = 'none';\n }\n if (this._headerElm) {\n // put back original width (fixes width and frozen+gridMenu on left header)\n this._headerElm.style.width = '100%';\n }\n this._buttonElm?.remove();\n this._menuElm?.remove();\n }\n\n protected populateCustomMenus(gridMenuOptions: GridMenuOption, customMenuElm: HTMLElement) {\n // Construct the custom menu items.\n if (!gridMenuOptions || !gridMenuOptions.customItems) {\n return;\n }\n\n // user could pass a title on top of the custom section\n if (this._gridMenuOptions?.customTitle) {\n this._customTitleElm = document.createElement('div');\n this._customTitleElm.className = 'title';\n this._customTitleElm.innerHTML = this._gridMenuOptions.customTitle;\n customMenuElm.appendChild(this._customTitleElm);\n }\n\n for (let i = 0, ln = gridMenuOptions.customItems.length; i < ln; i++) {\n let addClickListener = true;\n const item = gridMenuOptions.customItems[i];\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n columns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as GridMenuItem).itemVisibilityOverride, callbackArgs);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as GridMenuItem).itemUsabilityOverride, callbackArgs);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemCommandClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as GridMenuItem).disabled = isItemUsable ? false : true;\n }\n\n const liElm = document.createElement('div');\n liElm.className = 'slick-gridmenu-item';\n liElm.role = 'menuitem';\n\n if ((item as GridMenuItem).divider || item === 'divider') {\n liElm.classList.add('slick-gridmenu-item-divider');\n addClickListener = false;\n }\n if ((item as GridMenuItem).disabled) {\n liElm.classList.add('slick-gridmenu-item-disabled');\n }\n\n if ((item as GridMenuItem).hidden) {\n liElm.classList.add('slick-gridmenu-item-hidden');\n }\n\n if ((item as GridMenuItem).cssClass) {\n liElm.classList.add(...(item as GridMenuItem).cssClass!.split(' '));\n }\n\n if ((item as GridMenuItem).tooltip) {\n liElm.title = (item as GridMenuItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-gridmenu-icon';\n\n liElm.appendChild(iconElm);\n\n if ((item as GridMenuItem).iconCssClass) {\n iconElm.classList.add(...(item as GridMenuItem).iconCssClass!.split(' '));\n }\n\n if ((item as GridMenuItem).iconImage) {\n iconElm.style.backgroundImage = `url(${(item as GridMenuItem).iconImage})`;\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-gridmenu-content';\n textElm.innerHTML = (item as GridMenuItem).title || '';\n\n liElm.appendChild(textElm);\n\n if ((item as GridMenuItem).textCssClass) {\n textElm.classList.add(...(item as GridMenuItem).textCssClass!.split(' '));\n }\n\n customMenuElm.appendChild(liElm);\n\n if (addClickListener) {\n this._bindingEventService.bind(liElm, 'click', this.handleMenuItemClick.bind(this, item) as EventListener);\n }\n }\n }\n\n /** Build the column picker, the code comes almost untouched from the file \"slick.columnpicker.js\" */\n protected populateColumnPicker() {\n this.grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n // user could pass a title on top of the columns list\n if (this._gridMenuOptions?.columnTitle) {\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'title';\n this._columnTitleElm.innerHTML = this._gridMenuOptions.columnTitle;\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-gridmenu-list';\n this._listElm.role = 'menu';\n }\n\n /** Delete and then Recreate the Grid Menu (for example when we switch from regular to a frozen grid) */\n recreateGridMenu() {\n this.deleteMenu();\n this.init(this.grid);\n }\n\n showGridMenu(e: DOMMouseOrTouchEvent) {\n const targetEvent = e.touches ? e.touches[0] : e;\n e.preventDefault();\n\n // empty both the picker list & the command list\n Utils.emptyElement(this._listElm);\n Utils.emptyElement(this._customMenuElm);\n\n this.populateCustomMenus(this._gridMenuOptions || {}, this._customMenuElm);\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n\n // run the override function (when defined), if the result is false it won't go further\n if (this._gridMenuOptions && !this.runOverrideFunctionWhenExists(this._gridMenuOptions.menuUsabilityOverride, callbackArgs)) {\n return;\n }\n\n // notify of the onBeforeMenuShow only works when\n // this mean that we cannot notify when the grid menu is attach to a button event\n if (typeof e.stopPropagation === 'function') {\n if (this.onBeforeMenuShow.notify(callbackArgs, e, this).getReturnValue() == false) {\n return;\n }\n }\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n excludeCssClass = this.columns[i].excludeFromGridMenu ? 'hidden' : '';\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = this.columns[i]?.name || '';\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}-gridmenu-colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n if (this.grid.getColumnIndex(this.columns[i].id) != null && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n this._columnCheckboxes.push(checkboxElm);\n\n // get the column label from the picker value extractor (user can optionally provide a custom extractor)\n if (this._gridMenuOptions?.headerColumnValueExtractor) {\n columnLabel = this._gridMenuOptions.headerColumnValueExtractor(this.columns[i], this._gridOptions);\n } else {\n columnLabel = this._defaults.headerColumnValueExtractor(this.columns[i]);\n }\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-${columnId}`;\n labelElm.innerHTML = columnLabel || '';\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._gridMenuOptions && (!this._gridMenuOptions.hideForceFitButton || !this._gridMenuOptions.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!(this._gridMenuOptions?.hideForceFitButton)) {\n const forceFitTitle = (this._gridMenuOptions?.forceFitTitle) || this._defaults.forceFitTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle;\n liElm.role = 'menuitem';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-forcefit`;\n labelElm.textContent = forceFitTitle;\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!(this._gridMenuOptions?.hideSyncResizeButton)) {\n const syncResizeTitle = (this._gridMenuOptions?.syncResizeTitle) || this._defaults.syncResizeTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle;\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle;\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n let buttonElm = (e.target.nodeName === 'BUTTON' ? e.target : e.target.querySelector('button')) as HTMLButtonElement; // get button element\n if (!buttonElm) {\n buttonElm = e.target.parentElement as HTMLButtonElement; // external grid menu might fall in this last case if wrapped in a span/div\n }\n\n // we need to display the menu to properly calculate its width but we can however make it invisible\n this._menuElm.style.display = 'block';\n this._menuElm.style.opacity = '0';\n\n const menuIconOffset = Utils.offset(buttonElm); // get button offset position\n const menuWidth = this._menuElm.offsetWidth;\n const useClickToRepositionMenu = (this._gridMenuOptions?.useClickToRepositionMenu !== undefined) ? this._gridMenuOptions.useClickToRepositionMenu : this._defaults.useClickToRepositionMenu;\n const contentMinWidth = (this._gridMenuOptions?.contentMinWidth) ? this._gridMenuOptions.contentMinWidth : this._defaults.contentMinWidth;\n const currentMenuWidth = (contentMinWidth > menuWidth) ? contentMinWidth : menuWidth + 5;\n const nextPositionTop = (useClickToRepositionMenu && targetEvent.pageY > 0) ? targetEvent.pageY : menuIconOffset!.top + 10;\n const nextPositionLeft = (useClickToRepositionMenu && targetEvent.pageX > 0) ? targetEvent.pageX : menuIconOffset!.left + 10;\n const menuMarginBottom = (this._gridMenuOptions?.marginBottom !== undefined) ? this._gridMenuOptions.marginBottom : this._defaults.marginBottom;\n\n this._menuElm.style.top = `${nextPositionTop + 10}px`;\n this._menuElm.style.left = `${nextPositionLeft - currentMenuWidth + 10}px`;\n\n if (contentMinWidth > 0) {\n this._menuElm.style.minWidth = `${contentMinWidth}px`;\n }\n\n // set \"height\" when defined OR ELSE use the \"max-height\" with available window size and optional margin bottom\n if (this._gridMenuOptions?.height !== undefined) {\n this._menuElm.style.height = `${this._gridMenuOptions.height}px`;\n } else {\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY - menuMarginBottom}px`;\n }\n\n this._menuElm.style.display = 'block';\n this._menuElm.style.opacity = '1'; // restore menu visibility\n this._menuElm.appendChild(this._listElm);\n this._isMenuOpen = true;\n\n if (typeof e.stopPropagation === 'function') {\n if (this.onAfterMenuShow.notify(callbackArgs, e, this).getReturnValue() == false) {\n return;\n }\n }\n }\n\n protected handleBodyMouseDown(event: DOMMouseOrTouchEvent) {\n if ((this._menuElm !== event.target && !(this._menuElm?.contains(event.target)) && this._isMenuOpen) || event.target.className === 'close') {\n this.hideMenu(event);\n }\n }\n\n protected handleMenuItemClick(item: any, e: DOMMouseOrTouchEvent) {\n const command = item.command || '';\n\n if (item.disabled || item.divider || item === 'divider') {\n return;\n }\n\n if (command != null && command != '') {\n const callbackArgs = {\n grid: this.grid,\n command: command,\n item: item,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n this.onCommand.notify(callbackArgs, e, this);\n\n // execute action callback when defined\n if (typeof item.action === 'function') {\n item.action.call(this, e, callbackArgs);\n }\n }\n\n // does the user want to leave open the Grid Menu after executing a command?\n const leaveOpen = !!(this._gridMenuOptions?.leaveOpen);\n if (!leaveOpen && !e.defaultPrevented) {\n this.hideMenu(e);\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n e.preventDefault();\n e.stopPropagation();\n }\n\n hideMenu(e: DOMMouseOrTouchEvent) {\n if (this._menuElm) {\n Utils.hide(this._menuElm);\n this._isMenuOpen = false;\n\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n if (this.onMenuClose.notify(callbackArgs, e, this).getReturnValue() == false) {\n return;\n }\n }\n }\n\n /** Update the Titles of each sections (command, customTitle, ...) */\n updateAllTitles(gridMenuOptions: GridMenuOption) {\n if (this._customTitleElm?.innerHTML) {\n this._customTitleElm.innerHTML = gridMenuOptions.customTitle || '';\n }\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = gridMenuOptions.columnTitle || '';\n }\n }\n\n protected updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n protected updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked = e.target.checked;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n this.grid.setOptions({ syncColumnCellResize: !!(e.target.checked) });\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (columnCheckbox.checked) {\n if (this.columns[idx].hidden) { this.columns[idx].hidden = false; }\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n const callbackArgs = {\n columnId,\n showing: isChecked,\n grid: this.grid,\n allColumns: this.columns,\n columns: visibleColumns,\n visibleColumns: this.getVisibleColumns()\n };\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify(callbackArgs, e, this);\n }\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.GridMenu = SlickGridMenu;\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import type { Column, DOMMouseOrTouchEvent, GridMenuCommandItemCallbackArgs, GridMenuEventWithElementCallbackArgs, GridMenuItem, GridMenuOption, GridOption, onGridMenuColumnsChangedCallbackArgs } from '../models/index';\nimport { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A control to add a Grid Menu (hambuger menu on top-right of the grid)\n *\n * USAGE:\n *\n * Add the slick.gridmenu.(js|css) files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n * let gridMenuControl = new Slick.Controls.GridMenu(columns, grid, options);\n *\n * Available grid options, by defining a gridMenu object:\n *\n * let options = {\n * enableCellNavigation: true,\n * gridMenu: {\n * customTitle: \"Custom Menus\", // default to empty string\n * columnTitle: \"Columns\", // default to empty string\n * iconImage: \"some-image.png\", // this is the Grid Menu icon (hamburger icon)\n * iconCssClass: \"fa fa-bars\", // you can provide iconImage OR iconCssClass\n * leaveOpen: false, // do we want to leave the Grid Menu open after a command execution? (false by default)\n * menuWidth: 18, // width (icon) that will be use to resize the column header container (18 by default)\n * contentMinWidth: 0,\t\t\t\t\t\t\t // defaults to 0 (auto), minimum width of grid menu content (command, column list)\n * marginBottom: 15, // defaults to 15, margin to use at the bottom of the grid when using max-height (default)\n * resizeOnShowHeaderRow: false, // false by default\n * showButton: true, // true by default - it allows the user to control if the\n * // default gridMenu button (located on the top right corner by default CSS)\n * // should be created or omitted\n * useClickToRepositionMenu: true, // true by default\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\"\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\"\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n *\n * customItems: [\n * {\n * // custom menu item options\n * },\n * {\n * // custom menu item options\n * }\n * ]\n * }\n * };\n *\n *\n * Available menu options:\n * hideForceFitButton: Hide the \"Force fit columns\" button (defaults to false)\n * hideSyncResizeButton: Hide the \"Synchronous resize\" button (defaults to false)\n * forceFitTitle: Text of the title \"Force fit columns\"\n * contentMinWidth:\t\t\t\t\t\tminimum width of grid menu content (command, column list), defaults to 0 (auto)\n * height: Height of the Grid Menu content, when provided it will be used instead of the max-height (defaults to undefined)\n * menuWidth: Grid menu button width (defaults to 18)\n * resizeOnShowHeaderRow: Do we want to resize on the show header row event\n * syncResizeTitle: Text of the title \"Synchronous resize\"\n * useClickToRepositionMenu: Use the Click offset to reposition the Grid Menu (defaults to true), when set to False it will use the icon offset to reposition the grid menu\n * menuUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling the menu from being usable (must be combined with a custom formatter)\n * marginBottom: Margin to use at the bottom of the grid menu, only in effect when height is undefined (defaults to 15)\n * subItemChevronClass: CSS class that can be added on the right side of a sub-item parent (typically a chevron-right icon)\n *\n * Available custom menu item options:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * title: Menu item text.\n * divider: Whether the current item is a divider, not an actual command.\n * disabled: Whether the item/command is disabled.\n * hidden: Whether the item/command is hidden.\n * tooltip: Item tooltip.\n * command: A command identifier to be passed to the onCommand event handlers.\n * cssClass: A CSS class to be added to the menu item container.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * iconImage: A url to the icon image.\n * textCssClass: A CSS class to be added to the menu item text.\n * subMenuTitle: Optional sub-menu title that will shows up when sub-menu commmands/options list is opened\n * subMenuTitleCssClass: Optional sub-menu title CSS class to use with `subMenuTitle`\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n *\n * The plugin exposes the following events:\n *\n * onAfterMenuShow: Fired after the menu is shown. You can customize the menu or dismiss it by returning false.\n * * ONLY works with a JS event (as per slick.core code), so we cannot notify when it's a button event (when grid menu is attached to an external button, not the hamburger menu)\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * * ONLY works with a JS event (as per slick.core code), so we cannot notify when it's a button event (when grid menu is attached to an external button, not the hamburger menu)\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onMenuClose: Fired when the menu is closing.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onCommand: Fired on menu item click for buttons with 'command' specified.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * command: Button command identified.\n * button: Button options. Note that you can change the button options in your\n * event handler, and the column header will be automatically updated to\n * reflect them. This is useful if you want to implement something like a\n * toggle button.\n */\n\nexport class SlickGridMenu {\n // --\n // public API\n onAfterMenuShow = new SlickEvent();\n onBeforeMenuShow = new SlickEvent();\n onMenuClose = new SlickEvent();\n onCommand = new SlickEvent();\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _bindingEventService: BindingEventService_;\n protected _gridOptions: GridOption;\n protected _gridUid: string;\n protected _isMenuOpen = false;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _columnTitleElm!: HTMLElement;\n protected _customTitleElm!: HTMLElement;\n protected _customMenuElm!: HTMLDivElement;\n protected _headerElm: HTMLDivElement | null = null;\n protected _listElm!: HTMLElement;\n protected _buttonElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _subMenuParentId = '';\n protected _gridMenuOptions: GridMenuOption | null = null;\n protected _defaults: GridMenuOption = {\n showButton: true,\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n marginBottom: 15,\n menuWidth: 18,\n contentMinWidth: 0,\n resizeOnShowHeaderRow: false,\n syncResizeTitle: 'Synchronous resize',\n useClickToRepositionMenu: true,\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name as string,\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, gridOptions: GridOption) {\n this._gridUid = grid.getUID();\n this._gridOptions = gridOptions;\n this._gridMenuOptions = Utils.extend({}, gridOptions.gridMenu);\n this._bindingEventService = new BindingEventService();\n\n // when a grid optionally changes from a regular grid to a frozen grid, we need to destroy & recreate the grid menu\n // we do this change because the Grid Menu is on the left container for a regular grid, it is however on the right container for a frozen grid\n grid.onSetOptions.subscribe((_e, args) => {\n if (args && args.optionsBefore && args.optionsAfter) {\n const switchedFromRegularToFrozen = args.optionsBefore.frozenColumn! >= 0 && args.optionsAfter.frozenColumn === -1;\n const switchedFromFrozenToRegular = args.optionsBefore.frozenColumn === -1 && args.optionsAfter.frozenColumn! >= 0;\n if (switchedFromRegularToFrozen || switchedFromFrozenToRegular) {\n this.recreateGridMenu();\n }\n }\n });\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n this._gridOptions = grid.getOptions();\n this.createGridMenu();\n\n // subscribe to the grid, when it's destroyed, we should also destroy the Grid Menu\n grid.onBeforeDestroy.subscribe(this.destroy.bind(this));\n }\n\n setOptions(newOptions: GridMenuOption) {\n this._gridMenuOptions = Utils.extend({}, this._gridMenuOptions, newOptions);\n }\n\n protected createGridMenu() {\n const gridMenuWidth = (this._gridMenuOptions?.menuWidth) || this._defaults.menuWidth;\n if (this._gridOptions && this._gridOptions.hasOwnProperty('frozenColumn') && this._gridOptions.frozenColumn! >= 0) {\n this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-right`);\n } else {\n this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-left`);\n }\n this._headerElm!.style.width = `calc(100% - ${gridMenuWidth}px)`;\n\n // if header row is enabled, we need to resize its width also\n const enableResizeHeaderRow = (Utils.isDefined(this._gridMenuOptions?.resizeOnShowHeaderRow)) ? this._gridMenuOptions!.resizeOnShowHeaderRow : this._defaults.resizeOnShowHeaderRow;\n if (enableResizeHeaderRow && this._gridOptions.showHeaderRow) {\n const headerRow = document.querySelector(`.${this._gridUid}.slick-headerrow`);\n if (headerRow) {\n headerRow.style.width = `calc(100% - ${gridMenuWidth}px)`;\n }\n }\n\n const showButton = (this._gridMenuOptions?.showButton !== undefined) ? this._gridMenuOptions.showButton : this._defaults.showButton;\n if (showButton) {\n this._buttonElm = document.createElement('button');\n this._buttonElm.className = 'slick-gridmenu-button';\n this._buttonElm.ariaLabel = 'Grid Menu';\n\n if (this._gridMenuOptions?.iconCssClass) {\n this._buttonElm.classList.add(...this._gridMenuOptions.iconCssClass.split(' '));\n } else {\n const iconImageElm = document.createElement('img');\n iconImageElm.src = (this._gridMenuOptions?.iconImage) ? this._gridMenuOptions.iconImage : '../images/drag-handle.png';\n this._buttonElm.appendChild(iconImageElm);\n }\n\n this._headerElm!.parentElement!.insertBefore(this._buttonElm, this._headerElm!.parentElement!.firstChild);\n\n // add on click handler for the Grid Menu itself\n this._bindingEventService.bind(this._buttonElm, 'click', this.showGridMenu.bind(this) as EventListener);\n }\n\n this._menuElm = this.createMenu(0);\n this.populateColumnPicker();\n document.body.appendChild(this._menuElm);\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n /** Create the menu or sub-menu(s) but without the column picker which is a separate single process */\n createMenu(level = 0, item?: GridMenuItem | 'divider') {\n // create a new cell menu\n const maxHeight = isNaN(this._gridMenuOptions?.maxHeight as number) ? this._gridMenuOptions?.maxHeight : `${this._gridMenuOptions?.maxHeight ?? 0}px`;\n const width = isNaN(this._gridMenuOptions?.width as number) ? this._gridMenuOptions?.width : `${this._gridMenuOptions?.maxWidth ?? 0}px`;\n\n // to avoid having multiple sub-menu trees opened,\n // we need to somehow keep trace of which parent menu the tree belongs to\n // and we should keep ref of only the first sub-menu parent, we can use the command name (remove any whitespaces though)\n const subMenuCommand = (item as GridMenuItem)?.command;\n let subMenuId = (level === 1 && subMenuCommand) ? subMenuCommand.replaceAll(' ', '') : '';\n if (subMenuId) {\n this._subMenuParentId = subMenuId;\n }\n if (level > 1) {\n subMenuId = this._subMenuParentId;\n }\n\n const menuClasses = `slick-gridmenu slick-menu-level-${level} ${this._gridUid}`;\n const bodyMenuElm = document.body.querySelector(`.slick-gridmenu.slick-menu-level-${level}${this.getGridUidSelector()}`);\n\n // return menu/sub-menu if it's already opened unless we are on different sub-menu tree if so close them all\n if (bodyMenuElm) {\n if (bodyMenuElm.dataset.subMenuParent === subMenuId) {\n return bodyMenuElm;\n }\n this.destroySubMenus();\n }\n\n const menuElm = document.createElement('div');\n menuElm.role = 'menu';\n menuElm.className = menuClasses;\n if (level > 0) {\n menuElm.classList.add('slick-submenu');\n if (subMenuId) {\n menuElm.dataset.subMenuParent = subMenuId;\n }\n }\n menuElm.ariaLabel = level > 1 ? 'SubMenu' : 'Grid Menu';\n\n if (width) {\n menuElm.style.width = width as string;\n }\n if (maxHeight) {\n menuElm.style.maxHeight = maxHeight as string;\n }\n\n menuElm.style.display = 'none';\n\n let closeButtonElm: HTMLButtonElement | null = null;\n if (level === 0) {\n closeButtonElm = document.createElement('button');\n closeButtonElm.type = 'button';\n closeButtonElm.className = 'close';\n closeButtonElm.dataset.dismiss = 'slick-gridmenu';\n closeButtonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.innerHTML = '×';\n closeButtonElm.appendChild(spanCloseElm);\n menuElm.appendChild(closeButtonElm);\n }\n\n // -- Command List section\n this._customMenuElm = document.createElement('div');\n this._customMenuElm.className = `slick-gridmenu-custom slick-gridmenu-command-list slick-menu-level-${level}`;\n this._customMenuElm.role = 'menu';\n menuElm.appendChild(this._customMenuElm);\n\n const commandItems = (item as GridMenuItem)?.customItems ?? this._gridMenuOptions?.customItems ?? [];\n if (commandItems.length > 0) {\n\n // when creating sub-menu add its sub-menu title when exists\n if (item && level > 0) {\n this.addSubMenuTitleWhenExists(item, this._customMenuElm); // add sub-menu title when exists\n }\n }\n this.populateCustomMenus(commandItems, this._customMenuElm, { grid: this.grid, level });\n\n // increment level for possible next sub-menus if exists\n level++;\n\n return menuElm;\n }\n\n /** Destroy the plugin by unsubscribing every events & also delete the menu DOM elements */\n destroy() {\n this.onAfterMenuShow.unsubscribe();\n this.onBeforeMenuShow.unsubscribe();\n this.onMenuClose.unsubscribe();\n this.onCommand.unsubscribe();\n this.onColumnsChanged.unsubscribe();\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this.grid.onBeforeDestroy.unsubscribe();\n this.grid.onSetOptions.unsubscribe();\n this._bindingEventService.unbindAll();\n this._menuElm?.remove();\n this.deleteMenu();\n }\n\n /** Delete the menu DOM element but without unsubscribing any events */\n deleteMenu() {\n this._bindingEventService.unbindAll();\n const gridMenuElm = document.querySelector(`div.slick-gridmenu.${this._gridUid}`);\n if (gridMenuElm) {\n gridMenuElm.style.display = 'none';\n }\n if (this._headerElm) {\n // put back original width (fixes width and frozen+gridMenu on left header)\n this._headerElm.style.width = '100%';\n }\n this._buttonElm?.remove();\n this._menuElm?.remove();\n }\n\n /** Close and destroy all previously opened sub-menus */\n destroySubMenus() {\n document.querySelectorAll(`.slick-gridmenu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => subElm.remove());\n }\n\n /** Construct the custom command menu items. */\n protected populateCustomMenus(customItems: Array, customMenuElm: HTMLElement, args: { grid: SlickGrid, level: number }) {\n // user could pass a title on top of the custom section\n const isSubMenu = args.level > 0;\n if (this._gridMenuOptions?.customTitle && !isSubMenu) {\n this._customTitleElm = document.createElement('div');\n this._customTitleElm.className = 'title';\n this._customTitleElm.innerHTML = this._gridMenuOptions.customTitle;\n customMenuElm.appendChild(this._customTitleElm);\n }\n\n for (let i = 0, ln = customItems.length; i < ln; i++) {\n let addClickListener = true;\n const item = customItems[i];\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n columns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as GridMenuItem).itemVisibilityOverride, callbackArgs);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as GridMenuItem).itemUsabilityOverride, callbackArgs);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as GridMenuItem).disabled = isItemUsable ? false : true;\n }\n\n const liElm = document.createElement('div');\n liElm.className = 'slick-gridmenu-item';\n liElm.role = 'menuitem';\n\n if ((item as GridMenuItem).divider || item === 'divider') {\n liElm.classList.add('slick-gridmenu-item-divider');\n addClickListener = false;\n }\n if ((item as GridMenuItem).disabled) {\n liElm.classList.add('slick-gridmenu-item-disabled');\n }\n\n if ((item as GridMenuItem).hidden) {\n liElm.classList.add('slick-gridmenu-item-hidden');\n }\n\n if ((item as GridMenuItem).cssClass) {\n liElm.classList.add(...(item as GridMenuItem).cssClass!.split(' '));\n }\n\n if ((item as GridMenuItem).tooltip) {\n liElm.title = (item as GridMenuItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-gridmenu-icon';\n\n liElm.appendChild(iconElm);\n\n if ((item as GridMenuItem).iconCssClass) {\n iconElm.classList.add(...(item as GridMenuItem).iconCssClass!.split(' '));\n }\n\n if ((item as GridMenuItem).iconImage) {\n iconElm.style.backgroundImage = `url(${(item as GridMenuItem).iconImage})`;\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-gridmenu-content';\n textElm.innerHTML = (item as GridMenuItem).title || '';\n\n liElm.appendChild(textElm);\n\n if ((item as GridMenuItem).textCssClass) {\n textElm.classList.add(...(item as GridMenuItem).textCssClass!.split(' '));\n }\n\n customMenuElm.appendChild(liElm);\n\n if (addClickListener) {\n this._bindingEventService.bind(liElm, 'click', this.handleMenuItemClick.bind(this, item, args.level) as EventListener);\n }\n\n // the option/command item could be a sub-menu if it has another list of commands/options\n if ((item as GridMenuItem).customItems) {\n const chevronElm = document.createElement('span');\n chevronElm.className = 'sub-item-chevron';\n if (this._gridMenuOptions?.subItemChevronClass) {\n chevronElm.classList.add(...this._gridMenuOptions.subItemChevronClass.split(' '));\n } else {\n chevronElm.textContent = '\u2B9E'; // \u2B9E or \u25B8\n }\n\n liElm.classList.add('slick-submenu-item');\n liElm.appendChild(chevronElm);\n continue;\n }\n }\n }\n\n /** Build the column picker, the code comes almost untouched from the file \"slick.columnpicker.js\" */\n protected populateColumnPicker() {\n this.grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n // user could pass a title on top of the columns list\n if (this._gridMenuOptions?.columnTitle) {\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'title';\n this._columnTitleElm.innerHTML = this._gridMenuOptions.columnTitle;\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-gridmenu-list';\n this._listElm.role = 'menu';\n }\n\n /** Delete and then Recreate the Grid Menu (for example when we switch from regular to a frozen grid) */\n recreateGridMenu() {\n this.deleteMenu();\n this.init(this.grid);\n }\n\n showGridMenu(e: DOMMouseOrTouchEvent) {\n const targetEvent = e.touches ? e.touches[0] : e;\n e.preventDefault();\n\n // empty both the picker list & the command list\n Utils.emptyElement(this._listElm);\n Utils.emptyElement(this._customMenuElm);\n\n const commandItems = this._gridMenuOptions?.customItems ?? [];\n this.populateCustomMenus(commandItems, this._customMenuElm, { grid: this.grid, level: 0 });\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n\n // run the override function (when defined), if the result is false it won't go further\n if (this._gridMenuOptions && !this.runOverrideFunctionWhenExists(this._gridMenuOptions.menuUsabilityOverride, callbackArgs)) {\n return;\n }\n\n // notify of the onBeforeMenuShow only works when\n // this mean that we cannot notify when the grid menu is attach to a button event\n if (typeof e.stopPropagation === 'function') {\n if (this.onBeforeMenuShow.notify(callbackArgs, e, this).getReturnValue() === false) {\n return;\n }\n }\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n excludeCssClass = this.columns[i].excludeFromGridMenu ? 'hidden' : '';\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = this.columns[i]?.name || '';\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}-gridmenu-colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n if (Utils.isDefined(this.grid.getColumnIndex(this.columns[i].id)) && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n this._columnCheckboxes.push(checkboxElm);\n\n // get the column label from the picker value extractor (user can optionally provide a custom extractor)\n if (this._gridMenuOptions?.headerColumnValueExtractor) {\n columnLabel = this._gridMenuOptions.headerColumnValueExtractor(this.columns[i], this._gridOptions);\n } else {\n columnLabel = this._defaults.headerColumnValueExtractor!(this.columns[i]);\n }\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-${columnId}`;\n labelElm.innerHTML = columnLabel || '';\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._gridMenuOptions && (!this._gridMenuOptions.hideForceFitButton || !this._gridMenuOptions.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!(this._gridMenuOptions?.hideForceFitButton)) {\n const forceFitTitle = (this._gridMenuOptions?.forceFitTitle) || this._defaults.forceFitTitle as string;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle;\n liElm.role = 'menuitem';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-forcefit`;\n labelElm.textContent = forceFitTitle;\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!(this._gridMenuOptions?.hideSyncResizeButton)) {\n const syncResizeTitle = (this._gridMenuOptions?.syncResizeTitle) || this._defaults.syncResizeTitle as string;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle;\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle;\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n let buttonElm = (e.target.nodeName === 'BUTTON' ? e.target : e.target.querySelector('button')) as HTMLButtonElement; // get button element\n if (!buttonElm) {\n buttonElm = e.target.parentElement as HTMLButtonElement; // external grid menu might fall in this last case if wrapped in a span/div\n }\n\n // we need to display the menu to properly calculate its width but we can however make it invisible\n this._menuElm.style.display = 'block';\n this._menuElm.style.opacity = '0';\n\n this.repositionMenu(e, this._menuElm, buttonElm);\n\n // set \"height\" when defined OR ELSE use the \"max-height\" with available window size and optional margin bottom\n const menuMarginBottom = (this._gridMenuOptions?.marginBottom !== undefined) ? this._gridMenuOptions.marginBottom : this._defaults.marginBottom as number;\n if (this._gridMenuOptions?.height !== undefined) {\n this._menuElm.style.height = `${this._gridMenuOptions.height}px`;\n } else {\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY - menuMarginBottom}px`;\n }\n\n this._menuElm.style.display = 'block';\n this._menuElm.style.opacity = '1'; // restore menu visibility\n this._menuElm.appendChild(this._listElm);\n this._isMenuOpen = true;\n\n if (typeof e.stopPropagation === 'function') {\n if (this.onAfterMenuShow.notify(callbackArgs, e, this).getReturnValue() === false) {\n return;\n }\n }\n }\n\n protected getGridUidSelector() {\n const gridUid = this.grid.getUID() || '';\n return gridUid ? `.${gridUid}` : '';\n }\n\n protected handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n // did we click inside the menu or any of its sub-menu(s)\n let isMenuClicked = false;\n if (this._menuElm?.contains(e.target)) {\n isMenuClicked = true;\n }\n if (!isMenuClicked) {\n document\n .querySelectorAll(`.slick-gridmenu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => {\n if (subElm.contains(e.target)) {\n isMenuClicked = true;\n }\n });\n }\n\n if ((this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented && this._isMenuOpen) || e.target.className === 'close') {\n this.hideMenu(e);\n }\n }\n\n protected handleMenuItemClick(item: GridMenuItem | 'divider', level = 0, e: DOMMouseOrTouchEvent) {\n if (item !== 'divider' && !item.disabled && !item.divider) {\n const command = item.command || '';\n\n if (Utils.isDefined(command) && !item.customItems) {\n const callbackArgs: GridMenuCommandItemCallbackArgs = {\n grid: this.grid,\n command,\n item,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n this.onCommand.notify(callbackArgs, e, this);\n\n // execute action callback when defined\n if (typeof item.action === 'function') {\n item.action.call(this, e, callbackArgs);\n }\n\n // does the user want to leave open the Grid Menu after executing a command?\n const leaveOpen = !!(this._gridMenuOptions?.leaveOpen);\n if (!leaveOpen && !e.defaultPrevented) {\n this.hideMenu(e);\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n e.preventDefault();\n e.stopPropagation();\n } else if ((item as GridMenuItem).customItems) {\n this.repositionSubMenu(item, level, e);\n } else {\n this.destroySubMenus();\n }\n }\n }\n\n hideMenu(e: DOMMouseOrTouchEvent) {\n if (this._menuElm) {\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n if (this._isMenuOpen && this.onMenuClose.notify(callbackArgs, e, this).getReturnValue() === false) {\n return;\n }\n this._isMenuOpen = false;\n Utils.hide(this._menuElm);\n }\n this.destroySubMenus();\n }\n\n /** Update the Titles of each sections (command, customTitle, ...) */\n updateAllTitles(gridMenuOptions: GridMenuOption) {\n if (this._customTitleElm?.innerHTML) {\n this._customTitleElm.innerHTML = gridMenuOptions.customTitle || '';\n }\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = gridMenuOptions.columnTitle || '';\n }\n }\n\n protected addSubMenuTitleWhenExists(item: GridMenuItem | 'divider', commandOrOptionMenu: HTMLDivElement) {\n if (item !== 'divider' && item?.subMenuTitle) {\n const subMenuTitleElm = document.createElement('div');\n subMenuTitleElm.className = 'slick-menu-title';\n subMenuTitleElm.textContent = item.subMenuTitle as string;\n const subMenuTitleClass = item.subMenuTitleCssClass as string;\n if (subMenuTitleClass) {\n subMenuTitleElm.classList.add(...subMenuTitleClass.split(' '));\n }\n\n commandOrOptionMenu.appendChild(subMenuTitleElm);\n }\n }\n\n protected repositionSubMenu(item: GridMenuItem | 'divider', level: number, e: DOMMouseOrTouchEvent) {\n // when we're clicking a grid cell OR our last menu type (command/option) differs then we know that we need to start fresh and close any sub-menus that might still be open\n if (e.target.classList.contains('slick-cell')) {\n this.destroySubMenus();\n }\n\n // creating sub-menu, we'll also pass level & the item object since we might have \"subMenuTitle\" to show\n const subMenuElm = this.createMenu(level + 1, item);\n subMenuElm.style.display = 'block';\n document.body.appendChild(subMenuElm);\n this.repositionMenu(e, subMenuElm);\n }\n\n /**\n * Reposition the menu drop (up/down) and the side (left/right)\n * @param {*} event\n */\n protected repositionMenu(e: DOMMouseOrTouchEvent, menuElm: HTMLElement, buttonElm?: HTMLButtonElement) {\n const targetEvent = e.touches ? e.touches[0] : e;\n const isSubMenu = menuElm.classList.contains('slick-submenu');\n const parentElm = isSubMenu\n ? e.target.closest('.slick-gridmenu-item') as HTMLDivElement\n : targetEvent.target as HTMLElement;\n\n const menuIconOffset = Utils.offset(buttonElm || this._buttonElm); // get button offset position\n const menuWidth = menuElm.offsetWidth;\n const useClickToRepositionMenu = (this._gridMenuOptions?.useClickToRepositionMenu !== undefined) ? this._gridMenuOptions.useClickToRepositionMenu : this._defaults.useClickToRepositionMenu;\n const contentMinWidth = (this._gridMenuOptions?.contentMinWidth) ? this._gridMenuOptions.contentMinWidth : this._defaults.contentMinWidth as number;\n const currentMenuWidth = (contentMinWidth > menuWidth) ? contentMinWidth : menuWidth + 5;\n let menuOffsetTop = (useClickToRepositionMenu && targetEvent.pageY > 0) ? targetEvent.pageY : menuIconOffset!.top + 10;\n let menuOffsetLeft = (useClickToRepositionMenu && targetEvent.pageX > 0) ? targetEvent.pageX : menuIconOffset!.left + 10;\n\n if (isSubMenu && parentElm) {\n const parentOffset = Utils.offset(parentElm);\n menuOffsetLeft = parentOffset?.left ?? 0;\n menuOffsetTop = parentOffset?.top ?? 0;\n const gridPos = this.grid.getGridPosition();\n let subMenuPosCalc = menuOffsetLeft + Number(menuWidth); // calculate coordinate at caller element far right\n if (isSubMenu) {\n subMenuPosCalc += parentElm.clientWidth;\n }\n const browserWidth = document.documentElement.clientWidth;\n const dropSide = (subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth) ? 'left' : 'right';\n if (dropSide === 'left') {\n menuElm.classList.remove('dropright');\n menuElm.classList.add('dropleft');\n menuOffsetLeft -= menuWidth;\n } else {\n menuElm.classList.remove('dropleft');\n menuElm.classList.add('dropright');\n if (isSubMenu) {\n menuOffsetLeft += parentElm.offsetWidth;\n }\n }\n } else {\n menuOffsetTop += 10;\n menuOffsetLeft = menuOffsetLeft - currentMenuWidth + 10;\n }\n\n menuElm.style.top = `${menuOffsetTop}px`;\n menuElm.style.left = `${menuOffsetLeft}px`;\n\n if (contentMinWidth > 0) {\n this._menuElm.style.minWidth = `${contentMinWidth}px`;\n }\n }\n\n protected updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n protected updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked = e.target.checked;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n this.grid.setOptions({ syncColumnCellResize: !!(e.target.checked) });\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (columnCheckbox.checked) {\n if (this.columns[idx].hidden) { this.columns[idx].hidden = false; }\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n const callbackArgs = {\n columnId,\n showing: isChecked,\n grid: this.grid,\n allColumns: this.columns,\n columns: visibleColumns,\n visibleColumns: this.getVisibleColumns()\n };\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify(callbackArgs, e, this);\n }\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.GridMenu = SlickGridMenu;\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/controls/slick.pager.js.map b/dist/browser/controls/slick.pager.js.map index e671b8d6e..acfbf18d6 100644 --- a/dist/browser/controls/slick.pager.js.map +++ b/dist/browser/controls/slick.pager.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/controls/slick.pager.ts"], - "sourcesContent": ["import type { PagingInfo } from '../models/index';\nimport { BindingEventService as BindingEventService_, SlickGlobalEditorLock as SlickGlobalEditorLock_, Utils as Utils_ } from '../slick.core';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickGlobalEditorLock = IIFE_ONLY ? Slick.GlobalEditorLock : SlickGlobalEditorLock_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport interface GridPagerOption {\n showAllText: string;\n showPageText: string;\n showCountText: string;\n showCount: boolean;\n pagingOptions: Array<{ data: number; name: string; ariaLabel: string; }>;\n showPageSizes: boolean;\n}\n\nexport class SlickGridPager {\n // --\n // public API\n\n // --\n // protected props\n protected _container: HTMLElement; // the container might be a string, a jQuery object or a native element\n protected _statusElm!: HTMLElement;\n protected _bindingEventService: BindingEventService_;\n protected _options: GridPagerOption;\n protected _defaults: GridPagerOption = {\n showAllText: 'Showing all {rowCount} rows',\n showPageText: 'Showing page {pageNum} of {pageCount}',\n showCountText: 'From {countBegin} to {countEnd} of {rowCount} rows',\n showCount: false,\n pagingOptions: [\n { data: 0, name: 'All', ariaLabel: 'Show All Pages' },\n { data: -1, name: 'Auto', ariaLabel: 'Auto Page Size' },\n { data: 25, name: '25', ariaLabel: 'Show 25 rows per page' },\n { data: 50, name: '50', ariaLabel: 'Show 50 rows per page' },\n { data: 100, name: '100', ariaLabel: 'Show 100 rows per page' },\n ],\n showPageSizes: false\n };\n\n constructor(protected readonly dataView: SlickDataView, protected readonly grid: SlickGrid, selectorOrElm: HTMLElement | string, options?: Partial) {\n this._container = this.getContainerElement(selectorOrElm) as HTMLElement;\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._bindingEventService = new BindingEventService();\n this.init();\n }\n\n init() {\n this.constructPagerUI();\n this.updatePager(this.dataView.getPagingInfo());\n this.dataView.onPagingInfoChanged.subscribe((_e, pagingInfo) => {\n this.updatePager(pagingInfo);\n });\n }\n\n /** Destroy function when element is destroyed */\n destroy() {\n this.setPageSize(0);\n this._bindingEventService.unbindAll();\n this._container.innerHTML = '';\n }\n\n protected getNavState() {\n const cannotLeaveEditMode = !SlickGlobalEditorLock.commitCurrentEdit();\n const pagingInfo = this.dataView.getPagingInfo();\n const lastPage = pagingInfo.totalPages - 1;\n\n return {\n canGotoFirst: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum > 0,\n canGotoLast: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum !== lastPage,\n canGotoPrev: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum > 0,\n canGotoNext: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum < lastPage,\n pagingInfo: pagingInfo\n };\n }\n\n protected setPageSize(n: number) {\n this.dataView.setRefreshHints({\n isFilterUnchanged: true\n });\n this.dataView.setPagingOptions({ pageSize: n });\n }\n\n protected gotoFirst() {\n if (this.getNavState().canGotoFirst) {\n this.dataView.setPagingOptions({ pageNum: 0 });\n }\n }\n\n protected gotoLast() {\n const state = this.getNavState();\n if (state.canGotoLast) {\n this.dataView.setPagingOptions({ pageNum: state.pagingInfo.totalPages - 1 });\n }\n }\n\n protected gotoPrev() {\n const state = this.getNavState();\n if (state.canGotoPrev) {\n this.dataView.setPagingOptions({ pageNum: state.pagingInfo.pageNum - 1 });\n }\n }\n\n protected gotoNext() {\n const state = this.getNavState();\n if (state.canGotoNext) {\n this.dataView.setPagingOptions({ pageNum: state.pagingInfo.pageNum + 1 });\n }\n }\n\n protected getContainerElement(selectorOrElm: object | HTMLElement | string) {\n // the container might be a string, a jQuery object or a native element\n return typeof selectorOrElm === 'string'\n ? document.querySelector(selectorOrElm)\n : typeof selectorOrElm === 'object' && (selectorOrElm as any)[0]\n ? (selectorOrElm as any)[0] as HTMLElement\n : selectorOrElm;\n }\n\n protected constructPagerUI() {\n // the container might be a string, a jQuery object or a native element\n const container = this.getContainerElement(this._container) as HTMLElement | HTMLElement[];\n if (!container || ((container as any).jquery && !(container as HTMLElement[])[0])) return;\n\n const navElm = document.createElement('span');\n navElm.className = 'slick-pager-nav';\n\n const settingsElm = document.createElement('span');\n settingsElm.className = 'slick-pager-settings';\n\n this._statusElm = document.createElement('span');\n this._statusElm.className = 'slick-pager-status';\n\n const pagerSettingsElm = document.createElement('span');\n pagerSettingsElm.className = 'slick-pager-settings-expanded';\n pagerSettingsElm.textContent = 'Show: ';\n\n for (let o = 0; o < this._options.pagingOptions.length; o++) {\n const p = this._options.pagingOptions[o];\n\n const anchorElm = document.createElement('a');\n anchorElm.textContent = p.name;\n anchorElm.ariaLabel = p.ariaLabel;\n anchorElm.dataset.val = String(p.data);\n pagerSettingsElm.appendChild(anchorElm);\n\n this._bindingEventService.bind(anchorElm, 'click', ((e: any) => {\n const pagesize = e.target.dataset.val;\n if (pagesize !== undefined) {\n if (Number(pagesize) === -1) {\n const vp = this.grid.getViewport();\n this.setPageSize(vp.bottom - vp.top);\n } else {\n this.setPageSize(parseInt(pagesize));\n }\n }\n }));\n }\n\n pagerSettingsElm.style.display = this._options.showPageSizes ? 'block' : 'none';\n\n settingsElm.appendChild(pagerSettingsElm);\n\n // light bulb icon\n const displayPaginationContainer = document.createElement('span');\n const displayIconElm = document.createElement('span');\n displayPaginationContainer.className = 'sgi-container';\n displayIconElm.ariaLabel = 'Show Pagination Options';\n displayIconElm.role = 'button';\n displayIconElm.className = 'sgi sgi-lightbulb';\n displayPaginationContainer.appendChild(displayIconElm);\n\n this._bindingEventService.bind(displayIconElm, 'click', () => {\n const styleDisplay = pagerSettingsElm.style.display;\n pagerSettingsElm.style.display = styleDisplay === 'none' ? 'inline-flex' : 'none';\n });\n settingsElm.appendChild(displayPaginationContainer);\n\n const pageButtons = [\n { key: 'start', ariaLabel: 'First Page', callback: this.gotoFirst },\n { key: 'left', ariaLabel: 'Previous Page', callback: this.gotoPrev },\n { key: 'right', ariaLabel: 'Next Page', callback: this.gotoNext },\n { key: 'end', ariaLabel: 'Last Page', callback: this.gotoLast },\n ];\n\n pageButtons.forEach(pageBtn => {\n const iconElm = document.createElement('span');\n iconElm.className = 'sgi-container';\n\n const innerIconElm = document.createElement('span');\n innerIconElm.role = 'button';\n innerIconElm.ariaLabel = pageBtn.ariaLabel;\n innerIconElm.className = `sgi sgi-chevron-${pageBtn.key}`;\n this._bindingEventService.bind(innerIconElm, 'click', pageBtn.callback.bind(this));\n\n iconElm.appendChild(innerIconElm);\n navElm.appendChild(iconElm);\n });\n\n const slickPagerElm = document.createElement('div');\n slickPagerElm.className = 'slick-pager';\n\n slickPagerElm.appendChild(navElm);\n slickPagerElm.appendChild(this._statusElm);\n slickPagerElm.appendChild(settingsElm);\n\n (container as HTMLElement).appendChild(slickPagerElm);\n }\n\n protected updatePager(pagingInfo: PagingInfo) {\n if (!this._container || ((this._container as any).jquery && !(this._container as any)[0])) return;\n const state = this.getNavState();\n\n // remove disabled class on all icons\n this._container.querySelectorAll('.slick-pager-nav span')\n .forEach(pagerIcon => pagerIcon.classList.remove('sgi-state-disabled'));\n\n // add back disabled class to only necessary icons\n if (!state.canGotoFirst) {\n this._container!.querySelector('.sgi-chevron-start')!.classList.add('sgi-state-disabled');\n }\n if (!state.canGotoLast) {\n this._container!.querySelector('.sgi-chevron-end')!.classList.add('sgi-state-disabled');\n }\n if (!state.canGotoNext) {\n this._container!.querySelector('.sgi-chevron-right')!.classList.add('sgi-state-disabled');\n }\n if (!state.canGotoPrev) {\n this._container!.querySelector('.sgi-chevron-left')!.classList.add('sgi-state-disabled');\n }\n\n if (pagingInfo.pageSize === 0) {\n this._statusElm.textContent = (this._options.showAllText.replace('{rowCount}', pagingInfo.totalRows + '').replace('{pageCount}', pagingInfo.totalPages + ''));\n } else {\n this._statusElm.textContent = (this._options.showPageText.replace('{pageNum}', pagingInfo.pageNum + 1 + '').replace('{pageCount}', pagingInfo.totalPages + ''));\n }\n\n if (this._options.showCount && pagingInfo.pageSize !== 0) {\n const pageBegin = pagingInfo.pageNum * pagingInfo.pageSize;\n let currentText = this._statusElm.textContent;\n\n if (currentText) {\n currentText += ' - ';\n }\n\n this._statusElm.textContent =\n currentText +\n this._options.showCountText\n .replace('{rowCount}', String(pagingInfo.totalRows))\n .replace('{countBegin}', String(pageBegin + 1))\n .replace('{countEnd}', String(Math.min(pageBegin + pagingInfo.pageSize, pagingInfo.totalRows)));\n }\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.Pager = SlickGridPager;\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import type { PagingInfo } from '../models/index';\nimport { BindingEventService as BindingEventService_, SlickGlobalEditorLock as SlickGlobalEditorLock_, Utils as Utils_ } from '../slick.core';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickGlobalEditorLock = IIFE_ONLY ? Slick.GlobalEditorLock : SlickGlobalEditorLock_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport interface GridPagerOption {\n showAllText: string;\n showPageText: string;\n showCountText: string;\n showCount: boolean;\n pagingOptions: Array<{ data: number; name: string; ariaLabel: string; }>;\n showPageSizes: boolean;\n}\n\nexport class SlickGridPager {\n // --\n // public API\n\n // --\n // protected props\n protected _container: HTMLElement; // the container might be a string, a jQuery object or a native element\n protected _statusElm!: HTMLElement;\n protected _bindingEventService: BindingEventService_;\n protected _options: GridPagerOption;\n protected _defaults: GridPagerOption = {\n showAllText: 'Showing all {rowCount} rows',\n showPageText: 'Showing page {pageNum} of {pageCount}',\n showCountText: 'From {countBegin} to {countEnd} of {rowCount} rows',\n showCount: false,\n pagingOptions: [\n { data: 0, name: 'All', ariaLabel: 'Show All Pages' },\n { data: -1, name: 'Auto', ariaLabel: 'Auto Page Size' },\n { data: 25, name: '25', ariaLabel: 'Show 25 rows per page' },\n { data: 50, name: '50', ariaLabel: 'Show 50 rows per page' },\n { data: 100, name: '100', ariaLabel: 'Show 100 rows per page' },\n ],\n showPageSizes: false\n };\n\n constructor(protected readonly dataView: SlickDataView, protected readonly grid: SlickGrid, selectorOrElm: HTMLElement | string, options?: Partial) {\n this._container = this.getContainerElement(selectorOrElm) as HTMLElement;\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._bindingEventService = new BindingEventService();\n this.init();\n }\n\n init() {\n this.constructPagerUI();\n this.updatePager(this.dataView.getPagingInfo());\n this.dataView.onPagingInfoChanged.subscribe((_e, pagingInfo) => {\n this.updatePager(pagingInfo);\n });\n }\n\n /** Destroy function when element is destroyed */\n destroy() {\n this.setPageSize(0);\n this._bindingEventService.unbindAll();\n this._container.innerHTML = '';\n }\n\n protected getNavState() {\n const cannotLeaveEditMode = !SlickGlobalEditorLock.commitCurrentEdit();\n const pagingInfo = this.dataView.getPagingInfo();\n const lastPage = pagingInfo.totalPages - 1;\n\n return {\n canGotoFirst: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum > 0,\n canGotoLast: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum !== lastPage,\n canGotoPrev: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum > 0,\n canGotoNext: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum < lastPage,\n pagingInfo\n };\n }\n\n protected setPageSize(n: number) {\n this.dataView.setRefreshHints({\n isFilterUnchanged: true\n });\n this.dataView.setPagingOptions({ pageSize: n });\n }\n\n protected gotoFirst() {\n if (this.getNavState().canGotoFirst) {\n this.dataView.setPagingOptions({ pageNum: 0 });\n }\n }\n\n protected gotoLast() {\n const state = this.getNavState();\n if (state.canGotoLast) {\n this.dataView.setPagingOptions({ pageNum: state.pagingInfo.totalPages - 1 });\n }\n }\n\n protected gotoPrev() {\n const state = this.getNavState();\n if (state.canGotoPrev) {\n this.dataView.setPagingOptions({ pageNum: state.pagingInfo.pageNum - 1 });\n }\n }\n\n protected gotoNext() {\n const state = this.getNavState();\n if (state.canGotoNext) {\n this.dataView.setPagingOptions({ pageNum: state.pagingInfo.pageNum + 1 });\n }\n }\n\n protected getContainerElement(selectorOrElm: object | HTMLElement | string) {\n // the container might be a string, a jQuery object or a native element\n return typeof selectorOrElm === 'string'\n ? document.querySelector(selectorOrElm)\n : typeof selectorOrElm === 'object' && (selectorOrElm as any)[0]\n ? (selectorOrElm as any)[0] as HTMLElement\n : selectorOrElm;\n }\n\n protected constructPagerUI() {\n // the container might be a string, a jQuery object or a native element\n const container = this.getContainerElement(this._container) as HTMLElement | HTMLElement[];\n if (!container || ((container as any).jquery && !(container as HTMLElement[])[0])) { return; }\n\n const navElm = document.createElement('span');\n navElm.className = 'slick-pager-nav';\n\n const settingsElm = document.createElement('span');\n settingsElm.className = 'slick-pager-settings';\n\n this._statusElm = document.createElement('span');\n this._statusElm.className = 'slick-pager-status';\n\n const pagerSettingsElm = document.createElement('span');\n pagerSettingsElm.className = 'slick-pager-settings-expanded';\n pagerSettingsElm.textContent = 'Show: ';\n\n for (let o = 0; o < this._options.pagingOptions.length; o++) {\n const p = this._options.pagingOptions[o];\n\n const anchorElm = document.createElement('a');\n anchorElm.textContent = p.name;\n anchorElm.ariaLabel = p.ariaLabel;\n anchorElm.dataset.val = String(p.data);\n pagerSettingsElm.appendChild(anchorElm);\n\n this._bindingEventService.bind(anchorElm, 'click', ((e: any) => {\n const pagesize = e.target.dataset.val;\n if (pagesize !== undefined) {\n if (Number(pagesize) === -1) {\n const vp = this.grid.getViewport();\n this.setPageSize(vp.bottom - vp.top);\n } else {\n this.setPageSize(parseInt(pagesize));\n }\n }\n }));\n }\n\n pagerSettingsElm.style.display = this._options.showPageSizes ? 'block' : 'none';\n\n settingsElm.appendChild(pagerSettingsElm);\n\n // light bulb icon\n const displayPaginationContainer = document.createElement('span');\n const displayIconElm = document.createElement('span');\n displayPaginationContainer.className = 'sgi-container';\n displayIconElm.ariaLabel = 'Show Pagination Options';\n displayIconElm.role = 'button';\n displayIconElm.className = 'sgi sgi-lightbulb';\n displayPaginationContainer.appendChild(displayIconElm);\n\n this._bindingEventService.bind(displayIconElm, 'click', () => {\n const styleDisplay = pagerSettingsElm.style.display;\n pagerSettingsElm.style.display = styleDisplay === 'none' ? 'inline-flex' : 'none';\n });\n settingsElm.appendChild(displayPaginationContainer);\n\n const pageButtons = [\n { key: 'start', ariaLabel: 'First Page', callback: this.gotoFirst },\n { key: 'left', ariaLabel: 'Previous Page', callback: this.gotoPrev },\n { key: 'right', ariaLabel: 'Next Page', callback: this.gotoNext },\n { key: 'end', ariaLabel: 'Last Page', callback: this.gotoLast },\n ];\n\n pageButtons.forEach(pageBtn => {\n const iconElm = document.createElement('span');\n iconElm.className = 'sgi-container';\n\n const innerIconElm = document.createElement('span');\n innerIconElm.role = 'button';\n innerIconElm.ariaLabel = pageBtn.ariaLabel;\n innerIconElm.className = `sgi sgi-chevron-${pageBtn.key}`;\n this._bindingEventService.bind(innerIconElm, 'click', pageBtn.callback.bind(this));\n\n iconElm.appendChild(innerIconElm);\n navElm.appendChild(iconElm);\n });\n\n const slickPagerElm = document.createElement('div');\n slickPagerElm.className = 'slick-pager';\n\n slickPagerElm.appendChild(navElm);\n slickPagerElm.appendChild(this._statusElm);\n slickPagerElm.appendChild(settingsElm);\n\n (container as HTMLElement).appendChild(slickPagerElm);\n }\n\n protected updatePager(pagingInfo: PagingInfo) {\n if (!this._container || ((this._container as any).jquery && !(this._container as any)[0])) { return; }\n const state = this.getNavState();\n\n // remove disabled class on all icons\n this._container.querySelectorAll('.slick-pager-nav span')\n .forEach(pagerIcon => pagerIcon.classList.remove('sgi-state-disabled'));\n\n // add back disabled class to only necessary icons\n if (!state.canGotoFirst) {\n this._container!.querySelector('.sgi-chevron-start')!.classList.add('sgi-state-disabled');\n }\n if (!state.canGotoLast) {\n this._container!.querySelector('.sgi-chevron-end')!.classList.add('sgi-state-disabled');\n }\n if (!state.canGotoNext) {\n this._container!.querySelector('.sgi-chevron-right')!.classList.add('sgi-state-disabled');\n }\n if (!state.canGotoPrev) {\n this._container!.querySelector('.sgi-chevron-left')!.classList.add('sgi-state-disabled');\n }\n\n if (pagingInfo.pageSize === 0) {\n this._statusElm.textContent = (this._options.showAllText.replace('{rowCount}', pagingInfo.totalRows + '').replace('{pageCount}', pagingInfo.totalPages + ''));\n } else {\n this._statusElm.textContent = (this._options.showPageText.replace('{pageNum}', pagingInfo.pageNum + 1 + '').replace('{pageCount}', pagingInfo.totalPages + ''));\n }\n\n if (this._options.showCount && pagingInfo.pageSize !== 0) {\n const pageBegin = pagingInfo.pageNum * pagingInfo.pageSize;\n let currentText = this._statusElm.textContent;\n\n if (currentText) {\n currentText += ' - ';\n }\n\n this._statusElm.textContent =\n currentText +\n this._options.showCountText\n .replace('{rowCount}', String(pagingInfo.totalRows))\n .replace('{countBegin}', String(pageBegin + 1))\n .replace('{countEnd}', String(Math.min(pageBegin + pagingInfo.pageSize, pagingInfo.totalRows)));\n }\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.Pager = SlickGridPager;\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.autotooltips.js.map b/dist/browser/plugins/slick.autotooltips.js.map index 4b33fc741..54c590101 100644 --- a/dist/browser/plugins/slick.autotooltips.js.map +++ b/dist/browser/plugins/slick.autotooltips.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.autotooltips.ts"], - "sourcesContent": ["import type { AutoTooltipOption, Column, Plugin } from '../models/index';\nimport { Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * AutoTooltips plugin to show/hide tooltips when columns are too narrow to fit content.\n */\nexport class SlickAutoTooltips implements Plugin {\n // --\n // public API\n pluginName = 'AutoTooltips' as const;\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _options?: AutoTooltipOption\n protected _defaults: AutoTooltipOption = {\n enableForCells: true,\n enableForHeaderCells: false,\n maxToolTipLength: undefined,\n replaceExisting: true\n };\n\n /**\n * Constructor of the SlickGrid 3rd party plugin, it can optionally receive options\n * @param {boolean} [options.enableForCells=true] - Enable tooltip for grid cells\n * @param {boolean} [options.enableForHeaderCells=false] - Enable tooltip for header cells\n * @param {number} [options.maxToolTipLength=null] - The maximum length for a tooltip\n * @param {boolean} [options.replaceExisting=null] - Allow preventing custom tooltips from being overwritten by auto tooltips\n */\n constructor(options?: AutoTooltipOption) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n /**\n * Initialize plugin.\n */\n init(grid: SlickGrid) {\n this._grid = grid;\n if (this._options?.enableForCells) {\n this._grid.onMouseEnter.subscribe(this.handleMouseEnter.bind(this));\n }\n if (this._options?.enableForHeaderCells) {\n this._grid.onHeaderMouseEnter.subscribe(this.handleHeaderMouseEnter.bind(this));\n }\n }\n\n /**\n * Destroy plugin.\n */\n destroy() {\n if (this._options?.enableForCells) {\n this._grid.onMouseEnter.unsubscribe(this.handleMouseEnter.bind(this));\n }\n if (this._options?.enableForHeaderCells) {\n this._grid.onHeaderMouseEnter.unsubscribe(this.handleHeaderMouseEnter.bind(this));\n }\n }\n\n /**\n * Handle mouse entering grid cell to add/remove tooltip.\n * @param {MouseEvent} event - The event\n */\n protected handleMouseEnter(event: MouseEvent) {\n const cell = this._grid.getCellFromEvent(event);\n if (cell) {\n let node: HTMLElement | null = this._grid.getCellNode(cell.row, cell.cell);\n let text;\n if (this._options && node && (!node.title || this._options?.replaceExisting)) {\n if (node.clientWidth < node.scrollWidth) {\n text = node.textContent?.trim() ?? '';\n if (this._options?.maxToolTipLength && text.length > this._options?.maxToolTipLength) {\n text = text.substring(0, this._options.maxToolTipLength - 3) + '...';\n }\n } else {\n text = '';\n }\n node.title = text;\n }\n node = null;\n }\n }\n\n /**\n * Handle mouse entering header cell to add/remove tooltip.\n * @param {MouseEvent} event - The event\n * @param {object} args.column - The column definition\n */\n protected handleHeaderMouseEnter(event: MouseEvent, args: { column: Column; }) {\n const column = args.column;\n let node: HTMLDivElement | null;\n const targetElm = (event.target as HTMLDivElement);\n\n if (targetElm) {\n node = targetElm.closest('.slick-header-column');\n if (node && !(column?.toolTip)) {\n node.title = (targetElm.clientWidth < node.clientWidth) ? column?.name ?? '' : '';\n }\n }\n node = null;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n AutoTooltips: SlickAutoTooltips\n }\n });\n}\n"], - "mappings": ";;;;;;;AAKA,MAAM,QAAoB,MAAM,OAKnB,oBAAN,MAA0C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuB/C,YAAY,SAA6B;AApBzC;AAAA;AAAA,wCAAa;AAIb;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU,aAA+B;AAAA,QACvC,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,kBAAkB;AAAA,QAClB,iBAAiB;AAAA,MACnB;AAUE,WAAK,WAAW,MAAM,OAAO,IAAM,CAAC,GAAG,KAAK,WAAW,OAAO;AAAA,IAChE;AAAA;AAAA;AAAA;AAAA,IAKA,KAAK,MAAiB;AAxCxB;AAyCI,WAAK,QAAQ,OACT,UAAK,aAAL,WAAe,kBACjB,KAAK,MAAM,aAAa,UAAU,KAAK,iBAAiB,KAAK,IAAI,CAAC,IAEhE,UAAK,aAAL,WAAe,wBACjB,KAAK,MAAM,mBAAmB,UAAU,KAAK,uBAAuB,KAAK,IAAI,CAAC;AAAA,IAElF;AAAA;AAAA;AAAA;AAAA,IAKA,UAAU;AArDZ;AAsDI,OAAI,UAAK,aAAL,WAAe,kBACjB,KAAK,MAAM,aAAa,YAAY,KAAK,iBAAiB,KAAK,IAAI,CAAC,IAElE,UAAK,aAAL,WAAe,wBACjB,KAAK,MAAM,mBAAmB,YAAY,KAAK,uBAAuB,KAAK,IAAI,CAAC;AAAA,IAEpF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMU,iBAAiB,OAAmB;AAlEhD;AAmEI,UAAM,OAAO,KAAK,MAAM,iBAAiB,KAAK;AAC9C,UAAI,MAAM;AACR,YAAI,OAA2B,KAAK,MAAM,YAAY,KAAK,KAAK,KAAK,IAAI,GACrE;AACJ,QAAI,KAAK,YAAY,SAAS,CAAC,KAAK,UAAS,UAAK,aAAL,WAAe,qBACtD,KAAK,cAAc,KAAK,eAC1B,QAAO,gBAAK,gBAAL,mBAAkB,WAAlB,YAA4B,KAC/B,UAAK,aAAL,WAAe,oBAAoB,KAAK,WAAS,UAAK,aAAL,mBAAe,sBAClE,OAAO,KAAK,UAAU,GAAG,KAAK,SAAS,mBAAmB,CAAC,IAAI,UAGjE,OAAO,IAET,KAAK,QAAQ,OAEf,OAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOU,uBAAuB,OAAmB,MAA2B;AA3FjF;AA4FI,UAAM,SAAS,KAAK,QAChB,MACE,YAAa,MAAM;AAEzB,MAAI,cACF,OAAO,UAAU,QAAwB,sBAAsB,GAC3D,QAAQ,EAAE,yBAAQ,aACpB,KAAK,QAAS,UAAU,cAAc,KAAK,gBAAe,sCAAQ,SAAR,YAAqB,MAGnF,OAAO;AAAA,IACT;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;", + "sourcesContent": ["import type { AutoTooltipOption, Column, SlickPlugin } from '../models/index';\nimport { Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * AutoTooltips plugin to show/hide tooltips when columns are too narrow to fit content.\n */\nexport class SlickAutoTooltips implements SlickPlugin {\n // --\n // public API\n pluginName = 'AutoTooltips' as const;\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _options?: AutoTooltipOption;\n protected _defaults: AutoTooltipOption = {\n enableForCells: true,\n enableForHeaderCells: false,\n maxToolTipLength: undefined,\n replaceExisting: true\n };\n\n /**\n * Constructor of the SlickGrid 3rd party plugin, it can optionally receive options\n * @param {boolean} [options.enableForCells=true] - Enable tooltip for grid cells\n * @param {boolean} [options.enableForHeaderCells=false] - Enable tooltip for header cells\n * @param {number} [options.maxToolTipLength=null] - The maximum length for a tooltip\n * @param {boolean} [options.replaceExisting=null] - Allow preventing custom tooltips from being overwritten by auto tooltips\n */\n constructor(options?: AutoTooltipOption) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n /**\n * Initialize plugin.\n */\n init(grid: SlickGrid) {\n this._grid = grid;\n if (this._options?.enableForCells) {\n this._grid.onMouseEnter.subscribe(this.handleMouseEnter.bind(this));\n }\n if (this._options?.enableForHeaderCells) {\n this._grid.onHeaderMouseEnter.subscribe(this.handleHeaderMouseEnter.bind(this));\n }\n }\n\n /**\n * Destroy plugin.\n */\n destroy() {\n if (this._options?.enableForCells) {\n this._grid.onMouseEnter.unsubscribe(this.handleMouseEnter.bind(this));\n }\n if (this._options?.enableForHeaderCells) {\n this._grid.onHeaderMouseEnter.unsubscribe(this.handleHeaderMouseEnter.bind(this));\n }\n }\n\n /**\n * Handle mouse entering grid cell to add/remove tooltip.\n * @param {MouseEvent} event - The event\n */\n protected handleMouseEnter(event: MouseEvent) {\n const cell = this._grid.getCellFromEvent(event);\n if (cell) {\n let node: HTMLElement | null = this._grid.getCellNode(cell.row, cell.cell);\n let text;\n if (this._options && node && (!node.title || this._options?.replaceExisting)) {\n if (node.clientWidth < node.scrollWidth) {\n text = node.textContent?.trim() ?? '';\n if (this._options?.maxToolTipLength && text.length > this._options?.maxToolTipLength) {\n text = text.substring(0, this._options.maxToolTipLength - 3) + '...';\n }\n } else {\n text = '';\n }\n node.title = text;\n }\n node = null;\n }\n }\n\n /**\n * Handle mouse entering header cell to add/remove tooltip.\n * @param {MouseEvent} event - The event\n * @param {object} args.column - The column definition\n */\n protected handleHeaderMouseEnter(event: MouseEvent, args: { column: Column; }) {\n const column = args.column;\n let node: HTMLDivElement | null;\n const targetElm = (event.target as HTMLDivElement);\n\n if (targetElm) {\n node = targetElm.closest('.slick-header-column');\n if (node && !(column?.toolTip)) {\n node.title = (targetElm.clientWidth < node.clientWidth) ? column?.name ?? '' : '';\n }\n }\n node = null;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n AutoTooltips: SlickAutoTooltips\n }\n });\n}\n"], + "mappings": ";;;;;;;AAKA,MAAM,QAAoB,MAAM,OAKnB,oBAAN,MAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBpD,YAAY,SAA6B;AApBzC;AAAA;AAAA,wCAAa;AAIb;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU,aAA+B;AAAA,QACvC,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,kBAAkB;AAAA,QAClB,iBAAiB;AAAA,MACnB;AAUE,WAAK,WAAW,MAAM,OAAO,IAAM,CAAC,GAAG,KAAK,WAAW,OAAO;AAAA,IAChE;AAAA;AAAA;AAAA;AAAA,IAKA,KAAK,MAAiB;AAxCxB;AAyCI,WAAK,QAAQ,OACT,UAAK,aAAL,WAAe,kBACjB,KAAK,MAAM,aAAa,UAAU,KAAK,iBAAiB,KAAK,IAAI,CAAC,IAEhE,UAAK,aAAL,WAAe,wBACjB,KAAK,MAAM,mBAAmB,UAAU,KAAK,uBAAuB,KAAK,IAAI,CAAC;AAAA,IAElF;AAAA;AAAA;AAAA;AAAA,IAKA,UAAU;AArDZ;AAsDI,OAAI,UAAK,aAAL,WAAe,kBACjB,KAAK,MAAM,aAAa,YAAY,KAAK,iBAAiB,KAAK,IAAI,CAAC,IAElE,UAAK,aAAL,WAAe,wBACjB,KAAK,MAAM,mBAAmB,YAAY,KAAK,uBAAuB,KAAK,IAAI,CAAC;AAAA,IAEpF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMU,iBAAiB,OAAmB;AAlEhD;AAmEI,UAAM,OAAO,KAAK,MAAM,iBAAiB,KAAK;AAC9C,UAAI,MAAM;AACR,YAAI,OAA2B,KAAK,MAAM,YAAY,KAAK,KAAK,KAAK,IAAI,GACrE;AACJ,QAAI,KAAK,YAAY,SAAS,CAAC,KAAK,UAAS,UAAK,aAAL,WAAe,qBACtD,KAAK,cAAc,KAAK,eAC1B,QAAO,gBAAK,gBAAL,mBAAkB,WAAlB,YAA4B,KAC/B,UAAK,aAAL,WAAe,oBAAoB,KAAK,WAAS,UAAK,aAAL,mBAAe,sBAClE,OAAO,KAAK,UAAU,GAAG,KAAK,SAAS,mBAAmB,CAAC,IAAI,UAGjE,OAAO,IAET,KAAK,QAAQ,OAEf,OAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOU,uBAAuB,OAAmB,MAA2B;AA3FjF;AA4FI,UAAM,SAAS,KAAK,QAChB,MACE,YAAa,MAAM;AAEzB,MAAI,cACF,OAAO,UAAU,QAAwB,sBAAsB,GAC3D,QAAQ,EAAE,yBAAQ,aACpB,KAAK,QAAS,UAAU,cAAc,KAAK,gBAAe,sCAAQ,SAAR,YAAqB,MAGnF,OAAO;AAAA,IACT;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;", "names": [] } diff --git a/dist/browser/plugins/slick.cellcopymanager.js b/dist/browser/plugins/slick.cellcopymanager.js index 3f98796de..66cd7762a 100644 --- a/dist/browser/plugins/slick.cellcopymanager.js +++ b/dist/browser/plugins/slick.cellcopymanager.js @@ -27,7 +27,7 @@ handleKeyDown(e) { var _a, _b, _c; let ranges; - this._grid.getEditorLock().isActive() || (e.which == keyCode.ESCAPE && this._copiedRanges && (e.preventDefault(), this.clearCopySelection(), this.onCopyCancelled.notify({ ranges: this._copiedRanges }), this._copiedRanges = null), e.which == 67 && (e.ctrlKey || e.metaKey) && (ranges = (_b = (_a = this._grid.getSelectionModel()) == null ? void 0 : _a.getSelectedRanges()) != null ? _b : [], ranges.length !== 0 && (e.preventDefault(), this._copiedRanges = ranges, this.markCopySelection(ranges), this.onCopyCells.notify({ ranges }))), e.which == 86 && (e.ctrlKey || e.metaKey) && this._copiedRanges && (e.preventDefault(), ranges = (_c = this._grid.getSelectionModel()) == null ? void 0 : _c.getSelectedRanges(), this.onPasteCells.notify({ from: this._copiedRanges, to: ranges }), this._grid.getOptions().preserveCopiedSelectionOnPaste || (this.clearCopySelection(), this._copiedRanges = null))); + this._grid.getEditorLock().isActive() || (e.which === keyCode.ESCAPE && this._copiedRanges && (e.preventDefault(), this.clearCopySelection(), this.onCopyCancelled.notify({ ranges: this._copiedRanges }), this._copiedRanges = null), e.which === 67 && (e.ctrlKey || e.metaKey) && (ranges = (_b = (_a = this._grid.getSelectionModel()) == null ? void 0 : _a.getSelectedRanges()) != null ? _b : [], ranges.length !== 0 && (e.preventDefault(), this._copiedRanges = ranges, this.markCopySelection(ranges), this.onCopyCells.notify({ ranges }))), e.which === 86 && (e.ctrlKey || e.metaKey) && this._copiedRanges && (e.preventDefault(), ranges = (_c = this._grid.getSelectionModel()) == null ? void 0 : _c.getSelectedRanges(), this.onPasteCells.notify({ from: this._copiedRanges, to: ranges }), this._grid.getOptions().preserveCopiedSelectionOnPaste || (this.clearCopySelection(), this._copiedRanges = null))); } markCopySelection(ranges) { let columns = this._grid.getColumns(), hash = {}; diff --git a/dist/browser/plugins/slick.cellcopymanager.js.map b/dist/browser/plugins/slick.cellcopymanager.js.map index d140280ac..3b656e194 100644 --- a/dist/browser/plugins/slick.cellcopymanager.js.map +++ b/dist/browser/plugins/slick.cellcopymanager.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.cellcopymanager.ts"], - "sourcesContent": ["import type { CssStyleHash, Plugin } from '../models/index';\nimport { SlickEvent as SlickEvent_, keyCode as keyCode_, Utils as Utils_, SlickRange } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * This manager enables users to copy/paste cell data\n */\nexport class SlickCellCopyManager implements Plugin {\n // --\n // public API\n pluginName = 'CellCopyManager' as const;\n onCopyCells = new SlickEvent<{ ranges: SlickRange[] | null; }>();\n onCopyCancelled = new SlickEvent<{ ranges: SlickRange[] | null; }>();\n onPasteCells = new SlickEvent<{ from: SlickRange[] | undefined; to: SlickRange[] | undefined; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _copiedRanges?: SlickRange[] | null = null;\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));\n }\n\n destroy() {\n this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));\n }\n\n protected handleKeyDown(e: KeyboardEvent) {\n let ranges: SlickRange[] | undefined;\n if (!this._grid.getEditorLock().isActive()) {\n if (e.which == keyCode.ESCAPE) {\n if (this._copiedRanges) {\n e.preventDefault();\n this.clearCopySelection();\n this.onCopyCancelled.notify({ ranges: this._copiedRanges });\n this._copiedRanges = null;\n }\n }\n\n if (e.which == 67 && (e.ctrlKey || e.metaKey)) {\n ranges = this._grid.getSelectionModel()?.getSelectedRanges() ?? [];\n if (ranges.length !== 0) {\n e.preventDefault();\n this._copiedRanges = ranges;\n this.markCopySelection(ranges);\n this.onCopyCells.notify({ ranges });\n }\n }\n\n if (e.which == 86 && (e.ctrlKey || e.metaKey)) {\n if (this._copiedRanges) {\n e.preventDefault();\n ranges = this._grid.getSelectionModel()?.getSelectedRanges();\n this.onPasteCells.notify({ from: this._copiedRanges, to: ranges });\n if (!this._grid.getOptions().preserveCopiedSelectionOnPaste) {\n this.clearCopySelection();\n this._copiedRanges = null;\n }\n }\n }\n }\n }\n\n protected markCopySelection(ranges: SlickRange[]) {\n const columns = this._grid.getColumns();\n const hash: CssStyleHash = {};\n for (let i = 0; i < ranges.length; i++) {\n for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n hash[j] = {};\n for (let k = ranges[i].fromCell; k <= ranges[i].toCell; k++) {\n hash[j][columns[k].id] = 'copied';\n }\n }\n }\n this._grid.setCellCssStyles('copy-manager', hash);\n }\n\n protected clearCopySelection() {\n this._grid.removeCellCssStyles('copy-manager');\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellCopyManager: SlickCellCopyManager\n }\n });\n}\n"], - "mappings": ";;;;;;;AAKA,MAAM,UAAsB,MAAM,SAC5B,aAAyB,MAAM,OAC/B,QAAoB,MAAM,OAKnB,uBAAN,MAA6C;AAAA,IAA7C;AAGL;AAAA;AAAA,wCAAa;AACb,yCAAc,IAAI,WAA6C;AAC/D,6CAAkB,IAAI,WAA6C;AACnE,0CAAe,IAAI,WAA8E;AAIjG;AAAA;AAAA,0BAAU;AACV,0BAAU,iBAAsC;AAAA;AAAA,IAEhD,KAAK,MAAiB;AACpB,WAAK,QAAQ,MACb,KAAK,MAAM,UAAU,UAAU,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,IAC9D;AAAA,IAEA,UAAU;AACR,WAAK,MAAM,UAAU,YAAY,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,IAChE;AAAA,IAEU,cAAc,GAAkB;AAlC5C;AAmCI,UAAI;AACJ,MAAK,KAAK,MAAM,cAAc,EAAE,SAAS,MACnC,EAAE,SAAS,QAAQ,UACjB,KAAK,kBACP,EAAE,eAAe,GACjB,KAAK,mBAAmB,GACxB,KAAK,gBAAgB,OAAO,EAAE,QAAQ,KAAK,cAAc,CAAC,GAC1D,KAAK,gBAAgB,OAIrB,EAAE,SAAS,OAAO,EAAE,WAAW,EAAE,aACnC,UAAS,gBAAK,MAAM,kBAAkB,MAA7B,mBAAgC,wBAAhC,YAAuD,CAAC,GAC7D,OAAO,WAAW,MACpB,EAAE,eAAe,GACjB,KAAK,gBAAgB,QACrB,KAAK,kBAAkB,MAAM,GAC7B,KAAK,YAAY,OAAO,EAAE,OAAO,CAAC,KAIlC,EAAE,SAAS,OAAO,EAAE,WAAW,EAAE,YAC/B,KAAK,kBACP,EAAE,eAAe,GACjB,UAAS,UAAK,MAAM,kBAAkB,MAA7B,mBAAgC,qBACzC,KAAK,aAAa,OAAO,EAAE,MAAM,KAAK,eAAe,IAAI,OAAO,CAAC,GAC5D,KAAK,MAAM,WAAW,EAAE,mCAC3B,KAAK,mBAAmB,GACxB,KAAK,gBAAgB;AAAA,IAK/B;AAAA,IAEU,kBAAkB,QAAsB;AAChD,UAAM,UAAU,KAAK,MAAM,WAAW,GAChC,OAAqB,CAAC;AAC5B,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ;AACjC,iBAAS,IAAI,OAAO,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC,EAAE,OAAO,KAAK;AACzD,eAAK,CAAC,IAAI,CAAC;AACX,mBAAS,IAAI,OAAO,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,EAAE,QAAQ;AACtD,iBAAK,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE,IAAI;AAAA,QAE7B;AAEF,WAAK,MAAM,iBAAiB,gBAAgB,IAAI;AAAA,IAClD;AAAA,IAEU,qBAAqB;AAC7B,WAAK,MAAM,oBAAoB,cAAc;AAAA,IAC/C;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,iBAAiB;AAAA,IACnB;AAAA,EACF,CAAC;", + "sourcesContent": ["import type { CssStyleHash, SlickPlugin } from '../models/index';\nimport { SlickEvent as SlickEvent_, keyCode as keyCode_, Utils as Utils_, SlickRange } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * This manager enables users to copy/paste cell data\n */\nexport class SlickCellCopyManager implements SlickPlugin {\n // --\n // public API\n pluginName = 'CellCopyManager' as const;\n onCopyCells = new SlickEvent<{ ranges: SlickRange[] | null; }>();\n onCopyCancelled = new SlickEvent<{ ranges: SlickRange[] | null; }>();\n onPasteCells = new SlickEvent<{ from: SlickRange[] | undefined; to: SlickRange[] | undefined; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _copiedRanges?: SlickRange[] | null = null;\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));\n }\n\n destroy() {\n this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));\n }\n\n protected handleKeyDown(e: KeyboardEvent) {\n let ranges: SlickRange[] | undefined;\n if (!this._grid.getEditorLock().isActive()) {\n if (e.which === keyCode.ESCAPE) {\n if (this._copiedRanges) {\n e.preventDefault();\n this.clearCopySelection();\n this.onCopyCancelled.notify({ ranges: this._copiedRanges });\n this._copiedRanges = null;\n }\n }\n\n if (e.which === 67 && (e.ctrlKey || e.metaKey)) {\n ranges = this._grid.getSelectionModel()?.getSelectedRanges() ?? [];\n if (ranges.length !== 0) {\n e.preventDefault();\n this._copiedRanges = ranges;\n this.markCopySelection(ranges);\n this.onCopyCells.notify({ ranges });\n }\n }\n\n if (e.which === 86 && (e.ctrlKey || e.metaKey)) {\n if (this._copiedRanges) {\n e.preventDefault();\n ranges = this._grid.getSelectionModel()?.getSelectedRanges();\n this.onPasteCells.notify({ from: this._copiedRanges, to: ranges });\n if (!this._grid.getOptions().preserveCopiedSelectionOnPaste) {\n this.clearCopySelection();\n this._copiedRanges = null;\n }\n }\n }\n }\n }\n\n protected markCopySelection(ranges: SlickRange[]) {\n const columns = this._grid.getColumns();\n const hash: CssStyleHash = {};\n for (let i = 0; i < ranges.length; i++) {\n for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n hash[j] = {};\n for (let k = ranges[i].fromCell; k <= ranges[i].toCell; k++) {\n hash[j][columns[k].id] = 'copied';\n }\n }\n }\n this._grid.setCellCssStyles('copy-manager', hash);\n }\n\n protected clearCopySelection() {\n this._grid.removeCellCssStyles('copy-manager');\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellCopyManager: SlickCellCopyManager\n }\n });\n}\n"], + "mappings": ";;;;;;;AAKA,MAAM,UAAsB,MAAM,SAC5B,aAAyB,MAAM,OAC/B,QAAoB,MAAM,OAKnB,uBAAN,MAAkD;AAAA,IAAlD;AAGL;AAAA;AAAA,wCAAa;AACb,yCAAc,IAAI,WAA6C;AAC/D,6CAAkB,IAAI,WAA6C;AACnE,0CAAe,IAAI,WAA8E;AAIjG;AAAA;AAAA,0BAAU;AACV,0BAAU,iBAAsC;AAAA;AAAA,IAEhD,KAAK,MAAiB;AACpB,WAAK,QAAQ,MACb,KAAK,MAAM,UAAU,UAAU,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,IAC9D;AAAA,IAEA,UAAU;AACR,WAAK,MAAM,UAAU,YAAY,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,IAChE;AAAA,IAEU,cAAc,GAAkB;AAlC5C;AAmCI,UAAI;AACJ,MAAK,KAAK,MAAM,cAAc,EAAE,SAAS,MACnC,EAAE,UAAU,QAAQ,UAClB,KAAK,kBACP,EAAE,eAAe,GACjB,KAAK,mBAAmB,GACxB,KAAK,gBAAgB,OAAO,EAAE,QAAQ,KAAK,cAAc,CAAC,GAC1D,KAAK,gBAAgB,OAIrB,EAAE,UAAU,OAAO,EAAE,WAAW,EAAE,aACpC,UAAS,gBAAK,MAAM,kBAAkB,MAA7B,mBAAgC,wBAAhC,YAAuD,CAAC,GAC7D,OAAO,WAAW,MACpB,EAAE,eAAe,GACjB,KAAK,gBAAgB,QACrB,KAAK,kBAAkB,MAAM,GAC7B,KAAK,YAAY,OAAO,EAAE,OAAO,CAAC,KAIlC,EAAE,UAAU,OAAO,EAAE,WAAW,EAAE,YAChC,KAAK,kBACP,EAAE,eAAe,GACjB,UAAS,UAAK,MAAM,kBAAkB,MAA7B,mBAAgC,qBACzC,KAAK,aAAa,OAAO,EAAE,MAAM,KAAK,eAAe,IAAI,OAAO,CAAC,GAC5D,KAAK,MAAM,WAAW,EAAE,mCAC3B,KAAK,mBAAmB,GACxB,KAAK,gBAAgB;AAAA,IAK/B;AAAA,IAEU,kBAAkB,QAAsB;AAChD,UAAM,UAAU,KAAK,MAAM,WAAW,GAChC,OAAqB,CAAC;AAC5B,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ;AACjC,iBAAS,IAAI,OAAO,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC,EAAE,OAAO,KAAK;AACzD,eAAK,CAAC,IAAI,CAAC;AACX,mBAAS,IAAI,OAAO,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,EAAE,QAAQ;AACtD,iBAAK,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE,IAAI;AAAA,QAE7B;AAEF,WAAK,MAAM,iBAAiB,gBAAgB,IAAI;AAAA,IAClD;AAAA,IAEU,qBAAqB;AAC7B,WAAK,MAAM,oBAAoB,cAAc;AAAA,IAC/C;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,iBAAiB;AAAA,IACnB;AAAA,EACF,CAAC;", "names": [] } diff --git a/dist/browser/plugins/slick.cellexternalcopymanager.js b/dist/browser/plugins/slick.cellexternalcopymanager.js index 225feb6f8..2cccfeb18 100644 --- a/dist/browser/plugins/slick.cellexternalcopymanager.js +++ b/dist/browser/plugins/slick.cellexternalcopymanager.js @@ -112,7 +112,7 @@ else return; let oneCellToMultiple = !1, destH = clippedRange.length, destW = clippedRange.length ? clippedRange[0].length : 0; - clippedRange.length == 1 && clippedRange[0].length == 1 && selectedRange && (oneCellToMultiple = !0, destH = selectedRange.toRow - selectedRange.fromRow + 1, destW = selectedRange.toCell - selectedRange.fromCell + 1); + clippedRange.length === 1 && clippedRange[0].length === 1 && selectedRange && (oneCellToMultiple = !0, destH = selectedRange.toRow - selectedRange.fromRow + 1, destW = selectedRange.toCell - selectedRange.fromCell + 1); let availableRows = grid.getData().length - (activeRow || 0), addRows = 0; if (availableRows < destH && typeof this._options.newRowCreator == "function") { let d = grid.getData(); @@ -206,7 +206,7 @@ var _a, _b, _c, _d; let ranges; if (!this._grid.getEditorLock().isActive() || this._grid.getOptions().autoEdit) { - if (e.which == this.keyCodes.ESC && this._copiedRanges && (e.preventDefault(), this.clearCopySelection(), this.onCopyCancelled.notify({ ranges: this._copiedRanges }), this._copiedRanges = null), (e.which === this.keyCodes.C || e.which === this.keyCodes.INSERT) && (e.ctrlKey || e.metaKey) && !e.shiftKey && (typeof this._onCopyInit == "function" && this._onCopyInit.call(this), ranges = (_b = (_a = this._grid.getSelectionModel()) == null ? void 0 : _a.getSelectedRanges()) != null ? _b : [], ranges.length !== 0)) { + if (e.which === this.keyCodes.ESC && this._copiedRanges && (e.preventDefault(), this.clearCopySelection(), this.onCopyCancelled.notify({ ranges: this._copiedRanges }), this._copiedRanges = null), (e.which === this.keyCodes.C || e.which === this.keyCodes.INSERT) && (e.ctrlKey || e.metaKey) && !e.shiftKey && (typeof this._onCopyInit == "function" && this._onCopyInit.call(this), ranges = (_b = (_a = this._grid.getSelectionModel()) == null ? void 0 : _a.getSelectedRanges()) != null ? _b : [], ranges.length !== 0)) { this._copiedRanges = ranges, this.markCopySelection(ranges), this.onCopyCells.notify({ ranges }); let columns = this._grid.getColumns(), clipText = ""; for (let rg = 0; rg < ranges.length; rg++) { diff --git a/dist/browser/plugins/slick.cellexternalcopymanager.js.map b/dist/browser/plugins/slick.cellexternalcopymanager.js.map index 499a48350..4f849a4c8 100644 --- a/dist/browser/plugins/slick.cellexternalcopymanager.js.map +++ b/dist/browser/plugins/slick.cellexternalcopymanager.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.cellexternalcopymanager.ts"], - "sourcesContent": ["import type { CellRange, Column, CssStyleHash, ExcelCopyBufferOption, ExternalCopyClipCommand, Plugin } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\nimport { SlickEvent as SlickEvent_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nconst CLEAR_COPY_SELECTION_DELAY = 2000;\nconst CLIPBOARD_PASTE_DELAY = 100;\n\n/***\n This manager enables users to copy/paste data from/to an external Spreadsheet application\n such as MS-Excel\u00AE or OpenOffice-Spreadsheet.\n\n Since it is not possible to access directly the clipboard in javascript, the plugin uses\n a trick to do it's job. After detecting the keystroke, we dynamically create a textarea\n where the browser copies/pastes the serialized data.\n\n options:\n copiedCellStyle : sets the css className used for copied cells. default : \"copied\"\n copiedCellStyleLayerKey : sets the layer key for setting css values of copied cells. default : \"copy-manager\"\n dataItemColumnValueExtractor : option to specify a custom column value extractor function\n dataItemColumnValueSetter : option to specify a custom column value setter function\n clipboardCommandHandler : option to specify a custom handler for paste actions\n includeHeaderWhenCopying : set to true and the plugin will take the name property from each column (which is usually what appears in your header) and put that as the first row of the text that's copied to the clipboard\n bodyElement: option to specify a custom DOM element which to will be added the hidden textbox. It's useful if the grid is inside a modal dialog.\n onCopyInit: optional handler to run when copy action initializes\n onCopySuccess: optional handler to run when copy action is complete\n newRowCreator: function to add rows to table if paste overflows bottom of table, if this function is not provided new rows will be ignored.\n readOnlyMode: suppresses paste\n headerColumnValueExtractor : option to specify a custom column header value extractor function\n*/\nexport class SlickCellExternalCopyManager implements Plugin {\n // --\n // public API\n pluginName = 'CellExternalCopyManager' as const;\n onCopyCells = new SlickEvent<{ ranges: CellRange[]; }>();\n onCopyCancelled = new SlickEvent<{ ranges: CellRange[]; }>();\n onPasteCells = new SlickEvent<{ ranges: CellRange[]; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _bodyElement: HTMLElement;\n protected _copiedRanges: CellRange[] | null = null;\n protected _clearCopyTI?: NodeJS.Timeout;\n protected _copiedCellStyle: string;\n protected _copiedCellStyleLayerKey: string;\n protected _onCopyInit?: () => void;\n protected _onCopySuccess?: (rowCount: number) => void;\n protected _options: ExcelCopyBufferOption;\n\n protected keyCodes = {\n 'C': 67,\n 'V': 86,\n 'ESC': 27,\n 'INSERT': 45\n };\n\n constructor(options: ExcelCopyBufferOption) {\n this._options = options || {};\n this._copiedCellStyleLayerKey = this._options.copiedCellStyleLayerKey || 'copy-manager';\n this._copiedCellStyle = this._options.copiedCellStyle || 'copied';\n this._bodyElement = this._options.bodyElement || document.body;\n this._onCopyInit = this._options.onCopyInit || undefined;\n this._onCopySuccess = this._options.onCopySuccess || undefined;\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));\n\n // we need a cell selection model\n const cellSelectionModel = grid.getSelectionModel();\n if (!cellSelectionModel) {\n throw new Error('Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())');\n }\n // we give focus on the grid when a selection is done on it.\n // without this, if the user selects a range of cell without giving focus on a particular cell, the grid doesn't get the focus and key stroke handles (ctrl+c) don't work\n cellSelectionModel.onSelectedRangesChanged.subscribe(() => {\n if (!this._grid.getEditorLock().isActive()) {\n this._grid.focus();\n }\n });\n }\n\n destroy() {\n this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));\n }\n\n protected getHeaderValueForColumn(columnDef: Column) {\n if (this._options.headerColumnValueExtractor) {\n const val = this._options.headerColumnValueExtractor(columnDef);\n if (val) {\n return val;\n }\n }\n\n return columnDef.name;\n }\n\n protected getDataItemValueForColumn(item: any, columnDef: Column, event: Event): string {\n if (typeof this._options.dataItemColumnValueExtractor === 'function') {\n const val = this._options.dataItemColumnValueExtractor(item, columnDef) as string | null;\n if (val) {\n return val;\n }\n }\n\n let retVal = '';\n\n // if a custom getter is not defined, we call serializeValue of the editor to serialize\n if (columnDef?.editor) {\n const tmpP = document.createElement('p');\n const editor = new (columnDef.editor as any)({\n container: tmpP, // a dummy container\n column: columnDef,\n event,\n position: { top: 0, left: 0 }, // a dummy position required by some editors\n grid: this._grid,\n });\n editor.loadValue(item);\n retVal = editor.serializeValue();\n editor.destroy();\n tmpP.remove();\n } else {\n retVal = item[columnDef.field || ''];\n }\n\n return retVal;\n }\n\n protected setDataItemValueForColumn(item: any, columnDef: Column, value: string): null | string | void {\n if (columnDef.denyPaste) {\n return null;\n }\n\n if (this._options.dataItemColumnValueSetter) {\n return this._options.dataItemColumnValueSetter(item, columnDef, value) as string;\n }\n\n // if a custom setter is not defined, we call applyValue of the editor to unserialize\n if (columnDef.editor) {\n const tmpDiv = document.createElement('div');\n const editor = new (columnDef.editor as any)({\n container: tmpDiv, // a dummy container\n column: columnDef,\n position: { top: 0, left: 0 }, // a dummy position required by some editors\n grid: this._grid\n });\n editor.loadValue(item);\n editor.applyValue(item, value);\n editor.destroy();\n tmpDiv.remove();\n } else {\n item[columnDef.field] = value;\n }\n }\n\n\n protected _createTextBox(innerText: string) {\n const ta = document.createElement('textarea');\n ta.style.position = 'absolute';\n ta.style.left = '-1000px';\n ta.style.top = document.body.scrollTop + 'px';\n ta.value = innerText;\n this._bodyElement.appendChild(ta);\n ta.select();\n\n return ta;\n }\n\n protected _decodeTabularData(grid: SlickGrid, ta: HTMLTextAreaElement) {\n const columns = grid.getColumns();\n const clipText = ta.value;\n const clipRows = clipText.split(/[\\n\\f\\r]/);\n // trim trailing CR if present\n if (clipRows[clipRows.length - 1] === '') {\n clipRows.pop();\n }\n\n let j = 0;\n const clippedRange: any[] = [];\n\n this._bodyElement.removeChild(ta);\n for (let i = 0; i < clipRows.length; i++) {\n if (clipRows[i] !== '') {\n clippedRange[j++] = clipRows[i].split('\\t');\n } else {\n clippedRange[j++] = [''];\n }\n }\n const selectedCell = grid.getActiveCell();\n const ranges = grid.getSelectionModel()?.getSelectedRanges();\n const selectedRange = ranges && ranges.length ? ranges[0] : null; // pick only one selection\n let activeRow: number;\n let activeCell: number;\n\n if (selectedRange) {\n activeRow = selectedRange.fromRow;\n activeCell = selectedRange.fromCell;\n } else if (selectedCell) {\n activeRow = selectedCell.row;\n activeCell = selectedCell.cell;\n } else {\n // we don't know where to paste\n return;\n }\n\n let oneCellToMultiple = false;\n let destH = clippedRange.length;\n let destW = clippedRange.length ? clippedRange[0].length : 0;\n if (clippedRange.length == 1 && clippedRange[0].length == 1 && selectedRange) {\n oneCellToMultiple = true;\n destH = selectedRange.toRow - selectedRange.fromRow + 1;\n destW = selectedRange.toCell - selectedRange.fromCell + 1;\n }\n const availableRows = (grid.getData() as any[]).length - (activeRow || 0);\n let addRows = 0;\n\n // ignore new rows if we don't have a \"newRowCreator\"\n if (availableRows < destH && typeof this._options.newRowCreator === 'function') {\n const d = grid.getData();\n for (addRows = 1; addRows <= destH - availableRows; addRows++) {\n d.push({});\n }\n grid.setData(d);\n grid.render();\n }\n\n const overflowsBottomOfGrid = (activeRow || 0) + destH > grid.getDataLength();\n if (this._options.newRowCreator && overflowsBottomOfGrid) {\n const newRowsNeeded = (activeRow || 0) + destH - grid.getDataLength();\n this._options.newRowCreator(newRowsNeeded);\n }\n\n const clipCommand: ExternalCopyClipCommand = {\n isClipboardCommand: true,\n clippedRange,\n oldValues: [],\n cellExternalCopyManager: this,\n _options: this._options,\n setDataItemValueForColumn: this.setDataItemValueForColumn.bind(this),\n markCopySelection: this.markCopySelection.bind(this),\n oneCellToMultiple,\n activeRow,\n activeCell,\n destH,\n destW,\n maxDestY: grid.getDataLength(),\n maxDestX: grid.getColumns().length,\n h: 0,\n w: 0,\n\n execute: () => {\n clipCommand.h = 0;\n for (let y = 0; y < clipCommand.destH; y++) {\n clipCommand.oldValues[y] = [];\n clipCommand.w = 0;\n clipCommand.h++;\n for (let x = 0; x < clipCommand.destW; x++) {\n clipCommand.w++;\n const desty = activeRow + y;\n const destx = activeCell + x;\n\n if (desty < clipCommand.maxDestY && destx < clipCommand.maxDestX) {\n const dt = grid.getDataItem(desty);\n clipCommand.oldValues[y][x] = dt[columns[destx]['field']];\n if (oneCellToMultiple) {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clippedRange[0][0]);\n } else {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clippedRange[y] ? clippedRange[y][x] : '');\n }\n grid.updateCell(desty, destx);\n grid.onCellChange.notify({\n row: desty,\n cell: destx,\n item: dt,\n grid,\n column: {} as Column\n });\n }\n }\n }\n\n const bRange = new SlickRange(\n activeRow,\n activeCell,\n activeRow + clipCommand.h - 1,\n activeCell + clipCommand.w - 1\n );\n\n this.markCopySelection([bRange]);\n grid.getSelectionModel()?.setSelectedRanges([bRange]);\n this.onPasteCells.notify({ ranges: [bRange] });\n },\n\n undo: () => {\n for (let y = 0; y < clipCommand.destH; y++) {\n for (let x = 0; x < clipCommand.destW; x++) {\n const desty = activeRow + y;\n const destx = activeCell + x;\n\n if (desty < clipCommand.maxDestY && destx < clipCommand.maxDestX) {\n const dt = grid.getDataItem(desty);\n if (oneCellToMultiple) {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clipCommand.oldValues[0][0]);\n } else {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clipCommand.oldValues[y][x]);\n }\n grid.updateCell(desty, destx);\n grid.onCellChange.notify({\n row: desty,\n cell: destx,\n item: dt,\n grid,\n column: {} as Column\n });\n }\n }\n }\n\n const bRange = new SlickRange(\n activeRow,\n activeCell,\n activeRow + clipCommand.h - 1,\n activeCell + clipCommand.w - 1\n );\n\n this.markCopySelection([bRange]);\n grid.getSelectionModel()?.setSelectedRanges([bRange]);\n if (typeof this._options.onPasteCells === 'function') {\n this.onPasteCells.notify({ ranges: [bRange] });\n }\n\n if (addRows > 1) {\n const d = grid.getData();\n for (; addRows > 1; addRows--) {\n d.splice(d.length - 1, 1);\n }\n grid.setData(d);\n grid.render();\n }\n }\n };\n\n if (typeof this._options.clipboardCommandHandler === 'function') {\n this._options.clipboardCommandHandler(clipCommand);\n } else {\n clipCommand.execute();\n }\n }\n\n protected handleKeyDown(e: KeyboardEvent): boolean | void {\n let ranges: CellRange[];\n if (!this._grid.getEditorLock().isActive() || this._grid.getOptions().autoEdit) {\n if (e.which == this.keyCodes.ESC) {\n if (this._copiedRanges) {\n e.preventDefault();\n this.clearCopySelection();\n this.onCopyCancelled.notify({ ranges: this._copiedRanges });\n this._copiedRanges = null;\n }\n }\n\n if ((e.which === this.keyCodes.C || e.which === this.keyCodes.INSERT) && (e.ctrlKey || e.metaKey) && !e.shiftKey) { // CTRL+C or CTRL+INS\n if (typeof this._onCopyInit === 'function') {\n this._onCopyInit.call(this);\n }\n ranges = this._grid.getSelectionModel()?.getSelectedRanges() ?? [];\n if (ranges.length !== 0) {\n this._copiedRanges = ranges;\n this.markCopySelection(ranges);\n this.onCopyCells.notify({ ranges: ranges });\n\n const columns = this._grid.getColumns();\n let clipText = '';\n\n for (let rg = 0; rg < ranges.length; rg++) {\n const range = ranges[rg];\n const clipTextRows: string[] = [];\n for (let i = range.fromRow; i < range.toRow + 1; i++) {\n const clipTextCells: string[] = [];\n const dt = this._grid.getDataItem(i);\n\n if (clipTextRows.length === 0 && this._options.includeHeaderWhenCopying) {\n const clipTextHeaders: string[] = [];\n for (let j = range.fromCell; j < range.toCell + 1; j++) {\n if (columns[j].name!.length > 0 && !columns[j].hidden) {\n clipTextHeaders.push(this.getHeaderValueForColumn(columns[j]));\n }\n }\n clipTextRows.push(clipTextHeaders.join('\\t'));\n }\n\n for (let j = range.fromCell; j < range.toCell + 1; j++) {\n if (columns[j].name!.length > 0 && !columns[j].hidden) {\n clipTextCells.push(this.getDataItemValueForColumn(dt, columns[j], e));\n }\n }\n clipTextRows.push(clipTextCells.join('\\t'));\n }\n clipText += clipTextRows.join('\\r\\n') + '\\r\\n';\n }\n\n if ((window as any).clipboardData) {\n (window as any).clipboardData.setData('Text', clipText);\n return true;\n }\n else {\n const focusEl = document.activeElement as HTMLElement;\n const ta = this._createTextBox(clipText);\n ta.focus();\n\n setTimeout(() => {\n this._bodyElement.removeChild(ta);\n // restore focus when possible\n focusEl\n ? focusEl.focus()\n : console.log('No element to restore focus to after copy?');\n }, this._options?.clipboardPasteDelay ?? CLIPBOARD_PASTE_DELAY);\n\n if (typeof this._onCopySuccess === 'function') {\n let rowCount = 0;\n // If it's cell selection, use the toRow/fromRow fields\n if (ranges.length === 1) {\n rowCount = (ranges[0].toRow + 1) - ranges[0].fromRow;\n } else {\n rowCount = ranges.length;\n }\n this._onCopySuccess(rowCount);\n }\n\n return false;\n }\n }\n }\n\n if (!this._options.readOnlyMode && (\n (e.which === this.keyCodes.V && (e.ctrlKey || e.metaKey) && !e.shiftKey)\n || (e.which === this.keyCodes.INSERT && e.shiftKey && !e.ctrlKey)\n )) { // CTRL+V or Shift+INS\n const ta = this._createTextBox('');\n setTimeout(() => this._decodeTabularData(this._grid, ta), 100);\n return false;\n }\n }\n }\n\n protected markCopySelection(ranges: CellRange[]) {\n this.clearCopySelection();\n\n const columns = this._grid.getColumns();\n const hash: CssStyleHash = {};\n for (let i = 0; i < ranges.length; i++) {\n for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n hash[j] = {};\n for (let k = ranges[i].fromCell; k <= ranges[i].toCell && k < columns.length; k++) {\n hash[j][columns[k].id] = this._copiedCellStyle;\n }\n }\n }\n this._grid.setCellCssStyles(this._copiedCellStyleLayerKey, hash);\n clearTimeout(this._clearCopyTI as NodeJS.Timeout);\n this._clearCopyTI = setTimeout(() => {\n this.clearCopySelection();\n }, this._options?.clearCopySelectionDelay || CLEAR_COPY_SELECTION_DELAY);\n }\n\n clearCopySelection() {\n this._grid.removeCellCssStyles(this._copiedCellStyleLayerKey);\n }\n\n setIncludeHeaderWhenCopying(includeHeaderWhenCopying: boolean) {\n this._options.includeHeaderWhenCopying = includeHeaderWhenCopying;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellExternalCopyManager: SlickCellExternalCopyManager\n }\n });\n}\n"], - "mappings": "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", + "sourcesContent": ["import type { CellRange, Column, CssStyleHash, ExcelCopyBufferOption, ExternalCopyClipCommand, SlickPlugin } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\nimport { SlickEvent as SlickEvent_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nconst CLEAR_COPY_SELECTION_DELAY = 2000;\nconst CLIPBOARD_PASTE_DELAY = 100;\n\n/***\n This manager enables users to copy/paste data from/to an external Spreadsheet application\n such as MS-Excel\u00AE or OpenOffice-Spreadsheet.\n\n Since it is not possible to access directly the clipboard in javascript, the plugin uses\n a trick to do it's job. After detecting the keystroke, we dynamically create a textarea\n where the browser copies/pastes the serialized data.\n\n options:\n copiedCellStyle : sets the css className used for copied cells. default : \"copied\"\n copiedCellStyleLayerKey : sets the layer key for setting css values of copied cells. default : \"copy-manager\"\n dataItemColumnValueExtractor : option to specify a custom column value extractor function\n dataItemColumnValueSetter : option to specify a custom column value setter function\n clipboardCommandHandler : option to specify a custom handler for paste actions\n includeHeaderWhenCopying : set to true and the plugin will take the name property from each column (which is usually what appears in your header) and put that as the first row of the text that's copied to the clipboard\n bodyElement: option to specify a custom DOM element which to will be added the hidden textbox. It's useful if the grid is inside a modal dialog.\n onCopyInit: optional handler to run when copy action initializes\n onCopySuccess: optional handler to run when copy action is complete\n newRowCreator: function to add rows to table if paste overflows bottom of table, if this function is not provided new rows will be ignored.\n readOnlyMode: suppresses paste\n headerColumnValueExtractor : option to specify a custom column header value extractor function\n*/\nexport class SlickCellExternalCopyManager implements SlickPlugin {\n // --\n // public API\n pluginName = 'CellExternalCopyManager' as const;\n onCopyCells = new SlickEvent<{ ranges: CellRange[]; }>();\n onCopyCancelled = new SlickEvent<{ ranges: CellRange[]; }>();\n onPasteCells = new SlickEvent<{ ranges: CellRange[]; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _bodyElement: HTMLElement;\n protected _copiedRanges: CellRange[] | null = null;\n protected _clearCopyTI?: NodeJS.Timeout;\n protected _copiedCellStyle: string;\n protected _copiedCellStyleLayerKey: string;\n protected _onCopyInit?: () => void;\n protected _onCopySuccess?: (rowCount: number) => void;\n protected _options: ExcelCopyBufferOption;\n\n protected keyCodes = {\n 'C': 67,\n 'V': 86,\n 'ESC': 27,\n 'INSERT': 45\n };\n\n constructor(options: ExcelCopyBufferOption) {\n this._options = options || {};\n this._copiedCellStyleLayerKey = this._options.copiedCellStyleLayerKey || 'copy-manager';\n this._copiedCellStyle = this._options.copiedCellStyle || 'copied';\n this._bodyElement = this._options.bodyElement || document.body;\n this._onCopyInit = this._options.onCopyInit || undefined;\n this._onCopySuccess = this._options.onCopySuccess || undefined;\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));\n\n // we need a cell selection model\n const cellSelectionModel = grid.getSelectionModel();\n if (!cellSelectionModel) {\n throw new Error('Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())');\n }\n // we give focus on the grid when a selection is done on it.\n // without this, if the user selects a range of cell without giving focus on a particular cell, the grid doesn't get the focus and key stroke handles (ctrl+c) don't work\n cellSelectionModel.onSelectedRangesChanged.subscribe(() => {\n if (!this._grid.getEditorLock().isActive()) {\n this._grid.focus();\n }\n });\n }\n\n destroy() {\n this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));\n }\n\n protected getHeaderValueForColumn(columnDef: Column) {\n if (this._options.headerColumnValueExtractor) {\n const val = this._options.headerColumnValueExtractor(columnDef);\n if (val) {\n return val;\n }\n }\n\n return columnDef.name;\n }\n\n protected getDataItemValueForColumn(item: any, columnDef: Column, event: Event): string {\n if (typeof this._options.dataItemColumnValueExtractor === 'function') {\n const val = this._options.dataItemColumnValueExtractor(item, columnDef) as string | null;\n if (val) {\n return val;\n }\n }\n\n let retVal = '';\n\n // if a custom getter is not defined, we call serializeValue of the editor to serialize\n if (columnDef?.editor) {\n const tmpP = document.createElement('p');\n const editor = new (columnDef.editor as any)({\n container: tmpP, // a dummy container\n column: columnDef,\n event,\n position: { top: 0, left: 0 }, // a dummy position required by some editors\n grid: this._grid,\n });\n editor.loadValue(item);\n retVal = editor.serializeValue();\n editor.destroy();\n tmpP.remove();\n } else {\n retVal = item[columnDef.field || ''];\n }\n\n return retVal;\n }\n\n protected setDataItemValueForColumn(item: any, columnDef: Column, value: string): null | string | void {\n if (columnDef.denyPaste) {\n return null;\n }\n\n if (this._options.dataItemColumnValueSetter) {\n return this._options.dataItemColumnValueSetter(item, columnDef, value) as string;\n }\n\n // if a custom setter is not defined, we call applyValue of the editor to unserialize\n if (columnDef.editor) {\n const tmpDiv = document.createElement('div');\n const editor = new (columnDef.editor as any)({\n container: tmpDiv, // a dummy container\n column: columnDef,\n position: { top: 0, left: 0 }, // a dummy position required by some editors\n grid: this._grid\n });\n editor.loadValue(item);\n editor.applyValue(item, value);\n editor.destroy();\n tmpDiv.remove();\n } else {\n item[columnDef.field] = value;\n }\n }\n\n\n protected _createTextBox(innerText: string) {\n const ta = document.createElement('textarea');\n ta.style.position = 'absolute';\n ta.style.left = '-1000px';\n ta.style.top = document.body.scrollTop + 'px';\n ta.value = innerText;\n this._bodyElement.appendChild(ta);\n ta.select();\n\n return ta;\n }\n\n protected _decodeTabularData(grid: SlickGrid, ta: HTMLTextAreaElement) {\n const columns = grid.getColumns();\n const clipText = ta.value;\n const clipRows = clipText.split(/[\\n\\f\\r]/);\n // trim trailing CR if present\n if (clipRows[clipRows.length - 1] === '') {\n clipRows.pop();\n }\n\n let j = 0;\n const clippedRange: any[] = [];\n\n this._bodyElement.removeChild(ta);\n for (let i = 0; i < clipRows.length; i++) {\n if (clipRows[i] !== '') {\n clippedRange[j++] = clipRows[i].split('\\t');\n } else {\n clippedRange[j++] = [''];\n }\n }\n const selectedCell = grid.getActiveCell();\n const ranges = grid.getSelectionModel()?.getSelectedRanges();\n const selectedRange = ranges && ranges.length ? ranges[0] : null; // pick only one selection\n let activeRow: number;\n let activeCell: number;\n\n if (selectedRange) {\n activeRow = selectedRange.fromRow;\n activeCell = selectedRange.fromCell;\n } else if (selectedCell) {\n activeRow = selectedCell.row;\n activeCell = selectedCell.cell;\n } else {\n // we don't know where to paste\n return;\n }\n\n let oneCellToMultiple = false;\n let destH = clippedRange.length;\n let destW = clippedRange.length ? clippedRange[0].length : 0;\n if (clippedRange.length === 1 && clippedRange[0].length === 1 && selectedRange) {\n oneCellToMultiple = true;\n destH = selectedRange.toRow - selectedRange.fromRow + 1;\n destW = selectedRange.toCell - selectedRange.fromCell + 1;\n }\n const availableRows = (grid.getData() as any[]).length - (activeRow || 0);\n let addRows = 0;\n\n // ignore new rows if we don't have a \"newRowCreator\"\n if (availableRows < destH && typeof this._options.newRowCreator === 'function') {\n const d = grid.getData();\n for (addRows = 1; addRows <= destH - availableRows; addRows++) {\n d.push({});\n }\n grid.setData(d);\n grid.render();\n }\n\n const overflowsBottomOfGrid = (activeRow || 0) + destH > grid.getDataLength();\n if (this._options.newRowCreator && overflowsBottomOfGrid) {\n const newRowsNeeded = (activeRow || 0) + destH - grid.getDataLength();\n this._options.newRowCreator(newRowsNeeded);\n }\n\n const clipCommand: ExternalCopyClipCommand = {\n isClipboardCommand: true,\n clippedRange,\n oldValues: [],\n cellExternalCopyManager: this,\n _options: this._options,\n setDataItemValueForColumn: this.setDataItemValueForColumn.bind(this),\n markCopySelection: this.markCopySelection.bind(this),\n oneCellToMultiple,\n activeRow,\n activeCell,\n destH,\n destW,\n maxDestY: grid.getDataLength(),\n maxDestX: grid.getColumns().length,\n h: 0,\n w: 0,\n\n execute: () => {\n clipCommand.h = 0;\n for (let y = 0; y < clipCommand.destH; y++) {\n clipCommand.oldValues[y] = [];\n clipCommand.w = 0;\n clipCommand.h++;\n for (let x = 0; x < clipCommand.destW; x++) {\n clipCommand.w++;\n const desty = activeRow + y;\n const destx = activeCell + x;\n\n if (desty < clipCommand.maxDestY && destx < clipCommand.maxDestX) {\n const dt = grid.getDataItem(desty);\n clipCommand.oldValues[y][x] = dt[columns[destx]['field']];\n if (oneCellToMultiple) {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clippedRange[0][0]);\n } else {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clippedRange[y] ? clippedRange[y][x] : '');\n }\n grid.updateCell(desty, destx);\n grid.onCellChange.notify({\n row: desty,\n cell: destx,\n item: dt,\n grid,\n column: {} as Column\n });\n }\n }\n }\n\n const bRange = new SlickRange(\n activeRow,\n activeCell,\n activeRow + clipCommand.h - 1,\n activeCell + clipCommand.w - 1\n );\n\n this.markCopySelection([bRange]);\n grid.getSelectionModel()?.setSelectedRanges([bRange]);\n this.onPasteCells.notify({ ranges: [bRange] });\n },\n\n undo: () => {\n for (let y = 0; y < clipCommand.destH; y++) {\n for (let x = 0; x < clipCommand.destW; x++) {\n const desty = activeRow + y;\n const destx = activeCell + x;\n\n if (desty < clipCommand.maxDestY && destx < clipCommand.maxDestX) {\n const dt = grid.getDataItem(desty);\n if (oneCellToMultiple) {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clipCommand.oldValues[0][0]);\n } else {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clipCommand.oldValues[y][x]);\n }\n grid.updateCell(desty, destx);\n grid.onCellChange.notify({\n row: desty,\n cell: destx,\n item: dt,\n grid,\n column: {} as Column\n });\n }\n }\n }\n\n const bRange = new SlickRange(\n activeRow,\n activeCell,\n activeRow + clipCommand.h - 1,\n activeCell + clipCommand.w - 1\n );\n\n this.markCopySelection([bRange]);\n grid.getSelectionModel()?.setSelectedRanges([bRange]);\n if (typeof this._options.onPasteCells === 'function') {\n this.onPasteCells.notify({ ranges: [bRange] });\n }\n\n if (addRows > 1) {\n const d = grid.getData();\n for (; addRows > 1; addRows--) {\n d.splice(d.length - 1, 1);\n }\n grid.setData(d);\n grid.render();\n }\n }\n };\n\n if (typeof this._options.clipboardCommandHandler === 'function') {\n this._options.clipboardCommandHandler(clipCommand);\n } else {\n clipCommand.execute();\n }\n }\n\n protected handleKeyDown(e: KeyboardEvent): boolean | void {\n let ranges: CellRange[];\n if (!this._grid.getEditorLock().isActive() || this._grid.getOptions().autoEdit) {\n if (e.which === this.keyCodes.ESC) {\n if (this._copiedRanges) {\n e.preventDefault();\n this.clearCopySelection();\n this.onCopyCancelled.notify({ ranges: this._copiedRanges });\n this._copiedRanges = null;\n }\n }\n\n if ((e.which === this.keyCodes.C || e.which === this.keyCodes.INSERT) && (e.ctrlKey || e.metaKey) && !e.shiftKey) { // CTRL+C or CTRL+INS\n if (typeof this._onCopyInit === 'function') {\n this._onCopyInit.call(this);\n }\n ranges = this._grid.getSelectionModel()?.getSelectedRanges() ?? [];\n if (ranges.length !== 0) {\n this._copiedRanges = ranges;\n this.markCopySelection(ranges);\n this.onCopyCells.notify({ ranges });\n\n const columns = this._grid.getColumns();\n let clipText = '';\n\n for (let rg = 0; rg < ranges.length; rg++) {\n const range = ranges[rg];\n const clipTextRows: string[] = [];\n for (let i = range.fromRow; i < range.toRow + 1; i++) {\n const clipTextCells: string[] = [];\n const dt = this._grid.getDataItem(i);\n\n if (clipTextRows.length === 0 && this._options.includeHeaderWhenCopying) {\n const clipTextHeaders: string[] = [];\n for (let j = range.fromCell; j < range.toCell + 1; j++) {\n if (columns[j].name!.length > 0 && !columns[j].hidden) {\n clipTextHeaders.push(this.getHeaderValueForColumn(columns[j]));\n }\n }\n clipTextRows.push(clipTextHeaders.join('\\t'));\n }\n\n for (let j = range.fromCell; j < range.toCell + 1; j++) {\n if (columns[j].name!.length > 0 && !columns[j].hidden) {\n clipTextCells.push(this.getDataItemValueForColumn(dt, columns[j], e));\n }\n }\n clipTextRows.push(clipTextCells.join('\\t'));\n }\n clipText += clipTextRows.join('\\r\\n') + '\\r\\n';\n }\n\n if ((window as any).clipboardData) {\n (window as any).clipboardData.setData('Text', clipText);\n return true;\n }\n else {\n const focusEl = document.activeElement as HTMLElement;\n const ta = this._createTextBox(clipText);\n ta.focus();\n\n setTimeout(() => {\n this._bodyElement.removeChild(ta);\n // restore focus when possible\n focusEl\n ? focusEl.focus()\n : console.log('No element to restore focus to after copy?');\n }, this._options?.clipboardPasteDelay ?? CLIPBOARD_PASTE_DELAY);\n\n if (typeof this._onCopySuccess === 'function') {\n let rowCount = 0;\n // If it's cell selection, use the toRow/fromRow fields\n if (ranges.length === 1) {\n rowCount = (ranges[0].toRow + 1) - ranges[0].fromRow;\n } else {\n rowCount = ranges.length;\n }\n this._onCopySuccess(rowCount);\n }\n\n return false;\n }\n }\n }\n\n if (!this._options.readOnlyMode && (\n (e.which === this.keyCodes.V && (e.ctrlKey || e.metaKey) && !e.shiftKey)\n || (e.which === this.keyCodes.INSERT && e.shiftKey && !e.ctrlKey)\n )) { // CTRL+V or Shift+INS\n const ta = this._createTextBox('');\n setTimeout(() => this._decodeTabularData(this._grid, ta), 100);\n return false;\n }\n }\n }\n\n protected markCopySelection(ranges: CellRange[]) {\n this.clearCopySelection();\n\n const columns = this._grid.getColumns();\n const hash: CssStyleHash = {};\n for (let i = 0; i < ranges.length; i++) {\n for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n hash[j] = {};\n for (let k = ranges[i].fromCell; k <= ranges[i].toCell && k < columns.length; k++) {\n hash[j][columns[k].id] = this._copiedCellStyle;\n }\n }\n }\n this._grid.setCellCssStyles(this._copiedCellStyleLayerKey, hash);\n clearTimeout(this._clearCopyTI as NodeJS.Timeout);\n this._clearCopyTI = setTimeout(() => {\n this.clearCopySelection();\n }, this._options?.clearCopySelectionDelay || CLEAR_COPY_SELECTION_DELAY);\n }\n\n clearCopySelection() {\n this._grid.removeCellCssStyles(this._copiedCellStyleLayerKey);\n }\n\n setIncludeHeaderWhenCopying(includeHeaderWhenCopying: boolean) {\n this._options.includeHeaderWhenCopying = includeHeaderWhenCopying;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellExternalCopyManager: SlickCellExternalCopyManager\n }\n });\n}\n"], + "mappings": "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", "names": ["_a"] } diff --git a/dist/browser/plugins/slick.cellmenu.js b/dist/browser/plugins/slick.cellmenu.js index 6cafb4734..fdd7b5472 100644 --- a/dist/browser/plugins/slick.cellmenu.js +++ b/dist/browser/plugins/slick.cellmenu.js @@ -17,6 +17,7 @@ __publicField(this, "onOptionSelected", new SlickEvent()); // -- // protected props + __publicField(this, "_bindingEventService", new BindingEventService()); __publicField(this, "_cellMenuProperties"); __publicField(this, "_currentCell", -1); __publicField(this, "_currentRow", -1); @@ -26,8 +27,9 @@ __publicField(this, "_handler", new EventHandler()); __publicField(this, "_commandTitleElm"); __publicField(this, "_optionTitleElm"); + __publicField(this, "_lastMenuTypeClicked", ""); __publicField(this, "_menuElm"); - __publicField(this, "_bindingEventService", new BindingEventService()); + __publicField(this, "_subMenuParentId", ""); __publicField(this, "_defaults", { autoAdjustDrop: !0, // dropup/dropdown @@ -42,7 +44,7 @@ this._cellMenuProperties = Utils.extend({}, this._defaults, optionProperties); } init(grid) { - this._grid = grid, this._gridOptions = grid.getOptions(), this._gridUid = (grid == null ? void 0 : grid.getUID()) || "", this._handler.subscribe(this._grid.onClick, this.handleCellClick.bind(this)), this._cellMenuProperties.hideMenuOnScroll && this._handler.subscribe(this._grid.onScroll, this.destroyMenu.bind(this)); + this._grid = grid, this._gridOptions = grid.getOptions(), this._gridUid = (grid == null ? void 0 : grid.getUID()) || "", this._handler.subscribe(this._grid.onClick, this.handleCellClick.bind(this)), this._cellMenuProperties.hideMenuOnScroll && this._handler.subscribe(this._grid.onScroll, this.closeMenu.bind(this)); } setOptions(newOptions) { this._cellMenuProperties = Utils.extend({}, this._cellMenuProperties, newOptions); @@ -51,174 +53,194 @@ var _a; this.onAfterMenuShow.unsubscribe(), this.onBeforeMenuShow.unsubscribe(), this.onBeforeMenuClose.unsubscribe(), this.onCommand.unsubscribe(), this.onOptionSelected.unsubscribe(), this._handler.unsubscribeAll(), this._bindingEventService.unbindAll(), (_a = this._menuElm) == null || _a.remove(), this._commandTitleElm = null, this._optionTitleElm = null, this._menuElm = null; } - createMenu(e) { - var _a, _b, _c, _d; + createParentMenu(e) { + var _a, _b; let cell = this._grid.getCellFromEvent(e); this._currentCell = (_a = cell == null ? void 0 : cell.cell) != null ? _a : 0, this._currentRow = (_b = cell == null ? void 0 : cell.row) != null ? _b : 0; - let columnDef = this._grid.getColumns()[this._currentCell], dataContext = this._grid.getDataItem(this._currentRow), commandItems = this._cellMenuProperties.commandItems || [], optionItems = this._cellMenuProperties.optionItems || []; - if (!columnDef || !columnDef.cellMenu || !commandItems.length && !optionItems.length || (this.destroyMenu(), this.onBeforeMenuShow.notify({ + let columnDef = this._grid.getColumns()[this._currentCell], commandItems = this._cellMenuProperties.commandItems || [], optionItems = this._cellMenuProperties.optionItems || []; + if (!(!columnDef || !columnDef.cellMenu || !commandItems.length && !optionItems.length) && (this.closeMenu(), this.onBeforeMenuShow.notify({ cell: this._currentCell, row: this._currentRow, grid: this._grid - }, e, this).getReturnValue() == !1)) - return; - let maxHeight = isNaN(this._cellMenuProperties.maxHeight) ? this._cellMenuProperties.maxHeight : `${(_c = this._cellMenuProperties.maxHeight) != null ? _c : 0}px`, width = isNaN(this._cellMenuProperties.width) ? this._cellMenuProperties.width : `${(_d = this._cellMenuProperties.maxWidth) != null ? _d : 0}px`; - this._menuElm = document.createElement("div"), this._menuElm.className = `slick-cell-menu ${this._gridUid}`, this._menuElm.role = "menu", width && (this._menuElm.style.width = width), maxHeight && (this._menuElm.style.maxHeight = maxHeight), this._menuElm.style.top = `${e.pageY + 5}px`, this._menuElm.style.left = `${e.pageX}px`, this._menuElm.style.display = "none"; - let closeButtonElm = document.createElement("button"); - closeButtonElm.type = "button", closeButtonElm.className = "close", closeButtonElm.dataset.dismiss = "slick-cell-menu", closeButtonElm.ariaLabel = "Close"; - let spanCloseElm = document.createElement("span"); - if (spanCloseElm.className = "close", spanCloseElm.ariaHidden = "true", spanCloseElm.innerHTML = "×", closeButtonElm.appendChild(spanCloseElm), !this._cellMenuProperties.hideOptionSection && optionItems.length > 0) { + }, e, this).getReturnValue() !== !1 && (this._menuElm = this.createMenu(commandItems, optionItems), this._menuElm.style.top = `${e.pageY + 5}px`, this._menuElm.style.left = `${e.pageX}px`, this._menuElm.style.display = "block", document.body.appendChild(this._menuElm), this.onAfterMenuShow.notify({ + cell: this._currentCell, + row: this._currentRow, + grid: this._grid + }, e, this).getReturnValue() !== !1))) + return this._menuElm; + } + /** + * Create parent menu or sub-menu(s), a parent menu will start at level 0 while sub-menu(s) will be incremented + * @param commandItems - array of optional commands or dividers + * @param optionItems - array of optional options or dividers + * @param level - menu level + * @param item - command, option or divider + * @returns menu DOM element + */ + createMenu(commandItems, optionItems, level = 0, item) { + var _a, _b; + let columnDef = this._grid.getColumns()[this._currentCell], dataContext = this._grid.getDataItem(this._currentRow), maxHeight = isNaN(this._cellMenuProperties.maxHeight) ? this._cellMenuProperties.maxHeight : `${(_a = this._cellMenuProperties.maxHeight) != null ? _a : 0}px`, width = isNaN(this._cellMenuProperties.width) ? this._cellMenuProperties.width : `${(_b = this._cellMenuProperties.maxWidth) != null ? _b : 0}px`, subMenuCommand = item == null ? void 0 : item.command, subMenuId = level === 1 && subMenuCommand ? subMenuCommand.replaceAll(" ", "") : ""; + subMenuId && (this._subMenuParentId = subMenuId), level > 1 && (subMenuId = this._subMenuParentId); + let menuClasses = `slick-cell-menu slick-menu-level-${level} ${this._gridUid}`, bodyMenuElm = document.body.querySelector(`.slick-cell-menu.slick-menu-level-${level}${this.getGridUidSelector()}`); + if (bodyMenuElm) { + if (bodyMenuElm.dataset.subMenuParent === subMenuId) + return bodyMenuElm; + this.destroySubMenus(); + } + let menuElm = document.createElement("div"); + menuElm.className = menuClasses, level > 0 && (menuElm.classList.add("slick-submenu"), subMenuId && (menuElm.dataset.subMenuParent = subMenuId)), menuElm.ariaLabel = level > 1 ? "SubMenu" : "Cell Menu", menuElm.role = "menu", width && (menuElm.style.width = width), maxHeight && (menuElm.style.maxHeight = maxHeight), menuElm.style.display = "none"; + let closeButtonElm = null; + if (level === 0) { + closeButtonElm = document.createElement("button"), closeButtonElm.type = "button", closeButtonElm.className = "close", closeButtonElm.dataset.dismiss = "slick-cell-menu", closeButtonElm.ariaLabel = "Close"; + let spanCloseElm = document.createElement("span"); + spanCloseElm.className = "close", spanCloseElm.ariaHidden = "true", spanCloseElm.innerHTML = "×", closeButtonElm.appendChild(spanCloseElm); + } + if (!this._cellMenuProperties.hideOptionSection && optionItems.length > 0) { let optionMenuElm = document.createElement("div"); - optionMenuElm.className = "slick-cell-menu-option-list", optionMenuElm.role = "menu", this._cellMenuProperties.hideCloseButton || (this._bindingEventService.bind(closeButtonElm, "click", this.handleCloseButtonClicked.bind(this)), this._menuElm.appendChild(closeButtonElm)), this._menuElm.appendChild(optionMenuElm), this.populateOptionItems( + optionMenuElm.className = "slick-cell-menu-option-list", optionMenuElm.role = "menu", item && level > 0 && this.addSubMenuTitleWhenExists(item, optionMenuElm), closeButtonElm && !this._cellMenuProperties.hideCloseButton && (this._bindingEventService.bind(closeButtonElm, "click", this.handleCloseButtonClicked.bind(this)), menuElm.appendChild(closeButtonElm)), menuElm.appendChild(optionMenuElm), this.populateCommandOrOptionItems( + "option", this._cellMenuProperties, optionMenuElm, optionItems, - { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid } + { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid, level } ); } if (!this._cellMenuProperties.hideCommandSection && commandItems.length > 0) { let commandMenuElm = document.createElement("div"); - commandMenuElm.className = "slick-cell-menu-command-list", commandMenuElm.role = "menu", !this._cellMenuProperties.hideCloseButton && (optionItems.length === 0 || this._cellMenuProperties.hideOptionSection) && (this._bindingEventService.bind(closeButtonElm, "click", this.handleCloseButtonClicked.bind(this)), this._menuElm.appendChild(closeButtonElm)), this._menuElm.appendChild(commandMenuElm), this.populateCommandItems( + commandMenuElm.className = "slick-cell-menu-command-list", commandMenuElm.role = "menu", item && level > 0 && this.addSubMenuTitleWhenExists(item, commandMenuElm), closeButtonElm && !this._cellMenuProperties.hideCloseButton && (optionItems.length === 0 || this._cellMenuProperties.hideOptionSection) && (this._bindingEventService.bind(closeButtonElm, "click", this.handleCloseButtonClicked.bind(this)), menuElm.appendChild(closeButtonElm)), menuElm.appendChild(commandMenuElm), this.populateCommandOrOptionItems( + "command", this._cellMenuProperties, commandMenuElm, commandItems, - { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid } + { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid, level } ); } - if (this._menuElm.style.display = "block", document.body.appendChild(this._menuElm), this.onAfterMenuShow.notify({ - cell: this._currentCell, - row: this._currentRow, - grid: this._grid - }, e, this).getReturnValue() != !1) - return this._menuElm; + return level++, menuElm; + } + addSubMenuTitleWhenExists(item, commandOrOptionMenu) { + if (item !== "divider" && (item != null && item.subMenuTitle)) { + let subMenuTitleElm = document.createElement("div"); + subMenuTitleElm.className = "slick-menu-title", subMenuTitleElm.textContent = item.subMenuTitle; + let subMenuTitleClass = item.subMenuTitleCssClass; + subMenuTitleClass && subMenuTitleElm.classList.add(...subMenuTitleClass.split(" ")), commandOrOptionMenu.appendChild(subMenuTitleElm); + } } handleCloseButtonClicked(e) { - e.defaultPrevented || this.destroyMenu(e); + e.defaultPrevented || this.closeMenu(e); } - destroyMenu(e, args) { - var _a, _b, _c; - if (this._menuElm = this._menuElm || document.querySelector(`.slick-cell-menu.${this._gridUid}`), (_a = this._menuElm) != null && _a.remove) { + /** Close and destroy Cell Menu */ + closeMenu(e, args) { + var _a, _b; + if (this._menuElm) { if (this.onBeforeMenuClose.notify({ - cell: (_b = args == null ? void 0 : args.cell) != null ? _b : 0, - row: (_c = args == null ? void 0 : args.row) != null ? _c : 0, + cell: (_a = args == null ? void 0 : args.cell) != null ? _a : 0, + row: (_b = args == null ? void 0 : args.row) != null ? _b : 0, grid: this._grid - }, e, this).getReturnValue() == !1) + }, e, this).getReturnValue() === !1) return; this._menuElm.remove(), this._menuElm = null; } + this.destroySubMenus(); + } + /** Destroy all parent menus and any sub-menus */ + destroyAllMenus() { + this.destroySubMenus(), document.querySelectorAll(`.slick-cell-menu${this.getGridUidSelector()}`).forEach((subElm) => subElm.remove()); + } + /** Close and destroy all previously opened sub-menus */ + destroySubMenus() { + document.querySelectorAll(`.slick-cell-menu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => subElm.remove()); + } + repositionSubMenu(item, type, level, e) { + (e.target.classList.contains("slick-cell") || this._lastMenuTypeClicked !== type) && this.destroySubMenus(); + let subMenuElm = this.createMenu((item == null ? void 0 : item.commandItems) || [], (item == null ? void 0 : item.optionItems) || [], level + 1, item); + subMenuElm.style.display = "block", document.body.appendChild(subMenuElm), this.repositionMenu(e, subMenuElm); } /** * Reposition the menu drop (up/down) and the side (left/right) * @param {*} event */ - repositionMenu(e) { + repositionMenu(e, menuElm) { var _a, _b, _c, _d, _e, _f, _g; - if (this._menuElm && e.target) { - let parentElm = e.target.closest(".slick-cell"), parentOffset = parentElm && Utils.offset(parentElm), menuOffsetLeft = parentElm ? (_a = parentOffset == null ? void 0 : parentOffset.left) != null ? _a : 0 : e.pageX, menuOffsetTop = parentElm ? (_b = parentOffset == null ? void 0 : parentOffset.top) != null ? _b : 0 : e.pageY, parentCellWidth = parentElm.offsetWidth || 0, menuHeight = (_d = (_c = this._menuElm) == null ? void 0 : _c.offsetHeight) != null ? _d : 0, menuWidth = (_g = (_f = (_e = this._menuElm) == null ? void 0 : _e.offsetWidth) != null ? _f : this._cellMenuProperties.width) != null ? _g : 0, rowHeight = this._gridOptions.rowHeight, dropOffset = +(this._cellMenuProperties.autoAdjustDropOffset || 0), sideOffset = +(this._cellMenuProperties.autoAlignSideOffset || 0); + let isSubMenu = menuElm.classList.contains("slick-submenu"), parentElm = isSubMenu ? e.target.closest(".slick-cell-menu-item") : e.target.closest(".slick-cell"); + if (menuElm && parentElm) { + let parentOffset = Utils.offset(parentElm), menuOffsetLeft = parentElm ? (_a = parentOffset == null ? void 0 : parentOffset.left) != null ? _a : 0 : (_b = e == null ? void 0 : e.pageX) != null ? _b : 0, menuOffsetTop = parentElm ? (_c = parentOffset == null ? void 0 : parentOffset.top) != null ? _c : 0 : (_d = e == null ? void 0 : e.pageY) != null ? _d : 0, parentCellWidth = (parentElm == null ? void 0 : parentElm.offsetWidth) || 0, menuHeight = (_e = menuElm == null ? void 0 : menuElm.offsetHeight) != null ? _e : 0, menuWidth = Number((_g = (_f = menuElm == null ? void 0 : menuElm.offsetWidth) != null ? _f : this._cellMenuProperties.width) != null ? _g : 0), rowHeight = this._gridOptions.rowHeight, dropOffset = Number(this._cellMenuProperties.autoAdjustDropOffset || 0), sideOffset = Number(this._cellMenuProperties.autoAlignSideOffset || 0); if (this._cellMenuProperties.autoAdjustDrop) { let spaceBottom = Utils.calculateAvailableSpace(parentElm).bottom, spaceTop = Utils.calculateAvailableSpace(parentElm).top, spaceBottomRemaining = spaceBottom + dropOffset - rowHeight, spaceTopRemaining = spaceTop - dropOffset + rowHeight; - (spaceBottomRemaining < menuHeight && spaceTopRemaining > spaceBottomRemaining ? "top" : "bottom") === "top" ? (this._menuElm.classList.remove("dropdown"), this._menuElm.classList.add("dropup"), menuOffsetTop = menuOffsetTop - menuHeight - dropOffset) : (this._menuElm.classList.remove("dropup"), this._menuElm.classList.add("dropdown"), menuOffsetTop = menuOffsetTop + rowHeight + dropOffset); + (spaceBottomRemaining < menuHeight && spaceTopRemaining > spaceBottomRemaining ? "top" : "bottom") === "top" ? (menuElm.classList.remove("dropdown"), menuElm.classList.add("dropup"), isSubMenu ? menuOffsetTop -= menuHeight - dropOffset - parentElm.clientHeight : menuOffsetTop -= menuHeight - dropOffset) : (menuElm.classList.remove("dropup"), menuElm.classList.add("dropdown"), isSubMenu ? menuOffsetTop += dropOffset : menuOffsetTop += rowHeight + dropOffset); } if (this._cellMenuProperties.autoAlignSide) { - let gridPos = this._grid.getGridPosition(); - (menuOffsetLeft + +menuWidth >= gridPos.width ? "left" : "right") === "left" ? (this._menuElm.classList.remove("dropright"), this._menuElm.classList.add("dropleft"), menuOffsetLeft = menuOffsetLeft - (+menuWidth - parentCellWidth) - sideOffset) : (this._menuElm.classList.remove("dropleft"), this._menuElm.classList.add("dropright"), menuOffsetLeft = menuOffsetLeft + sideOffset); + let gridPos = this._grid.getGridPosition(), subMenuPosCalc = menuOffsetLeft + Number(menuWidth); + isSubMenu && (subMenuPosCalc += parentElm.clientWidth); + let browserWidth = document.documentElement.clientWidth; + (subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth ? "left" : "right") === "left" ? (menuElm.classList.remove("dropright"), menuElm.classList.add("dropleft"), isSubMenu ? menuOffsetLeft -= menuWidth - sideOffset : menuOffsetLeft -= menuWidth - parentCellWidth - sideOffset) : (menuElm.classList.remove("dropleft"), menuElm.classList.add("dropright"), isSubMenu ? menuOffsetLeft += sideOffset + parentElm.offsetWidth : menuOffsetLeft += sideOffset); } - this._menuElm.style.top = `${menuOffsetTop}px`, this._menuElm.style.left = `${menuOffsetLeft}px`; + menuElm.style.top = `${menuOffsetTop}px`, menuElm.style.left = `${menuOffsetLeft}px`; } } + getGridUidSelector() { + let gridUid = this._grid.getUID() || ""; + return gridUid ? `.${gridUid}` : ""; + } handleCellClick(evt, args) { + this.destroyAllMenus(); let e = evt instanceof SlickEventData ? evt.getNativeEvent() : evt, cell = this._grid.getCellFromEvent(e); if (cell) { let dataContext = this._grid.getDataItem(cell.row), columnDef = this._grid.getColumns()[cell.cell]; if (columnDef != null && columnDef.cellMenu && e.preventDefault(), this._cellMenuProperties = Utils.extend({}, this._cellMenuProperties, columnDef.cellMenu), args = args || {}, args.column = columnDef, args.dataContext = dataContext, args.grid = this._grid, !this.runOverrideFunctionWhenExists(this._cellMenuProperties.menuUsabilityOverride, args)) return; - this._menuElm = this.createMenu(e), this._menuElm && (this.repositionMenu(e), this._menuElm.setAttribute("aria-expanded", "true"), this._menuElm.style.display = "block"), this._bindingEventService.bind(document.body, "mousedown", this.handleBodyMouseDown.bind(this)); + this._menuElm = this.createParentMenu(e), this._menuElm && (this.repositionMenu(e, this._menuElm), this._menuElm.setAttribute("aria-expanded", "true"), this._menuElm.style.display = "block"), this._bindingEventService.bind(document.body, "mousedown", this.handleBodyMouseDown.bind(this)); } } + /** When users click outside the Cell Menu, we will typically close the Cell Menu (and any sub-menus) */ handleBodyMouseDown(e) { var _a; - this._menuElm != e.target && !((_a = this._menuElm) != null && _a.contains(e.target)) && (e.defaultPrevented || this.closeMenu(e, { cell: this._currentCell, row: this._currentRow, grid: this._grid })); - } - closeMenu(e, args) { - var _a; - if (this._menuElm) { - if (this.onBeforeMenuClose.notify({ - cell: args == null ? void 0 : args.cell, - row: args == null ? void 0 : args.row, - grid: this._grid - }, e, this).getReturnValue() == !1) - return; - (_a = this._menuElm) == null || _a.remove(), this._menuElm = null; - } - } - /** Construct the Option Items section. */ - populateOptionItems(cellMenu, optionMenuElm, optionItems, args) { - if (!(!args || !optionItems || !cellMenu)) { - cellMenu != null && cellMenu.optionTitle && (this._optionTitleElm = document.createElement("div"), this._optionTitleElm.className = "title", this._optionTitleElm.textContent = cellMenu.optionTitle, optionMenuElm.appendChild(this._optionTitleElm)); - for (let i = 0, ln = optionItems.length; i < ln; i++) { - let addClickListener = !0, item = optionItems[i], isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, args), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, args); - if (!isItemVisible) - continue; - Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable); - let liElm = document.createElement("div"); - liElm.className = "slick-cell-menu-item", liElm.role = "menuitem", (item.divider || item === "divider") && (liElm.classList.add("slick-cell-menu-item-divider"), addClickListener = !1), (item.disabled || !isItemUsable) && liElm.classList.add("slick-cell-menu-item-disabled"), item.hidden && liElm.classList.add("slick-cell-menu-item-hidden"), item.cssClass && liElm.classList.add(...item.cssClass.split(" ")), item.tooltip && (liElm.title = item.tooltip || ""); - let iconElm = document.createElement("div"); - iconElm.className = "slick-cell-menu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...item.iconCssClass.split(" ")), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`); - let textElm = document.createElement("span"); - textElm.className = "slick-cell-menu-content", textElm.textContent = item.title || "", liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), optionMenuElm.appendChild(liElm), addClickListener && this._bindingEventService.bind(liElm, "click", this.handleMenuItemOptionClick.bind(this, item)); - } - } - } - /** Construct the Command Items section. */ - populateCommandItems(cellMenu, commandMenuElm, commandItems, args) { - if (!(!args || !commandItems || !cellMenu)) { - cellMenu != null && cellMenu.commandTitle && (this._commandTitleElm = document.createElement("div"), this._commandTitleElm.className = "title", this._commandTitleElm.textContent = cellMenu.commandTitle, commandMenuElm.appendChild(this._commandTitleElm)); - for (let i = 0, ln = commandItems.length; i < ln; i++) { - let addClickListener = !0, item = commandItems[i], isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, args), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, args); - if (!isItemVisible) - continue; - Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable); - let liElm = document.createElement("div"); - liElm.className = "slick-cell-menu-item", liElm.role = "menuitem", (item.divider || item === "divider") && (liElm.classList.add("slick-cell-menu-item-divider"), addClickListener = !1), (item.disabled || !isItemUsable) && liElm.classList.add("slick-cell-menu-item-disabled"), item.hidden && liElm.classList.add("slick-cell-menu-item-hidden"), item.cssClass && liElm.classList.add(...item.cssClass.split(" ")), item.tooltip && (liElm.title = item.tooltip || ""); - let iconElm = document.createElement("div"); - iconElm.className = "slick-cell-menu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...item.iconCssClass.split(" ")), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`); - let textElm = document.createElement("span"); - textElm.className = "slick-cell-menu-content", textElm.textContent = item.title || "", liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), commandMenuElm.appendChild(liElm), addClickListener && this._bindingEventService.bind(liElm, "click", this.handleMenuItemCommandClick.bind(this, item)); - } - } + let isMenuClicked = !1; + (_a = this._menuElm) != null && _a.contains(e.target) && (isMenuClicked = !0), isMenuClicked || document.querySelectorAll(`.slick-cell-menu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => { + subElm.contains(e.target) && (isMenuClicked = !0); + }), this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented && this.closeMenu(e, { cell: this._currentCell, row: this._currentRow, grid: this._grid }); } - handleMenuItemCommandClick(item, e) { - if (!item || item.disabled || item.divider || item === "divider") + /** Build the Command Items section. */ + populateCommandOrOptionItems(itemType, cellMenu, commandOrOptionMenuElm, commandOrOptionItems, args) { + if (!args || !commandOrOptionItems || !cellMenu) return; - let command = item.command || "", row = this._currentRow, cell = this._currentCell, columnDef = this._grid.getColumns()[cell], dataContext = this._grid.getDataItem(row); - if (command !== null && command !== "") { - let callbackArgs = { - cell, - row, - grid: this._grid, - command, - item, - column: columnDef, - dataContext - }; - this.onCommand.notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs), e.defaultPrevented || this.closeMenu(e, { cell, row, grid: this._grid }); + let isSubMenu = args.level > 0; + cellMenu != null && cellMenu[`${itemType}Title`] && !isSubMenu && (this[`_${itemType}TitleElm`] = document.createElement("div"), this[`_${itemType}TitleElm`].className = "slick-menu-title", this[`_${itemType}TitleElm`].textContent = cellMenu[`${itemType}Title`], commandOrOptionMenuElm.appendChild(this[`_${itemType}TitleElm`])); + for (let i = 0, ln = commandOrOptionItems.length; i < ln; i++) { + let addClickListener = !0, item = commandOrOptionItems[i], isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, args), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, args); + if (!isItemVisible) + continue; + Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable); + let liElm = document.createElement("div"); + liElm.className = "slick-cell-menu-item", liElm.role = "menuitem", (item.divider || item === "divider") && (liElm.classList.add("slick-cell-menu-item-divider"), addClickListener = !1), (item.disabled || !isItemUsable) && liElm.classList.add("slick-cell-menu-item-disabled"), item.hidden && liElm.classList.add("slick-cell-menu-item-hidden"), item.cssClass && liElm.classList.add(...item.cssClass.split(" ")), item.tooltip && (liElm.title = item.tooltip || ""); + let iconElm = document.createElement("div"); + iconElm.className = "slick-cell-menu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...item.iconCssClass.split(" ")), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`); + let textElm = document.createElement("span"); + if (textElm.className = "slick-cell-menu-content", textElm.textContent = item.title || "", liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), commandOrOptionMenuElm.appendChild(liElm), addClickListener && this._bindingEventService.bind(liElm, "click", this.handleMenuItemClick.bind(this, item, itemType, args.level)), item.commandItems || item.optionItems) { + let chevronElm = document.createElement("span"); + chevronElm.className = "sub-item-chevron", this._cellMenuProperties.subItemChevronClass ? chevronElm.classList.add(...this._cellMenuProperties.subItemChevronClass.split(" ")) : chevronElm.textContent = "\u2B9E", liElm.classList.add("slick-submenu-item"), liElm.appendChild(chevronElm); + continue; + } } } - handleMenuItemOptionClick(item, e) { - if (!item || item.disabled || item.divider || item === "divider" || !this._grid.getEditorLock().commitCurrentEdit()) - return; - let option = item.option !== void 0 ? item.option : "", row = this._currentRow, cell = this._currentCell, columnDef = this._grid.getColumns()[cell], dataContext = this._grid.getDataItem(row); - if (option !== void 0) { - let callbackArgs = { - cell, - row, - grid: this._grid, - option, - item, - column: columnDef, - dataContext - }; - this.onOptionSelected.notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs), e.defaultPrevented || this.closeMenu(e, { cell, row, grid: this._grid }); + handleMenuItemClick(item, type, level = 0, e) { + if ((item == null ? void 0 : item[type]) !== void 0 && item !== "divider" && !item.disabled && !item.divider && this._currentCell !== void 0 && this._currentRow !== void 0) { + if (type === "option" && !this._grid.getEditorLock().commitCurrentEdit()) + return; + let optionOrCommand = item[type] !== void 0 ? item[type] : "", row = this._currentRow, cell = this._currentCell, columnDef = this._grid.getColumns()[cell], dataContext = this._grid.getDataItem(row); + if (optionOrCommand !== void 0 && !item[`${type}Items`]) { + let callbackArgs = { + cell, + row, + grid: this._grid, + [type]: optionOrCommand, + item, + column: columnDef, + dataContext + }; + this[type === "command" ? "onCommand" : "onOptionSelected"].notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs), e.defaultPrevented || this.closeMenu(e, { cell, row, grid: this._grid }); + } else + item.commandItems || item.optionItems ? this.repositionSubMenu(item, type, level, e) : this.destroySubMenus(); + this._lastMenuTypeClicked = type; } } /** diff --git a/dist/browser/plugins/slick.cellmenu.js.map b/dist/browser/plugins/slick.cellmenu.js.map index de08fee9f..2e5e2363a 100644 --- a/dist/browser/plugins/slick.cellmenu.js.map +++ b/dist/browser/plugins/slick.cellmenu.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.cellmenu.ts"], - "sourcesContent": ["import {\n BindingEventService as BindingEventService_,\n SlickEvent as SlickEvent_,\n SlickEventData as SlickEventData_,\n SlickEventHandler as SlickEventHandler_,\n Utils as Utils_\n} from '../slick.core';\nimport type {\n CellMenuOption,\n DOMMouseOrTouchEvent,\n GridOption,\n MenuCommandItem,\n MenuCommandItemCallbackArgs,\n MenuFromCellCallbackArgs,\n MenuOptionItem,\n MenuOptionItemCallbackArgs,\n Plugin\n} from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst EventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add Menu on a Cell click (click on the cell that has the cellMenu object defined)\n * The \"cellMenu\" is defined in a Column Definition object\n * Similar to the ContextMenu plugin (could be used in combo),\n * except that it subscribes to the cell \"onClick\" event (regular mouse click or touch).\n *\n * A general use of this plugin is for an Action Dropdown Menu to do certain things on the row that was clicked\n * You can use it to change the cell data property through a list of Options AND/OR through a list of Commands.\n *\n * USAGE:\n *\n * Add the slick.cellMenu.(js|css) files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n * var cellMenuPlugin = new Slick.Plugins.CellMenu(columns, grid, options);\n *\n * Available cellMenu options, by defining a cellMenu object:\n *\n * var columns = [\n * {\n * id: \"action\", name: \"Action\", field: \"action\", formatter: fakeButtonFormatter,\n * cellMenu: {\n * optionTitle: \"Change Effort Driven\",\n * optionItems: [\n * { option: true, title: \"True\", iconCssClass: 'checkmark' },\n * { option: false, title: \"False\" }\n * ],\n * commandTitle: \"Commands\",\n * commandItems: [\n * { command: \"delete-row\", title: \"Delete Row\", iconCssClass: \"sgi sgi-close\", cssClass: 'bold', textCssClass: \"red\" },\n * { divider: true },\n * \"divider\" // you can pass \"divider\" as a string or an object\n * { command: \"help\", title: \"Help\", iconCssClass: \"icon-help\" },\n * { command: \"help\", title: \"Disabled Command\", disabled: true },\n * ],\n * }\n * }\n * ];\n *\n *\n * Available cellMenu properties:\n * commandTitle: Title of the Command section (optional)\n * commandItems: Array of Command item objects (command/title pair)\n * optionTitle: Title of the Option section (optional)\n * optionItems: Array of Options item objects (option/title pair)\n * hideCloseButton: Hide the Close button on top right (defaults to false)\n * hideCommandSection: Hide the Commands section even when the commandItems array is filled (defaults to false)\n * hideMenuOnScroll: Do we want to hide the Cell Menu when a scrolling event occurs (defaults to true)?\n * hideOptionSection: Hide the Options section even when the optionItems array is filled (defaults to false)\n * maxHeight: Maximum height that the drop menu will have, can be a number (250) or text (\"none\")\n * width: Width that the drop menu will have, can be a number (250) or text (defaults to \"auto\")\n * autoAdjustDrop: Auto-align dropup or dropdown menu to the left or right depending on grid viewport available space (defaults to true)\n * autoAdjustDropOffset: Optionally add an offset to the auto-align of the drop menu (defaults to 0)\n * autoAlignSide: Auto-align drop menu to the left or right depending on grid viewport available space (defaults to true)\n * autoAlignSideOffset: Optionally add an offset to the left/right side auto-align (defaults to 0)\n * menuUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling the menu from being usable (must be combined with a custom formatter)\n *\n *\n * Available menu Command/Option item properties:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * command: A command identifier to be passed to the onCommand event handlers (when using \"commandItems\").\n * option: An option to be passed to the onOptionSelected event handlers (when using \"optionItems\").\n * title: Menu item text label.\n * divider: Boolean which tells if the current item is a divider, not an actual command. You could also pass \"divider\" instead of an object\n * disabled: Whether the item/command is disabled.\n * hidden: Whether the item/command is hidden.\n * tooltip: Item tooltip.\n * cssClass: A CSS class to be added to the menu item container.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * textCssClass: A CSS class to be added to the menu item text.\n * iconImage: A url to the icon image.\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n *\n * The plugin exposes the following events:\n *\n * onAfterMenuShow: Fired after the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n *\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n *\n * onBeforeMenuClose: Fired when the menu is closing.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * menu: Menu DOM element\n *\n * onCommand: Fired on menu option clicked from the Command items list\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * command: Menu command identified.\n * item: Menu item selected\n * column: Cell Column definition\n * dataContext: Cell Data Context (data object)\n *\n * onOptionSelected: Fired on menu option clicked from the Option items list\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * option: Menu option selected.\n * item: Menu item selected\n * column: Cell Column definition\n * dataContext: Cell Data Context (data object)\n *\n *\n * @param options {Object} Cell Menu Options\n * @class Slick.Plugins.CellMenu\n */\nexport class SlickCellMenu implements Plugin {\n // --\n // public API\n pluginName = 'CellMenu' as const;\n onAfterMenuShow = new SlickEvent();\n onBeforeMenuShow = new SlickEvent();\n onBeforeMenuClose = new SlickEvent();\n onCommand = new SlickEvent();\n onOptionSelected = new SlickEvent();\n\n // --\n // protected props\n protected _cellMenuProperties: CellMenuOption;\n protected _currentCell = -1;\n protected _currentRow = -1;\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _gridUid = '';\n protected _handler = new EventHandler();\n protected _commandTitleElm?: HTMLSpanElement;\n protected _optionTitleElm?: HTMLSpanElement;\n protected _menuElm?: HTMLDivElement | null;\n protected _bindingEventService = new BindingEventService();\n protected _defaults: CellMenuOption = {\n autoAdjustDrop: true, // dropup/dropdown\n autoAlignSide: true, // left/right\n autoAdjustDropOffset: 0,\n autoAlignSideOffset: 0,\n hideMenuOnScroll: true,\n maxHeight: 'none',\n width: 'auto',\n };\n\n constructor(optionProperties: Partial) {\n this._cellMenuProperties = Utils.extend({}, this._defaults, optionProperties);\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._gridOptions = grid.getOptions();\n this._gridUid = grid?.getUID() || '';\n this._handler.subscribe(this._grid.onClick, this.handleCellClick.bind(this));\n if (this._cellMenuProperties.hideMenuOnScroll) {\n this._handler.subscribe(this._grid.onScroll, this.destroyMenu.bind(this));\n }\n }\n\n setOptions(newOptions: Partial) {\n this._cellMenuProperties = Utils.extend({}, this._cellMenuProperties, newOptions);\n }\n\n destroy() {\n this.onAfterMenuShow.unsubscribe();\n this.onBeforeMenuShow.unsubscribe();\n this.onBeforeMenuClose.unsubscribe();\n this.onCommand.unsubscribe();\n this.onOptionSelected.unsubscribe();\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n this._menuElm?.remove();\n this._commandTitleElm = null as any;\n this._optionTitleElm = null as any;\n this._menuElm = null as any;\n }\n\n protected createMenu(e: DOMMouseOrTouchEvent) {\n const cell = this._grid.getCellFromEvent(e);\n this._currentCell = cell?.cell ?? 0;\n this._currentRow = cell?.row ?? 0;\n const columnDef = this._grid.getColumns()[this._currentCell];\n const dataContext = this._grid.getDataItem(this._currentRow);\n\n const commandItems = this._cellMenuProperties.commandItems || [];\n const optionItems = this._cellMenuProperties.optionItems || [];\n\n // make sure there's at least something to show before creating the Cell Menu\n if (!columnDef || !columnDef.cellMenu || (!commandItems.length && !optionItems.length)) {\n return;\n }\n\n // delete any prior Cell Menu\n this.destroyMenu();\n\n // Let the user modify the menu or cancel altogether,\n // or provide alternative menu implementation.\n if (this.onBeforeMenuShow.notify({\n cell: this._currentCell,\n row: this._currentRow,\n grid: this._grid\n }, e, this).getReturnValue() == false) {\n return;\n }\n\n // create a new cell menu\n const maxHeight = isNaN(this._cellMenuProperties.maxHeight as number) ? this._cellMenuProperties.maxHeight : `${this._cellMenuProperties.maxHeight ?? 0}px`;\n const width = isNaN(this._cellMenuProperties.width as number) ? this._cellMenuProperties.width : `${this._cellMenuProperties.maxWidth ?? 0}px`;\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-cell-menu ${this._gridUid}`;\n this._menuElm.role = 'menu';\n if (width) {\n this._menuElm.style.width = width as string;\n }\n if (maxHeight) {\n this._menuElm.style.maxHeight = maxHeight as string;\n }\n this._menuElm.style.top = `${e.pageY + 5}px`;\n this._menuElm.style.left = `${e.pageX}px`;\n this._menuElm.style.display = 'none';\n\n const closeButtonElm = document.createElement('button');\n closeButtonElm.type = 'button';\n closeButtonElm.className = 'close';\n closeButtonElm.dataset.dismiss = 'slick-cell-menu';\n closeButtonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.innerHTML = '×';\n closeButtonElm.appendChild(spanCloseElm);\n\n // -- Option List section\n if (!this._cellMenuProperties.hideOptionSection && optionItems.length > 0) {\n const optionMenuElm = document.createElement('div');\n optionMenuElm.className = 'slick-cell-menu-option-list';\n optionMenuElm.role = 'menu';\n\n if (!this._cellMenuProperties.hideCloseButton) {\n this._bindingEventService.bind(closeButtonElm, 'click', this.handleCloseButtonClicked.bind(this) as EventListener);\n this._menuElm.appendChild(closeButtonElm);\n }\n this._menuElm.appendChild(optionMenuElm)\n\n this.populateOptionItems(\n this._cellMenuProperties,\n optionMenuElm,\n optionItems,\n { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext: dataContext, grid: this._grid }\n );\n }\n\n // -- Command List section\n if (!this._cellMenuProperties.hideCommandSection && commandItems.length > 0) {\n const commandMenuElm = document.createElement('div');\n commandMenuElm.className = 'slick-cell-menu-command-list';\n commandMenuElm.role = 'menu';\n\n if (!this._cellMenuProperties.hideCloseButton && (optionItems.length === 0 || this._cellMenuProperties.hideOptionSection)) {\n this._bindingEventService.bind(closeButtonElm, 'click', this.handleCloseButtonClicked.bind(this) as EventListener);\n this._menuElm.appendChild(closeButtonElm);\n }\n\n this._menuElm.appendChild(commandMenuElm);\n this.populateCommandItems(\n this._cellMenuProperties,\n commandMenuElm,\n commandItems,\n { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext: dataContext, grid: this._grid }\n );\n }\n\n this._menuElm.style.display = 'block';\n document.body.appendChild(this._menuElm);\n\n if (this.onAfterMenuShow.notify({\n cell: this._currentCell,\n row: this._currentRow,\n grid: this._grid\n }, e, this).getReturnValue() == false) {\n return;\n }\n\n return this._menuElm;\n }\n\n protected handleCloseButtonClicked(e: DOMMouseOrTouchEvent) {\n if (!e.defaultPrevented) {\n this.destroyMenu(e);\n }\n }\n\n destroyMenu(e?: Event, args?: { cell: number; row: number; }) {\n this._menuElm = this._menuElm || document.querySelector(`.slick-cell-menu.${this._gridUid}`);\n\n if (this._menuElm?.remove) {\n if (this.onBeforeMenuClose.notify({\n cell: args?.cell ?? 0,\n row: args?.row ?? 0,\n grid: this._grid,\n }, e, this).getReturnValue() == false) {\n return;\n }\n this._menuElm.remove();\n this._menuElm = null as any;\n }\n }\n\n /**\n * Reposition the menu drop (up/down) and the side (left/right)\n * @param {*} event\n */\n repositionMenu(e: DOMMouseOrTouchEvent) {\n if (this._menuElm && e.target) {\n const parentElm = e.target.closest('.slick-cell') as HTMLDivElement;\n const parentOffset = (parentElm && Utils.offset(parentElm));\n let menuOffsetLeft = parentElm ? parentOffset?.left ?? 0 : e.pageX;\n let menuOffsetTop = parentElm ? parentOffset?.top ?? 0 : e.pageY;\n const parentCellWidth = parentElm.offsetWidth || 0;\n const menuHeight = this._menuElm?.offsetHeight ?? 0;\n const menuWidth = this._menuElm?.offsetWidth ?? this._cellMenuProperties.width ?? 0;\n const rowHeight = this._gridOptions.rowHeight;\n const dropOffset = +(this._cellMenuProperties.autoAdjustDropOffset || 0);\n const sideOffset = +(this._cellMenuProperties.autoAlignSideOffset || 0);\n\n // if autoAdjustDrop is enable, we first need to see what position the drop will be located (defaults to bottom)\n // without necessary toggling it's position just yet, we just want to know the future position for calculation\n if (this._cellMenuProperties.autoAdjustDrop) {\n // since we reposition menu below slick cell, we need to take it in consideration and do our calculation from that element\n const spaceBottom = Utils.calculateAvailableSpace(parentElm).bottom;\n const spaceTop = Utils.calculateAvailableSpace(parentElm).top;\n const spaceBottomRemaining = spaceBottom + dropOffset - rowHeight!;\n const spaceTopRemaining = spaceTop - dropOffset + rowHeight!;\n const dropPosition = (spaceBottomRemaining < menuHeight && spaceTopRemaining > spaceBottomRemaining) ? 'top' : 'bottom';\n if (dropPosition === 'top') {\n this._menuElm.classList.remove('dropdown');\n this._menuElm.classList.add('dropup');\n menuOffsetTop = menuOffsetTop - menuHeight - dropOffset;\n } else {\n this._menuElm.classList.remove('dropup');\n this._menuElm.classList.add('dropdown');\n menuOffsetTop = menuOffsetTop + rowHeight! + dropOffset;\n }\n }\n\n // when auto-align is set, it will calculate whether it has enough space in the viewport to show the drop menu on the right (default)\n // if there isn't enough space on the right, it will automatically align the drop menu to the left (defaults to the right)\n // to simulate an align left, we actually need to know the width of the drop menu\n if (this._cellMenuProperties.autoAlignSide) {\n const gridPos = this._grid.getGridPosition();\n const dropSide = ((menuOffsetLeft + (+menuWidth)) >= gridPos.width) ? 'left' : 'right';\n if (dropSide === 'left') {\n this._menuElm.classList.remove('dropright');\n this._menuElm.classList.add('dropleft');\n menuOffsetLeft = (menuOffsetLeft - (+menuWidth - parentCellWidth) - sideOffset);\n } else {\n this._menuElm.classList.remove('dropleft');\n this._menuElm.classList.add('dropright');\n menuOffsetLeft = menuOffsetLeft + sideOffset;\n }\n }\n\n // ready to reposition the menu\n this._menuElm.style.top = `${menuOffsetTop}px`;\n this._menuElm.style.left = `${menuOffsetLeft}px`;\n }\n }\n\n protected handleCellClick(evt: SlickEventData_ | DOMMouseOrTouchEvent, args: MenuCommandItemCallbackArgs) {\n const e = (evt instanceof SlickEventData) ? evt.getNativeEvent>() : evt;\n\n const cell = this._grid.getCellFromEvent(e);\n if (cell) {\n const dataContext = this._grid.getDataItem(cell.row);\n const columnDef = this._grid.getColumns()[cell.cell];\n\n // prevent event from bubbling but only on column that has a cell menu defined\n if (columnDef?.cellMenu) {\n e.preventDefault();\n }\n\n // merge the cellMenu of the column definition with the default properties\n this._cellMenuProperties = Utils.extend({}, this._cellMenuProperties, columnDef.cellMenu);\n\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.column = columnDef;\n args.dataContext = dataContext;\n args.grid = this._grid;\n if (!this.runOverrideFunctionWhenExists(this._cellMenuProperties.menuUsabilityOverride, args)) {\n return;\n }\n\n // create the DOM element\n this._menuElm = this.createMenu(e);\n\n // reposition the menu to where the user clicked\n if (this._menuElm) {\n this.repositionMenu(e);\n this._menuElm.setAttribute('aria-expanded', 'true');\n this._menuElm.style.display = 'block';\n }\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n }\n }\n\n protected handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n if (this._menuElm != e.target && !(this._menuElm?.contains(e.target))) {\n if (!e.defaultPrevented) {\n this.closeMenu(e, { cell: this._currentCell, row: this._currentRow, grid: this._grid });\n }\n }\n }\n\n closeMenu(e: DOMMouseOrTouchEvent, args: MenuFromCellCallbackArgs) {\n if (this._menuElm) {\n if (this.onBeforeMenuClose.notify({\n cell: args?.cell,\n row: args?.row,\n grid: this._grid,\n }, e, this).getReturnValue() == false) {\n return;\n }\n this._menuElm?.remove();\n this._menuElm = null;\n }\n }\n\n /** Construct the Option Items section. */\n protected populateOptionItems(cellMenu: CellMenuOption, optionMenuElm: HTMLElement, optionItems: Array, args: any) {\n if (!args || !optionItems || !cellMenu) {\n return;\n }\n\n // user could pass a title on top of the Options section\n if (cellMenu?.optionTitle) {\n this._optionTitleElm = document.createElement('div');\n this._optionTitleElm.className = 'title';\n this._optionTitleElm.textContent = cellMenu.optionTitle;\n optionMenuElm.appendChild(this._optionTitleElm);\n }\n\n for (let i = 0, ln = optionItems.length; i < ln; i++) {\n let addClickListener = true;\n const item = optionItems[i];\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as MenuOptionItem).itemVisibilityOverride, args);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as MenuOptionItem).itemUsabilityOverride, args);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemOptionClick\" has the correct flag and won't trigger an option clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as MenuOptionItem).disabled = isItemUsable ? false : true;\n }\n\n const liElm = document.createElement('div');\n liElm.className = 'slick-cell-menu-item';\n liElm.role = 'menuitem';\n\n if ((item as MenuOptionItem).divider || item === 'divider') {\n liElm.classList.add('slick-cell-menu-item-divider');\n addClickListener = false;\n }\n\n // if the item is disabled then add the disabled css class\n if ((item as MenuOptionItem).disabled || !isItemUsable) {\n liElm.classList.add('slick-cell-menu-item-disabled');\n }\n\n // if the item is hidden then add the hidden css class\n if ((item as MenuOptionItem).hidden) {\n liElm.classList.add('slick-cell-menu-item-hidden');\n }\n\n if ((item as MenuOptionItem).cssClass) {\n liElm.classList.add(...(item as MenuOptionItem).cssClass!.split(' '));\n }\n\n if ((item as MenuOptionItem).tooltip) {\n liElm.title = (item as MenuOptionItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-cell-menu-icon';\n\n liElm.appendChild(iconElm);\n\n if ((item as MenuOptionItem).iconCssClass) {\n iconElm.classList.add(...(item as MenuOptionItem).iconCssClass!.split(' '));\n }\n\n if ((item as MenuOptionItem).iconImage) {\n iconElm.style.backgroundImage = `url(${(item as MenuOptionItem).iconImage})`;\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-cell-menu-content';\n textElm.textContent = (item as MenuOptionItem).title || '';\n\n liElm.appendChild(textElm);\n\n if ((item as MenuOptionItem).textCssClass) {\n textElm.classList.add(...(item as MenuOptionItem).textCssClass!.split(' '));\n }\n\n optionMenuElm.appendChild(liElm);\n\n if (addClickListener) {\n this._bindingEventService.bind(liElm, 'click', this.handleMenuItemOptionClick.bind(this, item) as EventListener);\n }\n }\n }\n\n /** Construct the Command Items section. */\n protected populateCommandItems(cellMenu: CellMenuOption, commandMenuElm: HTMLElement, commandItems: Array, args: any) {\n if (!args || !commandItems || !cellMenu) {\n return;\n }\n\n // user could pass a title on top of the Commands section\n if (cellMenu?.commandTitle) {\n this._commandTitleElm = document.createElement('div');\n this._commandTitleElm.className = 'title';\n this._commandTitleElm.textContent = cellMenu.commandTitle;\n commandMenuElm.appendChild(this._commandTitleElm);\n }\n\n for (let i = 0, ln = commandItems.length; i < ln; i++) {\n let addClickListener = true;\n const item = commandItems[i];\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as MenuCommandItem).itemVisibilityOverride, args);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as MenuCommandItem).itemUsabilityOverride, args);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemCommandClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as MenuCommandItem).disabled = isItemUsable ? false : true;\n }\n\n const liElm = document.createElement('div');\n liElm.className = 'slick-cell-menu-item';\n liElm.role = 'menuitem';\n\n if ((item as MenuCommandItem).divider || item === 'divider') {\n liElm.classList.add('slick-cell-menu-item-divider');\n addClickListener = false;\n }\n\n // if the item is disabled then add the disabled css class\n if ((item as MenuCommandItem).disabled || !isItemUsable) {\n liElm.classList.add('slick-cell-menu-item-disabled');\n }\n\n // if the item is hidden then add the hidden css class\n if ((item as MenuCommandItem).hidden) {\n liElm.classList.add('slick-cell-menu-item-hidden');\n }\n\n if ((item as MenuCommandItem).cssClass) {\n liElm.classList.add(...(item as MenuCommandItem).cssClass!.split(' '));\n }\n\n if ((item as MenuCommandItem).tooltip) {\n liElm.title = (item as MenuCommandItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-cell-menu-icon';\n\n liElm.appendChild(iconElm);\n\n if ((item as MenuCommandItem).iconCssClass) {\n iconElm.classList.add(...(item as MenuCommandItem).iconCssClass!.split(' '));\n }\n\n if ((item as MenuCommandItem).iconImage) {\n iconElm.style.backgroundImage = `url(${(item as MenuCommandItem).iconImage})`;\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-cell-menu-content';\n textElm.textContent = (item as MenuCommandItem).title || '';\n\n liElm.appendChild(textElm);\n\n if ((item as MenuCommandItem).textCssClass) {\n textElm.classList.add(...(item as MenuCommandItem).textCssClass!.split(' '));\n }\n\n commandMenuElm.appendChild(liElm);\n\n if (addClickListener) {\n this._bindingEventService.bind(liElm, 'click', this.handleMenuItemCommandClick.bind(this, item) as EventListener);\n }\n }\n }\n\n protected handleMenuItemCommandClick(item: MenuCommandItem | 'divider', e: DOMMouseOrTouchEvent) {\n if (!item || (item as MenuCommandItem).disabled || (item as MenuCommandItem).divider || item === 'divider') {\n return;\n }\n\n const command = item.command || '';\n const row = this._currentRow;\n const cell = this._currentCell;\n const columnDef = this._grid.getColumns()[cell];\n const dataContext = this._grid.getDataItem(row);\n\n if (command !== null && command !== '') {\n // user could execute a callback through 2 ways\n // via the onCommand event and/or an action callback\n const callbackArgs = {\n cell,\n row,\n grid: this._grid,\n command,\n item,\n column: columnDef,\n dataContext,\n };\n this.onCommand.notify(callbackArgs, e, this);\n\n // execute action callback when defined\n if (typeof item.action === 'function') {\n item.action.call(this, e, callbackArgs);\n }\n\n if (!e.defaultPrevented) {\n this.closeMenu(e, { cell, row, grid: this._grid });\n }\n }\n }\n\n protected handleMenuItemOptionClick(item: MenuOptionItem | 'divider', e: DOMMouseOrTouchEvent) {\n if (!item || (item as MenuOptionItem).disabled || (item as MenuOptionItem).divider || item === 'divider') {\n return;\n }\n if (!this._grid.getEditorLock().commitCurrentEdit()) {\n return;\n }\n\n const option = item.option !== undefined ? item.option : '';\n const row = this._currentRow;\n const cell = this._currentCell;\n const columnDef = this._grid.getColumns()[cell];\n const dataContext = this._grid.getDataItem(row);\n\n if (option !== undefined) {\n // user could execute a callback through 2 ways\n // via the onOptionSelected event and/or an action callback\n const callbackArgs = {\n cell,\n row,\n grid: this._grid,\n option,\n item,\n column: columnDef,\n dataContext\n };\n this.onOptionSelected.notify(callbackArgs, e, this);\n\n // execute action callback when defined\n if (typeof item.action === 'function') {\n item.action.call(this, e, callbackArgs);\n }\n\n if (!e.defaultPrevented) {\n this.closeMenu(e, { cell, row, grid: this._grid });\n }\n }\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n CellMenu: SlickCellMenu\n }\n }\n });\n}\n"], - "mappings": ";;;;;;;AAqBA,MAAM,sBAAkC,MAAM,qBACxC,aAAyB,MAAM,OAC/B,iBAA6B,MAAM,WACnC,eAA2B,MAAM,cACjC,QAAoB,MAAM,OA0HnB,gBAAN,MAAsC;AAAA,IAiC3C,YAAY,kBAA2C;AA9BvD;AAAA;AAAA,wCAAa;AACb,6CAAkB,IAAI,WAAqC;AAC3D,8CAAmB,IAAI,WAAqC;AAC5D,+CAAoB,IAAI,WAAqC;AAC7D,uCAAY,IAAI,WAAwC;AACxD,8CAAmB,IAAI,WAAuC;AAI9D;AAAA;AAAA,0BAAU;AACV,0BAAU,gBAAe;AACzB,0BAAU,eAAc;AACxB,0BAAU;AACV,0BAAU;AACV,0BAAU,YAAW;AACrB,0BAAU,YAAW,IAAI,aAAa;AACtC,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU,wBAAuB,IAAI,oBAAoB;AACzD,0BAAU,aAA4B;AAAA,QACpC,gBAAgB;AAAA;AAAA,QAChB,eAAe;AAAA;AAAA,QACf,sBAAsB;AAAA,QACtB,qBAAqB;AAAA,QACrB,kBAAkB;AAAA,QAClB,WAAW;AAAA,QACX,OAAO;AAAA,MACT;AAGE,WAAK,sBAAsB,MAAM,OAAO,CAAC,GAAG,KAAK,WAAW,gBAAgB;AAAA,IAC9E;AAAA,IAEA,KAAK,MAAiB;AACpB,WAAK,QAAQ,MACb,KAAK,eAAe,KAAK,WAAW,GACpC,KAAK,YAAW,6BAAM,aAAY,IAClC,KAAK,SAAS,UAAU,KAAK,MAAM,SAAS,KAAK,gBAAgB,KAAK,IAAI,CAAC,GACvE,KAAK,oBAAoB,oBAC3B,KAAK,SAAS,UAAU,KAAK,MAAM,UAAU,KAAK,YAAY,KAAK,IAAI,CAAC;AAAA,IAE5E;AAAA,IAEA,WAAW,YAAqC;AAC9C,WAAK,sBAAsB,MAAM,OAAO,CAAC,GAAG,KAAK,qBAAqB,UAAU;AAAA,IAClF;AAAA,IAEA,UAAU;AAtMZ;AAuMI,WAAK,gBAAgB,YAAY,GACjC,KAAK,iBAAiB,YAAY,GAClC,KAAK,kBAAkB,YAAY,GACnC,KAAK,UAAU,YAAY,GAC3B,KAAK,iBAAiB,YAAY,GAClC,KAAK,SAAS,eAAe,GAC7B,KAAK,qBAAqB,UAAU,IACpC,UAAK,aAAL,WAAe,UACf,KAAK,mBAAmB,MACxB,KAAK,kBAAkB,MACvB,KAAK,WAAW;AAAA,IAClB;AAAA,IAEU,WAAW,GAAyC;AApNhE;AAqNI,UAAM,OAAO,KAAK,MAAM,iBAAiB,CAAC;AAC1C,WAAK,gBAAe,kCAAM,SAAN,YAAc,GAClC,KAAK,eAAc,kCAAM,QAAN,YAAa;AAChC,UAAM,YAAY,KAAK,MAAM,WAAW,EAAE,KAAK,YAAY,GACrD,cAAc,KAAK,MAAM,YAAY,KAAK,WAAW,GAErD,eAAe,KAAK,oBAAoB,gBAAgB,CAAC,GACzD,cAAc,KAAK,oBAAoB,eAAe,CAAC;AAY7D,UATI,CAAC,aAAa,CAAC,UAAU,YAAa,CAAC,aAAa,UAAU,CAAC,YAAY,WAK/E,KAAK,YAAY,GAIb,KAAK,iBAAiB,OAAO;AAAA,QAC/B,MAAM,KAAK;AAAA,QACX,KAAK,KAAK;AAAA,QACV,MAAM,KAAK;AAAA,MACb,GAAG,GAAG,IAAI,EAAE,eAAe,KAAK;AAC9B;AAIF,UAAM,YAAY,MAAM,KAAK,oBAAoB,SAAmB,IAAI,KAAK,oBAAoB,YAAY,IAAG,UAAK,oBAAoB,cAAzB,YAAsC,CAAC,MACjJ,QAAQ,MAAM,KAAK,oBAAoB,KAAe,IAAI,KAAK,oBAAoB,QAAQ,IAAG,UAAK,oBAAoB,aAAzB,YAAqC,CAAC;AAE1I,WAAK,WAAW,SAAS,cAAc,KAAK,GAC5C,KAAK,SAAS,YAAY,mBAAmB,KAAK,QAAQ,IAC1D,KAAK,SAAS,OAAO,QACjB,UACF,KAAK,SAAS,MAAM,QAAQ,QAE1B,cACF,KAAK,SAAS,MAAM,YAAY,YAElC,KAAK,SAAS,MAAM,MAAM,GAAG,EAAE,QAAQ,CAAC,MACxC,KAAK,SAAS,MAAM,OAAO,GAAG,EAAE,KAAK,MACrC,KAAK,SAAS,MAAM,UAAU;AAE9B,UAAM,iBAAiB,SAAS,cAAc,QAAQ;AACtD,qBAAe,OAAO,UACtB,eAAe,YAAY,SAC3B,eAAe,QAAQ,UAAU,mBACjC,eAAe,YAAY;AAE3B,UAAM,eAAe,SAAS,cAAc,MAAM;AAOlD,UANA,aAAa,YAAY,SACzB,aAAa,aAAa,QAC1B,aAAa,YAAY,WACzB,eAAe,YAAY,YAAY,GAGnC,CAAC,KAAK,oBAAoB,qBAAqB,YAAY,SAAS,GAAG;AACzE,YAAM,gBAAgB,SAAS,cAAc,KAAK;AAClD,sBAAc,YAAY,+BAC1B,cAAc,OAAO,QAEhB,KAAK,oBAAoB,oBAC5B,KAAK,qBAAqB,KAAK,gBAAgB,SAAS,KAAK,yBAAyB,KAAK,IAAI,CAAkB,GACjH,KAAK,SAAS,YAAY,cAAc,IAE1C,KAAK,SAAS,YAAY,aAAa,GAEvC,KAAK;AAAA,UACH,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA,EAAE,MAAM,KAAK,cAAc,KAAK,KAAK,aAAa,QAAQ,WAAW,aAA0B,MAAM,KAAK,MAAM;AAAA,QAClH;AAAA,MACF;AAGA,UAAI,CAAC,KAAK,oBAAoB,sBAAsB,aAAa,SAAS,GAAG;AAC3E,YAAM,iBAAiB,SAAS,cAAc,KAAK;AACnD,uBAAe,YAAY,gCAC3B,eAAe,OAAO,QAElB,CAAC,KAAK,oBAAoB,oBAAoB,YAAY,WAAW,KAAK,KAAK,oBAAoB,uBACrG,KAAK,qBAAqB,KAAK,gBAAgB,SAAS,KAAK,yBAAyB,KAAK,IAAI,CAAkB,GACjH,KAAK,SAAS,YAAY,cAAc,IAG1C,KAAK,SAAS,YAAY,cAAc,GACxC,KAAK;AAAA,UACH,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA,EAAE,MAAM,KAAK,cAAc,KAAK,KAAK,aAAa,QAAQ,WAAW,aAA0B,MAAM,KAAK,MAAM;AAAA,QAClH;AAAA,MACF;AAKA,UAHA,KAAK,SAAS,MAAM,UAAU,SAC9B,SAAS,KAAK,YAAY,KAAK,QAAQ,GAEnC,KAAK,gBAAgB,OAAO;AAAA,QAC9B,MAAM,KAAK;AAAA,QACX,KAAK,KAAK;AAAA,QACV,MAAM,KAAK;AAAA,MACb,GAAG,GAAG,IAAI,EAAE,eAAe,KAAK;AAIhC,eAAO,KAAK;AAAA,IACd;AAAA,IAEU,yBAAyB,GAA4C;AAC7E,MAAK,EAAE,oBACL,KAAK,YAAY,CAAC;AAAA,IAEtB;AAAA,IAEA,YAAY,GAAW,MAAuC;AAzUhE;AA4UI,UAFA,KAAK,WAAW,KAAK,YAAY,SAAS,cAAc,oBAAoB,KAAK,QAAQ,EAAE,IAEvF,UAAK,aAAL,WAAe,QAAQ;AACzB,YAAI,KAAK,kBAAkB,OAAO;AAAA,UAChC,OAAM,kCAAM,SAAN,YAAc;AAAA,UACpB,MAAK,kCAAM,QAAN,YAAa;AAAA,UAClB,MAAM,KAAK;AAAA,QACb,GAAG,GAAG,IAAI,EAAE,eAAe,KAAK;AAC9B;AAEF,aAAK,SAAS,OAAO,GACrB,KAAK,WAAW;AAAA,MAClB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,eAAe,GAAyC;AA7V1D;AA8VI,UAAI,KAAK,YAAY,EAAE,QAAQ;AAC7B,YAAM,YAAY,EAAE,OAAO,QAAQ,aAAa,GAC1C,eAAgB,aAAa,MAAM,OAAO,SAAS,GACrD,iBAAiB,aAAY,kDAAc,SAAd,YAAsB,IAAI,EAAE,OACzD,gBAAgB,aAAY,kDAAc,QAAd,YAAqB,IAAI,EAAE,OACrD,kBAAkB,UAAU,eAAe,GAC3C,cAAa,gBAAK,aAAL,mBAAe,iBAAf,YAA+B,GAC5C,aAAY,sBAAK,aAAL,mBAAe,gBAAf,YAA8B,KAAK,oBAAoB,UAAvD,YAAgE,GAC5E,YAAY,KAAK,aAAa,WAC9B,aAAa,EAAE,KAAK,oBAAoB,wBAAwB,IAChE,aAAa,EAAE,KAAK,oBAAoB,uBAAuB;AAIrE,YAAI,KAAK,oBAAoB,gBAAgB;AAE3C,cAAM,cAAc,MAAM,wBAAwB,SAAS,EAAE,QACvD,WAAW,MAAM,wBAAwB,SAAS,EAAE,KACpD,uBAAuB,cAAc,aAAa,WAClD,oBAAoB,WAAW,aAAa;AAElD,WADsB,uBAAuB,cAAc,oBAAoB,uBAAwB,QAAQ,cAC1F,SACnB,KAAK,SAAS,UAAU,OAAO,UAAU,GACzC,KAAK,SAAS,UAAU,IAAI,QAAQ,GACpC,gBAAgB,gBAAgB,aAAa,eAE7C,KAAK,SAAS,UAAU,OAAO,QAAQ,GACvC,KAAK,SAAS,UAAU,IAAI,UAAU,GACtC,gBAAgB,gBAAgB,YAAa;AAAA,QAEjD;AAKA,YAAI,KAAK,oBAAoB,eAAe;AAC1C,cAAM,UAAU,KAAK,MAAM,gBAAgB;AAE3C,WADmB,iBAAkB,CAAC,aAAe,QAAQ,QAAS,SAAS,aAC9D,UACf,KAAK,SAAS,UAAU,OAAO,WAAW,GAC1C,KAAK,SAAS,UAAU,IAAI,UAAU,GACtC,iBAAkB,kBAAkB,CAAC,YAAY,mBAAmB,eAEpE,KAAK,SAAS,UAAU,OAAO,UAAU,GACzC,KAAK,SAAS,UAAU,IAAI,WAAW,GACvC,iBAAiB,iBAAiB;AAAA,QAEtC;AAGA,aAAK,SAAS,MAAM,MAAM,GAAG,aAAa,MAC1C,KAAK,SAAS,MAAM,OAAO,GAAG,cAAc;AAAA,MAC9C;AAAA,IACF;AAAA,IAEU,gBAAgB,KAA6D,MAAmC;AACxH,UAAM,IAAK,eAAe,iBAAkB,IAAI,eAAqD,IAAI,KAEnG,OAAO,KAAK,MAAM,iBAAiB,CAAC;AAC1C,UAAI,MAAM;AACR,YAAM,cAAc,KAAK,MAAM,YAAY,KAAK,GAAG,GAC7C,YAAY,KAAK,MAAM,WAAW,EAAE,KAAK,IAAI;AAenD,YAZI,+BAAW,YACb,EAAE,eAAe,GAInB,KAAK,sBAAsB,MAAM,OAAO,CAAC,GAAG,KAAK,qBAAqB,UAAU,QAAQ,GAGxF,OAAO,QAAQ,CAAC,GAChB,KAAK,SAAS,WACd,KAAK,cAAc,aACnB,KAAK,OAAO,KAAK,OACb,CAAC,KAAK,8BAA2C,KAAK,oBAAoB,uBAAuB,IAAI;AACvG;AAIF,aAAK,WAAW,KAAK,WAAW,CAAC,GAG7B,KAAK,aACP,KAAK,eAAe,CAAC,GACrB,KAAK,SAAS,aAAa,iBAAiB,MAAM,GAClD,KAAK,SAAS,MAAM,UAAU,UAIhC,KAAK,qBAAqB,KAAK,SAAS,MAAM,aAAa,KAAK,oBAAoB,KAAK,IAAI,CAAkB;AAAA,MACjH;AAAA,IACF;AAAA,IAEU,oBAAoB,GAAyC;AA7bzE;AA8bI,MAAI,KAAK,YAAY,EAAE,UAAU,GAAE,UAAK,aAAL,WAAe,SAAS,EAAE,aACtD,EAAE,oBACL,KAAK,UAAU,GAAG,EAAE,MAAM,KAAK,cAAc,KAAK,KAAK,aAAa,MAAM,KAAK,MAAM,CAAC;AAAA,IAG5F;AAAA,IAEA,UAAU,GAAyC,MAAgC;AArcrF;AAscI,UAAI,KAAK,UAAU;AACjB,YAAI,KAAK,kBAAkB,OAAO;AAAA,UAChC,MAAM,6BAAM;AAAA,UACZ,KAAK,6BAAM;AAAA,UACX,MAAM,KAAK;AAAA,QACb,GAAG,GAAG,IAAI,EAAE,eAAe,KAAK;AAC9B;AAEF,mBAAK,aAAL,WAAe,UACf,KAAK,WAAW;AAAA,MAClB;AAAA,IACF;AAAA;AAAA,IAGU,oBAAoB,UAA0B,eAA4B,aAAgD,MAAW;AAC7I,UAAI,GAAC,QAAQ,CAAC,eAAe,CAAC,WAK9B;AAAA,QAAI,6BAAU,gBACZ,KAAK,kBAAkB,SAAS,cAAc,KAAK,GACnD,KAAK,gBAAgB,YAAY,SACjC,KAAK,gBAAgB,cAAc,SAAS,aAC5C,cAAc,YAAY,KAAK,eAAe;AAGhD,iBAAS,IAAI,GAAG,KAAK,YAAY,QAAQ,IAAI,IAAI,KAAK;AACpD,cAAI,mBAAmB,IACjB,OAAO,YAAY,CAAC,GAGpB,gBAAgB,KAAK,8BAA4C,KAAwB,wBAAwB,IAAI,GACrH,eAAe,KAAK,8BAA4C,KAAwB,uBAAuB,IAAI;AAGzH,cAAI,CAAC;AACH;AAKF,UAAI,OAAO,UAAU,eAAe,KAAK,MAAM,uBAAuB,MACnE,KAAwB,WAAW;AAGtC,cAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,gBAAM,YAAY,wBAClB,MAAM,OAAO,aAER,KAAwB,WAAW,SAAS,eAC/C,MAAM,UAAU,IAAI,8BAA8B,GAClD,mBAAmB,MAIhB,KAAwB,YAAY,CAAC,iBACxC,MAAM,UAAU,IAAI,+BAA+B,GAIhD,KAAwB,UAC3B,MAAM,UAAU,IAAI,6BAA6B,GAG9C,KAAwB,YAC3B,MAAM,UAAU,IAAI,GAAI,KAAwB,SAAU,MAAM,GAAG,CAAC,GAGjE,KAAwB,YAC3B,MAAM,QAAS,KAAwB,WAAW;AAGpD,cAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,kBAAQ,YAAY,wBAEpB,MAAM,YAAY,OAAO,GAEpB,KAAwB,gBAC3B,QAAQ,UAAU,IAAI,GAAI,KAAwB,aAAc,MAAM,GAAG,CAAC,GAGvE,KAAwB,cAC3B,QAAQ,MAAM,kBAAkB,OAAQ,KAAwB,SAAS;AAG3E,cAAM,UAAU,SAAS,cAAc,MAAM;AAC7C,kBAAQ,YAAY,2BACpB,QAAQ,cAAe,KAAwB,SAAS,IAExD,MAAM,YAAY,OAAO,GAEpB,KAAwB,gBAC3B,QAAQ,UAAU,IAAI,GAAI,KAAwB,aAAc,MAAM,GAAG,CAAC,GAG5E,cAAc,YAAY,KAAK,GAE3B,oBACF,KAAK,qBAAqB,KAAK,OAAO,SAAS,KAAK,0BAA0B,KAAK,MAAM,IAAI,CAAkB;AAAA,QAEnH;AAAA;AAAA,IACF;AAAA;AAAA,IAGU,qBAAqB,UAA0B,gBAA6B,cAAkD,MAAW;AACjJ,UAAI,GAAC,QAAQ,CAAC,gBAAgB,CAAC,WAK/B;AAAA,QAAI,6BAAU,iBACZ,KAAK,mBAAmB,SAAS,cAAc,KAAK,GACpD,KAAK,iBAAiB,YAAY,SAClC,KAAK,iBAAiB,cAAc,SAAS,cAC7C,eAAe,YAAY,KAAK,gBAAgB;AAGlD,iBAAS,IAAI,GAAG,KAAK,aAAa,QAAQ,IAAI,IAAI,KAAK;AACrD,cAAI,mBAAmB,IACjB,OAAO,aAAa,CAAC,GAGrB,gBAAgB,KAAK,8BAA4C,KAAyB,wBAAwB,IAAI,GACtH,eAAe,KAAK,8BAA4C,KAAyB,uBAAuB,IAAI;AAG1H,cAAI,CAAC;AACH;AAKF,UAAI,OAAO,UAAU,eAAe,KAAK,MAAM,uBAAuB,MACnE,KAAyB,WAAW;AAGvC,cAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,gBAAM,YAAY,wBAClB,MAAM,OAAO,aAER,KAAyB,WAAW,SAAS,eAChD,MAAM,UAAU,IAAI,8BAA8B,GAClD,mBAAmB,MAIhB,KAAyB,YAAY,CAAC,iBACzC,MAAM,UAAU,IAAI,+BAA+B,GAIhD,KAAyB,UAC5B,MAAM,UAAU,IAAI,6BAA6B,GAG9C,KAAyB,YAC5B,MAAM,UAAU,IAAI,GAAI,KAAyB,SAAU,MAAM,GAAG,CAAC,GAGlE,KAAyB,YAC5B,MAAM,QAAS,KAAyB,WAAW;AAGrD,cAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,kBAAQ,YAAY,wBAEpB,MAAM,YAAY,OAAO,GAEpB,KAAyB,gBAC5B,QAAQ,UAAU,IAAI,GAAI,KAAyB,aAAc,MAAM,GAAG,CAAC,GAGxE,KAAyB,cAC5B,QAAQ,MAAM,kBAAkB,OAAQ,KAAyB,SAAS;AAG5E,cAAM,UAAU,SAAS,cAAc,MAAM;AAC7C,kBAAQ,YAAY,2BACpB,QAAQ,cAAe,KAAyB,SAAS,IAEzD,MAAM,YAAY,OAAO,GAEpB,KAAyB,gBAC5B,QAAQ,UAAU,IAAI,GAAI,KAAyB,aAAc,MAAM,GAAG,CAAC,GAG7E,eAAe,YAAY,KAAK,GAE5B,oBACF,KAAK,qBAAqB,KAAK,OAAO,SAAS,KAAK,2BAA2B,KAAK,MAAM,IAAI,CAAkB;AAAA,QAEpH;AAAA;AAAA,IACF;AAAA,IAEU,2BAA2B,MAAmC,GAAyC;AAC/G,UAAI,CAAC,QAAS,KAAyB,YAAa,KAAyB,WAAW,SAAS;AAC/F;AAGF,UAAM,UAAU,KAAK,WAAW,IAC1B,MAAM,KAAK,aACX,OAAO,KAAK,cACZ,YAAY,KAAK,MAAM,WAAW,EAAE,IAAI,GACxC,cAAc,KAAK,MAAM,YAAY,GAAG;AAE9C,UAAI,YAAY,QAAQ,YAAY,IAAI;AAGtC,YAAM,eAAe;AAAA,UACnB;AAAA,UACA;AAAA,UACA,MAAM,KAAK;AAAA,UACX;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACF;AACA,aAAK,UAAU,OAAO,cAAc,GAAG,IAAI,GAGvC,OAAO,KAAK,UAAW,cACzB,KAAK,OAAO,KAAK,MAAM,GAAG,YAAY,GAGnC,EAAE,oBACL,KAAK,UAAU,GAAG,EAAE,MAAM,KAAK,MAAM,KAAK,MAAM,CAAC;AAAA,MAErD;AAAA,IACF;AAAA,IAEU,0BAA0B,MAAkC,GAAyC;AAI7G,UAHI,CAAC,QAAS,KAAwB,YAAa,KAAwB,WAAW,SAAS,aAG3F,CAAC,KAAK,MAAM,cAAc,EAAE,kBAAkB;AAChD;AAGF,UAAM,SAAS,KAAK,WAAW,SAAY,KAAK,SAAS,IACnD,MAAM,KAAK,aACX,OAAO,KAAK,cACZ,YAAY,KAAK,MAAM,WAAW,EAAE,IAAI,GACxC,cAAc,KAAK,MAAM,YAAY,GAAG;AAE9C,UAAI,WAAW,QAAW;AAGxB,YAAM,eAAe;AAAA,UACnB;AAAA,UACA;AAAA,UACA,MAAM,KAAK;AAAA,UACX;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACF;AACA,aAAK,iBAAiB,OAAO,cAAc,GAAG,IAAI,GAG9C,OAAO,KAAK,UAAW,cACzB,KAAK,OAAO,KAAK,MAAM,GAAG,YAAY,GAGnC,EAAE,oBACL,KAAK,UAAU,GAAG,EAAE,MAAM,KAAK,MAAM,KAAK,MAAM,CAAC;AAAA,MAErD;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQU,8BAAuC,YAAkD,MAAkB;AACnH,aAAI,OAAO,cAAe,aACjB,WAAW,KAAK,MAAM,IAAI,IAE5B;AAAA,IACT;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,SAAS;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF,CAAC;", + "sourcesContent": ["import {\n BindingEventService as BindingEventService_,\n SlickEvent as SlickEvent_,\n SlickEventData as SlickEventData_,\n SlickEventHandler as SlickEventHandler_,\n Utils as Utils_\n} from '../slick.core';\nimport type {\n CellMenuOption,\n Column,\n DOMMouseOrTouchEvent,\n GridOption,\n MenuCommandItem,\n MenuCommandItemCallbackArgs,\n MenuFromCellCallbackArgs,\n MenuOptionItem,\n MenuOptionItemCallbackArgs,\n MenuType,\n SlickPlugin\n} from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst EventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add Menu on a Cell click (click on the cell that has the cellMenu object defined)\n * The \"cellMenu\" is defined in a Column Definition object\n * Similar to the ContextMenu plugin (could be used in combo),\n * except that it subscribes to the cell \"onClick\" event (regular mouse click or touch).\n *\n * A general use of this plugin is for an Action Dropdown Menu to do certain things on the row that was clicked\n * You can use it to change the cell data property through a list of Options AND/OR through a list of Commands.\n *\n * USAGE:\n *\n * Add the slick.cellMenu.(js|css) files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n * var cellMenuPlugin = new Slick.Plugins.CellMenu(columns, grid, options);\n *\n * Available cellMenu options, by defining a cellMenu object:\n *\n * var columns = [\n * {\n * id: \"action\", name: \"Action\", field: \"action\", formatter: fakeButtonFormatter,\n * cellMenu: {\n * optionTitle: \"Change Effort Driven\",\n * optionItems: [\n * { option: true, title: \"True\", iconCssClass: 'checkmark' },\n * { option: false, title: \"False\" }\n * ],\n * commandTitle: \"Commands\",\n * commandItems: [\n * { command: \"delete-row\", title: \"Delete Row\", iconCssClass: \"sgi sgi-close\", cssClass: 'bold', textCssClass: \"red\" },\n * { divider: true },\n * \"divider\" // you can pass \"divider\" as a string or an object\n * { command: \"help\", title: \"Help\", iconCssClass: \"icon-help\" },\n * { command: \"help\", title: \"Disabled Command\", disabled: true },\n * ],\n * }\n * }\n * ];\n *\n *\n * Available cellMenu properties:\n * commandTitle: Title of the Command section (optional)\n * commandItems: Array of Command item objects (command/title pair)\n * optionTitle: Title of the Option section (optional)\n * optionItems: Array of Options item objects (option/title pair)\n * hideCloseButton: Hide the Close button on top right (defaults to false)\n * hideCommandSection: Hide the Commands section even when the commandItems array is filled (defaults to false)\n * hideMenuOnScroll: Do we want to hide the Cell Menu when a scrolling event occurs (defaults to true)?\n * hideOptionSection: Hide the Options section even when the optionItems array is filled (defaults to false)\n * maxHeight: Maximum height that the drop menu will have, can be a number (250) or text (\"none\")\n * width: Width that the drop menu will have, can be a number (250) or text (defaults to \"auto\")\n * autoAdjustDrop: Auto-align dropup or dropdown menu to the left or right depending on grid viewport available space (defaults to true)\n * autoAdjustDropOffset: Optionally add an offset to the auto-align of the drop menu (defaults to 0)\n * autoAlignSide: Auto-align drop menu to the left or right depending on grid viewport available space (defaults to true)\n * autoAlignSideOffset: Optionally add an offset to the left/right side auto-align (defaults to 0)\n * menuUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling the menu from being usable (must be combined with a custom formatter)\n * subItemChevronClass: CSS class that can be added on the right side of a sub-item parent (typically a chevron-right icon)\n *\n *\n * Available menu Command/Option item properties:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * command: A command identifier to be passed to the onCommand event handlers (when using \"commandItems\").\n * option: An option to be passed to the onOptionSelected event handlers (when using \"optionItems\").\n * title: Menu item text label.\n * divider: Boolean which tells if the current item is a divider, not an actual command. You could also pass \"divider\" instead of an object\n * disabled: Whether the item/command is disabled.\n * hidden: Whether the item/command is hidden.\n * subMenuTitle: Optional sub-menu title that will shows up when sub-menu commmands/options list is opened\n * subMenuTitleCssClass: Optional sub-menu title CSS class to use with `subMenuTitle`\n * tooltip: Item tooltip.\n * cssClass: A CSS class to be added to the menu item container.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * textCssClass: A CSS class to be added to the menu item text.\n * iconImage: A url to the icon image.\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n *\n * The plugin exposes the following events:\n *\n * onAfterMenuShow: Fired after the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n *\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n *\n * onBeforeMenuClose: Fired when the menu is closing.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * menu: Menu DOM element\n *\n * onCommand: Fired on menu option clicked from the Command items list\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * command: Menu command identified.\n * item: Menu item selected\n * column: Cell Column definition\n * dataContext: Cell Data Context (data object)\n *\n * onOptionSelected: Fired on menu option clicked from the Option items list\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * option: Menu option selected.\n * item: Menu item selected\n * column: Cell Column definition\n * dataContext: Cell Data Context (data object)\n *\n *\n * @param options {Object} Cell Menu Options\n * @class Slick.Plugins.CellMenu\n */\nexport class SlickCellMenu implements SlickPlugin {\n // --\n // public API\n pluginName = 'CellMenu' as const;\n onAfterMenuShow = new SlickEvent();\n onBeforeMenuShow = new SlickEvent();\n onBeforeMenuClose = new SlickEvent();\n onCommand = new SlickEvent();\n onOptionSelected = new SlickEvent();\n\n // --\n // protected props\n protected _bindingEventService = new BindingEventService();\n protected _cellMenuProperties: CellMenuOption;\n protected _currentCell = -1;\n protected _currentRow = -1;\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _gridUid = '';\n protected _handler = new EventHandler();\n protected _commandTitleElm?: HTMLSpanElement;\n protected _optionTitleElm?: HTMLSpanElement;\n protected _lastMenuTypeClicked = '';\n protected _menuElm?: HTMLDivElement | null;\n protected _subMenuParentId = '';\n protected _defaults: CellMenuOption = {\n autoAdjustDrop: true, // dropup/dropdown\n autoAlignSide: true, // left/right\n autoAdjustDropOffset: 0,\n autoAlignSideOffset: 0,\n hideMenuOnScroll: true,\n maxHeight: 'none',\n width: 'auto',\n };\n\n constructor(optionProperties: Partial) {\n this._cellMenuProperties = Utils.extend({}, this._defaults, optionProperties);\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._gridOptions = grid.getOptions();\n this._gridUid = grid?.getUID() || '';\n this._handler.subscribe(this._grid.onClick, this.handleCellClick.bind(this));\n if (this._cellMenuProperties.hideMenuOnScroll) {\n this._handler.subscribe(this._grid.onScroll, this.closeMenu.bind(this));\n }\n }\n\n setOptions(newOptions: Partial) {\n this._cellMenuProperties = Utils.extend({}, this._cellMenuProperties, newOptions);\n }\n\n destroy() {\n this.onAfterMenuShow.unsubscribe();\n this.onBeforeMenuShow.unsubscribe();\n this.onBeforeMenuClose.unsubscribe();\n this.onCommand.unsubscribe();\n this.onOptionSelected.unsubscribe();\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n this._menuElm?.remove();\n this._commandTitleElm = null as any;\n this._optionTitleElm = null as any;\n this._menuElm = null as any;\n }\n\n protected createParentMenu(e: DOMMouseOrTouchEvent) {\n const cell = this._grid.getCellFromEvent(e);\n this._currentCell = cell?.cell ?? 0;\n this._currentRow = cell?.row ?? 0;\n const columnDef = this._grid.getColumns()[this._currentCell];\n\n const commandItems = this._cellMenuProperties.commandItems || [];\n const optionItems = this._cellMenuProperties.optionItems || [];\n\n // make sure there's at least something to show before creating the Cell Menu\n if (!columnDef || !columnDef.cellMenu || (!commandItems.length && !optionItems.length)) {\n return;\n }\n\n // delete any prior Cell Menu\n this.closeMenu();\n\n // Let the user modify the menu or cancel altogether,\n // or provide alternative menu implementation.\n if (this.onBeforeMenuShow.notify({\n cell: this._currentCell,\n row: this._currentRow,\n grid: this._grid\n }, e, this).getReturnValue() === false) {\n return;\n }\n\n // create 1st parent menu container & reposition it\n this._menuElm = this.createMenu(commandItems, optionItems);\n this._menuElm.style.top = `${e.pageY + 5}px`;\n this._menuElm.style.left = `${e.pageX}px`;\n this._menuElm.style.display = 'block';\n document.body.appendChild(this._menuElm);\n\n if (this.onAfterMenuShow.notify({\n cell: this._currentCell,\n row: this._currentRow,\n grid: this._grid\n }, e, this).getReturnValue() === false) {\n return;\n }\n\n return this._menuElm;\n }\n\n /**\n * Create parent menu or sub-menu(s), a parent menu will start at level 0 while sub-menu(s) will be incremented\n * @param commandItems - array of optional commands or dividers\n * @param optionItems - array of optional options or dividers\n * @param level - menu level\n * @param item - command, option or divider\n * @returns menu DOM element\n */\n protected createMenu(commandItems: Array, optionItems: Array, level = 0, item?: MenuCommandItem | MenuOptionItem | 'divider') {\n const columnDef = this._grid.getColumns()[this._currentCell];\n const dataContext = this._grid.getDataItem(this._currentRow);\n\n // create a new cell menu\n const maxHeight = isNaN(this._cellMenuProperties.maxHeight as number) ? this._cellMenuProperties.maxHeight : `${this._cellMenuProperties.maxHeight ?? 0}px`;\n const width = isNaN(this._cellMenuProperties.width as number) ? this._cellMenuProperties.width : `${this._cellMenuProperties.maxWidth ?? 0}px`;\n\n // to avoid having multiple sub-menu trees opened,\n // we need to somehow keep trace of which parent menu the tree belongs to\n // and we should keep ref of only the first sub-menu parent, we can use the command name (remove any whitespaces though)\n const subMenuCommand = (item as MenuCommandItem)?.command;\n let subMenuId = (level === 1 && subMenuCommand) ? subMenuCommand.replaceAll(' ', '') : '';\n if (subMenuId) {\n this._subMenuParentId = subMenuId;\n }\n if (level > 1) {\n subMenuId = this._subMenuParentId;\n }\n\n const menuClasses = `slick-cell-menu slick-menu-level-${level} ${this._gridUid}`;\n const bodyMenuElm = document.body.querySelector(`.slick-cell-menu.slick-menu-level-${level}${this.getGridUidSelector()}`);\n\n // return menu/sub-menu if it's already opened unless we are on different sub-menu tree if so close them all\n if (bodyMenuElm) {\n if (bodyMenuElm.dataset.subMenuParent === subMenuId) {\n return bodyMenuElm;\n }\n this.destroySubMenus();\n }\n\n const menuElm = document.createElement('div');\n menuElm.className = menuClasses;\n if (level > 0) {\n menuElm.classList.add('slick-submenu');\n if (subMenuId) {\n menuElm.dataset.subMenuParent = subMenuId;\n }\n }\n menuElm.ariaLabel = level > 1 ? 'SubMenu' : 'Cell Menu';\n menuElm.role = 'menu';\n if (width) {\n menuElm.style.width = width as string;\n }\n if (maxHeight) {\n menuElm.style.maxHeight = maxHeight as string;\n }\n\n menuElm.style.display = 'none';\n\n let closeButtonElm: HTMLButtonElement | null = null;\n if (level === 0) {\n closeButtonElm = document.createElement('button');\n closeButtonElm.type = 'button';\n closeButtonElm.className = 'close';\n closeButtonElm.dataset.dismiss = 'slick-cell-menu';\n closeButtonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.innerHTML = '×';\n closeButtonElm.appendChild(spanCloseElm);\n }\n\n // -- Option List section\n if (!this._cellMenuProperties.hideOptionSection && optionItems.length > 0) {\n const optionMenuElm = document.createElement('div');\n optionMenuElm.className = 'slick-cell-menu-option-list';\n optionMenuElm.role = 'menu';\n\n // when creating sub-menu add its sub-menu title when exists\n if (item && level > 0) {\n this.addSubMenuTitleWhenExists(item, optionMenuElm); // add sub-menu title when exists\n }\n\n if (closeButtonElm && !this._cellMenuProperties.hideCloseButton) {\n this._bindingEventService.bind(closeButtonElm, 'click', this.handleCloseButtonClicked.bind(this) as EventListener);\n menuElm.appendChild(closeButtonElm);\n }\n menuElm.appendChild(optionMenuElm);\n\n this.populateCommandOrOptionItems(\n 'option',\n this._cellMenuProperties,\n optionMenuElm,\n optionItems,\n { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid, level }\n );\n }\n\n // -- Command List section\n if (!this._cellMenuProperties.hideCommandSection && commandItems.length > 0) {\n const commandMenuElm = document.createElement('div');\n commandMenuElm.className = 'slick-cell-menu-command-list';\n commandMenuElm.role = 'menu';\n\n // when creating sub-menu add its sub-menu title when exists\n if (item && level > 0) {\n this.addSubMenuTitleWhenExists(item, commandMenuElm); // add sub-menu title when exists\n }\n\n if (closeButtonElm && !this._cellMenuProperties.hideCloseButton && (optionItems.length === 0 || this._cellMenuProperties.hideOptionSection)) {\n this._bindingEventService.bind(closeButtonElm, 'click', this.handleCloseButtonClicked.bind(this) as EventListener);\n menuElm.appendChild(closeButtonElm);\n }\n menuElm.appendChild(commandMenuElm);\n\n this.populateCommandOrOptionItems(\n 'command',\n this._cellMenuProperties,\n commandMenuElm,\n commandItems,\n { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid, level }\n );\n }\n\n // increment level for possible next sub-menus if exists\n level++;\n\n return menuElm;\n }\n\n protected addSubMenuTitleWhenExists(item: MenuCommandItem | MenuOptionItem | 'divider', commandOrOptionMenu: HTMLDivElement) {\n if (item !== 'divider' && item?.subMenuTitle) {\n const subMenuTitleElm = document.createElement('div');\n subMenuTitleElm.className = 'slick-menu-title';\n subMenuTitleElm.textContent = item.subMenuTitle as string;\n const subMenuTitleClass = item.subMenuTitleCssClass as string;\n if (subMenuTitleClass) {\n subMenuTitleElm.classList.add(...subMenuTitleClass.split(' '));\n }\n\n commandOrOptionMenu.appendChild(subMenuTitleElm);\n }\n }\n\n protected handleCloseButtonClicked(e: DOMMouseOrTouchEvent) {\n if (!e.defaultPrevented) {\n this.closeMenu(e);\n }\n }\n\n /** Close and destroy Cell Menu */\n closeMenu(e?: DOMMouseOrTouchEvent, args?: MenuFromCellCallbackArgs) {\n if (this._menuElm) {\n if (this.onBeforeMenuClose.notify({\n cell: args?.cell ?? 0,\n row: args?.row ?? 0,\n grid: this._grid,\n }, e, this).getReturnValue() === false) {\n return;\n }\n this._menuElm.remove();\n this._menuElm = null;\n }\n this.destroySubMenus();\n }\n\n /** Destroy all parent menus and any sub-menus */\n destroyAllMenus() {\n this.destroySubMenus();\n document.querySelectorAll(`.slick-cell-menu${this.getGridUidSelector()}`)\n .forEach(subElm => subElm.remove());\n }\n\n /** Close and destroy all previously opened sub-menus */\n destroySubMenus() {\n document.querySelectorAll(`.slick-cell-menu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => subElm.remove());\n }\n\n protected repositionSubMenu(item: MenuCommandItem | MenuOptionItem | 'divider', type: MenuType, level: number, e: DOMMouseOrTouchEvent) {\n // when we're clicking a grid cell OR our last menu type (command/option) differs then we know that we need to start fresh and close any sub-menus that might still be open\n if (e.target.classList.contains('slick-cell') || this._lastMenuTypeClicked !== type) {\n this.destroySubMenus();\n }\n\n // creating sub-menu, we'll also pass level & the item object since we might have \"subMenuTitle\" to show\n const subMenuElm = this.createMenu((item as MenuCommandItem)?.commandItems || [], (item as MenuOptionItem)?.optionItems || [], level + 1, item);\n subMenuElm.style.display = 'block';\n document.body.appendChild(subMenuElm);\n this.repositionMenu(e, subMenuElm);\n }\n\n /**\n * Reposition the menu drop (up/down) and the side (left/right)\n * @param {*} event\n */\n repositionMenu(e: DOMMouseOrTouchEvent, menuElm: HTMLElement) {\n const isSubMenu = menuElm.classList.contains('slick-submenu');\n const parentElm = isSubMenu\n ? e.target.closest('.slick-cell-menu-item') as HTMLDivElement\n : e.target.closest('.slick-cell') as HTMLDivElement;\n\n if (menuElm && parentElm) {\n const parentOffset = Utils.offset(parentElm);\n let menuOffsetLeft = parentElm ? parentOffset?.left ?? 0 : e?.pageX ?? 0;\n let menuOffsetTop = parentElm ? parentOffset?.top ?? 0 : e?.pageY ?? 0;\n const parentCellWidth = parentElm?.offsetWidth || 0;\n const menuHeight = menuElm?.offsetHeight ?? 0;\n const menuWidth = Number(menuElm?.offsetWidth ?? this._cellMenuProperties.width ?? 0);\n const rowHeight = this._gridOptions.rowHeight;\n const dropOffset = Number(this._cellMenuProperties.autoAdjustDropOffset || 0);\n const sideOffset = Number(this._cellMenuProperties.autoAlignSideOffset || 0);\n\n // if autoAdjustDrop is enable, we first need to see what position the drop will be located (defaults to bottom)\n // without necessary toggling it's position just yet, we just want to know the future position for calculation\n if (this._cellMenuProperties.autoAdjustDrop) {\n // since we reposition menu below slick cell, we need to take it in consideration and do our calculation from that element\n const spaceBottom = Utils.calculateAvailableSpace(parentElm).bottom;\n const spaceTop = Utils.calculateAvailableSpace(parentElm).top;\n const spaceBottomRemaining = spaceBottom + dropOffset - rowHeight!;\n const spaceTopRemaining = spaceTop - dropOffset + rowHeight!;\n const dropPosition = (spaceBottomRemaining < menuHeight && spaceTopRemaining > spaceBottomRemaining) ? 'top' : 'bottom';\n if (dropPosition === 'top') {\n menuElm.classList.remove('dropdown');\n menuElm.classList.add('dropup');\n if (isSubMenu) {\n menuOffsetTop -= (menuHeight - dropOffset - parentElm.clientHeight);\n } else {\n menuOffsetTop -= menuHeight - dropOffset;\n }\n } else {\n menuElm.classList.remove('dropup');\n menuElm.classList.add('dropdown');\n if (isSubMenu) {\n menuOffsetTop += dropOffset;\n } else {\n menuOffsetTop += rowHeight! + dropOffset;\n }\n }\n }\n\n // when auto-align is set, it will calculate whether it has enough space in the viewport to show the drop menu on the right (default)\n // if there isn't enough space on the right, it will automatically align the drop menu to the left (defaults to the right)\n // to simulate an align left, we actually need to know the width of the drop menu\n if (this._cellMenuProperties.autoAlignSide) {\n const gridPos = this._grid.getGridPosition();\n let subMenuPosCalc = menuOffsetLeft + Number(menuWidth); // calculate coordinate at caller element far right\n if (isSubMenu) {\n subMenuPosCalc += parentElm.clientWidth;\n }\n const browserWidth = document.documentElement.clientWidth;\n const dropSide = (subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth) ? 'left' : 'right';\n if (dropSide === 'left') {\n menuElm.classList.remove('dropright');\n menuElm.classList.add('dropleft');\n if (isSubMenu) {\n menuOffsetLeft -= menuWidth - sideOffset;\n } else {\n menuOffsetLeft -= menuWidth - parentCellWidth - sideOffset;\n }\n } else {\n menuElm.classList.remove('dropleft');\n menuElm.classList.add('dropright');\n if (isSubMenu) {\n menuOffsetLeft += sideOffset + parentElm.offsetWidth;\n } else {\n menuOffsetLeft += sideOffset;\n }\n }\n }\n\n // ready to reposition the menu\n menuElm.style.top = `${menuOffsetTop}px`;\n menuElm.style.left = `${menuOffsetLeft}px`;\n }\n }\n\n protected getGridUidSelector() {\n const gridUid = this._grid.getUID() || '';\n return gridUid ? `.${gridUid}` : '';\n }\n\n protected handleCellClick(evt: SlickEventData_ | DOMMouseOrTouchEvent, args: MenuCommandItemCallbackArgs) {\n this.destroyAllMenus(); // make there's only 1 parent menu opened at a time\n const e = (evt instanceof SlickEventData) ? evt.getNativeEvent>() : evt;\n const cell = this._grid.getCellFromEvent(e);\n\n if (cell) {\n const dataContext = this._grid.getDataItem(cell.row);\n const columnDef = this._grid.getColumns()[cell.cell];\n\n // prevent event from bubbling but only on column that has a cell menu defined\n if (columnDef?.cellMenu) {\n e.preventDefault();\n }\n\n // merge the cellMenu of the column definition with the default properties\n this._cellMenuProperties = Utils.extend({}, this._cellMenuProperties, columnDef.cellMenu);\n\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.column = columnDef;\n args.dataContext = dataContext;\n args.grid = this._grid;\n if (!this.runOverrideFunctionWhenExists(this._cellMenuProperties.menuUsabilityOverride, args)) {\n return;\n }\n\n // create the DOM element\n this._menuElm = this.createParentMenu(e);\n\n // reposition the menu to where the user clicked\n if (this._menuElm) {\n this.repositionMenu(e, this._menuElm);\n this._menuElm.setAttribute('aria-expanded', 'true');\n this._menuElm.style.display = 'block';\n }\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n }\n }\n\n /** When users click outside the Cell Menu, we will typically close the Cell Menu (and any sub-menus) */\n protected handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n // did we click inside the menu or any of its sub-menu(s)\n let isMenuClicked = false;\n if (this._menuElm?.contains(e.target)) {\n isMenuClicked = true;\n }\n if (!isMenuClicked) {\n document\n .querySelectorAll(`.slick-cell-menu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => {\n if (subElm.contains(e.target)) {\n isMenuClicked = true;\n }\n });\n }\n\n if (this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented) {\n this.closeMenu(e, { cell: this._currentCell, row: this._currentRow, grid: this._grid });\n }\n }\n\n /** Build the Command Items section. */\n protected populateCommandOrOptionItems(\n itemType: MenuType,\n cellMenu: CellMenuOption,\n commandOrOptionMenuElm: HTMLElement,\n commandOrOptionItems: Array | Array,\n args: { cell: number, row: number, column: Column, dataContext: any, grid: SlickGrid, level: number }\n ) {\n if (!args || !commandOrOptionItems || !cellMenu) {\n return;\n }\n\n // user could pass a title on top of the Commands/Options section\n const isSubMenu = args.level > 0;\n if (cellMenu?.[`${itemType}Title`] && !isSubMenu) {\n this[`_${itemType}TitleElm`] = document.createElement('div');\n this[`_${itemType}TitleElm`]!.className = 'slick-menu-title';\n this[`_${itemType}TitleElm`]!.textContent = cellMenu[`${itemType}Title`] as string;\n commandOrOptionMenuElm.appendChild(this[`_${itemType}TitleElm`]!);\n }\n\n for (let i = 0, ln = commandOrOptionItems.length; i < ln; i++) {\n let addClickListener = true;\n const item = commandOrOptionItems[i];\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as MenuCommandItem | MenuOptionItem).itemVisibilityOverride, args);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as MenuCommandItem | MenuOptionItem).itemUsabilityOverride, args);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemClick\" has the correct flag and won't trigger a command/option clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as MenuCommandItem | MenuOptionItem).disabled = isItemUsable ? false : true;\n }\n\n const liElm = document.createElement('div');\n liElm.className = 'slick-cell-menu-item';\n liElm.role = 'menuitem';\n\n if ((item as MenuCommandItem | MenuOptionItem).divider || item === 'divider') {\n liElm.classList.add('slick-cell-menu-item-divider');\n addClickListener = false;\n }\n\n // if the item is disabled then add the disabled css class\n if ((item as MenuCommandItem | MenuOptionItem).disabled || !isItemUsable) {\n liElm.classList.add('slick-cell-menu-item-disabled');\n }\n\n // if the item is hidden then add the hidden css class\n if ((item as MenuCommandItem | MenuOptionItem).hidden) {\n liElm.classList.add('slick-cell-menu-item-hidden');\n }\n\n if ((item as MenuCommandItem | MenuOptionItem).cssClass) {\n liElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).cssClass!.split(' '));\n }\n\n if ((item as MenuCommandItem | MenuOptionItem).tooltip) {\n liElm.title = (item as MenuCommandItem | MenuOptionItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-cell-menu-icon';\n\n liElm.appendChild(iconElm);\n\n if ((item as MenuCommandItem | MenuOptionItem).iconCssClass) {\n iconElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).iconCssClass!.split(' '));\n }\n\n if ((item as MenuCommandItem | MenuOptionItem).iconImage) {\n iconElm.style.backgroundImage = `url(${(item as MenuCommandItem | MenuOptionItem).iconImage})`;\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-cell-menu-content';\n textElm.textContent = (item as MenuCommandItem | MenuOptionItem).title || '';\n\n liElm.appendChild(textElm);\n\n if ((item as MenuCommandItem | MenuOptionItem).textCssClass) {\n textElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).textCssClass!.split(' '));\n }\n\n commandOrOptionMenuElm.appendChild(liElm);\n\n if (addClickListener) {\n this._bindingEventService.bind(liElm, 'click', this.handleMenuItemClick.bind(this, item, itemType, args.level) as EventListener);\n }\n\n // the option/command item could be a sub-menu if it has another list of commands/options\n if ((item as MenuCommandItem).commandItems || (item as MenuOptionItem).optionItems) {\n const chevronElm = document.createElement('span');\n chevronElm.className = 'sub-item-chevron';\n if (this._cellMenuProperties.subItemChevronClass) {\n chevronElm.classList.add(...this._cellMenuProperties.subItemChevronClass.split(' '));\n } else {\n chevronElm.textContent = '\u2B9E'; // \u2B9E or \u25B8\n }\n\n liElm.classList.add('slick-submenu-item');\n liElm.appendChild(chevronElm);\n continue;\n }\n }\n }\n\n protected handleMenuItemClick(item: MenuCommandItem | MenuOptionItem | 'divider', type: MenuType, level = 0, e: DOMMouseOrTouchEvent) {\n if ((item as never)?.[type] !== undefined && item !== 'divider' && !item.disabled && !(item as MenuCommandItem | MenuOptionItem).divider && this._currentCell !== undefined && this._currentRow !== undefined) {\n if (type === 'option' && !this._grid.getEditorLock().commitCurrentEdit()) {\n return;\n }\n const optionOrCommand = (item as any)[type] !== undefined ? (item as any)[type] : '';\n const row = this._currentRow;\n const cell = this._currentCell;\n const columnDef = this._grid.getColumns()[cell];\n const dataContext = this._grid.getDataItem(row);\n\n if (optionOrCommand !== undefined && !(item as any)[`${type}Items`]) {\n // user could execute a callback through 2 ways\n // via the onCommand/onOptionSelected event and/or an action callback\n const callbackArgs = {\n cell,\n row,\n grid: this._grid,\n [type]: optionOrCommand,\n item,\n column: columnDef,\n dataContext,\n };\n const eventType = type === 'command' ? 'onCommand' : 'onOptionSelected';\n this[eventType].notify(callbackArgs as any, e, this);\n\n // execute action callback when defined\n if (typeof item.action === 'function') {\n (item as any).action.call(this, e, callbackArgs);\n }\n\n // unless prevented, close the menu\n if (!e.defaultPrevented) {\n this.closeMenu(e, { cell, row, grid: this._grid });\n }\n } else if ((item as MenuCommandItem).commandItems || (item as MenuOptionItem).optionItems) {\n this.repositionSubMenu(item, type, level, e);\n } else {\n this.destroySubMenus();\n }\n this._lastMenuTypeClicked = type;\n }\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n CellMenu: SlickCellMenu\n }\n }\n });\n}\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.cellrangedecorator.js.map b/dist/browser/plugins/slick.cellrangedecorator.js.map index e2d8c7573..9293b632f 100644 --- a/dist/browser/plugins/slick.cellrangedecorator.js.map +++ b/dist/browser/plugins/slick.cellrangedecorator.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.cellrangedecorator.ts"], - "sourcesContent": ["import type { CSSStyleDeclarationWritable, CellRange, CellRangeDecoratorOption, Plugin } from '../models/index';\nimport { Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * Displays an overlay on top of a given cell range.\n *\n * TODO:\n * Currently, it blocks mouse events to DOM nodes behind it.\n * Use FF and WebKit-specific \"pointer-events\" CSS style, or some kind of event forwarding.\n * Could also construct the borders separately using 4 individual DIVs.\n *\n * @param {Grid} grid\n * @param {Object} options\n */\nexport class SlickCellRangeDecorator implements Plugin {\n // --\n // public API\n pluginName = 'CellRangeDecorator' as const;\n\n // --\n // protected props\n protected _options: CellRangeDecoratorOption;\n protected _elem?: HTMLDivElement | null;\n protected _defaults = {\n selectionCssClass: 'slick-range-decorator',\n selectionCss: {\n zIndex: '9999',\n border: '2px dashed red'\n },\n offset: { top: -1, left: -1, height: -2, width: -2 }\n } as CellRangeDecoratorOption;\n\n constructor(protected readonly grid: SlickGrid, options?: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n destroy() {\n this.hide();\n }\n\n init() { }\n\n hide() {\n this._elem?.remove();\n this._elem = null;\n }\n\n show(range: CellRange) {\n if (!this._elem) {\n this._elem = document.createElement('div')\n this._elem.className = this._options.selectionCssClass;\n Object.keys(this._options.selectionCss as CSSStyleDeclaration).forEach((cssStyleKey) => {\n this._elem!.style[cssStyleKey as CSSStyleDeclarationWritable] = this._options.selectionCss[cssStyleKey as CSSStyleDeclarationWritable];\n });\n this._elem.style.position = 'absolute';\n const canvasNode = this.grid.getActiveCanvasNode();\n if (canvasNode) {\n canvasNode.appendChild(this._elem);\n }\n }\n\n const from = this.grid.getCellNodeBox(range.fromRow, range.fromCell);\n const to = this.grid.getCellNodeBox(range.toRow, range.toCell);\n\n if (from && to && this._options?.offset) {\n this._elem.style.top = `${from.top + this._options.offset.top}px`;\n this._elem.style.left = `${from.left + this._options.offset.left}px`;\n this._elem.style.height = `${to.bottom - from.top + this._options.offset.height}px`;\n this._elem.style.width = `${to.right - from.left + this._options.offset.width}px`;\n }\n\n return this._elem;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellRangeDecorator: SlickCellRangeDecorator\n }\n });\n}\n"], - "mappings": ";;;;;;;AAKA,MAAM,QAAoB,MAAM,OAanB,0BAAN,MAAgD;AAAA,IAkBrD,YAA+B,MAAiB,SAA6C;AAA9D;AAf/B;AAAA;AAAA,wCAAa;AAIb;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU,aAAY;AAAA,QACpB,mBAAmB;AAAA,QACnB,cAAc;AAAA,UACZ,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,QACA,QAAQ,EAAE,KAAK,IAAI,MAAM,IAAI,QAAQ,IAAI,OAAO,GAAG;AAAA,MACrD;AAGE,WAAK,WAAW,MAAM,OAAO,IAAM,CAAC,GAAG,KAAK,WAAW,OAAO;AAAA,IAChE;AAAA,IAEA,UAAU;AACR,WAAK,KAAK;AAAA,IACZ;AAAA,IAEA,OAAO;AAAA,IAAE;AAAA,IAET,OAAO;AA9CT;AA+CI,iBAAK,UAAL,WAAY,UACZ,KAAK,QAAQ;AAAA,IACf;AAAA,IAEA,KAAK,OAAkB;AAnDzB;AAoDI,UAAI,CAAC,KAAK,OAAO;AACf,aAAK,QAAQ,SAAS,cAAc,KAAK,GACzC,KAAK,MAAM,YAAY,KAAK,SAAS,mBACrC,OAAO,KAAK,KAAK,SAAS,YAAmC,EAAE,QAAQ,CAAC,gBAAgB;AACtF,eAAK,MAAO,MAAM,WAA0C,IAAI,KAAK,SAAS,aAAa,WAA0C;AAAA,QACvI,CAAC,GACD,KAAK,MAAM,MAAM,WAAW;AAC5B,YAAM,aAAa,KAAK,KAAK,oBAAoB;AACjD,QAAI,cACF,WAAW,YAAY,KAAK,KAAK;AAAA,MAErC;AAEA,UAAM,OAAO,KAAK,KAAK,eAAe,MAAM,SAAS,MAAM,QAAQ,GAC7D,KAAK,KAAK,KAAK,eAAe,MAAM,OAAO,MAAM,MAAM;AAE7D,aAAI,QAAQ,QAAM,UAAK,aAAL,WAAe,YAC/B,KAAK,MAAM,MAAM,MAAM,GAAG,KAAK,MAAM,KAAK,SAAS,OAAO,GAAG,MAC7D,KAAK,MAAM,MAAM,OAAO,GAAG,KAAK,OAAO,KAAK,SAAS,OAAO,IAAI,MAChE,KAAK,MAAM,MAAM,SAAS,GAAG,GAAG,SAAS,KAAK,MAAM,KAAK,SAAS,OAAO,MAAM,MAC/E,KAAK,MAAM,MAAM,QAAQ,GAAG,GAAG,QAAQ,KAAK,OAAO,KAAK,SAAS,OAAO,KAAK,OAGxE,KAAK;AAAA,IACd;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,oBAAoB;AAAA,IACtB;AAAA,EACF,CAAC;", + "sourcesContent": ["import type { CSSStyleDeclarationWritable, CellRange, CellRangeDecoratorOption, SlickPlugin } from '../models/index';\nimport { Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * Displays an overlay on top of a given cell range.\n *\n * TODO:\n * Currently, it blocks mouse events to DOM nodes behind it.\n * Use FF and WebKit-specific \"pointer-events\" CSS style, or some kind of event forwarding.\n * Could also construct the borders separately using 4 individual DIVs.\n *\n * @param {Grid} grid\n * @param {Object} options\n */\nexport class SlickCellRangeDecorator implements SlickPlugin {\n // --\n // public API\n pluginName = 'CellRangeDecorator' as const;\n\n // --\n // protected props\n protected _options: CellRangeDecoratorOption;\n protected _elem?: HTMLDivElement | null;\n protected _defaults = {\n selectionCssClass: 'slick-range-decorator',\n selectionCss: {\n zIndex: '9999',\n border: '2px dashed red'\n },\n offset: { top: -1, left: -1, height: -2, width: -2 }\n } as CellRangeDecoratorOption;\n\n constructor(protected readonly grid: SlickGrid, options?: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n destroy() {\n this.hide();\n }\n\n init() { }\n\n hide() {\n this._elem?.remove();\n this._elem = null;\n }\n\n show(range: CellRange) {\n if (!this._elem) {\n this._elem = document.createElement('div');\n this._elem.className = this._options.selectionCssClass;\n Object.keys(this._options.selectionCss as CSSStyleDeclaration).forEach((cssStyleKey) => {\n this._elem!.style[cssStyleKey as CSSStyleDeclarationWritable] = this._options.selectionCss[cssStyleKey as CSSStyleDeclarationWritable];\n });\n this._elem.style.position = 'absolute';\n const canvasNode = this.grid.getActiveCanvasNode();\n if (canvasNode) {\n canvasNode.appendChild(this._elem);\n }\n }\n\n const from = this.grid.getCellNodeBox(range.fromRow, range.fromCell);\n const to = this.grid.getCellNodeBox(range.toRow, range.toCell);\n\n if (from && to && this._options?.offset) {\n this._elem.style.top = `${from.top + this._options.offset.top}px`;\n this._elem.style.left = `${from.left + this._options.offset.left}px`;\n this._elem.style.height = `${to.bottom - from.top + this._options.offset.height}px`;\n this._elem.style.width = `${to.right - from.left + this._options.offset.width}px`;\n }\n\n return this._elem;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellRangeDecorator: SlickCellRangeDecorator\n }\n });\n}\n"], + "mappings": ";;;;;;;AAKA,MAAM,QAAoB,MAAM,OAanB,0BAAN,MAAqD;AAAA,IAkB1D,YAA+B,MAAiB,SAA6C;AAA9D;AAf/B;AAAA;AAAA,wCAAa;AAIb;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU,aAAY;AAAA,QACpB,mBAAmB;AAAA,QACnB,cAAc;AAAA,UACZ,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,QACA,QAAQ,EAAE,KAAK,IAAI,MAAM,IAAI,QAAQ,IAAI,OAAO,GAAG;AAAA,MACrD;AAGE,WAAK,WAAW,MAAM,OAAO,IAAM,CAAC,GAAG,KAAK,WAAW,OAAO;AAAA,IAChE;AAAA,IAEA,UAAU;AACR,WAAK,KAAK;AAAA,IACZ;AAAA,IAEA,OAAO;AAAA,IAAE;AAAA,IAET,OAAO;AA9CT;AA+CI,iBAAK,UAAL,WAAY,UACZ,KAAK,QAAQ;AAAA,IACf;AAAA,IAEA,KAAK,OAAkB;AAnDzB;AAoDI,UAAI,CAAC,KAAK,OAAO;AACf,aAAK,QAAQ,SAAS,cAAc,KAAK,GACzC,KAAK,MAAM,YAAY,KAAK,SAAS,mBACrC,OAAO,KAAK,KAAK,SAAS,YAAmC,EAAE,QAAQ,CAAC,gBAAgB;AACtF,eAAK,MAAO,MAAM,WAA0C,IAAI,KAAK,SAAS,aAAa,WAA0C;AAAA,QACvI,CAAC,GACD,KAAK,MAAM,MAAM,WAAW;AAC5B,YAAM,aAAa,KAAK,KAAK,oBAAoB;AACjD,QAAI,cACF,WAAW,YAAY,KAAK,KAAK;AAAA,MAErC;AAEA,UAAM,OAAO,KAAK,KAAK,eAAe,MAAM,SAAS,MAAM,QAAQ,GAC7D,KAAK,KAAK,KAAK,eAAe,MAAM,OAAO,MAAM,MAAM;AAE7D,aAAI,QAAQ,QAAM,UAAK,aAAL,WAAe,YAC/B,KAAK,MAAM,MAAM,MAAM,GAAG,KAAK,MAAM,KAAK,SAAS,OAAO,GAAG,MAC7D,KAAK,MAAM,MAAM,OAAO,GAAG,KAAK,OAAO,KAAK,SAAS,OAAO,IAAI,MAChE,KAAK,MAAM,MAAM,SAAS,GAAG,GAAG,SAAS,KAAK,MAAM,KAAK,SAAS,OAAO,MAAM,MAC/E,KAAK,MAAM,MAAM,QAAQ,GAAG,GAAG,QAAQ,KAAK,OAAO,KAAK,SAAS,OAAO,KAAK,OAGxE,KAAK;AAAA,IACd;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,oBAAoB;AAAA,IACtB;AAAA,EACF,CAAC;", "names": [] } diff --git a/dist/browser/plugins/slick.cellrangeselector.js.map b/dist/browser/plugins/slick.cellrangeselector.js.map index 56c6f8fd2..ac911011d 100644 --- a/dist/browser/plugins/slick.cellrangeselector.js.map +++ b/dist/browser/plugins/slick.cellrangeselector.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.cellrangeselector.ts"], - "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData, SlickEventHandler as SlickEventHandler_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\nimport { Draggable as Draggable_ } from '../slick.interactions';\nimport { SlickCellRangeDecorator as SlickCellRangeDecorator_ } from './slick.cellrangedecorator';\nimport type { CellRangeSelectorOption, DOMMouseOrTouchEvent, DragPosition, DragRange, GridOption, MouseOffsetViewport, OnScrollEventArgs, Plugin } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst Draggable = IIFE_ONLY ? Slick.Draggable : Draggable_;\nconst SlickCellRangeDecorator = IIFE_ONLY ? Slick.CellRangeDecorator : SlickCellRangeDecorator_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport class SlickCellRangeSelector implements Plugin {\n // --\n // public API\n pluginName = 'CellRangeSelector' as const;\n onBeforeCellRangeSelected = new SlickEvent<{ row: number; cell: number; }>();\n onCellRangeSelected = new SlickEvent<{ range: SlickRange_; }>();\n onCellRangeSelecting = new SlickEvent<{ range: SlickRange_; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _currentlySelectedRange: DragRange | null = null;\n protected _canvas: HTMLElement | null = null;\n protected _decorator!: SlickCellRangeDecorator_;\n protected _gridOptions!: GridOption;\n protected _activeCanvas!: HTMLElement;\n protected _dragging = false;\n protected _handler = new SlickEventHandler();\n protected _options: CellRangeSelectorOption;\n protected _defaults = {\n autoScroll: true,\n minIntervalToShowNextCell: 30,\n maxIntervalToShowNextCell: 600, // better to a multiple of minIntervalToShowNextCell\n accelerateInterval: 5, // increase 5ms when cursor 1px outside the viewport.\n selectionCss: {\n border: '2px dashed blue'\n }\n } as CellRangeSelectorOption;\n\n // Frozen row & column variables\n protected _rowOffset = 0;\n protected _columnOffset = 0;\n protected _isRightCanvas = false;\n protected _isBottomCanvas = false;\n\n // autoScroll related constiables\n protected _activeViewport!: HTMLElement;\n protected _autoScrollTimerId?: NodeJS.Timeout;\n protected _draggingMouseOffset!: MouseOffsetViewport;\n protected _moveDistanceForOneCell!: { x: number; y: number; };\n protected _xDelayForNextCell = 0;\n protected _yDelayForNextCell = 0;\n protected _viewportHeight = 0;\n protected _viewportWidth = 0;\n protected _isRowMoveRegistered = false;\n\n // Scrollings\n protected _scrollLeft = 0;\n protected _scrollTop = 0;\n\n constructor(options?: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n init(grid: SlickGrid) {\n if (Draggable === undefined) {\n throw new Error('Slick.Draggable is undefined, make sure to import \"slick.interactions.js\"');\n }\n\n this._decorator = this._options.cellDecorator || new SlickCellRangeDecorator(grid, this._options);\n this._grid = grid;\n this._canvas = this._grid.getCanvasNode();\n this._gridOptions = this._grid.getOptions();\n this._handler\n .subscribe(this._grid.onScroll, this.handleScroll.bind(this))\n .subscribe(this._grid.onDragInit, this.handleDragInit.bind(this))\n .subscribe(this._grid.onDragStart, this.handleDragStart.bind(this))\n .subscribe(this._grid.onDrag, this.handleDrag.bind(this))\n .subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));\n }\n\n destroy() {\n this._handler.unsubscribeAll();\n this._activeCanvas = null as any;\n this._activeViewport = null as any;\n this._canvas = null;\n this._decorator?.destroy();\n }\n\n getCellDecorator() {\n return this._decorator;\n }\n\n protected handleScroll(_e: DOMMouseOrTouchEvent, args: OnScrollEventArgs) {\n this._scrollTop = args.scrollTop;\n this._scrollLeft = args.scrollLeft;\n }\n\n protected handleDragInit(e: Event) {\n // Set the active canvas node because the decorator needs to append its\n // box to the correct canvas\n this._activeCanvas = this._grid.getActiveCanvasNode(e);\n this._activeViewport = this._grid.getActiveViewportNode(e);\n\n const scrollbarDimensions = this._grid.getDisplayedScrollbarDimensions()\n this._viewportWidth = this._activeViewport.offsetWidth - scrollbarDimensions.width;\n this._viewportHeight = this._activeViewport.offsetHeight - scrollbarDimensions.height;\n\n this._moveDistanceForOneCell = {\n x: this._grid.getAbsoluteColumnMinWidth() / 2,\n y: this._grid.getOptions().rowHeight! / 2\n }\n this._isRowMoveRegistered = this.hasRowMoveManager();\n\n this._rowOffset = 0;\n this._columnOffset = 0;\n this._isBottomCanvas = this._activeCanvas.classList.contains('grid-canvas-bottom');\n\n if (this._gridOptions.frozenRow! > -1 && this._isBottomCanvas) {\n const canvasSelector = `.${this._grid.getUID()} .grid-canvas-${this._gridOptions.frozenBottom ? 'bottom' : 'top'}`;\n const canvasElm = document.querySelector(canvasSelector);\n if (canvasElm) {\n this._rowOffset = canvasElm.clientHeight || 0;\n }\n }\n\n this._isRightCanvas = this._activeCanvas.classList.contains('grid-canvas-right');\n\n if (this._gridOptions.frozenColumn! > -1 && this._isRightCanvas) {\n const canvasLeftElm = document.querySelector(`.${this._grid.getUID()} .grid-canvas-left`);\n if (canvasLeftElm) {\n this._columnOffset = canvasLeftElm.clientWidth || 0;\n }\n }\n\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n e.preventDefault();\n }\n\n protected handleDragStart(e: DOMMouseOrTouchEvent, dd: DragPosition) {\n const cell = this._grid.getCellFromEvent(e);\n if (cell && this.onBeforeCellRangeSelected.notify(cell).getReturnValue() !== false && this._grid.canCellBeSelected(cell.row, cell.cell)) {\n this._dragging = true;\n e.stopImmediatePropagation();\n }\n if (!this._dragging) {\n return;\n }\n\n this._grid.focus();\n\n const canvasOffset = Utils.offset(this._canvas);\n\n let startX = dd.startX - (canvasOffset?.left ?? 0);\n if (this._gridOptions.frozenColumn! >= 0 && this._isRightCanvas) {\n startX += this._scrollLeft;\n }\n\n let startY = dd.startY - (canvasOffset?.top ?? 0);\n if (this._gridOptions.frozenRow! >= 0 && this._isBottomCanvas) {\n startY += this._scrollTop;\n }\n\n const start = this._grid.getCellFromPoint(startX, startY);\n\n dd.range = { start: start, end: {} };\n this._currentlySelectedRange = dd.range;\n return this._decorator.show(new SlickRange(start.row, start.cell));\n }\n\n protected handleDrag(evt: SlickEventData, dd: DragPosition) {\n if (!this._dragging && !this._isRowMoveRegistered) {\n return;\n }\n if (!this._isRowMoveRegistered) {\n evt.stopImmediatePropagation();\n }\n\n const e = evt.getNativeEvent();\n if (this._options.autoScroll) {\n this._draggingMouseOffset = this.getMouseOffsetViewport(e, dd);\n if (this._draggingMouseOffset.isOutsideViewport) {\n return this.handleDragOutsideViewport();\n }\n }\n this.stopIntervalTimer();\n this.handleDragTo(e, dd);\n }\n\n protected getMouseOffsetViewport(e: MouseEvent | TouchEvent, dd: DragPosition): MouseOffsetViewport {\n const targetEvent: MouseEvent | Touch = (e as TouchEvent)?.touches?.[0] ?? e;\n const viewportLeft = this._activeViewport.scrollLeft;\n const viewportTop = this._activeViewport.scrollTop;\n const viewportRight = viewportLeft + this._viewportWidth;\n const viewportBottom = viewportTop + this._viewportHeight;\n\n const viewportOffset = Utils.offset(this._activeViewport);\n const viewportOffsetLeft = viewportOffset?.left ?? 0;\n const viewportOffsetTop = viewportOffset?.top ?? 0;\n const viewportOffsetRight = viewportOffsetLeft + this._viewportWidth;\n const viewportOffsetBottom = viewportOffsetTop + this._viewportHeight;\n\n const result = {\n e: e,\n dd: dd,\n viewport: {\n left: viewportLeft,\n top: viewportTop,\n right: viewportRight,\n bottom: viewportBottom,\n offset: {\n left: viewportOffsetLeft,\n top: viewportOffsetTop,\n right: viewportOffsetRight,\n bottom: viewportOffsetBottom\n }\n },\n // Consider the viewport as the origin, the `offset` is based on the coordinate system:\n // the cursor is on the viewport's left/bottom when it is less than 0, and on the right/top when greater than 0.\n offset: {\n x: 0,\n y: 0\n },\n isOutsideViewport: false\n }\n // ... horizontal\n if (targetEvent.pageX < viewportOffsetLeft) {\n result.offset.x = targetEvent.pageX - viewportOffsetLeft;\n } else if (targetEvent.pageX > viewportOffsetRight) {\n result.offset.x = targetEvent.pageX - viewportOffsetRight;\n }\n // ... vertical\n if (targetEvent.pageY < viewportOffsetTop) {\n result.offset.y = viewportOffsetTop - targetEvent.pageY;\n } else if (targetEvent.pageY > viewportOffsetBottom) {\n result.offset.y = viewportOffsetBottom - targetEvent.pageY;\n }\n result.isOutsideViewport = !!result.offset.x || !!result.offset.y;\n return result;\n }\n\n protected handleDragOutsideViewport() {\n this._xDelayForNextCell = this._options.maxIntervalToShowNextCell - Math.abs(this._draggingMouseOffset.offset.x) * this._options.accelerateInterval;\n this._yDelayForNextCell = this._options.maxIntervalToShowNextCell - Math.abs(this._draggingMouseOffset.offset.y) * this._options.accelerateInterval;\n // only one timer is created to handle the case that cursor outside the viewport\n if (!this._autoScrollTimerId) {\n let xTotalDelay = 0;\n let yTotalDelay = 0;\n this._autoScrollTimerId = setInterval(() => {\n let xNeedUpdate = false;\n let yNeedUpdate = false;\n // ... horizontal\n if (this._draggingMouseOffset.offset.x) {\n xTotalDelay += this._options.minIntervalToShowNextCell;\n xNeedUpdate = xTotalDelay >= this._xDelayForNextCell;\n } else {\n xTotalDelay = 0;\n }\n // ... vertical\n if (this._draggingMouseOffset.offset.y) {\n yTotalDelay += this._options.minIntervalToShowNextCell;\n yNeedUpdate = yTotalDelay >= this._yDelayForNextCell;\n } else {\n yTotalDelay = 0;\n }\n if (xNeedUpdate || yNeedUpdate) {\n if (xNeedUpdate) {\n xTotalDelay = 0;\n }\n if (yNeedUpdate) {\n yTotalDelay = 0;\n }\n this.handleDragToNewPosition(xNeedUpdate, yNeedUpdate);\n }\n }, this._options.minIntervalToShowNextCell);\n }\n }\n\n protected handleDragToNewPosition(xNeedUpdate: boolean, yNeedUpdate: boolean) {\n let pageX = this._draggingMouseOffset.e.pageX;\n let pageY = this._draggingMouseOffset.e.pageY;\n const mouseOffsetX = this._draggingMouseOffset.offset.x;\n const mouseOffsetY = this._draggingMouseOffset.offset.y;\n const viewportOffset = this._draggingMouseOffset.viewport.offset;\n // ... horizontal\n if (xNeedUpdate && mouseOffsetX) {\n if (mouseOffsetX > 0) {\n pageX = viewportOffset.right + this._moveDistanceForOneCell.x;\n } else {\n pageX = viewportOffset.left - this._moveDistanceForOneCell.x;\n }\n }\n // ... vertical\n if (yNeedUpdate && mouseOffsetY) {\n if (mouseOffsetY > 0) {\n pageY = viewportOffset.top - this._moveDistanceForOneCell.y;\n } else {\n pageY = viewportOffset.bottom + this._moveDistanceForOneCell.y;\n }\n }\n this.handleDragTo({ pageX, pageY }, this._draggingMouseOffset.dd);\n }\n\n protected stopIntervalTimer() {\n if (this._autoScrollTimerId) {\n clearInterval(this._autoScrollTimerId);\n this._autoScrollTimerId = undefined;\n }\n }\n\n protected handleDragTo(e: { pageX: number; pageY: number; }, dd: DragPosition) {\n const targetEvent: MouseEvent | Touch = (e as unknown as TouchEvent)?.touches?.[0] ?? e;\n const canvasOffset = Utils.offset(this._activeCanvas);\n const end = this._grid.getCellFromPoint(\n targetEvent.pageX - (canvasOffset?.left ?? 0) + this._columnOffset,\n targetEvent.pageY - (canvasOffset?.top ?? 0) + this._rowOffset\n );\n\n // ... frozen column(s),\n if (this._gridOptions.frozenColumn! >= 0 && (!this._isRightCanvas && (end.cell > this._gridOptions.frozenColumn!)) || (this._isRightCanvas && (end.cell <= this._gridOptions.frozenColumn!))) {\n return;\n }\n\n // ... or frozen row(s)\n if (this._gridOptions.frozenRow! >= 0 && (!this._isBottomCanvas && (end.row >= this._gridOptions.frozenRow!)) || (this._isBottomCanvas && (end.row < this._gridOptions.frozenRow!))) {\n return;\n }\n\n // scrolling the viewport to display the target `end` cell if it is not fully displayed\n if (this._options.autoScroll && this._draggingMouseOffset) {\n const endCellBox = this._grid.getCellNodeBox(end.row, end.cell);\n if (!endCellBox) {\n return;\n }\n const viewport = this._draggingMouseOffset.viewport;\n if (endCellBox.left < viewport.left || endCellBox.right > viewport.right\n || endCellBox.top < viewport.top || endCellBox.bottom > viewport.bottom) {\n this._grid.scrollCellIntoView(end.row, end.cell);\n }\n }\n\n // ... or regular grid (without any frozen options)\n if (!this._grid.canCellBeSelected(end.row, end.cell)) {\n return;\n }\n\n if (dd?.range) {\n dd.range.end = end;\n\n const range = new SlickRange(dd.range.start.row ?? 0, dd.range.start.cell ?? 0, end.row, end.cell);\n this._decorator.show(range);\n this.onCellRangeSelecting.notify({\n range: range\n });\n }\n }\n\n protected hasRowMoveManager() {\n return !!(this._grid.getPluginByName('RowMoveManager') || this._grid.getPluginByName('CrossGridRowMoveManager'));\n }\n\n protected handleDragEnd(e: Event, dd: DragPosition) {\n if (!this._dragging) {\n return;\n }\n\n this._dragging = false;\n e.stopImmediatePropagation();\n\n this.stopIntervalTimer();\n this._decorator.hide();\n this.onCellRangeSelected.notify({\n range: new SlickRange(\n dd.range.start.row ?? 0,\n dd.range.start.cell ?? 0,\n dd.range.end.row,\n dd.range.end.cell\n )\n });\n }\n\n getCurrentRange() {\n return this._currentlySelectedRange;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(Slick, {\n CellRangeSelector: SlickCellRangeSelector\n });\n}\n"], - "mappings": "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", + "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData, SlickEventHandler as SlickEventHandler_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\nimport { Draggable as Draggable_ } from '../slick.interactions';\nimport { SlickCellRangeDecorator as SlickCellRangeDecorator_ } from './slick.cellrangedecorator';\nimport type { CellRangeSelectorOption, DOMMouseOrTouchEvent, DragPosition, DragRange, GridOption, MouseOffsetViewport, OnScrollEventArgs, SlickPlugin } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst Draggable = IIFE_ONLY ? Slick.Draggable : Draggable_;\nconst SlickCellRangeDecorator = IIFE_ONLY ? Slick.CellRangeDecorator : SlickCellRangeDecorator_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport class SlickCellRangeSelector implements SlickPlugin {\n // --\n // public API\n pluginName = 'CellRangeSelector' as const;\n onBeforeCellRangeSelected = new SlickEvent<{ row: number; cell: number; }>();\n onCellRangeSelected = new SlickEvent<{ range: SlickRange_; }>();\n onCellRangeSelecting = new SlickEvent<{ range: SlickRange_; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _currentlySelectedRange: DragRange | null = null;\n protected _canvas: HTMLElement | null = null;\n protected _decorator!: SlickCellRangeDecorator_;\n protected _gridOptions!: GridOption;\n protected _activeCanvas!: HTMLElement;\n protected _dragging = false;\n protected _handler = new SlickEventHandler();\n protected _options: CellRangeSelectorOption;\n protected _defaults = {\n autoScroll: true,\n minIntervalToShowNextCell: 30,\n maxIntervalToShowNextCell: 600, // better to a multiple of minIntervalToShowNextCell\n accelerateInterval: 5, // increase 5ms when cursor 1px outside the viewport.\n selectionCss: {\n border: '2px dashed blue'\n }\n } as CellRangeSelectorOption;\n\n // Frozen row & column variables\n protected _rowOffset = 0;\n protected _columnOffset = 0;\n protected _isRightCanvas = false;\n protected _isBottomCanvas = false;\n\n // autoScroll related constiables\n protected _activeViewport!: HTMLElement;\n protected _autoScrollTimerId?: NodeJS.Timeout;\n protected _draggingMouseOffset!: MouseOffsetViewport;\n protected _moveDistanceForOneCell!: { x: number; y: number; };\n protected _xDelayForNextCell = 0;\n protected _yDelayForNextCell = 0;\n protected _viewportHeight = 0;\n protected _viewportWidth = 0;\n protected _isRowMoveRegistered = false;\n\n // Scrollings\n protected _scrollLeft = 0;\n protected _scrollTop = 0;\n\n constructor(options?: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n init(grid: SlickGrid) {\n if (Draggable === undefined) {\n throw new Error('Slick.Draggable is undefined, make sure to import \"slick.interactions.js\"');\n }\n\n this._decorator = this._options.cellDecorator || new SlickCellRangeDecorator(grid, this._options);\n this._grid = grid;\n this._canvas = this._grid.getCanvasNode();\n this._gridOptions = this._grid.getOptions();\n this._handler\n .subscribe(this._grid.onScroll, this.handleScroll.bind(this))\n .subscribe(this._grid.onDragInit, this.handleDragInit.bind(this))\n .subscribe(this._grid.onDragStart, this.handleDragStart.bind(this))\n .subscribe(this._grid.onDrag, this.handleDrag.bind(this))\n .subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));\n }\n\n destroy() {\n this._handler.unsubscribeAll();\n this._activeCanvas = null as any;\n this._activeViewport = null as any;\n this._canvas = null;\n this._decorator?.destroy();\n }\n\n getCellDecorator() {\n return this._decorator;\n }\n\n protected handleScroll(_e: DOMMouseOrTouchEvent, args: OnScrollEventArgs) {\n this._scrollTop = args.scrollTop;\n this._scrollLeft = args.scrollLeft;\n }\n\n protected handleDragInit(e: Event) {\n // Set the active canvas node because the decorator needs to append its\n // box to the correct canvas\n this._activeCanvas = this._grid.getActiveCanvasNode(e);\n this._activeViewport = this._grid.getActiveViewportNode(e);\n\n const scrollbarDimensions = this._grid.getDisplayedScrollbarDimensions();\n this._viewportWidth = this._activeViewport.offsetWidth - scrollbarDimensions.width;\n this._viewportHeight = this._activeViewport.offsetHeight - scrollbarDimensions.height;\n\n this._moveDistanceForOneCell = {\n x: this._grid.getAbsoluteColumnMinWidth() / 2,\n y: this._grid.getOptions().rowHeight! / 2\n };\n this._isRowMoveRegistered = this.hasRowMoveManager();\n\n this._rowOffset = 0;\n this._columnOffset = 0;\n this._isBottomCanvas = this._activeCanvas.classList.contains('grid-canvas-bottom');\n\n if (this._gridOptions.frozenRow! > -1 && this._isBottomCanvas) {\n const canvasSelector = `.${this._grid.getUID()} .grid-canvas-${this._gridOptions.frozenBottom ? 'bottom' : 'top'}`;\n const canvasElm = document.querySelector(canvasSelector);\n if (canvasElm) {\n this._rowOffset = canvasElm.clientHeight || 0;\n }\n }\n\n this._isRightCanvas = this._activeCanvas.classList.contains('grid-canvas-right');\n\n if (this._gridOptions.frozenColumn! > -1 && this._isRightCanvas) {\n const canvasLeftElm = document.querySelector(`.${this._grid.getUID()} .grid-canvas-left`);\n if (canvasLeftElm) {\n this._columnOffset = canvasLeftElm.clientWidth || 0;\n }\n }\n\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n e.preventDefault();\n }\n\n protected handleDragStart(e: DOMMouseOrTouchEvent, dd: DragPosition) {\n const cell = this._grid.getCellFromEvent(e);\n if (cell && this.onBeforeCellRangeSelected.notify(cell).getReturnValue() !== false && this._grid.canCellBeSelected(cell.row, cell.cell)) {\n this._dragging = true;\n e.stopImmediatePropagation();\n }\n if (!this._dragging) {\n return;\n }\n\n this._grid.focus();\n\n const canvasOffset = Utils.offset(this._canvas);\n\n let startX = dd.startX - (canvasOffset?.left ?? 0);\n if (this._gridOptions.frozenColumn! >= 0 && this._isRightCanvas) {\n startX += this._scrollLeft;\n }\n\n let startY = dd.startY - (canvasOffset?.top ?? 0);\n if (this._gridOptions.frozenRow! >= 0 && this._isBottomCanvas) {\n startY += this._scrollTop;\n }\n\n const start = this._grid.getCellFromPoint(startX, startY);\n\n dd.range = { start, end: {} };\n this._currentlySelectedRange = dd.range;\n return this._decorator.show(new SlickRange(start.row, start.cell));\n }\n\n protected handleDrag(evt: SlickEventData, dd: DragPosition) {\n if (!this._dragging && !this._isRowMoveRegistered) {\n return;\n }\n if (!this._isRowMoveRegistered) {\n evt.stopImmediatePropagation();\n }\n\n const e = evt.getNativeEvent();\n if (this._options.autoScroll) {\n this._draggingMouseOffset = this.getMouseOffsetViewport(e, dd);\n if (this._draggingMouseOffset.isOutsideViewport) {\n return this.handleDragOutsideViewport();\n }\n }\n this.stopIntervalTimer();\n this.handleDragTo(e, dd);\n }\n\n protected getMouseOffsetViewport(e: MouseEvent | TouchEvent, dd: DragPosition): MouseOffsetViewport {\n const targetEvent: MouseEvent | Touch = (e as TouchEvent)?.touches?.[0] ?? e;\n const viewportLeft = this._activeViewport.scrollLeft;\n const viewportTop = this._activeViewport.scrollTop;\n const viewportRight = viewportLeft + this._viewportWidth;\n const viewportBottom = viewportTop + this._viewportHeight;\n\n const viewportOffset = Utils.offset(this._activeViewport);\n const viewportOffsetLeft = viewportOffset?.left ?? 0;\n const viewportOffsetTop = viewportOffset?.top ?? 0;\n const viewportOffsetRight = viewportOffsetLeft + this._viewportWidth;\n const viewportOffsetBottom = viewportOffsetTop + this._viewportHeight;\n\n const result = {\n e,\n dd,\n viewport: {\n left: viewportLeft,\n top: viewportTop,\n right: viewportRight,\n bottom: viewportBottom,\n offset: {\n left: viewportOffsetLeft,\n top: viewportOffsetTop,\n right: viewportOffsetRight,\n bottom: viewportOffsetBottom\n }\n },\n // Consider the viewport as the origin, the `offset` is based on the coordinate system:\n // the cursor is on the viewport's left/bottom when it is less than 0, and on the right/top when greater than 0.\n offset: {\n x: 0,\n y: 0\n },\n isOutsideViewport: false\n };\n // ... horizontal\n if (targetEvent.pageX < viewportOffsetLeft) {\n result.offset.x = targetEvent.pageX - viewportOffsetLeft;\n } else if (targetEvent.pageX > viewportOffsetRight) {\n result.offset.x = targetEvent.pageX - viewportOffsetRight;\n }\n // ... vertical\n if (targetEvent.pageY < viewportOffsetTop) {\n result.offset.y = viewportOffsetTop - targetEvent.pageY;\n } else if (targetEvent.pageY > viewportOffsetBottom) {\n result.offset.y = viewportOffsetBottom - targetEvent.pageY;\n }\n result.isOutsideViewport = !!result.offset.x || !!result.offset.y;\n return result;\n }\n\n protected handleDragOutsideViewport() {\n this._xDelayForNextCell = this._options.maxIntervalToShowNextCell - Math.abs(this._draggingMouseOffset.offset.x) * this._options.accelerateInterval;\n this._yDelayForNextCell = this._options.maxIntervalToShowNextCell - Math.abs(this._draggingMouseOffset.offset.y) * this._options.accelerateInterval;\n // only one timer is created to handle the case that cursor outside the viewport\n if (!this._autoScrollTimerId) {\n let xTotalDelay = 0;\n let yTotalDelay = 0;\n this._autoScrollTimerId = setInterval(() => {\n let xNeedUpdate = false;\n let yNeedUpdate = false;\n // ... horizontal\n if (this._draggingMouseOffset.offset.x) {\n xTotalDelay += this._options.minIntervalToShowNextCell;\n xNeedUpdate = xTotalDelay >= this._xDelayForNextCell;\n } else {\n xTotalDelay = 0;\n }\n // ... vertical\n if (this._draggingMouseOffset.offset.y) {\n yTotalDelay += this._options.minIntervalToShowNextCell;\n yNeedUpdate = yTotalDelay >= this._yDelayForNextCell;\n } else {\n yTotalDelay = 0;\n }\n if (xNeedUpdate || yNeedUpdate) {\n if (xNeedUpdate) {\n xTotalDelay = 0;\n }\n if (yNeedUpdate) {\n yTotalDelay = 0;\n }\n this.handleDragToNewPosition(xNeedUpdate, yNeedUpdate);\n }\n }, this._options.minIntervalToShowNextCell);\n }\n }\n\n protected handleDragToNewPosition(xNeedUpdate: boolean, yNeedUpdate: boolean) {\n let pageX = this._draggingMouseOffset.e.pageX;\n let pageY = this._draggingMouseOffset.e.pageY;\n const mouseOffsetX = this._draggingMouseOffset.offset.x;\n const mouseOffsetY = this._draggingMouseOffset.offset.y;\n const viewportOffset = this._draggingMouseOffset.viewport.offset;\n // ... horizontal\n if (xNeedUpdate && mouseOffsetX) {\n if (mouseOffsetX > 0) {\n pageX = viewportOffset.right + this._moveDistanceForOneCell.x;\n } else {\n pageX = viewportOffset.left - this._moveDistanceForOneCell.x;\n }\n }\n // ... vertical\n if (yNeedUpdate && mouseOffsetY) {\n if (mouseOffsetY > 0) {\n pageY = viewportOffset.top - this._moveDistanceForOneCell.y;\n } else {\n pageY = viewportOffset.bottom + this._moveDistanceForOneCell.y;\n }\n }\n this.handleDragTo({ pageX, pageY }, this._draggingMouseOffset.dd);\n }\n\n protected stopIntervalTimer() {\n if (this._autoScrollTimerId) {\n clearInterval(this._autoScrollTimerId);\n this._autoScrollTimerId = undefined;\n }\n }\n\n protected handleDragTo(e: { pageX: number; pageY: number; }, dd: DragPosition) {\n const targetEvent: MouseEvent | Touch = (e as unknown as TouchEvent)?.touches?.[0] ?? e;\n const canvasOffset = Utils.offset(this._activeCanvas);\n const end = this._grid.getCellFromPoint(\n targetEvent.pageX - (canvasOffset?.left ?? 0) + this._columnOffset,\n targetEvent.pageY - (canvasOffset?.top ?? 0) + this._rowOffset\n );\n\n // ... frozen column(s),\n if (this._gridOptions.frozenColumn! >= 0 && (!this._isRightCanvas && (end.cell > this._gridOptions.frozenColumn!)) || (this._isRightCanvas && (end.cell <= this._gridOptions.frozenColumn!))) {\n return;\n }\n\n // ... or frozen row(s)\n if (this._gridOptions.frozenRow! >= 0 && (!this._isBottomCanvas && (end.row >= this._gridOptions.frozenRow!)) || (this._isBottomCanvas && (end.row < this._gridOptions.frozenRow!))) {\n return;\n }\n\n // scrolling the viewport to display the target `end` cell if it is not fully displayed\n if (this._options.autoScroll && this._draggingMouseOffset) {\n const endCellBox = this._grid.getCellNodeBox(end.row, end.cell);\n if (!endCellBox) {\n return;\n }\n const viewport = this._draggingMouseOffset.viewport;\n if (endCellBox.left < viewport.left || endCellBox.right > viewport.right\n || endCellBox.top < viewport.top || endCellBox.bottom > viewport.bottom) {\n this._grid.scrollCellIntoView(end.row, end.cell);\n }\n }\n\n // ... or regular grid (without any frozen options)\n if (!this._grid.canCellBeSelected(end.row, end.cell)) {\n return;\n }\n\n if (dd?.range) {\n dd.range.end = end;\n\n const range = new SlickRange(dd.range.start.row ?? 0, dd.range.start.cell ?? 0, end.row, end.cell);\n this._decorator.show(range);\n this.onCellRangeSelecting.notify({\n range\n });\n }\n }\n\n protected hasRowMoveManager() {\n return !!(this._grid.getPluginByName('RowMoveManager') || this._grid.getPluginByName('CrossGridRowMoveManager'));\n }\n\n protected handleDragEnd(e: Event, dd: DragPosition) {\n if (!this._dragging) {\n return;\n }\n\n this._dragging = false;\n e.stopImmediatePropagation();\n\n this.stopIntervalTimer();\n this._decorator.hide();\n this.onCellRangeSelected.notify({\n range: new SlickRange(\n dd.range.start.row ?? 0,\n dd.range.start.cell ?? 0,\n dd.range.end.row,\n dd.range.end.cell\n )\n });\n }\n\n getCurrentRange() {\n return this._currentlySelectedRange;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(Slick, {\n CellRangeSelector: SlickCellRangeSelector\n });\n}\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.cellselectionmodel.js b/dist/browser/plugins/slick.cellselectionmodel.js index d2f24b32e..92a82f7cd 100644 --- a/dist/browser/plugins/slick.cellselectionmodel.js +++ b/dist/browser/plugins/slick.cellselectionmodel.js @@ -13,6 +13,7 @@ __publicField(this, "onSelectedRangesChanged", new SlickEvent()); // -- // protected props + __publicField(this, "_cachedPageRowCount", 0); __publicField(this, "_dataView"); __publicField(this, "_grid"); __publicField(this, "_prevSelectedRow"); @@ -51,6 +52,10 @@ } return !areDifferent; } + /** Provide a way to force a recalculation of page row count (for example on grid resize) */ + resetPageRowCount() { + this._cachedPageRowCount = 0; + } setSelectedRanges(ranges, caller = "SlickCellSelectionModel.setSelectedRanges") { if ((!this._ranges || this._ranges.length === 0) && (!ranges || ranges.length === 0)) return; @@ -75,7 +80,7 @@ } handleActiveCellChange(_e, args) { var _a, _b; - this._prevSelectedRow = void 0, (_a = this._options) != null && _a.selectActiveCell && args.row != null && args.cell != null ? this.setSelectedRanges([new SlickRange(args.row, args.cell)]) : (_b = this._options) != null && _b.selectActiveCell || this.setSelectedRanges([]); + this._prevSelectedRow = void 0, (_a = this._options) != null && _a.selectActiveCell && Utils.isDefined(args.row) && Utils.isDefined(args.cell) ? this.setSelectedRanges([new SlickRange(args.row, args.cell)]) : (_b = this._options) != null && _b.selectActiveCell || this.setSelectedRanges([]); } isKeyAllowed(key) { return ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "PageDown", "PageUp", "Home", "End"].some((k) => k === key); @@ -85,8 +90,8 @@ let ranges, last, active = this._grid.getActiveCell(), metaKey = e.ctrlKey || e.metaKey, dataLn = 0; if (this._dataView ? dataLn = ((_a = this._dataView) == null ? void 0 : _a.getPagingInfo().pageSize) || this._dataView.getLength() : dataLn = this._grid.getDataLength(), active && e.shiftKey && !metaKey && !e.altKey && this.isKeyAllowed(e.key)) { ranges = this.getSelectedRanges().slice(), ranges.length || ranges.push(new SlickRange(active.row, active.cell)), last = ranges.pop(), last.contains(active.row, active.cell) || (last = new SlickRange(active.row, active.cell)); - let dRow = last.toRow - last.fromRow, dCell = last.toCell - last.fromCell, dirRow = active.row == last.fromRow ? 1 : -1, dirCell = active.cell == last.fromCell ? 1 : -1, pageRowCount = this._grid.getViewportRowCount(), isSingleKeyMove = e.key.startsWith("Arrow"), toRow = 0; - isSingleKeyMove ? (e.key === "ArrowLeft" ? dCell -= dirCell : e.key === "ArrowRight" ? dCell += dirCell : e.key === "ArrowUp" ? dRow -= dirRow : e.key === "ArrowDown" && (dRow += dirRow), toRow = active.row + dirRow * dRow) : (this._prevSelectedRow === void 0 && (this._prevSelectedRow = active.row), e.key === "Home" ? toRow = 0 : e.key === "End" ? toRow = dataLn - 1 : e.key === "PageUp" ? (this._prevSelectedRow >= 0 && (toRow = this._prevSelectedRow - pageRowCount), toRow < 0 && (toRow = 0)) : e.key === "PageDown" && (this._prevSelectedRow <= dataLn - 1 && (toRow = this._prevSelectedRow + pageRowCount), toRow > dataLn - 1 && (toRow = dataLn - 1)), this._prevSelectedRow = toRow); + let dRow = last.toRow - last.fromRow, dCell = last.toCell - last.fromCell, dirRow = active.row === last.fromRow ? 1 : -1, dirCell = active.cell === last.fromCell ? 1 : -1, isSingleKeyMove = e.key.startsWith("Arrow"), toRow = 0; + isSingleKeyMove ? (e.key === "ArrowLeft" ? dCell -= dirCell : e.key === "ArrowRight" ? dCell += dirCell : e.key === "ArrowUp" ? dRow -= dirRow : e.key === "ArrowDown" && (dRow += dirRow), toRow = active.row + dirRow * dRow) : (this._cachedPageRowCount < 1 && (this._cachedPageRowCount = this._grid.getViewportRowCount()), this._prevSelectedRow === void 0 && (this._prevSelectedRow = active.row), e.key === "Home" ? toRow = 0 : e.key === "End" ? toRow = dataLn - 1 : e.key === "PageUp" ? (this._prevSelectedRow >= 0 && (toRow = this._prevSelectedRow - this._cachedPageRowCount), toRow < 0 && (toRow = 0)) : e.key === "PageDown" && (this._prevSelectedRow <= dataLn - 1 && (toRow = this._prevSelectedRow + this._cachedPageRowCount), toRow > dataLn - 1 && (toRow = dataLn - 1)), this._prevSelectedRow = toRow); let new_last = new SlickRange(active.row, active.cell, toRow, active.cell + dirCell * dCell); if (this.removeInvalidRanges([new_last]).length) { ranges.push(new_last); diff --git a/dist/browser/plugins/slick.cellselectionmodel.js.map b/dist/browser/plugins/slick.cellselectionmodel.js.map index 436c7d8dd..60c4b42b7 100644 --- a/dist/browser/plugins/slick.cellselectionmodel.js.map +++ b/dist/browser/plugins/slick.cellselectionmodel.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.cellselectionmodel.ts"], - "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\nimport { SlickCellRangeSelector as SlickCellRangeSelector_ } from './slick.cellrangeselector';\nimport type { CellRange, OnActiveCellChangedEventArgs } from '../models/index';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst SlickCellRangeSelector = IIFE_ONLY ? Slick.CellRangeSelector : SlickCellRangeSelector_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport interface CellSelectionModelOption {\n selectActiveCell: boolean;\n cellRangeSelector?: SlickCellRangeSelector_;\n}\n\nexport class SlickCellSelectionModel {\n // --\n // public API\n pluginName = 'CellSelectionModel' as const;\n onSelectedRangesChanged = new SlickEvent();\n\n // --\n // protected props\n protected _dataView?: SlickDataView;\n protected _grid!: SlickGrid;\n protected _prevSelectedRow?: number;\n protected _prevKeyDown = '';\n protected _ranges: CellRange[] = [];\n protected _selector: SlickCellRangeSelector_;\n protected _options?: CellSelectionModelOption;\n protected _defaults: CellSelectionModelOption = {\n selectActiveCell: true\n };\n\n constructor(options?: { selectActiveCell: boolean; cellRangeSelector: SlickCellRangeSelector_; }) {\n if (options === undefined || options.cellRangeSelector === undefined) {\n this._selector = new SlickCellRangeSelector({ selectionCss: { border: '2px solid black' } as CSSStyleDeclaration });\n } else {\n this._selector = options.cellRangeSelector;\n }\n }\n\n init(grid: SlickGrid) {\n this._options = Utils.extend(true, {}, this._defaults, this._options);\n this._grid = grid;\n if (grid.hasDataView()) {\n this._dataView = grid.getData();\n }\n this._grid.onActiveCellChanged.subscribe(this.handleActiveCellChange.bind(this));\n this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));\n grid.registerPlugin(this._selector);\n this._selector.onCellRangeSelected.subscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onBeforeCellRangeSelected.subscribe(this.handleBeforeCellRangeSelected.bind(this));\n }\n\n destroy() {\n this._grid.onActiveCellChanged.unsubscribe(this.handleActiveCellChange.bind(this));\n this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));\n this._selector.onCellRangeSelected.unsubscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onBeforeCellRangeSelected.unsubscribe(this.handleBeforeCellRangeSelected.bind(this));\n this._grid.unregisterPlugin(this._selector);\n this._selector?.destroy();\n }\n\n protected removeInvalidRanges(ranges: CellRange[]) {\n const result: CellRange[] = [];\n\n for (let i = 0; i < ranges.length; i++) {\n const r = ranges[i];\n if (this._grid.canCellBeSelected(r.fromRow, r.fromCell) && this._grid.canCellBeSelected(r.toRow, r.toCell)) {\n result.push(r);\n }\n }\n\n return result;\n }\n\n protected rangesAreEqual(range1: CellRange[], range2: CellRange[]) {\n let areDifferent = (range1.length !== range2.length);\n if (!areDifferent) {\n for (let i = 0; i < range1.length; i++) {\n if (\n range1[i].fromCell !== range2[i].fromCell\n || range1[i].fromRow !== range2[i].fromRow\n || range1[i].toCell !== range2[i].toCell\n || range1[i].toRow !== range2[i].toRow\n ) {\n areDifferent = true;\n break;\n }\n }\n }\n return !areDifferent;\n }\n\n setSelectedRanges(ranges: CellRange[], caller = 'SlickCellSelectionModel.setSelectedRanges') {\n // simple check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n if ((!this._ranges || this._ranges.length === 0) && (!ranges || ranges.length === 0)) { return; }\n\n // if range has not changed, don't fire onSelectedRangesChanged\n const rangeHasChanged = !this.rangesAreEqual(this._ranges, ranges);\n\n this._ranges = this.removeInvalidRanges(ranges);\n if (rangeHasChanged) {\n // provide extra \"caller\" argument through SlickEventData to avoid breaking pubsub event that only accepts an array of selected range\n const eventData = new SlickEventData(null, this._ranges);\n Object.defineProperty(eventData, 'detail', { writable: true, configurable: true, value: { caller: caller || \"SlickCellSelectionModel.setSelectedRanges\" } });\n this.onSelectedRangesChanged.notify(this._ranges, eventData);\n }\n }\n\n getSelectedRanges() {\n return this._ranges;\n }\n\n refreshSelections() {\n this.setSelectedRanges(this.getSelectedRanges());\n }\n\n protected handleBeforeCellRangeSelected(e: Event): boolean | void {\n if (this._grid.getEditorLock().isActive()) {\n e.stopPropagation();\n return false;\n }\n }\n\n protected handleCellRangeSelected(_e: any, args: { range: CellRange; }) {\n this._grid.setActiveCell(args.range.fromRow, args.range.fromCell, false, false, true);\n this.setSelectedRanges([args.range]);\n }\n\n protected handleActiveCellChange(_e: Event, args: OnActiveCellChangedEventArgs) {\n this._prevSelectedRow = undefined;\n if (this._options?.selectActiveCell && args.row != null && args.cell != null) {\n this.setSelectedRanges([new SlickRange(args.row, args.cell)]);\n } else if (!this._options?.selectActiveCell) {\n // clear the previous selection once the cell changes\n this.setSelectedRanges([]);\n }\n }\n\n protected isKeyAllowed(key: string) {\n return ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'PageDown', 'PageUp', 'Home', 'End'].some(k => k === key);\n }\n\n protected handleKeyDown(e: KeyboardEvent) {\n let ranges: CellRange[], last: SlickRange_;\n const active = this._grid.getActiveCell();\n const metaKey = e.ctrlKey || e.metaKey;\n let dataLn = 0;\n if (this._dataView) {\n dataLn = this._dataView?.getPagingInfo().pageSize || this._dataView.getLength();\n } else {\n dataLn = this._grid.getDataLength();\n }\n\n if (active && e.shiftKey && !metaKey && !e.altKey && this.isKeyAllowed(e.key)) {\n\n ranges = this.getSelectedRanges().slice();\n if (!ranges.length)\n ranges.push(new SlickRange(active.row, active.cell));\n\n // keyboard can work with last range only\n last = ranges.pop() as SlickRange_;\n\n // can't handle selection out of active cell\n if (!last.contains(active.row, active.cell)) {\n last = new SlickRange(active.row, active.cell);\n }\n\n let dRow = last.toRow - last.fromRow;\n let dCell = last.toCell - last.fromCell;\n\n // walking direction\n const dirRow = active.row == last.fromRow ? 1 : -1;\n const dirCell = active.cell == last.fromCell ? 1 : -1;\n const pageRowCount = this._grid.getViewportRowCount();\n const isSingleKeyMove = e.key.startsWith('Arrow');\n let toRow = 0;\n\n if (isSingleKeyMove) {\n // single cell move: (Arrow{Up/ArrowDown/ArrowLeft/ArrowRight})\n if (e.key === 'ArrowLeft') {\n dCell -= dirCell;\n } else if (e.key === 'ArrowRight') {\n dCell += dirCell;\n } else if (e.key === 'ArrowUp') {\n dRow -= dirRow;\n } else if (e.key === 'ArrowDown') {\n dRow += dirRow;\n }\n toRow = active.row + dirRow * dRow;\n } else {\n // multiple cell moves: (Home, End, Page{Up/Down})\n if (this._prevSelectedRow === undefined) {\n this._prevSelectedRow = active.row;\n }\n\n if (e.key === 'Home') {\n toRow = 0;\n } else if (e.key === 'End') {\n toRow = dataLn - 1;\n } else if (e.key === 'PageUp') {\n if (this._prevSelectedRow >= 0) {\n toRow = this._prevSelectedRow - pageRowCount;\n }\n if (toRow < 0) {\n toRow = 0;\n }\n } else if (e.key === 'PageDown') {\n if (this._prevSelectedRow <= dataLn - 1) {\n toRow = this._prevSelectedRow + pageRowCount;\n }\n if (toRow > dataLn - 1) {\n toRow = dataLn - 1;\n }\n }\n this._prevSelectedRow = toRow;\n }\n\n // define new selection range\n const new_last = new SlickRange(active.row, active.cell, toRow, active.cell + dirCell * dCell);\n if (this.removeInvalidRanges([new_last]).length) {\n ranges.push(new_last);\n const viewRow = dirRow > 0 ? new_last.toRow : new_last.fromRow;\n const viewCell = dirCell > 0 ? new_last.toCell : new_last.fromCell;\n\n if (isSingleKeyMove) {\n this._grid.scrollRowIntoView(viewRow);\n this._grid.scrollCellIntoView(viewRow, viewCell);\n } else {\n this._grid.scrollRowIntoView(toRow);\n this._grid.scrollCellIntoView(toRow, viewCell);\n }\n } else {\n ranges.push(last);\n }\n\n this.setSelectedRanges(ranges);\n\n e.preventDefault();\n e.stopPropagation();\n this._prevKeyDown = e.key;\n }\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellSelectionModel: SlickCellSelectionModel\n }\n });\n}\n"], - "mappings": "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", + "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\nimport { SlickCellRangeSelector as SlickCellRangeSelector_ } from './slick.cellrangeselector';\nimport type { CellRange, OnActiveCellChangedEventArgs } from '../models/index';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst SlickCellRangeSelector = IIFE_ONLY ? Slick.CellRangeSelector : SlickCellRangeSelector_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport interface CellSelectionModelOption {\n selectActiveCell: boolean;\n cellRangeSelector?: SlickCellRangeSelector_;\n}\n\nexport class SlickCellSelectionModel {\n // --\n // public API\n pluginName = 'CellSelectionModel' as const;\n onSelectedRangesChanged = new SlickEvent();\n\n // --\n // protected props\n protected _cachedPageRowCount = 0;\n protected _dataView?: SlickDataView;\n protected _grid!: SlickGrid;\n protected _prevSelectedRow?: number;\n protected _prevKeyDown = '';\n protected _ranges: CellRange[] = [];\n protected _selector: SlickCellRangeSelector_;\n protected _options?: CellSelectionModelOption;\n protected _defaults: CellSelectionModelOption = {\n selectActiveCell: true\n };\n\n constructor(options?: { selectActiveCell: boolean; cellRangeSelector: SlickCellRangeSelector_; }) {\n if (options === undefined || options.cellRangeSelector === undefined) {\n this._selector = new SlickCellRangeSelector({ selectionCss: { border: '2px solid black' } as CSSStyleDeclaration });\n } else {\n this._selector = options.cellRangeSelector;\n }\n }\n\n init(grid: SlickGrid) {\n this._options = Utils.extend(true, {}, this._defaults, this._options);\n this._grid = grid;\n if (grid.hasDataView()) {\n this._dataView = grid.getData();\n }\n this._grid.onActiveCellChanged.subscribe(this.handleActiveCellChange.bind(this));\n this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));\n grid.registerPlugin(this._selector);\n this._selector.onCellRangeSelected.subscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onBeforeCellRangeSelected.subscribe(this.handleBeforeCellRangeSelected.bind(this));\n }\n\n destroy() {\n this._grid.onActiveCellChanged.unsubscribe(this.handleActiveCellChange.bind(this));\n this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));\n this._selector.onCellRangeSelected.unsubscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onBeforeCellRangeSelected.unsubscribe(this.handleBeforeCellRangeSelected.bind(this));\n this._grid.unregisterPlugin(this._selector);\n this._selector?.destroy();\n }\n\n protected removeInvalidRanges(ranges: CellRange[]) {\n const result: CellRange[] = [];\n\n for (let i = 0; i < ranges.length; i++) {\n const r = ranges[i];\n if (this._grid.canCellBeSelected(r.fromRow, r.fromCell) && this._grid.canCellBeSelected(r.toRow, r.toCell)) {\n result.push(r);\n }\n }\n\n return result;\n }\n\n protected rangesAreEqual(range1: CellRange[], range2: CellRange[]) {\n let areDifferent = (range1.length !== range2.length);\n if (!areDifferent) {\n for (let i = 0; i < range1.length; i++) {\n if (\n range1[i].fromCell !== range2[i].fromCell\n || range1[i].fromRow !== range2[i].fromRow\n || range1[i].toCell !== range2[i].toCell\n || range1[i].toRow !== range2[i].toRow\n ) {\n areDifferent = true;\n break;\n }\n }\n }\n return !areDifferent;\n }\n\n /** Provide a way to force a recalculation of page row count (for example on grid resize) */\n resetPageRowCount() {\n this._cachedPageRowCount = 0;\n }\n\n setSelectedRanges(ranges: CellRange[], caller = 'SlickCellSelectionModel.setSelectedRanges') {\n // simple check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n if ((!this._ranges || this._ranges.length === 0) && (!ranges || ranges.length === 0)) { return; }\n\n // if range has not changed, don't fire onSelectedRangesChanged\n const rangeHasChanged = !this.rangesAreEqual(this._ranges, ranges);\n\n this._ranges = this.removeInvalidRanges(ranges);\n if (rangeHasChanged) {\n // provide extra \"caller\" argument through SlickEventData to avoid breaking pubsub event that only accepts an array of selected range\n const eventData = new SlickEventData(null, this._ranges);\n Object.defineProperty(eventData, 'detail', { writable: true, configurable: true, value: { caller: caller || \"SlickCellSelectionModel.setSelectedRanges\" } });\n this.onSelectedRangesChanged.notify(this._ranges, eventData);\n }\n }\n\n getSelectedRanges() {\n return this._ranges;\n }\n\n refreshSelections() {\n this.setSelectedRanges(this.getSelectedRanges());\n }\n\n protected handleBeforeCellRangeSelected(e: Event): boolean | void {\n if (this._grid.getEditorLock().isActive()) {\n e.stopPropagation();\n return false;\n }\n }\n\n protected handleCellRangeSelected(_e: any, args: { range: CellRange; }) {\n this._grid.setActiveCell(args.range.fromRow, args.range.fromCell, false, false, true);\n this.setSelectedRanges([args.range]);\n }\n\n protected handleActiveCellChange(_e: Event, args: OnActiveCellChangedEventArgs) {\n this._prevSelectedRow = undefined;\n if (this._options?.selectActiveCell && Utils.isDefined(args.row) && Utils.isDefined(args.cell)) {\n this.setSelectedRanges([new SlickRange(args.row, args.cell)]);\n } else if (!this._options?.selectActiveCell) {\n // clear the previous selection once the cell changes\n this.setSelectedRanges([]);\n }\n }\n\n protected isKeyAllowed(key: string) {\n return ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'PageDown', 'PageUp', 'Home', 'End'].some(k => k === key);\n }\n\n protected handleKeyDown(e: KeyboardEvent) {\n let ranges: CellRange[], last: SlickRange_;\n const active = this._grid.getActiveCell();\n const metaKey = e.ctrlKey || e.metaKey;\n let dataLn = 0;\n if (this._dataView) {\n dataLn = this._dataView?.getPagingInfo().pageSize || this._dataView.getLength();\n } else {\n dataLn = this._grid.getDataLength();\n }\n\n if (active && e.shiftKey && !metaKey && !e.altKey && this.isKeyAllowed(e.key)) {\n\n ranges = this.getSelectedRanges().slice();\n if (!ranges.length) {\n ranges.push(new SlickRange(active.row, active.cell));\n }\n // keyboard can work with last range only\n last = ranges.pop() as SlickRange_;\n\n // can't handle selection out of active cell\n if (!last.contains(active.row, active.cell)) {\n last = new SlickRange(active.row, active.cell);\n }\n\n let dRow = last.toRow - last.fromRow;\n let dCell = last.toCell - last.fromCell;\n\n // walking direction\n const dirRow = active.row === last.fromRow ? 1 : -1;\n const dirCell = active.cell === last.fromCell ? 1 : -1;\n const isSingleKeyMove = e.key.startsWith('Arrow');\n let toRow = 0;\n\n if (isSingleKeyMove) {\n // single cell move: (Arrow{Up/ArrowDown/ArrowLeft/ArrowRight})\n if (e.key === 'ArrowLeft') {\n dCell -= dirCell;\n } else if (e.key === 'ArrowRight') {\n dCell += dirCell;\n } else if (e.key === 'ArrowUp') {\n dRow -= dirRow;\n } else if (e.key === 'ArrowDown') {\n dRow += dirRow;\n }\n toRow = active.row + dirRow * dRow;\n } else {\n // multiple cell moves: (Home, End, Page{Up/Down})\n if (this._cachedPageRowCount < 1) {\n this._cachedPageRowCount = this._grid.getViewportRowCount();\n }\n if (this._prevSelectedRow === undefined) {\n this._prevSelectedRow = active.row;\n }\n\n if (e.key === 'Home') {\n toRow = 0;\n } else if (e.key === 'End') {\n toRow = dataLn - 1;\n } else if (e.key === 'PageUp') {\n if (this._prevSelectedRow >= 0) {\n toRow = this._prevSelectedRow - this._cachedPageRowCount;\n }\n if (toRow < 0) {\n toRow = 0;\n }\n } else if (e.key === 'PageDown') {\n if (this._prevSelectedRow <= dataLn - 1) {\n toRow = this._prevSelectedRow + this._cachedPageRowCount;\n }\n if (toRow > dataLn - 1) {\n toRow = dataLn - 1;\n }\n }\n this._prevSelectedRow = toRow;\n }\n\n // define new selection range\n const new_last = new SlickRange(active.row, active.cell, toRow, active.cell + dirCell * dCell);\n if (this.removeInvalidRanges([new_last]).length) {\n ranges.push(new_last);\n const viewRow = dirRow > 0 ? new_last.toRow : new_last.fromRow;\n const viewCell = dirCell > 0 ? new_last.toCell : new_last.fromCell;\n\n if (isSingleKeyMove) {\n this._grid.scrollRowIntoView(viewRow);\n this._grid.scrollCellIntoView(viewRow, viewCell);\n } else {\n this._grid.scrollRowIntoView(toRow);\n this._grid.scrollCellIntoView(toRow, viewCell);\n }\n } else {\n ranges.push(last);\n }\n\n this.setSelectedRanges(ranges);\n\n e.preventDefault();\n e.stopPropagation();\n this._prevKeyDown = e.key;\n }\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellSelectionModel: SlickCellSelectionModel\n }\n });\n}\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.checkboxselectcolumn.js b/dist/browser/plugins/slick.checkboxselectcolumn.js index 51f015d9c..b7fc26f49 100644 --- a/dist/browser/plugins/slick.checkboxselectcolumn.js +++ b/dist/browser/plugins/slick.checkboxselectcolumn.js @@ -113,7 +113,7 @@ } } handleKeyDown(e, args) { - e.which == 32 && this._grid.getColumns()[args.cell].id === this._options.columnId && ((!this._grid.getEditorLock().isActive() || this._grid.getEditorLock().commitCurrentEdit()) && this.toggleRowSelection(args.row), e.preventDefault(), e.stopImmediatePropagation()); + e.which === 32 && this._grid.getColumns()[args.cell].id === this._options.columnId && ((!this._grid.getEditorLock().isActive() || this._grid.getEditorLock().commitCurrentEdit()) && this.toggleRowSelection(args.row), e.preventDefault(), e.stopImmediatePropagation()); } handleClick(e, args) { if (this._grid.getColumns()[args.cell].id === this._options.columnId && e.target.type === "checkbox") { @@ -148,7 +148,7 @@ this._grid.setSelectedRows(this._grid.getSelectedRows().filter((n) => removeRows.indexOf(n) < 0), "SlickCheckboxSelectColumn.deSelectRows"); } handleHeaderClick(e, args) { - if (args.column.id == this._options.columnId && e.target.type === "checkbox") { + if (args.column.id === this._options.columnId && e.target.type === "checkbox") { if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) { e.preventDefault(), e.stopImmediatePropagation(); return; @@ -177,7 +177,7 @@ this._checkboxColumnCellIndex = 0; let colArr = this._grid.getColumns(); for (let i = 0; i < colArr.length; i++) - colArr[i].id == this._options.columnId && (this._checkboxColumnCellIndex = i); + colArr[i].id === this._options.columnId && (this._checkboxColumnCellIndex = i); } return this._checkboxColumnCellIndex; } diff --git a/dist/browser/plugins/slick.checkboxselectcolumn.js.map b/dist/browser/plugins/slick.checkboxselectcolumn.js.map index 5376f82f7..797a13422 100644 --- a/dist/browser/plugins/slick.checkboxselectcolumn.js.map +++ b/dist/browser/plugins/slick.checkboxselectcolumn.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.checkboxselectcolumn.ts"], - "sourcesContent": ["import type { CheckboxSelectorOption, Column, DOMEvent, Plugin, SelectableOverrideCallback } from '../models/index';\nimport { BindingEventService as BindingEventService_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport class SlickCheckboxSelectColumn implements Plugin {\n // --\n // public API\n pluginName = 'CheckboxSelectColumn' as const;\n\n // --\n // protected props\n protected _dataView!: SlickDataView;\n protected _grid!: SlickGrid;\n protected _isUsingDataView = false;\n protected _selectableOverride: SelectableOverrideCallback | null = null;\n protected _headerRowNode?: HTMLElement;\n protected _selectAll_UID: number;\n protected _handler = new SlickEventHandler();\n protected _selectedRowsLookup: any = {};\n protected _checkboxColumnCellIndex: number | null = null;\n protected _options: CheckboxSelectorOption;\n protected _defaults: CheckboxSelectorOption = {\n columnId: '_checkbox_selector',\n cssClass: undefined,\n hideSelectAllCheckbox: false,\n toolTip: 'Select/Deselect All',\n width: 30,\n applySelectOnAllPages: false, // defaults to false, when that is enabled the \"Select All\" will be applied to all pages (when using Pagination)\n hideInColumnTitleRow: false,\n hideInFilterHeaderRow: true\n };\n protected _isSelectAllChecked = false;\n protected _bindingEventService: BindingEventService_;\n\n constructor(options?: Partial) {\n this._bindingEventService = new BindingEventService();\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._selectAll_UID = this.createUID();\n\n // user could override the checkbox icon logic from within the options or after instantiating the plugin\n if (typeof this._options.selectableOverride === 'function') {\n this.selectableOverride(this._options.selectableOverride);\n }\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._isUsingDataView = !Array.isArray(grid.getData());\n if (this._isUsingDataView) {\n this._dataView = grid.getData();\n }\n this._handler\n .subscribe(this._grid.onSelectedRowsChanged, this.handleSelectedRowsChanged.bind(this))\n .subscribe(this._grid.onClick, this.handleClick.bind(this))\n .subscribe(this._grid.onKeyDown, this.handleKeyDown.bind(this));\n\n if (this._isUsingDataView && this._dataView && this._options.applySelectOnAllPages) {\n this._handler\n .subscribe(this._dataView.onSelectedRowIdsChanged, this.handleDataViewSelectedIdsChanged.bind(this))\n .subscribe(this._dataView.onPagingInfoChanged, this.handleDataViewSelectedIdsChanged.bind(this))\n }\n\n if (!this._options.hideInFilterHeaderRow) {\n this.addCheckboxToFilterHeaderRow(grid);\n }\n if (!this._options.hideInColumnTitleRow) {\n this._handler.subscribe(this._grid.onHeaderClick, this.handleHeaderClick.bind(this));\n }\n }\n\n destroy() {\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n }\n\n getOptions() {\n return this._options;\n }\n\n setOptions(options: Partial) {\n this._options = Utils.extend(true, {}, this._options, options);\n\n if (this._options.hideSelectAllCheckbox) {\n this.hideSelectAllFromColumnHeaderTitleRow();\n this.hideSelectAllFromColumnHeaderFilterRow();\n } else {\n if (!this._options.hideInColumnTitleRow) {\n this.renderSelectAllCheckbox(this._isSelectAllChecked);\n this._handler.subscribe(this._grid.onHeaderClick, this.handleHeaderClick.bind(this));\n } else {\n this.hideSelectAllFromColumnHeaderTitleRow();\n }\n\n if (!this._options.hideInFilterHeaderRow) {\n const selectAllContainerElm = this._headerRowNode?.querySelector('#filter-checkbox-selectall-container');\n if (selectAllContainerElm) {\n selectAllContainerElm.style.display = 'flex';\n const selectAllInputElm = selectAllContainerElm.querySelector('input[type=\"checkbox\"]');\n if (selectAllInputElm) {\n selectAllInputElm.checked = this._isSelectAllChecked;\n }\n }\n } else {\n this.hideSelectAllFromColumnHeaderFilterRow();\n }\n }\n }\n\n protected hideSelectAllFromColumnHeaderTitleRow() {\n this._grid.updateColumnHeader(this._options.columnId || '', '', '');\n }\n\n protected hideSelectAllFromColumnHeaderFilterRow() {\n const selectAllContainerElm = this._headerRowNode?.querySelector('#filter-checkbox-selectall-container');\n if (selectAllContainerElm) {\n selectAllContainerElm.style.display = 'none';\n }\n }\n\n protected handleSelectedRowsChanged() {\n const selectedRows = this._grid.getSelectedRows();\n const lookup: any = {};\n let row = 0, i = 0, k = 0;\n let disabledCount = 0;\n if (typeof this._selectableOverride === 'function') {\n for (k = 0; k < this._grid.getDataLength(); k++) {\n // If we are allowed to select the row\n const dataItem = this._grid.getDataItem(k);\n if (!this.checkSelectableOverride(i, dataItem, this._grid)) {\n disabledCount++;\n }\n }\n }\n\n const removeList: number[] = [];\n for (i = 0; i < selectedRows.length; i++) {\n row = selectedRows[i];\n\n // If we are allowed to select the row\n const rowItem = this._grid.getDataItem(row);\n if (this.checkSelectableOverride(i, rowItem, this._grid)) {\n lookup[row] = true;\n if (lookup[row] !== this._selectedRowsLookup[row]) {\n this._grid.invalidateRow(row);\n delete this._selectedRowsLookup[row];\n }\n }\n else {\n removeList.push(row);\n }\n }\n for (const selectedRow in this._selectedRowsLookup) {\n this._grid.invalidateRow(+selectedRow);\n }\n this._selectedRowsLookup = lookup;\n this._grid.render();\n this._isSelectAllChecked = (selectedRows?.length ?? 0) + disabledCount >= this._grid.getDataLength();\n\n if (!this._isUsingDataView || !this._options.applySelectOnAllPages) {\n if (!this._options.hideInColumnTitleRow && !this._options.hideSelectAllCheckbox) {\n this.renderSelectAllCheckbox(this._isSelectAllChecked);\n }\n if (!this._options.hideInFilterHeaderRow) {\n const selectAllElm = this._headerRowNode?.querySelector(`#header-filter-selector${this._selectAll_UID}`);\n if (selectAllElm) {\n selectAllElm.checked = this._isSelectAllChecked;\n }\n }\n }\n\n // Remove items that shouln't of been selected in the first place (Got here Ctrl + click)\n if (removeList.length > 0) {\n for (i = 0; i < removeList.length; i++) {\n const remIdx = selectedRows.indexOf(removeList[i]);\n selectedRows.splice(remIdx, 1);\n }\n this._grid.setSelectedRows(selectedRows, 'click.cleanup');\n }\n }\n\n protected handleDataViewSelectedIdsChanged() {\n const selectedIds = this._dataView.getAllSelectedFilteredIds();\n const filteredItems = this._dataView.getFilteredItems();\n let disabledCount = 0;\n\n if (typeof this._selectableOverride === 'function' && selectedIds.length > 0) {\n for (let k = 0; k < this._dataView.getItemCount(); k++) {\n // If we are allowed to select the row\n const dataItem: T = this._dataView.getItemByIdx(k);\n const idProperty = this._dataView.getIdPropertyName();\n const dataItemId = dataItem[idProperty as keyof T];\n const foundItemIdx = filteredItems.findIndex(function (item) {\n return item[idProperty as keyof T] === dataItemId;\n });\n if (foundItemIdx >= 0 && !this.checkSelectableOverride(k, dataItem, this._grid)) {\n disabledCount++;\n }\n }\n }\n this._isSelectAllChecked = (selectedIds && selectedIds.length) + disabledCount >= filteredItems.length;\n\n if (!this._options.hideInColumnTitleRow && !this._options.hideSelectAllCheckbox) {\n this.renderSelectAllCheckbox(this._isSelectAllChecked);\n }\n if (!this._options.hideInFilterHeaderRow) {\n const selectAllElm = this._headerRowNode?.querySelector(`#header-filter-selector${this._selectAll_UID}`);\n if (selectAllElm) {\n selectAllElm.checked = this._isSelectAllChecked;\n }\n }\n }\n\n protected handleKeyDown(e: KeyboardEvent, args: any) {\n if (e.which == 32) {\n if (this._grid.getColumns()[args.cell].id === this._options.columnId) {\n // if editing, try to commit\n if (!this._grid.getEditorLock().isActive() || this._grid.getEditorLock().commitCurrentEdit()) {\n this.toggleRowSelection(args.row);\n }\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n }\n }\n\n protected handleClick(e: DOMEvent, args: { row: number; cell: number; }) {\n // clicking on a row select checkbox\n if (this._grid.getColumns()[args.cell].id === this._options.columnId && e.target.type === 'checkbox') {\n // if editing, try to commit\n if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {\n e.preventDefault();\n e.stopImmediatePropagation();\n return;\n }\n\n this.toggleRowSelection(args.row);\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n\n protected toggleRowSelection(row: number) {\n const dataContext = this._grid.getDataItem(row);\n if (!this.checkSelectableOverride(row, dataContext, this._grid)) {\n return;\n }\n\n if (this._selectedRowsLookup[row]) {\n const newSelectedRows = this._grid.getSelectedRows().filter((n) => n !== row);\n this._grid.setSelectedRows(newSelectedRows, 'click.toggle');\n } else {\n this._grid.setSelectedRows(this._grid.getSelectedRows().concat(row), 'click.toggle');\n }\n this._grid.setActiveCell(row, this.getCheckboxColumnCellIndex());\n }\n\n selectRows(rowArray: number[]) {\n const addRows: number[] = [];\n for (let i = 0, l = rowArray.length; i < l; i++) {\n if (!this._selectedRowsLookup[rowArray[i]]) {\n addRows[addRows.length] = rowArray[i];\n }\n }\n this._grid.setSelectedRows(this._grid.getSelectedRows().concat(addRows), 'SlickCheckboxSelectColumn.selectRows');\n }\n\n deSelectRows(rowArray: number[]) {\n const removeRows: number[] = [];\n for (let i = 0, l = rowArray.length; i < l; i++) {\n if (this._selectedRowsLookup[rowArray[i]]) {\n removeRows[removeRows.length] = rowArray[i];\n }\n }\n\n this._grid.setSelectedRows(this._grid.getSelectedRows().filter((n) => removeRows.indexOf(n) < 0), 'SlickCheckboxSelectColumn.deSelectRows');\n }\n\n protected handleHeaderClick(e: DOMEvent, args: any) {\n if (args.column.id == this._options.columnId && e.target.type === 'checkbox') {\n // if editing, try to commit\n if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {\n e.preventDefault();\n e.stopImmediatePropagation();\n return;\n }\n\n let isAllSelected = e.target.checked;\n const caller = isAllSelected ? 'click.selectAll' : 'click.unselectAll';\n const rows: number[] = [];\n\n if (isAllSelected) {\n for (let i = 0; i < this._grid.getDataLength(); i++) {\n // Get the row and check it's a selectable row before pushing it onto the stack\n const rowItem = this._grid.getDataItem(i);\n if (!rowItem.__group && !rowItem.__groupTotals && this.checkSelectableOverride(i, rowItem, this._grid)) {\n rows.push(i);\n }\n }\n isAllSelected = true;\n }\n if (this._isUsingDataView && this._dataView && this._options.applySelectOnAllPages) {\n const ids: Array = [];\n const filteredItems = this._dataView.getFilteredItems();\n for (let j = 0; j < filteredItems.length; j++) {\n // Get the row and check it's a selectable ID (it could be in a different page) before pushing it onto the stack\n const dataviewRowItem: T = filteredItems[j];\n if (this.checkSelectableOverride(j, dataviewRowItem, this._grid)) {\n ids.push(dataviewRowItem[this._dataView.getIdPropertyName() as keyof T] as number | string);\n }\n }\n this._dataView.setSelectedIds(ids, { isRowBeingAdded: isAllSelected });\n }\n this._grid.setSelectedRows(rows, caller);\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n\n protected getCheckboxColumnCellIndex() {\n if (this._checkboxColumnCellIndex === null) {\n this._checkboxColumnCellIndex = 0;\n const colArr = this._grid.getColumns();\n for (let i = 0; i < colArr.length; i++) {\n if (colArr[i].id == this._options.columnId) {\n this._checkboxColumnCellIndex = i;\n }\n }\n }\n return this._checkboxColumnCellIndex;\n }\n\n getColumnDefinition() {\n return {\n id: this._options.columnId,\n name: (this._options.hideSelectAllCheckbox || this._options.hideInColumnTitleRow) ? '' : ``,\n toolTip: (this._options.hideSelectAllCheckbox || this._options.hideInColumnTitleRow) ? '' : this._options.toolTip,\n field: \"sel\",\n width: this._options.width,\n resizable: false,\n sortable: false,\n cssClass: this._options.cssClass,\n hideSelectAllCheckbox: this._options.hideSelectAllCheckbox,\n formatter: this.checkboxSelectionFormatter.bind(this),\n // exclude from all menus, defaults to true unless the option is provided differently by the user\n excludeFromColumnPicker: this._options.excludeFromColumnPicker ?? true,\n excludeFromGridMenu: this._options.excludeFromGridMenu ?? true,\n excludeFromHeaderMenu: this._options.excludeFromHeaderMenu ?? true,\n };\n }\n\n protected addCheckboxToFilterHeaderRow(grid: SlickGrid) {\n this._handler.subscribe(grid.onHeaderRowCellRendered, (_e: any, args: any) => {\n if (args.column.field === \"sel\") {\n Utils.emptyElement(args.node);\n const spanElm = document.createElement('span');\n spanElm.id = 'filter-checkbox-selectall-container';\n\n const inputElm = document.createElement('input');\n inputElm.type = 'checkbox';\n inputElm.id = `header-filter-selector${this._selectAll_UID}`;\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `header-filter-selector${this._selectAll_UID}`;\n\n spanElm.appendChild(inputElm);\n spanElm.appendChild(labelElm);\n args.node.appendChild(spanElm);\n this._headerRowNode = args.node;\n\n this._bindingEventService.bind(spanElm, 'click', ((e: DOMEvent) => this.handleHeaderClick(e, args)) as EventListener);\n }\n });\n }\n\n protected createUID() {\n return Math.round(10000000 * Math.random());\n }\n\n protected checkboxSelectionFormatter(row: number, _cell: number, _val: any, _columnDef: Column, dataContext: any, grid: SlickGrid) {\n const UID = this.createUID() + row;\n\n if (dataContext) {\n if (!this.checkSelectableOverride(row, dataContext, grid)) {\n return null;\n } else {\n return this._selectedRowsLookup[row]\n ? ``\n : ``;\n }\n }\n return null;\n }\n\n protected checkSelectableOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._selectableOverride === 'function') {\n return this._selectableOverride(row, dataContext, grid);\n }\n return true;\n }\n\n protected renderSelectAllCheckbox(isSelectAllChecked?: boolean) {\n if (isSelectAllChecked) {\n this._grid.updateColumnHeader(this._options.columnId || '', ``, this._options.toolTip);\n } else {\n this._grid.updateColumnHeader(this._options.columnId || '', ``, this._options.toolTip);\n }\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row a selectable row.\n * In order word, user can choose which rows to be selectable or not by providing his own logic.\n * @param overrideFn: override function callback\n */\n selectableOverride(overrideFn: SelectableOverrideCallback) {\n this._selectableOverride = overrideFn;\n }\n\n\n // Utils.extend(this, {\n // \"init\": init,\n // \"destroy\": destroy,\n // \"deSelectRows\": deSelectRows,\n // \"selectRows\": selectRows,\n // \"getColumnDefinition\": getColumnDefinition,\n // \"getOptions\": getOptions,\n // \"selectableOverride\": selectableOverride,\n // \"setOptions\": setOptions,\n // });\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CheckboxSelectColumn: SlickCheckboxSelectColumn\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import type { CheckboxSelectorOption, Column, DOMEvent, SlickPlugin, SelectableOverrideCallback } from '../models/index';\nimport { BindingEventService as BindingEventService_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport class SlickCheckboxSelectColumn implements SlickPlugin {\n // --\n // public API\n pluginName = 'CheckboxSelectColumn' as const;\n\n // --\n // protected props\n protected _dataView!: SlickDataView;\n protected _grid!: SlickGrid;\n protected _isUsingDataView = false;\n protected _selectableOverride: SelectableOverrideCallback | null = null;\n protected _headerRowNode?: HTMLElement;\n protected _selectAll_UID: number;\n protected _handler = new SlickEventHandler();\n protected _selectedRowsLookup: any = {};\n protected _checkboxColumnCellIndex: number | null = null;\n protected _options: CheckboxSelectorOption;\n protected _defaults: CheckboxSelectorOption = {\n columnId: '_checkbox_selector',\n cssClass: undefined,\n hideSelectAllCheckbox: false,\n toolTip: 'Select/Deselect All',\n width: 30,\n applySelectOnAllPages: false, // defaults to false, when that is enabled the \"Select All\" will be applied to all pages (when using Pagination)\n hideInColumnTitleRow: false,\n hideInFilterHeaderRow: true\n };\n protected _isSelectAllChecked = false;\n protected _bindingEventService: BindingEventService_;\n\n constructor(options?: Partial) {\n this._bindingEventService = new BindingEventService();\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._selectAll_UID = this.createUID();\n\n // user could override the checkbox icon logic from within the options or after instantiating the plugin\n if (typeof this._options.selectableOverride === 'function') {\n this.selectableOverride(this._options.selectableOverride);\n }\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._isUsingDataView = !Array.isArray(grid.getData());\n if (this._isUsingDataView) {\n this._dataView = grid.getData();\n }\n this._handler\n .subscribe(this._grid.onSelectedRowsChanged, this.handleSelectedRowsChanged.bind(this))\n .subscribe(this._grid.onClick, this.handleClick.bind(this))\n .subscribe(this._grid.onKeyDown, this.handleKeyDown.bind(this));\n\n if (this._isUsingDataView && this._dataView && this._options.applySelectOnAllPages) {\n this._handler\n .subscribe(this._dataView.onSelectedRowIdsChanged, this.handleDataViewSelectedIdsChanged.bind(this))\n .subscribe(this._dataView.onPagingInfoChanged, this.handleDataViewSelectedIdsChanged.bind(this));\n }\n\n if (!this._options.hideInFilterHeaderRow) {\n this.addCheckboxToFilterHeaderRow(grid);\n }\n if (!this._options.hideInColumnTitleRow) {\n this._handler.subscribe(this._grid.onHeaderClick, this.handleHeaderClick.bind(this));\n }\n }\n\n destroy() {\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n }\n\n getOptions() {\n return this._options;\n }\n\n setOptions(options: Partial) {\n this._options = Utils.extend(true, {}, this._options, options);\n\n if (this._options.hideSelectAllCheckbox) {\n this.hideSelectAllFromColumnHeaderTitleRow();\n this.hideSelectAllFromColumnHeaderFilterRow();\n } else {\n if (!this._options.hideInColumnTitleRow) {\n this.renderSelectAllCheckbox(this._isSelectAllChecked);\n this._handler.subscribe(this._grid.onHeaderClick, this.handleHeaderClick.bind(this));\n } else {\n this.hideSelectAllFromColumnHeaderTitleRow();\n }\n\n if (!this._options.hideInFilterHeaderRow) {\n const selectAllContainerElm = this._headerRowNode?.querySelector('#filter-checkbox-selectall-container');\n if (selectAllContainerElm) {\n selectAllContainerElm.style.display = 'flex';\n const selectAllInputElm = selectAllContainerElm.querySelector('input[type=\"checkbox\"]');\n if (selectAllInputElm) {\n selectAllInputElm.checked = this._isSelectAllChecked;\n }\n }\n } else {\n this.hideSelectAllFromColumnHeaderFilterRow();\n }\n }\n }\n\n protected hideSelectAllFromColumnHeaderTitleRow() {\n this._grid.updateColumnHeader(this._options.columnId || '', '', '');\n }\n\n protected hideSelectAllFromColumnHeaderFilterRow() {\n const selectAllContainerElm = this._headerRowNode?.querySelector('#filter-checkbox-selectall-container');\n if (selectAllContainerElm) {\n selectAllContainerElm.style.display = 'none';\n }\n }\n\n protected handleSelectedRowsChanged() {\n const selectedRows = this._grid.getSelectedRows();\n const lookup: any = {};\n let row = 0, i = 0, k = 0;\n let disabledCount = 0;\n if (typeof this._selectableOverride === 'function') {\n for (k = 0; k < this._grid.getDataLength(); k++) {\n // If we are allowed to select the row\n const dataItem = this._grid.getDataItem(k);\n if (!this.checkSelectableOverride(i, dataItem, this._grid)) {\n disabledCount++;\n }\n }\n }\n\n const removeList: number[] = [];\n for (i = 0; i < selectedRows.length; i++) {\n row = selectedRows[i];\n\n // If we are allowed to select the row\n const rowItem = this._grid.getDataItem(row);\n if (this.checkSelectableOverride(i, rowItem, this._grid)) {\n lookup[row] = true;\n if (lookup[row] !== this._selectedRowsLookup[row]) {\n this._grid.invalidateRow(row);\n delete this._selectedRowsLookup[row];\n }\n }\n else {\n removeList.push(row);\n }\n }\n for (const selectedRow in this._selectedRowsLookup) {\n this._grid.invalidateRow(+selectedRow);\n }\n this._selectedRowsLookup = lookup;\n this._grid.render();\n this._isSelectAllChecked = (selectedRows?.length ?? 0) + disabledCount >= this._grid.getDataLength();\n\n if (!this._isUsingDataView || !this._options.applySelectOnAllPages) {\n if (!this._options.hideInColumnTitleRow && !this._options.hideSelectAllCheckbox) {\n this.renderSelectAllCheckbox(this._isSelectAllChecked);\n }\n if (!this._options.hideInFilterHeaderRow) {\n const selectAllElm = this._headerRowNode?.querySelector(`#header-filter-selector${this._selectAll_UID}`);\n if (selectAllElm) {\n selectAllElm.checked = this._isSelectAllChecked;\n }\n }\n }\n\n // Remove items that shouln't of been selected in the first place (Got here Ctrl + click)\n if (removeList.length > 0) {\n for (i = 0; i < removeList.length; i++) {\n const remIdx = selectedRows.indexOf(removeList[i]);\n selectedRows.splice(remIdx, 1);\n }\n this._grid.setSelectedRows(selectedRows, 'click.cleanup');\n }\n }\n\n protected handleDataViewSelectedIdsChanged() {\n const selectedIds = this._dataView.getAllSelectedFilteredIds();\n const filteredItems = this._dataView.getFilteredItems();\n let disabledCount = 0;\n\n if (typeof this._selectableOverride === 'function' && selectedIds.length > 0) {\n for (let k = 0; k < this._dataView.getItemCount(); k++) {\n // If we are allowed to select the row\n const dataItem: T = this._dataView.getItemByIdx(k);\n const idProperty = this._dataView.getIdPropertyName();\n const dataItemId = dataItem[idProperty as keyof T];\n const foundItemIdx = filteredItems.findIndex(function (item) {\n return item[idProperty as keyof T] === dataItemId;\n });\n if (foundItemIdx >= 0 && !this.checkSelectableOverride(k, dataItem, this._grid)) {\n disabledCount++;\n }\n }\n }\n this._isSelectAllChecked = (selectedIds && selectedIds.length) + disabledCount >= filteredItems.length;\n\n if (!this._options.hideInColumnTitleRow && !this._options.hideSelectAllCheckbox) {\n this.renderSelectAllCheckbox(this._isSelectAllChecked);\n }\n if (!this._options.hideInFilterHeaderRow) {\n const selectAllElm = this._headerRowNode?.querySelector(`#header-filter-selector${this._selectAll_UID}`);\n if (selectAllElm) {\n selectAllElm.checked = this._isSelectAllChecked;\n }\n }\n }\n\n protected handleKeyDown(e: KeyboardEvent, args: any) {\n if (e.which === 32) {\n if (this._grid.getColumns()[args.cell].id === this._options.columnId) {\n // if editing, try to commit\n if (!this._grid.getEditorLock().isActive() || this._grid.getEditorLock().commitCurrentEdit()) {\n this.toggleRowSelection(args.row);\n }\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n }\n }\n\n protected handleClick(e: DOMEvent, args: { row: number; cell: number; }) {\n // clicking on a row select checkbox\n if (this._grid.getColumns()[args.cell].id === this._options.columnId && e.target.type === 'checkbox') {\n // if editing, try to commit\n if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {\n e.preventDefault();\n e.stopImmediatePropagation();\n return;\n }\n\n this.toggleRowSelection(args.row);\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n\n protected toggleRowSelection(row: number) {\n const dataContext = this._grid.getDataItem(row);\n if (!this.checkSelectableOverride(row, dataContext, this._grid)) {\n return;\n }\n\n if (this._selectedRowsLookup[row]) {\n const newSelectedRows = this._grid.getSelectedRows().filter((n) => n !== row);\n this._grid.setSelectedRows(newSelectedRows, 'click.toggle');\n } else {\n this._grid.setSelectedRows(this._grid.getSelectedRows().concat(row), 'click.toggle');\n }\n this._grid.setActiveCell(row, this.getCheckboxColumnCellIndex());\n }\n\n selectRows(rowArray: number[]) {\n const addRows: number[] = [];\n for (let i = 0, l = rowArray.length; i < l; i++) {\n if (!this._selectedRowsLookup[rowArray[i]]) {\n addRows[addRows.length] = rowArray[i];\n }\n }\n this._grid.setSelectedRows(this._grid.getSelectedRows().concat(addRows), 'SlickCheckboxSelectColumn.selectRows');\n }\n\n deSelectRows(rowArray: number[]) {\n const removeRows: number[] = [];\n for (let i = 0, l = rowArray.length; i < l; i++) {\n if (this._selectedRowsLookup[rowArray[i]]) {\n removeRows[removeRows.length] = rowArray[i];\n }\n }\n\n this._grid.setSelectedRows(this._grid.getSelectedRows().filter((n) => removeRows.indexOf(n) < 0), 'SlickCheckboxSelectColumn.deSelectRows');\n }\n\n protected handleHeaderClick(e: DOMEvent, args: any) {\n if (args.column.id === this._options.columnId && e.target.type === 'checkbox') {\n // if editing, try to commit\n if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {\n e.preventDefault();\n e.stopImmediatePropagation();\n return;\n }\n\n let isAllSelected = e.target.checked;\n const caller = isAllSelected ? 'click.selectAll' : 'click.unselectAll';\n const rows: number[] = [];\n\n if (isAllSelected) {\n for (let i = 0; i < this._grid.getDataLength(); i++) {\n // Get the row and check it's a selectable row before pushing it onto the stack\n const rowItem = this._grid.getDataItem(i);\n if (!rowItem.__group && !rowItem.__groupTotals && this.checkSelectableOverride(i, rowItem, this._grid)) {\n rows.push(i);\n }\n }\n isAllSelected = true;\n }\n if (this._isUsingDataView && this._dataView && this._options.applySelectOnAllPages) {\n const ids: Array = [];\n const filteredItems = this._dataView.getFilteredItems();\n for (let j = 0; j < filteredItems.length; j++) {\n // Get the row and check it's a selectable ID (it could be in a different page) before pushing it onto the stack\n const dataviewRowItem: T = filteredItems[j];\n if (this.checkSelectableOverride(j, dataviewRowItem, this._grid)) {\n ids.push(dataviewRowItem[this._dataView.getIdPropertyName() as keyof T] as number | string);\n }\n }\n this._dataView.setSelectedIds(ids, { isRowBeingAdded: isAllSelected });\n }\n this._grid.setSelectedRows(rows, caller);\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n\n protected getCheckboxColumnCellIndex() {\n if (this._checkboxColumnCellIndex === null) {\n this._checkboxColumnCellIndex = 0;\n const colArr = this._grid.getColumns();\n for (let i = 0; i < colArr.length; i++) {\n if (colArr[i].id === this._options.columnId) {\n this._checkboxColumnCellIndex = i;\n }\n }\n }\n return this._checkboxColumnCellIndex;\n }\n\n getColumnDefinition() {\n return {\n id: this._options.columnId,\n name: (this._options.hideSelectAllCheckbox || this._options.hideInColumnTitleRow) ? '' : ``,\n toolTip: (this._options.hideSelectAllCheckbox || this._options.hideInColumnTitleRow) ? '' : this._options.toolTip,\n field: \"sel\",\n width: this._options.width,\n resizable: false,\n sortable: false,\n cssClass: this._options.cssClass,\n hideSelectAllCheckbox: this._options.hideSelectAllCheckbox,\n formatter: this.checkboxSelectionFormatter.bind(this),\n // exclude from all menus, defaults to true unless the option is provided differently by the user\n excludeFromColumnPicker: this._options.excludeFromColumnPicker ?? true,\n excludeFromGridMenu: this._options.excludeFromGridMenu ?? true,\n excludeFromHeaderMenu: this._options.excludeFromHeaderMenu ?? true,\n };\n }\n\n protected addCheckboxToFilterHeaderRow(grid: SlickGrid) {\n this._handler.subscribe(grid.onHeaderRowCellRendered, (_e: any, args: any) => {\n if (args.column.field === \"sel\") {\n Utils.emptyElement(args.node);\n const spanElm = document.createElement('span');\n spanElm.id = 'filter-checkbox-selectall-container';\n\n const inputElm = document.createElement('input');\n inputElm.type = 'checkbox';\n inputElm.id = `header-filter-selector${this._selectAll_UID}`;\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `header-filter-selector${this._selectAll_UID}`;\n\n spanElm.appendChild(inputElm);\n spanElm.appendChild(labelElm);\n args.node.appendChild(spanElm);\n this._headerRowNode = args.node;\n\n this._bindingEventService.bind(spanElm, 'click', ((e: DOMEvent) => this.handleHeaderClick(e, args)) as EventListener);\n }\n });\n }\n\n protected createUID() {\n return Math.round(10000000 * Math.random());\n }\n\n protected checkboxSelectionFormatter(row: number, _cell: number, _val: any, _columnDef: Column, dataContext: any, grid: SlickGrid) {\n const UID = this.createUID() + row;\n\n if (dataContext) {\n if (!this.checkSelectableOverride(row, dataContext, grid)) {\n return null;\n } else {\n return this._selectedRowsLookup[row]\n ? ``\n : ``;\n }\n }\n return null;\n }\n\n protected checkSelectableOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._selectableOverride === 'function') {\n return this._selectableOverride(row, dataContext, grid);\n }\n return true;\n }\n\n protected renderSelectAllCheckbox(isSelectAllChecked?: boolean) {\n if (isSelectAllChecked) {\n this._grid.updateColumnHeader(this._options.columnId || '', ``, this._options.toolTip);\n } else {\n this._grid.updateColumnHeader(this._options.columnId || '', ``, this._options.toolTip);\n }\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row a selectable row.\n * In order word, user can choose which rows to be selectable or not by providing his own logic.\n * @param overrideFn: override function callback\n */\n selectableOverride(overrideFn: SelectableOverrideCallback) {\n this._selectableOverride = overrideFn;\n }\n\n\n // Utils.extend(this, {\n // \"init\": init,\n // \"destroy\": destroy,\n // \"deSelectRows\": deSelectRows,\n // \"selectRows\": selectRows,\n // \"getColumnDefinition\": getColumnDefinition,\n // \"getOptions\": getOptions,\n // \"selectableOverride\": selectableOverride,\n // \"setOptions\": setOptions,\n // });\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CheckboxSelectColumn: SlickCheckboxSelectColumn\n }\n });\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.contextmenu.js b/dist/browser/plugins/slick.contextmenu.js index 32b1a56a7..b783ecfa5 100644 --- a/dist/browser/plugins/slick.contextmenu.js +++ b/dist/browser/plugins/slick.contextmenu.js @@ -17,6 +17,7 @@ __publicField(this, "onOptionSelected", new SlickEvent()); // -- // protected props + __publicField(this, "_bindingEventService", new BindingEventService()); __publicField(this, "_contextMenuProperties"); __publicField(this, "_currentCell", -1); __publicField(this, "_currentRow", -1); @@ -26,8 +27,9 @@ __publicField(this, "_handler", new EventHandler()); __publicField(this, "_commandTitleElm"); __publicField(this, "_optionTitleElm"); + __publicField(this, "_lastMenuTypeClicked", ""); __publicField(this, "_menuElm"); - __publicField(this, "_bindingEventService", new BindingEventService()); + __publicField(this, "_subMenuParentId", ""); __publicField(this, "_defaults", { autoAdjustDrop: !0, // dropup/dropdown @@ -53,61 +55,93 @@ var _a; this.onAfterMenuShow.unsubscribe(), this.onBeforeMenuShow.unsubscribe(), this.onBeforeMenuClose.unsubscribe(), this.onCommand.unsubscribe(), this.onOptionSelected.unsubscribe(), this._handler.unsubscribeAll(), this._bindingEventService.unbindAll(), (_a = this._menuElm) == null || _a.remove(), this._commandTitleElm = null, this._optionTitleElm = null, this._menuElm = null; } - createMenu(evt) { - var _a, _b, _c, _d, _e, _f, _g, _h; + createParentMenu(evt) { + var _a, _b, _c, _d, _e, _f; let e = evt instanceof SlickEventData ? evt.getNativeEvent() : evt, targetEvent = (_b = (_a = e.touches) == null ? void 0 : _a[0]) != null ? _b : e, cell = this._grid.getCellFromEvent(e); this._currentCell = (_c = cell == null ? void 0 : cell.cell) != null ? _c : 0, this._currentRow = (_d = cell == null ? void 0 : cell.row) != null ? _d : 0; - let columnDef = this._grid.getColumns()[this._currentCell], dataContext = this._grid.getDataItem(this._currentRow), isColumnOptionAllowed = this.checkIsColumnAllowed((_e = this._contextMenuProperties.optionShownOverColumnIds) != null ? _e : [], columnDef.id), isColumnCommandAllowed = this.checkIsColumnAllowed((_f = this._contextMenuProperties.commandShownOverColumnIds) != null ? _f : [], columnDef.id), commandItems = this._contextMenuProperties.commandItems || [], optionItems = this._contextMenuProperties.optionItems || []; - if (!columnDef || !isColumnCommandAllowed && !isColumnOptionAllowed || !commandItems.length && !optionItems.length || (this.destroyMenu(e), this.onBeforeMenuShow.notify({ + let columnDef = this._grid.getColumns()[this._currentCell], isColumnOptionAllowed = this.checkIsColumnAllowed((_e = this._contextMenuProperties.optionShownOverColumnIds) != null ? _e : [], columnDef.id), isColumnCommandAllowed = this.checkIsColumnAllowed((_f = this._contextMenuProperties.commandShownOverColumnIds) != null ? _f : [], columnDef.id), commandItems = this._contextMenuProperties.commandItems || [], optionItems = this._contextMenuProperties.optionItems || []; + if (!(!columnDef || !isColumnCommandAllowed && !isColumnOptionAllowed || !commandItems.length && !optionItems.length) && (this.destroyMenu(e), this.onBeforeMenuShow.notify({ cell: this._currentCell, row: this._currentRow, grid: this._grid - }, e, this).getReturnValue() == !1)) - return; - let maxHeight = isNaN(this._contextMenuProperties.maxHeight) ? this._contextMenuProperties.maxHeight : `${(_g = this._contextMenuProperties.maxHeight) != null ? _g : 0}px`, width = isNaN(this._contextMenuProperties.width) ? this._contextMenuProperties.width : `${(_h = this._contextMenuProperties.maxWidth) != null ? _h : 0}px`; - this._menuElm = document.createElement("div"), this._menuElm.className = `slick-context-menu ${this._gridUid}`, this._menuElm.role = "menu", width && (this._menuElm.style.width = width), maxHeight && (this._menuElm.style.maxHeight = maxHeight), this._menuElm.style.top = `${targetEvent.pageY}px`, this._menuElm.style.left = `${targetEvent.pageX}px`, this._menuElm.style.display = "none"; - let closeButtonElm = document.createElement("button"); - closeButtonElm.type = "button", closeButtonElm.className = "close", closeButtonElm.dataset.dismiss = "slick-context-menu", closeButtonElm.ariaLabel = "Close"; - let spanCloseElm = document.createElement("span"); - if (spanCloseElm.className = "close", spanCloseElm.ariaHidden = "true", spanCloseElm.innerHTML = "×", closeButtonElm.appendChild(spanCloseElm), !this._contextMenuProperties.hideOptionSection && isColumnOptionAllowed && optionItems.length > 0) { + }, e, this).getReturnValue() !== !1 && (this._menuElm = this.createMenu(commandItems, optionItems), this._menuElm.style.top = `${targetEvent.pageY}px`, this._menuElm.style.left = `${targetEvent.pageX}px`, this._menuElm.style.display = "block", document.body.appendChild(this._menuElm), this.onAfterMenuShow.notify({ + cell: this._currentCell, + row: this._currentRow, + grid: this._grid + }, e, this).getReturnValue() !== !1))) + return this._menuElm; + } + createMenu(commandItems, optionItems, level = 0, item) { + var _a, _b, _c, _d; + let columnDef = this._grid.getColumns()[this._currentCell], dataContext = this._grid.getDataItem(this._currentRow), isColumnOptionAllowed = this.checkIsColumnAllowed((_a = this._contextMenuProperties.optionShownOverColumnIds) != null ? _a : [], columnDef.id), isColumnCommandAllowed = this.checkIsColumnAllowed((_b = this._contextMenuProperties.commandShownOverColumnIds) != null ? _b : [], columnDef.id), maxHeight = isNaN(this._contextMenuProperties.maxHeight) ? this._contextMenuProperties.maxHeight : `${(_c = this._contextMenuProperties.maxHeight) != null ? _c : 0}px`, width = isNaN(this._contextMenuProperties.width) ? this._contextMenuProperties.width : `${(_d = this._contextMenuProperties.maxWidth) != null ? _d : 0}px`, subMenuCommand = item == null ? void 0 : item.command, subMenuId = level === 1 && subMenuCommand ? subMenuCommand.replaceAll(" ", "") : ""; + subMenuId && (this._subMenuParentId = subMenuId), level > 1 && (subMenuId = this._subMenuParentId); + let menuClasses = `slick-context-menu slick-menu-level-${level} ${this._gridUid}`, bodyMenuElm = document.body.querySelector(`.slick-context-menu.slick-menu-level-${level}${this.getGridUidSelector()}`); + if (bodyMenuElm) { + if (bodyMenuElm.dataset.subMenuParent === subMenuId) + return bodyMenuElm; + this.destroySubMenus(); + } + let menuElm = document.createElement("div"); + menuElm.className = menuClasses, level > 0 && (menuElm.classList.add("slick-submenu"), subMenuId && (menuElm.dataset.subMenuParent = subMenuId)), menuElm.ariaLabel = level > 1 ? "SubMenu" : "Context Menu", menuElm.role = "menu", width && (menuElm.style.width = width), maxHeight && (menuElm.style.maxHeight = maxHeight), menuElm.style.display = "none"; + let closeButtonElm = null; + if (level === 0) { + closeButtonElm = document.createElement("button"), closeButtonElm.type = "button", closeButtonElm.className = "close", closeButtonElm.dataset.dismiss = "slick-context-menu", closeButtonElm.ariaLabel = "Close"; + let spanCloseElm = document.createElement("span"); + spanCloseElm.className = "close", spanCloseElm.ariaHidden = "true", spanCloseElm.innerHTML = "×", closeButtonElm.appendChild(spanCloseElm); + } + if (!this._contextMenuProperties.hideOptionSection && isColumnOptionAllowed && optionItems.length > 0) { let optionMenuElm = document.createElement("div"); - optionMenuElm.className = "slick-context-menu-option-list", optionMenuElm.role = "menu", this._contextMenuProperties.hideCloseButton || (this._bindingEventService.bind(closeButtonElm, "click", this.handleCloseButtonClicked.bind(this)), this._menuElm.appendChild(closeButtonElm)), this._menuElm.appendChild(optionMenuElm), this.populateOptionItems( + optionMenuElm.className = "slick-context-menu-option-list", optionMenuElm.role = "menu", item && level > 0 && this.addSubMenuTitleWhenExists(item, optionMenuElm), closeButtonElm && !this._contextMenuProperties.hideCloseButton && (this._bindingEventService.bind(closeButtonElm, "click", this.handleCloseButtonClicked.bind(this)), menuElm.appendChild(closeButtonElm)), menuElm.appendChild(optionMenuElm), this.populateCommandOrOptionItems( + "option", this._contextMenuProperties, optionMenuElm, optionItems, - { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid } + { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid, level } ); } if (!this._contextMenuProperties.hideCommandSection && isColumnCommandAllowed && commandItems.length > 0) { let commandMenuElm = document.createElement("div"); - commandMenuElm.className = "slick-context-menu-command-list", commandMenuElm.role = "menu", !this._contextMenuProperties.hideCloseButton && (!isColumnOptionAllowed || optionItems.length === 0 || this._contextMenuProperties.hideOptionSection) && (this._bindingEventService.bind(closeButtonElm, "click", this.handleCloseButtonClicked.bind(this)), this._menuElm.appendChild(closeButtonElm)), this._menuElm.appendChild(commandMenuElm), this.populateCommandItems( + commandMenuElm.className = "slick-context-menu-command-list", commandMenuElm.role = "menu", item && level > 0 && this.addSubMenuTitleWhenExists(item, commandMenuElm), closeButtonElm && !this._contextMenuProperties.hideCloseButton && (!isColumnOptionAllowed || optionItems.length === 0 || this._contextMenuProperties.hideOptionSection) && (this._bindingEventService.bind(closeButtonElm, "click", this.handleCloseButtonClicked.bind(this)), menuElm.appendChild(closeButtonElm)), menuElm.appendChild(commandMenuElm), this.populateCommandOrOptionItems( + "command", this._contextMenuProperties, commandMenuElm, commandItems, - { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid } + { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid, level } ); } - if (this._menuElm.style.display = "block", document.body.appendChild(this._menuElm), this.onAfterMenuShow.notify({ - cell: this._currentCell, - row: this._currentRow, - grid: this._grid - }, e, this).getReturnValue() != !1) - return this._menuElm; + return level++, menuElm; + } + addSubMenuTitleWhenExists(item, commandOrOptionMenu) { + if (item !== "divider" && (item != null && item.subMenuTitle)) { + let subMenuTitleElm = document.createElement("div"); + subMenuTitleElm.className = "slick-menu-title", subMenuTitleElm.textContent = item.subMenuTitle; + let subMenuTitleClass = item.subMenuTitleCssClass; + subMenuTitleClass && subMenuTitleElm.classList.add(...subMenuTitleClass.split(" ")), commandOrOptionMenu.appendChild(subMenuTitleElm); + } } handleCloseButtonClicked(e) { e.defaultPrevented || this.destroyMenu(e); } destroyMenu(e, args) { var _a, _b, _c; - if (this._menuElm = this._menuElm || document.querySelector(`.slick-context-menu.${this._gridUid}`), (_a = this._menuElm) != null && _a.remove) { + if (this._menuElm = this._menuElm || document.querySelector(`.slick-context-menu${this.getGridUidSelector()}`), (_a = this._menuElm) != null && _a.remove) { if (this.onBeforeMenuClose.notify({ cell: (_b = args == null ? void 0 : args.cell) != null ? _b : 0, row: (_c = args == null ? void 0 : args.row) != null ? _c : 0, grid: this._grid - }, e, this).getReturnValue() == !1) + }, e, this).getReturnValue() === !1) return; this._menuElm.remove(), this._menuElm = null; } + this.destroySubMenus(); + } + /** Destroy all parent menus and any sub-menus */ + destroyAllMenus() { + this.destroySubMenus(), document.querySelectorAll(`.slick-context-menu${this.getGridUidSelector()}`).forEach((subElm) => subElm.remove()); + } + /** Close and destroy all previously opened sub-menus */ + destroySubMenus() { + document.querySelectorAll(`.slick-context-menu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => subElm.remove()); } checkIsColumnAllowed(columnIds, columnId) { let isAllowedColumn = !1; @@ -118,7 +152,12 @@ isAllowedColumn = !0; return isAllowedColumn; } + getGridUidSelector() { + let gridUid = this._grid.getUID() || ""; + return gridUid ? `.${gridUid}` : ""; + } handleOnContextMenu(evt, args) { + this.destroyAllMenus(); let e = evt instanceof SlickEventData ? evt.getNativeEvent() : evt; e.preventDefault(); let cell = this._grid.getCellFromEvent(e); @@ -126,99 +165,87 @@ let columnDef = this._grid.getColumns()[cell.cell], dataContext = this._grid.getDataItem(cell.row); if (args = args || {}, args.cell = cell.cell, args.row = cell.row, args.column = columnDef, args.dataContext = dataContext, args.grid = this._grid, !this.runOverrideFunctionWhenExists(this._contextMenuProperties.menuUsabilityOverride, args)) return; - this._menuElm = this.createMenu(e), this._menuElm && (this.repositionMenu(e), this._menuElm.style.display = "block"), this._bindingEventService.bind(document.body, "click", (e2) => { - e2.defaultPrevented || this.destroyMenu(e2, { cell: this._currentCell, row: this._currentRow }); - }); + this._menuElm = this.createParentMenu(e), this._menuElm && (this.repositionMenu(e, this._menuElm), this._menuElm.style.display = "block"), this._bindingEventService.bind(document.body, "mousedown", this.handleBodyMouseDown.bind(this)); } } - /** Construct the Option Items section. */ - populateOptionItems(contextMenu, optionMenuElm, optionItems, args) { - if (!(!args || !optionItems || !contextMenu)) { - contextMenu != null && contextMenu.optionTitle && (this._optionTitleElm = document.createElement("div"), this._optionTitleElm.className = "title", this._optionTitleElm.textContent = contextMenu.optionTitle, optionMenuElm.appendChild(this._optionTitleElm)); - for (let i = 0, ln = optionItems.length; i < ln; i++) { - let addClickListener = !0, item = optionItems[i], isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, args), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, args); - if (!isItemVisible) - continue; - Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable); - let liElm = document.createElement("div"); - liElm.className = "slick-context-menu-item", liElm.role = "menuitem", (item.divider || item === "divider") && (liElm.classList.add("slick-context-menu-item-divider"), addClickListener = !1), (item.disabled || !isItemUsable) && liElm.classList.add("slick-context-menu-item-disabled"), item.hidden && liElm.classList.add("slick-context-menu-item-hidden"), item.cssClass && liElm.classList.add(...item.cssClass.split(" ")), item.tooltip && (liElm.title = item.tooltip || ""); - let iconElm = document.createElement("div"); - iconElm.role = "button", iconElm.className = "slick-context-menu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...item.iconCssClass.split(" ")), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`); - let textElm = document.createElement("span"); - textElm.className = "slick-context-menu-content", textElm.textContent = item.title || "", liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), optionMenuElm.appendChild(liElm), addClickListener && this._bindingEventService.bind(liElm, "click", this.handleMenuItemOptionClick.bind(this, item)); - } - } + /** When users click outside the Cell Menu, we will typically close the Cell Menu (and any sub-menus) */ + handleBodyMouseDown(e) { + var _a; + let isMenuClicked = !1; + (_a = this._menuElm) != null && _a.contains(e.target) && (isMenuClicked = !0), isMenuClicked || document.querySelectorAll(`.slick-context-menu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => { + subElm.contains(e.target) && (isMenuClicked = !0); + }), this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented && this.destroyMenu(e, { cell: this._currentCell, row: this._currentRow }); } /** Construct the Command Items section. */ - populateCommandItems(contextMenu, commandMenuElm, commandItems, args) { - if (!(!args || !commandItems || !contextMenu)) { - contextMenu != null && contextMenu.commandTitle && (this._commandTitleElm = document.createElement("div"), this._commandTitleElm.className = "title", this._commandTitleElm.textContent = contextMenu.commandTitle, commandMenuElm.appendChild(this._commandTitleElm)); - for (let i = 0, ln = commandItems.length; i < ln; i++) { - let addClickListener = !0, item = commandItems[i], isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, args), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, args); - if (!isItemVisible) - continue; - Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable); - let liElm = document.createElement("div"); - liElm.className = "slick-context-menu-item", liElm.role = "menuitem", (item.divider || item === "divider") && (liElm.classList.add("slick-context-menu-item-divider"), addClickListener = !1), (item.disabled || !isItemUsable) && liElm.classList.add("slick-context-menu-item-disabled"), item.hidden && liElm.classList.add("slick-context-menu-item-hidden"), item.cssClass && liElm.classList.add(...item.cssClass.split(" ")), item.tooltip && (liElm.title = item.tooltip || ""); - let iconElm = document.createElement("div"); - iconElm.className = "slick-context-menu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...item.iconCssClass.split(" ")), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`); - let textElm = document.createElement("span"); - textElm.className = "slick-context-menu-content", textElm.textContent = item.title || "", liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), commandMenuElm.appendChild(liElm), addClickListener && this._bindingEventService.bind(liElm, "click", this.handleMenuItemCommandClick.bind(this, item)); + populateCommandOrOptionItems(itemType, contextMenu, commandOrOptionMenuElm, commandOrOptionItems, args) { + if (!args || !commandOrOptionItems || !contextMenu) + return; + let isSubMenu = args.level > 0; + contextMenu != null && contextMenu[`${itemType}Title`] && !isSubMenu && (this[`_${itemType}TitleElm`] = document.createElement("div"), this[`_${itemType}TitleElm`].className = "slick-menu-title", this[`_${itemType}TitleElm`].textContent = contextMenu[`${itemType}Title`], commandOrOptionMenuElm.appendChild(this[`_${itemType}TitleElm`])); + for (let i = 0, ln = commandOrOptionItems.length; i < ln; i++) { + let addClickListener = !0, item = commandOrOptionItems[i], isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, args), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, args); + if (!isItemVisible) + continue; + Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable); + let liElm = document.createElement("div"); + liElm.className = "slick-context-menu-item", liElm.role = "menuitem", (item.divider || item === "divider") && (liElm.classList.add("slick-context-menu-item-divider"), addClickListener = !1), (item.disabled || !isItemUsable) && liElm.classList.add("slick-context-menu-item-disabled"), item.hidden && liElm.classList.add("slick-context-menu-item-hidden"), item.cssClass && liElm.classList.add(...item.cssClass.split(" ")), item.tooltip && (liElm.title = item.tooltip || ""); + let iconElm = document.createElement("div"); + iconElm.className = "slick-context-menu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...item.iconCssClass.split(" ")), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`); + let textElm = document.createElement("span"); + if (textElm.className = "slick-context-menu-content", textElm.textContent = item.title || "", liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), commandOrOptionMenuElm.appendChild(liElm), addClickListener && this._bindingEventService.bind(liElm, "click", this.handleMenuItemClick.bind(this, item, itemType, args.level)), item.commandItems || item.optionItems) { + let chevronElm = document.createElement("span"); + chevronElm.className = "sub-item-chevron", this._contextMenuProperties.subItemChevronClass ? chevronElm.classList.add(...this._contextMenuProperties.subItemChevronClass.split(" ")) : chevronElm.textContent = "\u2B9E", liElm.classList.add("slick-submenu-item"), liElm.appendChild(chevronElm); + continue; } } } - handleMenuItemCommandClick(item, e) { - if (!item || item.disabled || item.divider) - return; - let command = item.command || "", row = this._currentRow, cell = this._currentCell, columnDef = this._grid.getColumns()[cell], dataContext = this._grid.getDataItem(row), cellValue; - if (Object.prototype.hasOwnProperty.call(dataContext, columnDef == null ? void 0 : columnDef.field) && (cellValue = dataContext[columnDef.field]), command !== null && command !== "") { - let callbackArgs = { - cell, - row, - grid: this._grid, - command, - item, - column: columnDef, - dataContext, - value: cellValue - }; - this.onCommand.notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs); + handleMenuItemClick(item, type, level = 0, e) { + if ((item == null ? void 0 : item[type]) !== void 0 && item !== "divider" && !item.disabled && !item.divider && this._currentCell !== void 0 && this._currentRow !== void 0) { + if (type === "option" && !this._grid.getEditorLock().commitCurrentEdit()) + return; + let optionOrCommand = item[type] !== void 0 ? item[type] : "", row = this._currentRow, cell = this._currentCell, columnDef = this._grid.getColumns()[cell], dataContext = this._grid.getDataItem(row), cellValue; + if (Object.prototype.hasOwnProperty.call(dataContext, columnDef == null ? void 0 : columnDef.field) && (cellValue = dataContext[columnDef.field]), optionOrCommand !== void 0 && !item[`${type}Items`]) { + let callbackArgs = { + cell, + row, + grid: this._grid, + [type]: optionOrCommand, + item, + column: columnDef, + dataContext, + value: cellValue + }; + this[type === "command" ? "onCommand" : "onOptionSelected"].notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs), e.defaultPrevented || this.destroyMenu(e, { cell, row }); + } else + item.commandItems || item.optionItems ? this.repositionSubMenu(item, type, level, e) : this.destroySubMenus(); + this._lastMenuTypeClicked = type; } } - handleMenuItemOptionClick(item, e) { - if (item.disabled || item.divider || !this._grid.getEditorLock().commitCurrentEdit()) - return; - let option = item.option !== void 0 ? item.option : "", row = this._currentRow, cell = this._currentCell, columnDef = this._grid.getColumns()[cell], dataContext = this._grid.getDataItem(row); - if (option !== void 0) { - let callbackArgs = { - cell, - row, - grid: this._grid, - option, - item, - column: columnDef, - dataContext - }; - this.onOptionSelected.notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs); - } + repositionSubMenu(item, type, level, e) { + (e.target.classList.contains("slick-cell") || this._lastMenuTypeClicked !== type) && this.destroySubMenus(); + let subMenuElm = this.createMenu((item == null ? void 0 : item.commandItems) || [], (item == null ? void 0 : item.optionItems) || [], level + 1, item); + subMenuElm.style.display = "block", document.body.appendChild(subMenuElm), this.repositionMenu(e, subMenuElm); } /** * Reposition the menu drop (up/down) and the side (left/right) * @param {*} event */ - repositionMenu(e) { - var _a, _b, _c, _d, _e; - if (this._menuElm && e.target) { - let targetEvent = (_b = (_a = e.touches) == null ? void 0 : _a[0]) != null ? _b : e, parentElm = e.target.closest(".slick-cell"), parentOffset = parentElm && Utils.offset(parentElm), menuOffsetLeft = targetEvent.pageX, menuOffsetTop = parentElm ? (_c = parentOffset == null ? void 0 : parentOffset.top) != null ? _c : 0 : targetEvent.pageY, menuHeight = ((_d = this._menuElm) == null ? void 0 : _d.offsetHeight) || 0, menuWidth = ((_e = this._menuElm) == null ? void 0 : _e.offsetWidth) || this._contextMenuProperties.width || 0, rowHeight = this._gridOptions.rowHeight, dropOffset = this._contextMenuProperties.autoAdjustDropOffset, sideOffset = this._contextMenuProperties.autoAlignSideOffset; + repositionMenu(e, menuElm) { + var _a, _b, _c, _d; + let isSubMenu = menuElm.classList.contains("slick-submenu"), targetEvent = (_b = (_a = e.touches) == null ? void 0 : _a[0]) != null ? _b : e, parentElm = isSubMenu ? e.target.closest(".slick-context-menu-item") : e.target.closest(".slick-cell"); + if (menuElm && parentElm) { + let parentOffset = Utils.offset(parentElm), menuOffsetLeft = isSubMenu && parentElm ? (_c = parentOffset == null ? void 0 : parentOffset.left) != null ? _c : 0 : targetEvent.pageX, menuOffsetTop = parentElm ? (_d = parentOffset == null ? void 0 : parentOffset.top) != null ? _d : 0 : targetEvent.pageY, menuHeight = (menuElm == null ? void 0 : menuElm.offsetHeight) || 0, menuWidth = Number((menuElm == null ? void 0 : menuElm.offsetWidth) || this._contextMenuProperties.width || 0), rowHeight = this._gridOptions.rowHeight, dropOffset = Number(this._contextMenuProperties.autoAdjustDropOffset || 0), sideOffset = Number(this._contextMenuProperties.autoAlignSideOffset || 0); if (this._contextMenuProperties.autoAdjustDrop) { - let spaceBottom = Utils.calculateAvailableSpace(parentElm).bottom, spaceTop = Utils.calculateAvailableSpace(parentElm).top, spaceBottomRemaining = spaceBottom + (dropOffset || 0) - rowHeight, spaceTopRemaining = spaceTop - (dropOffset || 0) + rowHeight; - (spaceBottomRemaining < menuHeight && spaceTopRemaining > spaceBottomRemaining ? "top" : "bottom") === "top" ? (this._menuElm.classList.remove("dropdown"), this._menuElm.classList.add("dropup"), menuOffsetTop = menuOffsetTop - menuHeight - (dropOffset || 0)) : (this._menuElm.classList.remove("dropup"), this._menuElm.classList.add("dropdown"), menuOffsetTop = menuOffsetTop + rowHeight + (dropOffset || 0)); + let spaceBottom = Utils.calculateAvailableSpace(parentElm).bottom, spaceTop = Utils.calculateAvailableSpace(parentElm).top, spaceBottomRemaining = spaceBottom + dropOffset - rowHeight, spaceTopRemaining = spaceTop - dropOffset + rowHeight; + (spaceBottomRemaining < menuHeight && spaceTopRemaining > spaceBottomRemaining ? "top" : "bottom") === "top" ? (menuElm.classList.remove("dropdown"), menuElm.classList.add("dropup"), isSubMenu ? menuOffsetTop -= menuHeight - dropOffset - parentElm.clientHeight : menuOffsetTop -= menuHeight - dropOffset) : (menuElm.classList.remove("dropup"), menuElm.classList.add("dropdown"), isSubMenu ? menuOffsetTop += dropOffset : menuOffsetTop += rowHeight + dropOffset); } if (this._contextMenuProperties.autoAlignSide) { - let gridPos = this._grid.getGridPosition(); - (menuOffsetLeft + +menuWidth >= gridPos.width ? "left" : "right") === "left" ? (this._menuElm.classList.remove("dropright"), this._menuElm.classList.add("dropleft"), menuOffsetLeft = menuOffsetLeft - +menuWidth - (sideOffset || 0)) : (this._menuElm.classList.remove("dropleft"), this._menuElm.classList.add("dropright"), menuOffsetLeft = menuOffsetLeft + (sideOffset || 0)); + let gridPos = this._grid.getGridPosition(), subMenuPosCalc = menuOffsetLeft + Number(menuWidth); + isSubMenu && (subMenuPosCalc += parentElm.clientWidth); + let browserWidth = document.documentElement.clientWidth; + (subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth ? "left" : "right") === "left" ? (menuElm.classList.remove("dropright"), menuElm.classList.add("dropleft"), menuOffsetLeft -= menuWidth - sideOffset) : (menuElm.classList.remove("dropleft"), menuElm.classList.add("dropright"), isSubMenu ? menuOffsetLeft += sideOffset + parentElm.offsetWidth : menuOffsetLeft += sideOffset); } - this._menuElm.style.top = `${menuOffsetTop}px`, this._menuElm.style.left = `${menuOffsetLeft}px`; + menuElm.style.top = `${menuOffsetTop}px`, menuElm.style.left = `${menuOffsetLeft}px`; } } /** diff --git a/dist/browser/plugins/slick.contextmenu.js.map b/dist/browser/plugins/slick.contextmenu.js.map index 0c2d4cc11..46f86f3a1 100644 --- a/dist/browser/plugins/slick.contextmenu.js.map +++ b/dist/browser/plugins/slick.contextmenu.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.contextmenu.ts"], - "sourcesContent": ["import {\n BindingEventService as BindingEventService_,\n SlickEvent as SlickEvent_,\n SlickEventData as SlickEventData_,\n SlickEventHandler as SlickEventHandler_,\n Utils as Utils_\n} from '../slick.core';\nimport type {\n ContextMenuOption,\n DOMMouseOrTouchEvent,\n GridOption,\n MenuCommandItem,\n MenuCommandItemCallbackArgs,\n MenuFromCellCallbackArgs,\n MenuOptionItem,\n MenuOptionItemCallbackArgs,\n Plugin\n} from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst EventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add Context Menu (mouse right+click), it subscribes to the cell \"onContextMenu\" event.\n * The \"contextMenu\" is defined in the Grid Options object\n * You can use it to change a data property (only 1) through a list of Options AND/OR through a list of Commands.\n * A good example of a Command would be an Export to CSV, that can be run from anywhere in the grid by doing a mouse right+click\n *\n * Note:\n * There is only 1 list of Options, so typically that would be use for 1 column\n * if you plan to use different Options for different columns, then the CellMenu plugin might be better suited.\n *\n * USAGE:\n *\n * Add the slick.contextmenu.(js|css) files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n * var contextMenuPlugin = new Slick.Plugins.ContextMenu(columns, grid, options);\n *\n * Available grid options, by defining a contextMenu object:\n *\n * var options = {\n * enableCellNavigation: true,\n * contextMenu: {\n * optionTitle: 'Change Priority',\n * optionShownOverColumnIds: [\"priority\"],\n * optionItems: [\n * { option: 0, title: 'none', cssClass: 'italic' },\n * { divider: true },\n * \"divider\" // just the string is also accepted\n * { option: 1, iconCssClass: 'fa fa-fire grey', title: 'Low' },\n * { option: 3, iconCssClass: 'fa fa-fire red', title: 'High' },\n * { option: 2, iconCssClass: 'fa fa-fire orange', title: 'Medium' },\n * { option: 4, iconCssClass: 'fa fa-fire', title: 'Extreme', disabled: true },\n * ],\n * commandTitle: 'Commands',\n * commandShownOverColumnIds: [\"title\", \"complete\", \"start\", \"finish\", \"effortDriven\"],\n * commandItems: [\n * { command: 'export-excel', title: 'Export to CSV', iconCssClass: 'fa fa-file-excel-o', cssClass: '' },\n * { command: 'delete-row', title: 'Delete Row', cssClass: 'bold', textCssClass: 'red' },\n * { command: 'help', title: 'Help', iconCssClass: 'fa fa-question-circle',},\n * { divider: true },\n * ],\n * }\n * };\n *\n *\n * Available contextMenu properties:\n * commandTitle: Title of the Command section (optional)\n * commandItems: Array of Command item objects (command/title pair)\n * commandShownOverColumnIds: Define which column to show the Commands list. If not defined (defaults), the menu will be shown over all columns\n * optionTitle: Title of the Option section (optional)\n * optionItems: Array of Options item objects (option/title pair)\n * optionShownOverColumnIds: Define which column to show the Options list. If not defined (defaults), the menu will be shown over all columns\n * hideCloseButton: Hide the Close button on top right (defaults to false)\n * hideCommandSection: Hide the Commands section even when the commandItems array is filled (defaults to false)\n * hideMenuOnScroll: Do we want to hide the Cell Menu when a scrolling event occurs (defaults to false)?\n * hideOptionSection: Hide the Options section even when the optionItems array is filled (defaults to false)\n * maxHeight: Maximum height that the drop menu will have, can be a number (250) or text (\"none\")\n * width: Width that the drop menu will have, can be a number (250) or text (defaults to \"auto\")\n * autoAdjustDrop: Auto-align dropup or dropdown menu to the left or right depending on grid viewport available space (defaults to true)\n * autoAdjustDropOffset: Optionally add an offset to the auto-align of the drop menu (defaults to -4)\n * autoAlignSide: Auto-align drop menu to the left or right depending on grid viewport available space (defaults to true)\n * autoAlignSideOffset: Optionally add an offset to the left/right side auto-align (defaults to 0)\n * menuUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling the menu from being usable (must be combined with a custom formatter)\n *\n *\n * Available menu Command/Option item properties:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * command: A command identifier to be passed to the onCommand event handlers (when using \"commandItems\").\n * option: An option to be passed to the onOptionSelected event handlers (when using \"optionItems\").\n * title: Menu item text.\n * divider: Boolean which tell if the current item is a divider, not an actual command. You could also pass \"divider\" instead of an object\n * disabled: Whether the item/command is disabled.\n * hidden: Whether the item/command is hidden.\n * tooltip: Item tooltip.\n * cssClass: A CSS class to be added to the menu item container.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * textCssClass: A CSS class to be added to the menu item text.\n * iconImage: A url to the icon image.\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n * The plugin exposes the following events:\n *\n * onAfterMenuShow: Fired after the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n *\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n *\n * onBeforeMenuClose: Fired when the menu is closing.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * menu: Menu DOM element\n *\n * onCommand: Fired on menu option clicked from the Command items list\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * command: Menu command identified.\n * item: Menu item selected\n * column: Cell Column definition\n * dataContext: Cell Data Context (data object)\n * value: Value of the cell we triggered the context menu from\n *\n * onOptionSelected: Fired on menu option clicked from the Option items list\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * option: Menu option selected.\n * item: Menu item selected\n * column: Cell Column definition\n * dataContext: Cell Data Context (data object)\n *\n *\n * @param options {Object} Context Menu Options\n * @class Slick.Plugins.ContextMenu\n */\nexport class SlickContextMenu implements Plugin {\n // --\n // public API\n pluginName = 'ContextMenu' as const;\n onAfterMenuShow = new SlickEvent();\n onBeforeMenuShow = new SlickEvent();\n onBeforeMenuClose = new SlickEvent();\n onCommand = new SlickEvent();\n onOptionSelected = new SlickEvent();\n\n // --\n // protected props\n protected _contextMenuProperties: ContextMenuOption;\n protected _currentCell = -1;\n protected _currentRow = -1;\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _gridUid = '';\n protected _handler = new EventHandler();\n protected _commandTitleElm?: HTMLSpanElement;\n protected _optionTitleElm?: HTMLSpanElement;\n protected _menuElm?: HTMLDivElement | null;\n protected _bindingEventService = new BindingEventService();\n protected _defaults: ContextMenuOption = {\n autoAdjustDrop: true, // dropup/dropdown\n autoAlignSide: true, // left/right\n autoAdjustDropOffset: -4,\n autoAlignSideOffset: 0,\n hideMenuOnScroll: false,\n maxHeight: 'none',\n width: 'auto',\n optionShownOverColumnIds: [],\n commandShownOverColumnIds: [],\n };\n\n constructor(optionProperties: Partial) {\n this._contextMenuProperties = Utils.extend({}, this._defaults, optionProperties);\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._gridOptions = grid.getOptions();\n this._gridUid = grid?.getUID() || '';\n this._handler.subscribe(this._grid.onContextMenu, this.handleOnContextMenu.bind(this));\n if (this._contextMenuProperties.hideMenuOnScroll) {\n this._handler.subscribe(this._grid.onScroll, this.destroyMenu.bind(this));\n }\n }\n\n setOptions(newOptions: Partial) {\n this._contextMenuProperties = Utils.extend({}, this._contextMenuProperties, newOptions);\n\n // on the array properties, we want to make sure to overwrite them and not just extending them\n if (newOptions.commandShownOverColumnIds) {\n this._contextMenuProperties.commandShownOverColumnIds = newOptions.commandShownOverColumnIds;\n }\n if (newOptions.optionShownOverColumnIds) {\n this._contextMenuProperties.optionShownOverColumnIds = newOptions.optionShownOverColumnIds;\n }\n }\n\n destroy() {\n this.onAfterMenuShow.unsubscribe();\n this.onBeforeMenuShow.unsubscribe();\n this.onBeforeMenuClose.unsubscribe();\n this.onCommand.unsubscribe();\n this.onOptionSelected.unsubscribe();\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n this._menuElm?.remove();\n this._commandTitleElm = null as any;\n this._optionTitleElm = null as any;\n this._menuElm = null as any;\n }\n\n protected createMenu(evt: SlickEventData_ | MouseEvent) {\n const e = evt instanceof SlickEventData ? evt.getNativeEvent() : evt;\n const targetEvent = (e as TouchEvent).touches?.[0] ?? e;\n const cell = this._grid.getCellFromEvent(e);\n this._currentCell = cell?.cell ?? 0;\n this._currentRow = cell?.row ?? 0;\n const columnDef = this._grid.getColumns()[this._currentCell];\n const dataContext = this._grid.getDataItem(this._currentRow);\n\n const isColumnOptionAllowed = this.checkIsColumnAllowed(this._contextMenuProperties.optionShownOverColumnIds ?? [], columnDef.id);\n const isColumnCommandAllowed = this.checkIsColumnAllowed(this._contextMenuProperties.commandShownOverColumnIds ?? [], columnDef.id);\n const commandItems = this._contextMenuProperties.commandItems || [];\n const optionItems = this._contextMenuProperties.optionItems || [];\n\n // make sure there's at least something to show before creating the Context Menu\n if (!columnDef || (!isColumnCommandAllowed && !isColumnOptionAllowed) || (!commandItems.length && !optionItems.length)) {\n return;\n }\n\n // delete any prior context menu\n this.destroyMenu(e);\n\n // Let the user modify the menu or cancel altogether,\n // or provide alternative menu implementation.\n if (this.onBeforeMenuShow.notify({\n cell: this._currentCell,\n row: this._currentRow,\n grid: this._grid\n }, e, this).getReturnValue() == false) {\n return;\n }\n\n // create a new context menu\n const maxHeight = isNaN(this._contextMenuProperties.maxHeight as number) ? this._contextMenuProperties.maxHeight : `${this._contextMenuProperties.maxHeight ?? 0}px`;\n const width = isNaN(this._contextMenuProperties.width as number) ? this._contextMenuProperties.width : `${this._contextMenuProperties.maxWidth ?? 0}px`;\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-context-menu ${this._gridUid}`;\n this._menuElm.role = 'menu';\n if (width) {\n this._menuElm.style.width = width as string;\n }\n if (maxHeight) {\n this._menuElm.style.maxHeight = maxHeight as string;\n }\n this._menuElm.style.top = `${targetEvent.pageY}px`;\n this._menuElm.style.left = `${targetEvent.pageX}px`;\n this._menuElm.style.display = 'none';\n\n const closeButtonElm = document.createElement('button');\n closeButtonElm.type = 'button';\n closeButtonElm.className = 'close';\n closeButtonElm.dataset.dismiss = 'slick-context-menu';\n closeButtonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.innerHTML = '×';\n closeButtonElm.appendChild(spanCloseElm);\n\n // -- Option List section\n if (!this._contextMenuProperties.hideOptionSection && isColumnOptionAllowed && optionItems.length > 0) {\n const optionMenuElm = document.createElement('div');\n optionMenuElm.className = 'slick-context-menu-option-list';\n optionMenuElm.role = 'menu';\n\n if (!this._contextMenuProperties.hideCloseButton) {\n this._bindingEventService.bind(closeButtonElm, 'click', this.handleCloseButtonClicked.bind(this) as EventListener);\n this._menuElm.appendChild(closeButtonElm);\n }\n this._menuElm.appendChild(optionMenuElm)\n\n this.populateOptionItems(\n this._contextMenuProperties,\n optionMenuElm,\n optionItems,\n { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext: dataContext, grid: this._grid }\n );\n }\n\n // -- Command List section\n if (!this._contextMenuProperties.hideCommandSection && isColumnCommandAllowed && commandItems.length > 0) {\n const commandMenuElm = document.createElement('div');\n commandMenuElm.className = 'slick-context-menu-command-list';\n commandMenuElm.role = 'menu';\n\n if (!this._contextMenuProperties.hideCloseButton && (!isColumnOptionAllowed || optionItems.length === 0 || this._contextMenuProperties.hideOptionSection)) {\n this._bindingEventService.bind(closeButtonElm, 'click', this.handleCloseButtonClicked.bind(this) as EventListener);\n this._menuElm.appendChild(closeButtonElm);\n }\n\n this._menuElm.appendChild(commandMenuElm);\n this.populateCommandItems(\n this._contextMenuProperties,\n commandMenuElm,\n commandItems,\n { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext: dataContext, grid: this._grid }\n );\n }\n\n this._menuElm.style.display = 'block';\n document.body.appendChild(this._menuElm);\n\n if (this.onAfterMenuShow.notify({\n cell: this._currentCell,\n row: this._currentRow,\n grid: this._grid\n }, e, this).getReturnValue() == false) {\n return;\n }\n\n return this._menuElm;\n }\n\n protected handleCloseButtonClicked(e: MouseEvent | TouchEvent) {\n if (!e.defaultPrevented) {\n this.destroyMenu(e);\n }\n }\n\n destroyMenu(e?: Event, args?: { cell: number; row: number; }) {\n this._menuElm = this._menuElm || document.querySelector(`.slick-context-menu.${this._gridUid}`);\n\n if (this._menuElm?.remove) {\n if (this.onBeforeMenuClose.notify({\n cell: args?.cell ?? 0,\n row: args?.row ?? 0,\n grid: this._grid,\n }, e, this).getReturnValue() == false) {\n return;\n }\n this._menuElm.remove();\n this._menuElm = null;\n }\n }\n\n protected checkIsColumnAllowed(columnIds: Array, columnId: number | string) {\n let isAllowedColumn = false;\n\n if (columnIds?.length > 0) {\n for (let o = 0, ln = columnIds.length; o < ln; o++) {\n if (columnIds[o] === columnId) {\n isAllowedColumn = true;\n }\n }\n } else {\n isAllowedColumn = true;\n }\n return isAllowedColumn;\n }\n\n protected handleOnContextMenu(evt: SlickEventData_ | DOMMouseOrTouchEvent, args: MenuCommandItemCallbackArgs) {\n const e = evt instanceof SlickEventData ? evt.getNativeEvent>() : evt;\n e.preventDefault();\n const cell = this._grid.getCellFromEvent(e);\n\n if (cell) {\n\n const columnDef = this._grid.getColumns()[cell.cell];\n const dataContext = this._grid.getDataItem(cell.row);\n\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.cell = cell.cell;\n args.row = cell.row;\n args.column = columnDef;\n args.dataContext = dataContext;\n args.grid = this._grid;\n\n if (!this.runOverrideFunctionWhenExists(this._contextMenuProperties.menuUsabilityOverride, args)) {\n return;\n }\n\n // create the DOM element\n this._menuElm = this.createMenu(e as MouseEvent);\n\n // reposition the menu to where the user clicked\n if (this._menuElm) {\n this.repositionMenu(e);\n this._menuElm.style.display = 'block';\n }\n\n this._bindingEventService.bind(document.body, 'click', (e) => {\n if (!e.defaultPrevented) {\n this.destroyMenu(e, { cell: this._currentCell, row: this._currentRow });\n }\n });\n }\n }\n\n /** Construct the Option Items section. */\n protected populateOptionItems(contextMenu: ContextMenuOption, optionMenuElm: HTMLElement, optionItems: Array, args: any) {\n if (!args || !optionItems || !contextMenu) {\n return;\n }\n\n // user could pass a title on top of the Options section\n if (contextMenu?.optionTitle) {\n this._optionTitleElm = document.createElement('div');\n this._optionTitleElm.className = 'title';\n this._optionTitleElm.textContent = contextMenu.optionTitle;\n optionMenuElm.appendChild(this._optionTitleElm);\n }\n\n for (let i = 0, ln = optionItems.length; i < ln; i++) {\n let addClickListener = true;\n const item = optionItems[i];\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as MenuOptionItem).itemVisibilityOverride, args);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as MenuOptionItem).itemUsabilityOverride, args);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemOptionClick\" has the correct flag and won't trigger an option clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as MenuOptionItem).disabled = isItemUsable ? false : true;\n }\n\n const liElm = document.createElement('div');\n liElm.className = 'slick-context-menu-item';\n liElm.role = 'menuitem';\n\n if ((item as MenuOptionItem).divider || item === 'divider') {\n liElm.classList.add('slick-context-menu-item-divider');\n addClickListener = false;\n }\n\n // if the item is disabled then add the disabled css class\n if ((item as MenuOptionItem).disabled || !isItemUsable) {\n liElm.classList.add('slick-context-menu-item-disabled');\n }\n\n // if the item is hidden then add the hidden css class\n if ((item as MenuOptionItem).hidden) {\n liElm.classList.add('slick-context-menu-item-hidden');\n }\n\n if ((item as MenuOptionItem).cssClass) {\n liElm.classList.add(...(item as MenuOptionItem).cssClass!.split(' '));\n }\n\n if ((item as MenuOptionItem).tooltip) {\n liElm.title = (item as MenuOptionItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.role = 'button';\n iconElm.className = 'slick-context-menu-icon';\n\n liElm.appendChild(iconElm);\n\n if ((item as MenuOptionItem).iconCssClass) {\n iconElm.classList.add(...(item as MenuOptionItem).iconCssClass!.split(' '));\n }\n\n if ((item as MenuOptionItem).iconImage) {\n iconElm.style.backgroundImage = `url(${(item as MenuOptionItem).iconImage})`;\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-context-menu-content';\n textElm.textContent = (item as MenuOptionItem).title || '';\n\n liElm.appendChild(textElm);\n\n if ((item as MenuOptionItem).textCssClass) {\n textElm.classList.add(...(item as MenuOptionItem).textCssClass!.split(' '));\n }\n\n optionMenuElm.appendChild(liElm);\n\n if (addClickListener) {\n this._bindingEventService.bind(liElm, 'click', this.handleMenuItemOptionClick.bind(this, item) as EventListener);\n }\n }\n }\n\n /** Construct the Command Items section. */\n protected populateCommandItems(contextMenu: ContextMenuOption, commandMenuElm: HTMLElement, commandItems: Array, args: any) {\n if (!args || !commandItems || !contextMenu) {\n return;\n }\n\n // user could pass a title on top of the Commands section\n if (contextMenu?.commandTitle) {\n this._commandTitleElm = document.createElement('div');\n this._commandTitleElm.className = 'title';\n this._commandTitleElm.textContent = contextMenu.commandTitle;\n commandMenuElm.appendChild(this._commandTitleElm);\n }\n\n for (let i = 0, ln = commandItems.length; i < ln; i++) {\n let addClickListener = true;\n const item = commandItems[i];\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as MenuCommandItem).itemVisibilityOverride, args);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as MenuCommandItem).itemUsabilityOverride, args);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemCommandClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as MenuCommandItem).disabled = isItemUsable ? false : true;\n }\n\n const liElm = document.createElement('div');\n liElm.className = 'slick-context-menu-item';\n liElm.role = 'menuitem';\n\n if ((item as MenuCommandItem).divider || item === 'divider') {\n liElm.classList.add('slick-context-menu-item-divider');\n addClickListener = false;\n }\n\n // if the item is disabled then add the disabled css class\n if ((item as MenuCommandItem).disabled || !isItemUsable) {\n liElm.classList.add('slick-context-menu-item-disabled');\n }\n\n // if the item is hidden then add the hidden css class\n if ((item as MenuCommandItem).hidden) {\n liElm.classList.add('slick-context-menu-item-hidden');\n }\n\n if ((item as MenuCommandItem).cssClass) {\n liElm.classList.add(...(item as MenuCommandItem).cssClass!.split(' '));\n }\n\n if ((item as MenuCommandItem).tooltip) {\n liElm.title = (item as MenuCommandItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-context-menu-icon';\n\n liElm.appendChild(iconElm);\n\n if ((item as MenuCommandItem).iconCssClass) {\n iconElm.classList.add(...(item as MenuCommandItem).iconCssClass!.split(' '));\n }\n\n if ((item as MenuCommandItem).iconImage) {\n iconElm.style.backgroundImage = `url(${(item as MenuCommandItem).iconImage})`;\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-context-menu-content';\n textElm.textContent = (item as MenuCommandItem).title || '';\n\n liElm.appendChild(textElm);\n\n if ((item as MenuCommandItem).textCssClass) {\n textElm.classList.add(...(item as MenuCommandItem).textCssClass!.split(' '));\n }\n\n commandMenuElm.appendChild(liElm);\n\n if (addClickListener) {\n this._bindingEventService.bind(liElm, 'click', this.handleMenuItemCommandClick.bind(this, item) as EventListener);\n }\n }\n }\n\n protected handleMenuItemCommandClick(item: MenuCommandItem | 'divider', e: DOMMouseOrTouchEvent) {\n if (!item || (item as MenuCommandItem).disabled || (item as MenuCommandItem).divider) {\n return;\n }\n\n const command = (item as MenuCommandItem).command || '';\n const row = this._currentRow;\n const cell = this._currentCell;\n const columnDef = this._grid.getColumns()[cell];\n const dataContext = this._grid.getDataItem(row);\n let cellValue;\n\n if (Object.prototype.hasOwnProperty.call(dataContext, columnDef?.field)) {\n cellValue = dataContext[columnDef.field];\n }\n\n if (command !== null && command !== '') {\n // user could execute a callback through 2 ways\n // via the onCommand event and/or an action callback\n const callbackArgs = {\n cell,\n row,\n grid: this._grid,\n command,\n item: item as MenuCommandItem,\n column: columnDef,\n dataContext,\n value: cellValue\n };\n this.onCommand.notify(callbackArgs, e, this);\n\n // execute action callback when defined\n if (typeof (item as MenuCommandItem).action === 'function') {\n (item as any).action.call(this, e, callbackArgs);\n }\n }\n }\n\n protected handleMenuItemOptionClick(item: MenuOptionItem | 'divider', e: DOMMouseOrTouchEvent) {\n if ((item as MenuOptionItem).disabled || (item as MenuOptionItem).divider) {\n return;\n }\n if (!this._grid.getEditorLock().commitCurrentEdit()) {\n return;\n }\n\n const option = (item as MenuOptionItem).option !== undefined ? (item as MenuOptionItem).option : '';\n const row = this._currentRow;\n const cell = this._currentCell;\n const columnDef = this._grid.getColumns()[cell];\n const dataContext = this._grid.getDataItem(row);\n\n if (option !== undefined) {\n // user could execute a callback through 2 ways\n // via the onOptionSelected event and/or an action callback\n const callbackArgs = {\n cell,\n row,\n grid: this._grid,\n option,\n item: item as MenuOptionItem,\n column: columnDef,\n dataContext,\n };\n this.onOptionSelected.notify(callbackArgs, e, this);\n\n // execute action callback when defined\n if (typeof (item as MenuOptionItem).action === 'function') {\n (item as any).action.call(this, e, callbackArgs);\n }\n }\n }\n\n /**\n * Reposition the menu drop (up/down) and the side (left/right)\n * @param {*} event\n */\n protected repositionMenu(e: DOMMouseOrTouchEvent) {\n if (this._menuElm && e.target) {\n const targetEvent = (e as TouchEvent).touches?.[0] ?? e;\n const parentElm = e.target.closest('.slick-cell') as HTMLDivElement;\n const parentOffset = (parentElm && Utils.offset(parentElm));\n let menuOffsetLeft = targetEvent.pageX;\n let menuOffsetTop = parentElm ? parentOffset?.top ?? 0 : targetEvent.pageY;\n const menuHeight = this._menuElm?.offsetHeight || 0;\n const menuWidth = this._menuElm?.offsetWidth || this._contextMenuProperties.width || 0;\n const rowHeight = this._gridOptions.rowHeight;\n const dropOffset = this._contextMenuProperties.autoAdjustDropOffset;\n const sideOffset = this._contextMenuProperties.autoAlignSideOffset;\n\n // if autoAdjustDrop is enable, we first need to see what position the drop will be located\n // without necessary toggling it's position just yet, we just want to know the future position for calculation\n if (this._contextMenuProperties.autoAdjustDrop) {\n // since we reposition menu below slick cell, we need to take it in consideration and do our calculation from that element\n const spaceBottom = Utils.calculateAvailableSpace(parentElm).bottom;\n const spaceTop = Utils.calculateAvailableSpace(parentElm).top;\n const spaceBottomRemaining = spaceBottom + (dropOffset || 0) - rowHeight!;\n const spaceTopRemaining = spaceTop - (dropOffset || 0) + rowHeight!;\n const dropPosition = (spaceBottomRemaining < menuHeight && spaceTopRemaining > spaceBottomRemaining) ? 'top' : 'bottom';\n if (dropPosition === 'top') {\n this._menuElm.classList.remove('dropdown');\n this._menuElm.classList.add('dropup');\n menuOffsetTop = menuOffsetTop - menuHeight - (dropOffset || 0);\n } else {\n this._menuElm.classList.remove('dropup');\n this._menuElm.classList.add('dropdown');\n menuOffsetTop = menuOffsetTop + rowHeight! + (dropOffset || 0);\n }\n }\n\n // when auto-align is set, it will calculate whether it has enough space in the viewport to show the drop menu on the right (default)\n // if there isn't enough space on the right, it will automatically align the drop menu to the left\n // to simulate an align left, we actually need to know the width of the drop menu\n if (this._contextMenuProperties.autoAlignSide) {\n const gridPos = this._grid.getGridPosition();\n const dropSide = ((menuOffsetLeft + (+menuWidth)) >= gridPos.width) ? 'left' : 'right';\n if (dropSide === 'left') {\n this._menuElm.classList.remove('dropright');\n this._menuElm.classList.add('dropleft');\n menuOffsetLeft = (menuOffsetLeft - (+menuWidth) - (sideOffset || 0));\n } else {\n this._menuElm.classList.remove('dropleft');\n this._menuElm.classList.add('dropright');\n menuOffsetLeft = menuOffsetLeft + (sideOffset || 0);\n }\n }\n\n // ready to reposition the menu\n this._menuElm.style.top = `${menuOffsetTop}px`;\n this._menuElm.style.left = `${menuOffsetLeft}px`;\n }\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n ContextMenu: SlickContextMenu\n }\n }\n });\n}\n\n"], - "mappings": "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", - "names": ["e"] + "sourcesContent": ["import {\n BindingEventService as BindingEventService_,\n SlickEvent as SlickEvent_,\n SlickEventData as SlickEventData_,\n SlickEventHandler as SlickEventHandler_,\n Utils as Utils_\n} from '../slick.core';\nimport type {\n Column,\n ContextMenuOption,\n DOMMouseOrTouchEvent,\n GridOption,\n MenuCommandItem,\n MenuCommandItemCallbackArgs,\n MenuFromCellCallbackArgs,\n MenuOptionItem,\n MenuOptionItemCallbackArgs,\n MenuType,\n SlickPlugin\n} from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst EventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add Context Menu (mouse right+click), it subscribes to the cell \"onContextMenu\" event.\n * The \"contextMenu\" is defined in the Grid Options object\n * You can use it to change a data property (only 1) through a list of Options AND/OR through a list of Commands.\n * A good example of a Command would be an Export to CSV, that can be run from anywhere in the grid by doing a mouse right+click\n *\n * Note:\n * There is only 1 list of Options, so typically that would be use for 1 column\n * if you plan to use different Options for different columns, then the CellMenu plugin might be better suited.\n *\n * USAGE:\n *\n * Add the slick.contextmenu.(js|css) files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n * var contextMenuPlugin = new Slick.Plugins.ContextMenu(columns, grid, options);\n *\n * Available grid options, by defining a contextMenu object:\n *\n * var options = {\n * enableCellNavigation: true,\n * contextMenu: {\n * optionTitle: 'Change Priority',\n * optionShownOverColumnIds: [\"priority\"],\n * optionItems: [\n * { option: 0, title: 'none', cssClass: 'italic' },\n * { divider: true },\n * \"divider\" // just the string is also accepted\n * { option: 1, iconCssClass: 'fa fa-fire grey', title: 'Low' },\n * { option: 3, iconCssClass: 'fa fa-fire red', title: 'High' },\n * { option: 2, iconCssClass: 'fa fa-fire orange', title: 'Medium' },\n * { option: 4, iconCssClass: 'fa fa-fire', title: 'Extreme', disabled: true },\n * ],\n * commandTitle: 'Commands',\n * commandShownOverColumnIds: [\"title\", \"complete\", \"start\", \"finish\", \"effortDriven\"],\n * commandItems: [\n * { command: 'export-excel', title: 'Export to CSV', iconCssClass: 'fa fa-file-excel-o', cssClass: '' },\n * { command: 'delete-row', title: 'Delete Row', cssClass: 'bold', textCssClass: 'red' },\n * { command: 'help', title: 'Help', iconCssClass: 'fa fa-question-circle',},\n * { divider: true },\n * ],\n * }\n * };\n *\n *\n * Available contextMenu properties:\n * commandTitle: Title of the Command section (optional)\n * commandItems: Array of Command item objects (command/title pair)\n * commandShownOverColumnIds: Define which column to show the Commands list. If not defined (defaults), the menu will be shown over all columns\n * optionTitle: Title of the Option section (optional)\n * optionItems: Array of Options item objects (option/title pair)\n * optionShownOverColumnIds: Define which column to show the Options list. If not defined (defaults), the menu will be shown over all columns\n * hideCloseButton: Hide the Close button on top right (defaults to false)\n * hideCommandSection: Hide the Commands section even when the commandItems array is filled (defaults to false)\n * hideMenuOnScroll: Do we want to hide the Cell Menu when a scrolling event occurs (defaults to false)?\n * hideOptionSection: Hide the Options section even when the optionItems array is filled (defaults to false)\n * maxHeight: Maximum height that the drop menu will have, can be a number (250) or text (\"none\")\n * width: Width that the drop menu will have, can be a number (250) or text (defaults to \"auto\")\n * autoAdjustDrop: Auto-align dropup or dropdown menu to the left or right depending on grid viewport available space (defaults to true)\n * autoAdjustDropOffset: Optionally add an offset to the auto-align of the drop menu (defaults to -4)\n * autoAlignSide: Auto-align drop menu to the left or right depending on grid viewport available space (defaults to true)\n * autoAlignSideOffset: Optionally add an offset to the left/right side auto-align (defaults to 0)\n * menuUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling the menu from being usable (must be combined with a custom formatter)\n * subItemChevronClass: CSS class that can be added on the right side of a sub-item parent (typically a chevron-right icon)\n *\n *\n * Available menu Command/Option item properties:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * command: A command identifier to be passed to the onCommand event handlers (when using \"commandItems\").\n * option: An option to be passed to the onOptionSelected event handlers (when using \"optionItems\").\n * title: Menu item text.\n * divider: Boolean which tell if the current item is a divider, not an actual command. You could also pass \"divider\" instead of an object\n * disabled: Whether the item/command is disabled.\n * hidden: Whether the item/command is hidden.\n * subMenuTitle: Optional sub-menu title that will shows up when sub-menu commmands/options list is opened\n * subMenuTitleCssClass: Optional sub-menu title CSS class to use with `subMenuTitle`\n * tooltip: Item tooltip.\n * cssClass: A CSS class to be added to the menu item container.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * textCssClass: A CSS class to be added to the menu item text.\n * iconImage: A url to the icon image.\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n * The plugin exposes the following events:\n *\n * onAfterMenuShow: Fired after the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n *\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n *\n * onBeforeMenuClose: Fired when the menu is closing.\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * menu: Menu DOM element\n *\n * onCommand: Fired on menu option clicked from the Command items list\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * command: Menu command identified.\n * item: Menu item selected\n * column: Cell Column definition\n * dataContext: Cell Data Context (data object)\n * value: Value of the cell we triggered the context menu from\n *\n * onOptionSelected: Fired on menu option clicked from the Option items list\n * Event args:\n * cell: Cell or column index\n * row: Row index\n * grid: Reference to the grid.\n * option: Menu option selected.\n * item: Menu item selected\n * column: Cell Column definition\n * dataContext: Cell Data Context (data object)\n *\n *\n * @param options {Object} Context Menu Options\n * @class Slick.Plugins.ContextMenu\n */\nexport class SlickContextMenu implements SlickPlugin {\n // --\n // public API\n pluginName = 'ContextMenu' as const;\n onAfterMenuShow = new SlickEvent();\n onBeforeMenuShow = new SlickEvent();\n onBeforeMenuClose = new SlickEvent();\n onCommand = new SlickEvent();\n onOptionSelected = new SlickEvent();\n\n // --\n // protected props\n protected _bindingEventService = new BindingEventService();\n protected _contextMenuProperties: ContextMenuOption;\n protected _currentCell = -1;\n protected _currentRow = -1;\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _gridUid = '';\n protected _handler = new EventHandler();\n protected _commandTitleElm?: HTMLSpanElement;\n protected _optionTitleElm?: HTMLSpanElement;\n protected _lastMenuTypeClicked = '';\n protected _menuElm?: HTMLDivElement | null;\n protected _subMenuParentId = '';\n protected _defaults: ContextMenuOption = {\n autoAdjustDrop: true, // dropup/dropdown\n autoAlignSide: true, // left/right\n autoAdjustDropOffset: -4,\n autoAlignSideOffset: 0,\n hideMenuOnScroll: false,\n maxHeight: 'none',\n width: 'auto',\n optionShownOverColumnIds: [],\n commandShownOverColumnIds: [],\n };\n\n constructor(optionProperties: Partial) {\n this._contextMenuProperties = Utils.extend({}, this._defaults, optionProperties);\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._gridOptions = grid.getOptions();\n this._gridUid = grid?.getUID() || '';\n this._handler.subscribe(this._grid.onContextMenu, this.handleOnContextMenu.bind(this));\n if (this._contextMenuProperties.hideMenuOnScroll) {\n this._handler.subscribe(this._grid.onScroll, this.destroyMenu.bind(this));\n }\n }\n\n setOptions(newOptions: Partial) {\n this._contextMenuProperties = Utils.extend({}, this._contextMenuProperties, newOptions);\n\n // on the array properties, we want to make sure to overwrite them and not just extending them\n if (newOptions.commandShownOverColumnIds) {\n this._contextMenuProperties.commandShownOverColumnIds = newOptions.commandShownOverColumnIds;\n }\n if (newOptions.optionShownOverColumnIds) {\n this._contextMenuProperties.optionShownOverColumnIds = newOptions.optionShownOverColumnIds;\n }\n }\n\n destroy() {\n this.onAfterMenuShow.unsubscribe();\n this.onBeforeMenuShow.unsubscribe();\n this.onBeforeMenuClose.unsubscribe();\n this.onCommand.unsubscribe();\n this.onOptionSelected.unsubscribe();\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n this._menuElm?.remove();\n this._commandTitleElm = null as any;\n this._optionTitleElm = null as any;\n this._menuElm = null as any;\n }\n\n protected createParentMenu(evt: SlickEventData_ | MouseEvent) {\n const e = evt instanceof SlickEventData ? evt.getNativeEvent() : evt;\n const targetEvent = (e as TouchEvent).touches?.[0] ?? e;\n const cell = this._grid.getCellFromEvent(e);\n this._currentCell = cell?.cell ?? 0;\n this._currentRow = cell?.row ?? 0;\n const columnDef = this._grid.getColumns()[this._currentCell];\n\n const isColumnOptionAllowed = this.checkIsColumnAllowed(this._contextMenuProperties.optionShownOverColumnIds ?? [], columnDef.id);\n const isColumnCommandAllowed = this.checkIsColumnAllowed(this._contextMenuProperties.commandShownOverColumnIds ?? [], columnDef.id);\n const commandItems = this._contextMenuProperties.commandItems || [];\n const optionItems = this._contextMenuProperties.optionItems || [];\n\n // make sure there's at least something to show before creating the Context Menu\n if (!columnDef || (!isColumnCommandAllowed && !isColumnOptionAllowed) || (!commandItems.length && !optionItems.length)) {\n return;\n }\n\n // delete any prior context menu\n this.destroyMenu(e);\n\n // Let the user modify the menu or cancel altogether,\n // or provide alternative menu implementation.\n if (this.onBeforeMenuShow.notify({\n cell: this._currentCell,\n row: this._currentRow,\n grid: this._grid\n }, e, this).getReturnValue() === false) {\n return;\n }\n\n // create 1st parent menu container & reposition it\n this._menuElm = this.createMenu(commandItems, optionItems);\n this._menuElm.style.top = `${targetEvent.pageY}px`;\n this._menuElm.style.left = `${targetEvent.pageX}px`;\n this._menuElm.style.display = 'block';\n document.body.appendChild(this._menuElm);\n\n if (this.onAfterMenuShow.notify({\n cell: this._currentCell,\n row: this._currentRow,\n grid: this._grid\n }, e, this).getReturnValue() === false) {\n return;\n }\n\n return this._menuElm;\n }\n\n protected createMenu(commandItems: Array, optionItems: Array, level = 0, item?: MenuCommandItem | MenuOptionItem | 'divider') {\n const columnDef = this._grid.getColumns()[this._currentCell];\n const dataContext = this._grid.getDataItem(this._currentRow);\n const isColumnOptionAllowed = this.checkIsColumnAllowed(this._contextMenuProperties.optionShownOverColumnIds ?? [], columnDef.id);\n const isColumnCommandAllowed = this.checkIsColumnAllowed(this._contextMenuProperties.commandShownOverColumnIds ?? [], columnDef.id);\n\n // create a new context menu\n const maxHeight = isNaN(this._contextMenuProperties.maxHeight as number) ? this._contextMenuProperties.maxHeight : `${this._contextMenuProperties.maxHeight ?? 0}px`;\n const width = isNaN(this._contextMenuProperties.width as number) ? this._contextMenuProperties.width : `${this._contextMenuProperties.maxWidth ?? 0}px`;\n\n // to avoid having multiple sub-menu trees opened,\n // we need to somehow keep trace of which parent menu the tree belongs to\n // and we should keep ref of only the first sub-menu parent, we can use the command name (remove any whitespaces though)\n const subMenuCommand = (item as MenuCommandItem)?.command;\n let subMenuId = (level === 1 && subMenuCommand) ? subMenuCommand.replaceAll(' ', '') : '';\n if (subMenuId) {\n this._subMenuParentId = subMenuId;\n }\n if (level > 1) {\n subMenuId = this._subMenuParentId;\n }\n\n const menuClasses = `slick-context-menu slick-menu-level-${level} ${this._gridUid}`;\n const bodyMenuElm = document.body.querySelector(`.slick-context-menu.slick-menu-level-${level}${this.getGridUidSelector()}`);\n\n // return menu/sub-menu if it's already opened unless we are on different sub-menu tree if so close them all\n if (bodyMenuElm) {\n if (bodyMenuElm.dataset.subMenuParent === subMenuId) {\n return bodyMenuElm;\n }\n this.destroySubMenus();\n }\n\n const menuElm = document.createElement('div');\n menuElm.className = menuClasses;\n if (level > 0) {\n menuElm.classList.add('slick-submenu');\n if (subMenuId) {\n menuElm.dataset.subMenuParent = subMenuId;\n }\n }\n menuElm.ariaLabel = level > 1 ? 'SubMenu' : 'Context Menu';\n menuElm.role = 'menu';\n if (width) {\n menuElm.style.width = width as string;\n }\n if (maxHeight) {\n menuElm.style.maxHeight = maxHeight as string;\n }\n\n menuElm.style.display = 'none';\n\n let closeButtonElm: HTMLButtonElement | null = null;\n if (level === 0) {\n closeButtonElm = document.createElement('button');\n closeButtonElm.type = 'button';\n closeButtonElm.className = 'close';\n closeButtonElm.dataset.dismiss = 'slick-context-menu';\n closeButtonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.innerHTML = '×';\n closeButtonElm.appendChild(spanCloseElm);\n }\n\n // -- Option List section\n if (!this._contextMenuProperties.hideOptionSection && isColumnOptionAllowed && optionItems.length > 0) {\n const optionMenuElm = document.createElement('div');\n optionMenuElm.className = 'slick-context-menu-option-list';\n optionMenuElm.role = 'menu';\n\n // when creating sub-menu add its sub-menu title when exists\n if (item && level > 0) {\n this.addSubMenuTitleWhenExists(item, optionMenuElm); // add sub-menu title when exists\n }\n\n if (closeButtonElm && !this._contextMenuProperties.hideCloseButton) {\n this._bindingEventService.bind(closeButtonElm, 'click', this.handleCloseButtonClicked.bind(this) as EventListener);\n menuElm.appendChild(closeButtonElm);\n }\n menuElm.appendChild(optionMenuElm);\n\n this.populateCommandOrOptionItems(\n 'option',\n this._contextMenuProperties,\n optionMenuElm,\n optionItems,\n { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid, level }\n );\n }\n\n // -- Command List section\n if (!this._contextMenuProperties.hideCommandSection && isColumnCommandAllowed && commandItems.length > 0) {\n const commandMenuElm = document.createElement('div');\n commandMenuElm.className = 'slick-context-menu-command-list';\n commandMenuElm.role = 'menu';\n\n // when creating sub-menu add its sub-menu title when exists\n if (item && level > 0) {\n this.addSubMenuTitleWhenExists(item, commandMenuElm); // add sub-menu title when exists\n }\n\n if (closeButtonElm && !this._contextMenuProperties.hideCloseButton && (!isColumnOptionAllowed || optionItems.length === 0 || this._contextMenuProperties.hideOptionSection)) {\n this._bindingEventService.bind(closeButtonElm, 'click', this.handleCloseButtonClicked.bind(this) as EventListener);\n menuElm.appendChild(closeButtonElm);\n }\n\n menuElm.appendChild(commandMenuElm);\n this.populateCommandOrOptionItems(\n 'command',\n this._contextMenuProperties,\n commandMenuElm,\n commandItems,\n { cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid, level }\n );\n }\n\n // increment level for possible next sub-menus if exists\n level++;\n\n return menuElm;\n }\n\n protected addSubMenuTitleWhenExists(item: MenuCommandItem | MenuOptionItem | 'divider', commandOrOptionMenu: HTMLDivElement) {\n if (item !== 'divider' && item?.subMenuTitle) {\n const subMenuTitleElm = document.createElement('div');\n subMenuTitleElm.className = 'slick-menu-title';\n subMenuTitleElm.textContent = item.subMenuTitle as string;\n const subMenuTitleClass = item.subMenuTitleCssClass as string;\n if (subMenuTitleClass) {\n subMenuTitleElm.classList.add(...subMenuTitleClass.split(' '));\n }\n\n commandOrOptionMenu.appendChild(subMenuTitleElm);\n }\n }\n\n protected handleCloseButtonClicked(e: MouseEvent | TouchEvent) {\n if (!e.defaultPrevented) {\n this.destroyMenu(e);\n }\n }\n\n destroyMenu(e?: Event, args?: { cell: number; row: number; }) {\n this._menuElm = this._menuElm || document.querySelector(`.slick-context-menu${this.getGridUidSelector()}`);\n\n if (this._menuElm?.remove) {\n if (this.onBeforeMenuClose.notify({\n cell: args?.cell ?? 0,\n row: args?.row ?? 0,\n grid: this._grid,\n }, e, this).getReturnValue() === false) {\n return;\n }\n this._menuElm.remove();\n this._menuElm = null;\n }\n this.destroySubMenus();\n }\n\n /** Destroy all parent menus and any sub-menus */\n destroyAllMenus() {\n this.destroySubMenus();\n document.querySelectorAll(`.slick-context-menu${this.getGridUidSelector()}`)\n .forEach(subElm => subElm.remove());\n }\n\n /** Close and destroy all previously opened sub-menus */\n destroySubMenus() {\n document.querySelectorAll(`.slick-context-menu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => subElm.remove());\n }\n\n protected checkIsColumnAllowed(columnIds: Array, columnId: number | string) {\n let isAllowedColumn = false;\n\n if (columnIds?.length > 0) {\n for (let o = 0, ln = columnIds.length; o < ln; o++) {\n if (columnIds[o] === columnId) {\n isAllowedColumn = true;\n }\n }\n } else {\n isAllowedColumn = true;\n }\n return isAllowedColumn;\n }\n\n protected getGridUidSelector() {\n const gridUid = this._grid.getUID() || '';\n return gridUid ? `.${gridUid}` : '';\n }\n\n protected handleOnContextMenu(evt: SlickEventData_ | DOMMouseOrTouchEvent, args: MenuCommandItemCallbackArgs) {\n this.destroyAllMenus(); // make there's only 1 parent menu opened at a time\n const e = evt instanceof SlickEventData ? evt.getNativeEvent>() : evt;\n e.preventDefault();\n const cell = this._grid.getCellFromEvent(e);\n\n if (cell) {\n const columnDef = this._grid.getColumns()[cell.cell];\n const dataContext = this._grid.getDataItem(cell.row);\n\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.cell = cell.cell;\n args.row = cell.row;\n args.column = columnDef;\n args.dataContext = dataContext;\n args.grid = this._grid;\n\n if (!this.runOverrideFunctionWhenExists(this._contextMenuProperties.menuUsabilityOverride, args)) {\n return;\n }\n\n // create the DOM element\n this._menuElm = this.createParentMenu(e as MouseEvent);\n\n // reposition the menu to where the user clicked\n if (this._menuElm) {\n this.repositionMenu(e, this._menuElm);\n this._menuElm.style.display = 'block';\n }\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n }\n }\n\n /** When users click outside the Cell Menu, we will typically close the Cell Menu (and any sub-menus) */\n protected handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n // did we click inside the menu or any of its sub-menu(s)\n let isMenuClicked = false;\n if (this._menuElm?.contains(e.target)) {\n isMenuClicked = true;\n }\n if (!isMenuClicked) {\n document\n .querySelectorAll(`.slick-context-menu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => {\n if (subElm.contains(e.target)) {\n isMenuClicked = true;\n }\n });\n }\n\n if (this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented) {\n this.destroyMenu(e, { cell: this._currentCell, row: this._currentRow });\n }\n }\n\n /** Construct the Command Items section. */\n protected populateCommandOrOptionItems(\n itemType: MenuType,\n contextMenu: ContextMenuOption,\n commandOrOptionMenuElm: HTMLElement,\n commandOrOptionItems: Array | Array,\n args: { cell: number, row: number, column: Column, dataContext: any, grid: SlickGrid, level: number }\n ) {\n if (!args || !commandOrOptionItems || !contextMenu) {\n return;\n }\n\n // user could pass a title on top of the Commands/Options section\n const isSubMenu = args.level > 0;\n if (contextMenu?.[`${itemType}Title`] && !isSubMenu) {\n this[`_${itemType}TitleElm`] = document.createElement('div');\n this[`_${itemType}TitleElm`]!.className = 'slick-menu-title';\n this[`_${itemType}TitleElm`]!.textContent = contextMenu[`${itemType}Title`] as string;\n commandOrOptionMenuElm.appendChild(this[`_${itemType}TitleElm`]!);\n }\n\n for (let i = 0, ln = commandOrOptionItems.length; i < ln; i++) {\n let addClickListener = true;\n const item = commandOrOptionItems[i];\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as MenuCommandItem | MenuOptionItem).itemVisibilityOverride, args);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as MenuCommandItem | MenuOptionItem).itemUsabilityOverride, args);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as MenuCommandItem | MenuOptionItem).disabled = isItemUsable ? false : true;\n }\n\n const liElm = document.createElement('div');\n liElm.className = 'slick-context-menu-item';\n liElm.role = 'menuitem';\n\n if ((item as MenuCommandItem | MenuOptionItem).divider || item === 'divider') {\n liElm.classList.add('slick-context-menu-item-divider');\n addClickListener = false;\n }\n\n // if the item is disabled then add the disabled css class\n if ((item as MenuCommandItem | MenuOptionItem).disabled || !isItemUsable) {\n liElm.classList.add('slick-context-menu-item-disabled');\n }\n\n // if the item is hidden then add the hidden css class\n if ((item as MenuCommandItem | MenuOptionItem).hidden) {\n liElm.classList.add('slick-context-menu-item-hidden');\n }\n\n if ((item as MenuCommandItem | MenuOptionItem).cssClass) {\n liElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).cssClass!.split(' '));\n }\n\n if ((item as MenuCommandItem | MenuOptionItem).tooltip) {\n liElm.title = (item as MenuCommandItem | MenuOptionItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-context-menu-icon';\n\n liElm.appendChild(iconElm);\n\n if ((item as MenuCommandItem | MenuOptionItem).iconCssClass) {\n iconElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).iconCssClass!.split(' '));\n }\n\n if ((item as MenuCommandItem | MenuOptionItem).iconImage) {\n iconElm.style.backgroundImage = `url(${(item as MenuCommandItem | MenuOptionItem).iconImage})`;\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-context-menu-content';\n textElm.textContent = (item as MenuCommandItem | MenuOptionItem).title || '';\n\n liElm.appendChild(textElm);\n\n if ((item as MenuCommandItem | MenuOptionItem).textCssClass) {\n textElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).textCssClass!.split(' '));\n }\n\n commandOrOptionMenuElm.appendChild(liElm);\n\n if (addClickListener) {\n this._bindingEventService.bind(liElm, 'click', this.handleMenuItemClick.bind(this, item, itemType, args.level) as EventListener);\n }\n\n // the option/command item could be a sub-menu if it has another list of commands/options\n if ((item as MenuCommandItem).commandItems || (item as MenuOptionItem).optionItems) {\n const chevronElm = document.createElement('span');\n chevronElm.className = 'sub-item-chevron';\n if (this._contextMenuProperties.subItemChevronClass) {\n chevronElm.classList.add(...this._contextMenuProperties.subItemChevronClass.split(' '));\n } else {\n chevronElm.textContent = '\u2B9E'; // \u2B9E or \u25B8\n }\n\n liElm.classList.add('slick-submenu-item');\n liElm.appendChild(chevronElm);\n continue;\n }\n }\n }\n\n protected handleMenuItemClick(item: MenuCommandItem | MenuOptionItem | 'divider', type: MenuType, level = 0, e: DOMMouseOrTouchEvent) {\n if ((item as never)?.[type] !== undefined && item !== 'divider' && !item.disabled && !(item as MenuCommandItem | MenuOptionItem).divider && this._currentCell !== undefined && this._currentRow !== undefined) {\n if (type === 'option' && !this._grid.getEditorLock().commitCurrentEdit()) {\n return;\n }\n const optionOrCommand = (item as any)[type] !== undefined ? (item as any)[type] : '';\n const row = this._currentRow;\n const cell = this._currentCell;\n const columnDef = this._grid.getColumns()[cell];\n const dataContext = this._grid.getDataItem(row);\n let cellValue;\n\n if (Object.prototype.hasOwnProperty.call(dataContext, columnDef?.field)) {\n cellValue = dataContext[columnDef.field];\n }\n\n if (optionOrCommand !== undefined && !(item as any)[`${type}Items`]) {\n // user could execute a callback through 2 ways\n // via the onCommand event and/or an action callback\n const callbackArgs = {\n cell,\n row,\n grid: this._grid,\n [type]: optionOrCommand,\n item,\n column: columnDef,\n dataContext,\n value: cellValue\n };\n const eventType = type === 'command' ? 'onCommand' : 'onOptionSelected';\n this[eventType].notify(callbackArgs as any, e, this);\n\n // execute action callback when defined\n if (typeof (item as MenuCommandItem).action === 'function') {\n (item as any).action.call(this, e, callbackArgs);\n }\n\n if (!e.defaultPrevented) {\n this.destroyMenu(e, { cell, row });\n }\n } else if ((item as MenuCommandItem).commandItems || (item as MenuOptionItem).optionItems) {\n this.repositionSubMenu(item, type, level, e);\n } else {\n this.destroySubMenus();\n }\n this._lastMenuTypeClicked = type;\n }\n }\n\n protected repositionSubMenu(item: MenuCommandItem | MenuOptionItem | 'divider', type: MenuType, level: number, e: DOMMouseOrTouchEvent) {\n // when we're clicking a grid cell OR our last menu type (command/option) differs then we know that we need to start fresh and close any sub-menus that might still be open\n if (e.target.classList.contains('slick-cell') || this._lastMenuTypeClicked !== type) {\n this.destroySubMenus();\n }\n\n // creating sub-menu, we'll also pass level & the item object since we might have \"subMenuTitle\" to show\n const subMenuElm = this.createMenu((item as MenuCommandItem)?.commandItems || [], (item as MenuOptionItem)?.optionItems || [], level + 1, item);\n subMenuElm.style.display = 'block';\n document.body.appendChild(subMenuElm);\n this.repositionMenu(e, subMenuElm);\n }\n\n /**\n * Reposition the menu drop (up/down) and the side (left/right)\n * @param {*} event\n */\n protected repositionMenu(e: DOMMouseOrTouchEvent, menuElm: HTMLElement) {\n const isSubMenu = menuElm.classList.contains('slick-submenu');\n const targetEvent = (e as TouchEvent).touches?.[0] ?? e;\n const parentElm = isSubMenu\n ? e.target.closest('.slick-context-menu-item') as HTMLDivElement\n : e.target.closest('.slick-cell') as HTMLDivElement;\n\n if (menuElm && parentElm) {\n const parentOffset = Utils.offset(parentElm);\n let menuOffsetLeft = (isSubMenu && parentElm) ? parentOffset?.left ?? 0 : targetEvent.pageX;\n let menuOffsetTop = parentElm ? parentOffset?.top ?? 0 : targetEvent.pageY;\n const menuHeight = menuElm?.offsetHeight || 0;\n const menuWidth = Number(menuElm?.offsetWidth || this._contextMenuProperties.width || 0);\n const rowHeight = this._gridOptions.rowHeight;\n const dropOffset = Number(this._contextMenuProperties.autoAdjustDropOffset || 0);\n const sideOffset = Number(this._contextMenuProperties.autoAlignSideOffset || 0);\n\n // if autoAdjustDrop is enable, we first need to see what position the drop will be located\n // without necessary toggling it's position just yet, we just want to know the future position for calculation\n if (this._contextMenuProperties.autoAdjustDrop) {\n // since we reposition menu below slick cell, we need to take it in consideration and do our calculation from that element\n const spaceBottom = Utils.calculateAvailableSpace(parentElm).bottom;\n const spaceTop = Utils.calculateAvailableSpace(parentElm).top;\n const spaceBottomRemaining = spaceBottom + dropOffset - rowHeight!;\n const spaceTopRemaining = spaceTop - dropOffset + rowHeight!;\n const dropPosition = (spaceBottomRemaining < menuHeight && spaceTopRemaining > spaceBottomRemaining) ? 'top' : 'bottom';\n if (dropPosition === 'top') {\n menuElm.classList.remove('dropdown');\n menuElm.classList.add('dropup');\n if (isSubMenu) {\n menuOffsetTop -= (menuHeight - dropOffset - parentElm.clientHeight);\n } else {\n menuOffsetTop -= menuHeight - dropOffset;\n }\n } else {\n menuElm.classList.remove('dropup');\n menuElm.classList.add('dropdown');\n if (isSubMenu) {\n menuOffsetTop += dropOffset;\n } else {\n menuOffsetTop += rowHeight! + dropOffset;\n }\n }\n }\n\n // when auto-align is set, it will calculate whether it has enough space in the viewport to show the drop menu on the right (default)\n // if there isn't enough space on the right, it will automatically align the drop menu to the left\n // to simulate an align left, we actually need to know the width of the drop menu\n if (this._contextMenuProperties.autoAlignSide) {\n const gridPos = this._grid.getGridPosition();\n let subMenuPosCalc = menuOffsetLeft + Number(menuWidth); // calculate coordinate at caller element far right\n if (isSubMenu) {\n subMenuPosCalc += parentElm.clientWidth;\n }\n const browserWidth = document.documentElement.clientWidth;\n const dropSide = (subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth) ? 'left' : 'right';\n if (dropSide === 'left') {\n menuElm.classList.remove('dropright');\n menuElm.classList.add('dropleft');\n menuOffsetLeft -= menuWidth - sideOffset;\n } else {\n menuElm.classList.remove('dropleft');\n menuElm.classList.add('dropright');\n if (isSubMenu) {\n menuOffsetLeft += sideOffset + parentElm.offsetWidth;\n } else {\n menuOffsetLeft += sideOffset;\n }\n }\n }\n\n // ready to reposition the menu\n menuElm.style.top = `${menuOffsetTop}px`;\n menuElm.style.left = `${menuOffsetLeft}px`;\n }\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n ContextMenu: SlickContextMenu\n }\n }\n });\n}\n\n"], + "mappings": "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", + "names": [] } diff --git a/dist/browser/plugins/slick.crossgridrowmovemanager.js.map b/dist/browser/plugins/slick.crossgridrowmovemanager.js.map index 220426b99..ab1b96d8a 100644 --- a/dist/browser/plugins/slick.crossgridrowmovemanager.js.map +++ b/dist/browser/plugins/slick.crossgridrowmovemanager.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.crossgridrowmovemanager.ts"], - "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, DragRowMove, FormatterResultObject, CrossGridRowMoveManagerOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * Row Move Manager options:\n * cssClass: A CSS class to be added to the menu item container.\n * columnId: Column definition id (defaults to \"_move\")\n * cancelEditOnDrag: Do we want to cancel any Editing while dragging a row (defaults to false)\n * disableRowSelection: Do we want to disable the row selection? (defaults to false)\n * hideRowMoveShadow: Do we want to hide the row move shadow clone? (defaults to true)\n * rowMoveShadowMarginTop: When row move shadow is shown, optional margin-top (defaults to 0)\n * rowMoveShadowMarginLeft: When row move shadow is shown, optional margin-left (defaults to 0)\n * rowMoveShadowOpacity: When row move shadow is shown, what is its opacity? (defaults to 0.95)\n * rowMoveShadowScale: When row move shadow is shown, what is its size scale? (default to 0.75)\n * singleRowMove: Do we want a single row move? Setting this to false means that it's a multple row move (defaults to false)\n * width: Width of the column\n * usabilityOverride: Callback method that user can override the default behavior of the row being moveable or not\n *\n */\nexport class SlickCrossGridRowMoveManager {\n // --\n // public API\n pluginName = 'CrossGridRowMoveManager' as const;\n onBeforeMoveRows = new SlickEvent<{ rows: number[]; insertBefore: number; fromGrid: SlickGrid; toGrid: SlickGrid; }>();\n onMoveRows = new SlickEvent<{ rows: number[]; insertBefore: number; fromGrid: SlickGrid; toGrid: SlickGrid; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _canvas!: HTMLElement;\n protected _dragging = false;\n protected _toGrid!: SlickGrid;\n protected _toCanvas!: HTMLElement;\n protected _usabilityOverride?: UsabilityOverrideFn;\n protected _eventHandler: SlickEventHandler_;\n protected _options: CrossGridRowMoveManagerOption;\n protected _defaults: CrossGridRowMoveManagerOption = {\n columnId: '_move',\n cssClass: undefined,\n cancelEditOnDrag: false,\n disableRowSelection: false,\n hideRowMoveShadow: true,\n rowMoveShadowMarginTop: 0,\n rowMoveShadowMarginLeft: 0,\n rowMoveShadowOpacity: 0.95,\n rowMoveShadowScale: 0.75,\n singleRowMove: false,\n toGrid: undefined as any,\n width: 40,\n };\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._canvas = this._grid.getCanvasNode();\n this._toGrid = this._options.toGrid;\n this._toCanvas = this._toGrid.getCanvasNode();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options?.usabilityOverride === 'function') {\n this.usabilityOverride(this._options.usabilityOverride);\n }\n\n this._eventHandler\n .subscribe(this._grid.onDragInit, this.handleDragInit.bind(this))\n .subscribe(this._grid.onDragStart, this.handleDragStart.bind(this))\n .subscribe(this._grid.onDrag, this.handleDrag.bind(this))\n .subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));\n }\n\n destroy() {\n this._eventHandler.unsubscribeAll();\n }\n\n setOptions(newOptions: CrossGridRowMoveManagerOption) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n\n protected handleDragInit(e: SlickEventData_) {\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n }\n\n protected handleDragStart(e: DOMEvent, dd: DragRowMove & { fromGrid: SlickGrid; toGrid: SlickGrid; }): boolean | void {\n const cell = this._grid.getCellFromEvent(e) || { cell: -1, row: -1 };\n const currentRow = cell?.row ?? 0;\n const dataContext = this._grid.getDataItem(currentRow);\n\n if (!this.checkUsabilityOverride(currentRow, dataContext, this._grid)) {\n return;\n }\n\n if (this._options.cancelEditOnDrag && this._grid.getEditorLock().isActive()) {\n this._grid.getEditorLock().cancelCurrentEdit();\n }\n\n if (this._grid.getEditorLock().isActive() || !this.isHandlerColumn(cell.cell)) {\n return false;\n }\n\n this._dragging = true;\n e.stopImmediatePropagation();\n\n // optionally create a shadow element of the row so that we can see all the time which row exactly we're dragging\n if (!this._options.hideRowMoveShadow) {\n const cellNodeElm = this._grid.getCellNode(cell.row, cell.cell);\n const slickRowElm = cellNodeElm?.closest('.slick-row');\n if (slickRowElm) {\n dd.clonedSlickRow = slickRowElm.cloneNode(true) as HTMLDivElement;\n dd.clonedSlickRow.classList.add('slick-reorder-shadow-row');\n dd.clonedSlickRow.style.display = 'none';\n dd.clonedSlickRow.style.marginLeft = Number(this._options.rowMoveShadowMarginLeft || 0) + 'px';\n dd.clonedSlickRow.style.marginTop = Number(this._options.rowMoveShadowMarginTop || 0) + 'px';\n dd.clonedSlickRow.style.opacity = `${this._options.rowMoveShadowOpacity || 0.95}`;\n dd.clonedSlickRow.style.transform = `scale(${this._options.rowMoveShadowScale || 0.75})`;\n this._canvas.appendChild(dd.clonedSlickRow);\n }\n }\n\n let selectedRows = this._options.singleRowMove ? [cell.row] : this._grid.getSelectedRows();\n if (selectedRows.length === 0 || !selectedRows.some(selectedRow => selectedRow === cell.row)) {\n selectedRows = [cell.row];\n if (!this._options.disableRowSelection) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n selectedRows.sort((a, b) => a - b);\n\n const rowHeight = this._grid.getOptions().rowHeight;\n\n dd.fromGrid = this._grid;\n dd.toGrid = this._toGrid;\n dd.selectedRows = selectedRows;\n\n dd.selectionProxy = document.createElement('div');\n dd.selectionProxy.className = 'slick-reorder-proxy';\n dd.selectionProxy.style.display = 'none';\n dd.selectionProxy.style.position = 'absolute';\n dd.selectionProxy.style.zIndex = '99999';\n dd.selectionProxy.style.width = `${this._toCanvas.clientWidth}px`;\n dd.selectionProxy.style.height = `${rowHeight! * selectedRows.length}px`;\n this._toCanvas.appendChild(dd.selectionProxy);\n\n dd.guide = document.createElement('div');\n dd.guide.className = 'slick-reorder-guide';\n dd.guide.style.position = 'absolute';\n dd.guide.style.zIndex = '99999';\n dd.guide.style.width = `${this._toCanvas.clientWidth}px`;\n dd.guide.style.top = `-1000px`;\n this._toCanvas.appendChild(dd.guide);\n\n dd.insertBefore = -1;\n }\n\n protected handleDrag(evt: SlickEventData_, dd: DragRowMove): boolean | void {\n if (!this._dragging) {\n return;\n }\n\n evt.stopImmediatePropagation();\n const e = evt.getNativeEvent();\n\n const targetEvent = (e as TouchEvent).touches?.[0] ?? e;\n const top = targetEvent.pageY - (Utils.offset(this._toCanvas)?.top ?? 0);\n dd.selectionProxy.style.top = `${top - 5}px`;\n dd.selectionProxy.style.display = 'block';\n\n // if the row move shadow is enabled, we'll also make it follow the mouse cursor\n if (dd.clonedSlickRow) {\n dd.clonedSlickRow.style.top = `${top - 6}px`;\n dd.clonedSlickRow.style.display = 'block';\n }\n\n const insertBefore = Math.max(0, Math.min(Math.round(top / this._toGrid.getOptions().rowHeight!), this._toGrid.getDataLength()));\n if (insertBefore !== dd.insertBefore) {\n const eventData = {\n fromGrid: this._grid,\n toGrid: this._toGrid,\n rows: dd.selectedRows,\n insertBefore: insertBefore\n };\n\n if (this.onBeforeMoveRows.notify(eventData).getReturnValue() === false) {\n dd.canMove = false;\n } else {\n dd.canMove = true;\n }\n\n // if there's a UsabilityOverride defined, we also need to verify that the condition is valid\n if (this._usabilityOverride && dd.canMove) {\n const insertBeforeDataContext = this._toGrid.getDataItem(insertBefore);\n dd.canMove = this.checkUsabilityOverride(insertBefore, insertBeforeDataContext, this._toGrid);\n }\n\n // if the new target is possible we'll display the dark blue bar (representin the acceptability) at the target position\n // else it won't show up (it will be off the screen)\n if (!dd.canMove) {\n dd.guide.style.top = '-1000px';\n } else {\n dd.guide.style.top = `${insertBefore * (this._toGrid.getOptions().rowHeight || 0)}px`;\n }\n\n dd.insertBefore = insertBefore;\n }\n }\n\n protected handleDragEnd(e: SlickEventData_, dd: DragRowMove) {\n if (!this._dragging) {\n return;\n }\n this._dragging = false;\n e.stopImmediatePropagation();\n\n dd.guide?.remove();\n dd.selectionProxy?.remove();\n dd.clonedSlickRow?.remove();\n\n if (dd.canMove) {\n const eventData = {\n fromGrid: this._grid,\n toGrid: this._toGrid,\n rows: dd.selectedRows,\n insertBefore: dd.insertBefore\n };\n // TODO: this._grid.remapCellCssClasses ?\n this.onMoveRows.notify(eventData);\n }\n }\n\n getColumnDefinition(): Column {\n const columnId = String(this._options?.columnId ?? this._defaults.columnId);\n\n return {\n id: columnId,\n name: '',\n field: 'move',\n behavior: 'selectAndMove',\n excludeFromColumnPicker: true,\n excludeFromGridMenu: true,\n excludeFromHeaderMenu: true,\n selectable: false,\n resizable: false,\n width: this._options.width || 40,\n formatter: this.moveIconFormatter.bind(this)\n };\n }\n\n protected moveIconFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultObject | string {\n if (!this.checkUsabilityOverride(row, dataContext, grid)) {\n return '';\n } else {\n return { addClasses: `cell-reorder dnd ${this._options.cssClass || ''}`, text: '' };\n }\n }\n\n protected checkUsabilityOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._usabilityOverride === 'function') {\n return this._usabilityOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row moveable.\n * In order word, user can choose which rows to be an available as moveable (or not) by providing his own logic show/hide icon and usability.\n * @param overrideFn: override function callback\n */\n usabilityOverride(overrideFn: UsabilityOverrideFn) {\n this._usabilityOverride = overrideFn;\n }\n\n isHandlerColumn(columnIndex: number | string) {\n return /move|selectAndMove/.test(this._grid.getColumns()[+columnIndex].behavior || '');\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CrossGridRowMoveManager: SlickCrossGridRowMoveManager\n }\n });\n}\n\n"], + "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, DragRowMove, FormatterResultObject, CrossGridRowMoveManagerOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * Row Move Manager options:\n * cssClass: A CSS class to be added to the menu item container.\n * columnId: Column definition id (defaults to \"_move\")\n * cancelEditOnDrag: Do we want to cancel any Editing while dragging a row (defaults to false)\n * disableRowSelection: Do we want to disable the row selection? (defaults to false)\n * hideRowMoveShadow: Do we want to hide the row move shadow clone? (defaults to true)\n * rowMoveShadowMarginTop: When row move shadow is shown, optional margin-top (defaults to 0)\n * rowMoveShadowMarginLeft: When row move shadow is shown, optional margin-left (defaults to 0)\n * rowMoveShadowOpacity: When row move shadow is shown, what is its opacity? (defaults to 0.95)\n * rowMoveShadowScale: When row move shadow is shown, what is its size scale? (default to 0.75)\n * singleRowMove: Do we want a single row move? Setting this to false means that it's a multple row move (defaults to false)\n * width: Width of the column\n * usabilityOverride: Callback method that user can override the default behavior of the row being moveable or not\n *\n */\nexport class SlickCrossGridRowMoveManager {\n // --\n // public API\n pluginName = 'CrossGridRowMoveManager' as const;\n onBeforeMoveRows = new SlickEvent<{ rows: number[]; insertBefore: number; fromGrid: SlickGrid; toGrid: SlickGrid; }>();\n onMoveRows = new SlickEvent<{ rows: number[]; insertBefore: number; fromGrid: SlickGrid; toGrid: SlickGrid; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _canvas!: HTMLElement;\n protected _dragging = false;\n protected _toGrid!: SlickGrid;\n protected _toCanvas!: HTMLElement;\n protected _usabilityOverride?: UsabilityOverrideFn;\n protected _eventHandler: SlickEventHandler_;\n protected _options: CrossGridRowMoveManagerOption;\n protected _defaults: CrossGridRowMoveManagerOption = {\n columnId: '_move',\n cssClass: undefined,\n cancelEditOnDrag: false,\n disableRowSelection: false,\n hideRowMoveShadow: true,\n rowMoveShadowMarginTop: 0,\n rowMoveShadowMarginLeft: 0,\n rowMoveShadowOpacity: 0.95,\n rowMoveShadowScale: 0.75,\n singleRowMove: false,\n toGrid: undefined as any,\n width: 40,\n };\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._canvas = this._grid.getCanvasNode();\n this._toGrid = this._options.toGrid;\n this._toCanvas = this._toGrid.getCanvasNode();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options?.usabilityOverride === 'function') {\n this.usabilityOverride(this._options.usabilityOverride);\n }\n\n this._eventHandler\n .subscribe(this._grid.onDragInit, this.handleDragInit.bind(this))\n .subscribe(this._grid.onDragStart, this.handleDragStart.bind(this))\n .subscribe(this._grid.onDrag, this.handleDrag.bind(this))\n .subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));\n }\n\n destroy() {\n this._eventHandler.unsubscribeAll();\n }\n\n setOptions(newOptions: CrossGridRowMoveManagerOption) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n\n protected handleDragInit(e: SlickEventData_) {\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n }\n\n protected handleDragStart(e: DOMEvent, dd: DragRowMove & { fromGrid: SlickGrid; toGrid: SlickGrid; }): boolean | void {\n const cell = this._grid.getCellFromEvent(e) || { cell: -1, row: -1 };\n const currentRow = cell?.row ?? 0;\n const dataContext = this._grid.getDataItem(currentRow);\n\n if (!this.checkUsabilityOverride(currentRow, dataContext, this._grid)) {\n return;\n }\n\n if (this._options.cancelEditOnDrag && this._grid.getEditorLock().isActive()) {\n this._grid.getEditorLock().cancelCurrentEdit();\n }\n\n if (this._grid.getEditorLock().isActive() || !this.isHandlerColumn(cell.cell)) {\n return false;\n }\n\n this._dragging = true;\n e.stopImmediatePropagation();\n\n // optionally create a shadow element of the row so that we can see all the time which row exactly we're dragging\n if (!this._options.hideRowMoveShadow) {\n const cellNodeElm = this._grid.getCellNode(cell.row, cell.cell);\n const slickRowElm = cellNodeElm?.closest('.slick-row');\n if (slickRowElm) {\n dd.clonedSlickRow = slickRowElm.cloneNode(true) as HTMLDivElement;\n dd.clonedSlickRow.classList.add('slick-reorder-shadow-row');\n dd.clonedSlickRow.style.display = 'none';\n dd.clonedSlickRow.style.marginLeft = Number(this._options.rowMoveShadowMarginLeft || 0) + 'px';\n dd.clonedSlickRow.style.marginTop = Number(this._options.rowMoveShadowMarginTop || 0) + 'px';\n dd.clonedSlickRow.style.opacity = `${this._options.rowMoveShadowOpacity || 0.95}`;\n dd.clonedSlickRow.style.transform = `scale(${this._options.rowMoveShadowScale || 0.75})`;\n this._canvas.appendChild(dd.clonedSlickRow);\n }\n }\n\n let selectedRows = this._options.singleRowMove ? [cell.row] : this._grid.getSelectedRows();\n if (selectedRows.length === 0 || !selectedRows.some(selectedRow => selectedRow === cell.row)) {\n selectedRows = [cell.row];\n if (!this._options.disableRowSelection) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n selectedRows.sort((a, b) => a - b);\n\n const rowHeight = this._grid.getOptions().rowHeight;\n\n dd.fromGrid = this._grid;\n dd.toGrid = this._toGrid;\n dd.selectedRows = selectedRows;\n\n dd.selectionProxy = document.createElement('div');\n dd.selectionProxy.className = 'slick-reorder-proxy';\n dd.selectionProxy.style.display = 'none';\n dd.selectionProxy.style.position = 'absolute';\n dd.selectionProxy.style.zIndex = '99999';\n dd.selectionProxy.style.width = `${this._toCanvas.clientWidth}px`;\n dd.selectionProxy.style.height = `${rowHeight! * selectedRows.length}px`;\n this._toCanvas.appendChild(dd.selectionProxy);\n\n dd.guide = document.createElement('div');\n dd.guide.className = 'slick-reorder-guide';\n dd.guide.style.position = 'absolute';\n dd.guide.style.zIndex = '99999';\n dd.guide.style.width = `${this._toCanvas.clientWidth}px`;\n dd.guide.style.top = `-1000px`;\n this._toCanvas.appendChild(dd.guide);\n\n dd.insertBefore = -1;\n }\n\n protected handleDrag(evt: SlickEventData_, dd: DragRowMove): boolean | void {\n if (!this._dragging) {\n return;\n }\n\n evt.stopImmediatePropagation();\n const e = evt.getNativeEvent();\n\n const targetEvent = (e as TouchEvent).touches?.[0] ?? e;\n const top = targetEvent.pageY - (Utils.offset(this._toCanvas)?.top ?? 0);\n dd.selectionProxy.style.top = `${top - 5}px`;\n dd.selectionProxy.style.display = 'block';\n\n // if the row move shadow is enabled, we'll also make it follow the mouse cursor\n if (dd.clonedSlickRow) {\n dd.clonedSlickRow.style.top = `${top - 6}px`;\n dd.clonedSlickRow.style.display = 'block';\n }\n\n const insertBefore = Math.max(0, Math.min(Math.round(top / this._toGrid.getOptions().rowHeight!), this._toGrid.getDataLength()));\n if (insertBefore !== dd.insertBefore) {\n const eventData = {\n fromGrid: this._grid,\n toGrid: this._toGrid,\n rows: dd.selectedRows,\n insertBefore\n };\n\n if (this.onBeforeMoveRows.notify(eventData).getReturnValue() === false) {\n dd.canMove = false;\n } else {\n dd.canMove = true;\n }\n\n // if there's a UsabilityOverride defined, we also need to verify that the condition is valid\n if (this._usabilityOverride && dd.canMove) {\n const insertBeforeDataContext = this._toGrid.getDataItem(insertBefore);\n dd.canMove = this.checkUsabilityOverride(insertBefore, insertBeforeDataContext, this._toGrid);\n }\n\n // if the new target is possible we'll display the dark blue bar (representin the acceptability) at the target position\n // else it won't show up (it will be off the screen)\n if (!dd.canMove) {\n dd.guide.style.top = '-1000px';\n } else {\n dd.guide.style.top = `${insertBefore * (this._toGrid.getOptions().rowHeight || 0)}px`;\n }\n\n dd.insertBefore = insertBefore;\n }\n }\n\n protected handleDragEnd(e: SlickEventData_, dd: DragRowMove) {\n if (!this._dragging) {\n return;\n }\n this._dragging = false;\n e.stopImmediatePropagation();\n\n dd.guide?.remove();\n dd.selectionProxy?.remove();\n dd.clonedSlickRow?.remove();\n\n if (dd.canMove) {\n const eventData = {\n fromGrid: this._grid,\n toGrid: this._toGrid,\n rows: dd.selectedRows,\n insertBefore: dd.insertBefore\n };\n // TODO: this._grid.remapCellCssClasses ?\n this.onMoveRows.notify(eventData);\n }\n }\n\n getColumnDefinition(): Column {\n const columnId = String(this._options?.columnId ?? this._defaults.columnId);\n\n return {\n id: columnId,\n name: '',\n field: 'move',\n behavior: 'selectAndMove',\n excludeFromColumnPicker: true,\n excludeFromGridMenu: true,\n excludeFromHeaderMenu: true,\n selectable: false,\n resizable: false,\n width: this._options.width || 40,\n formatter: this.moveIconFormatter.bind(this)\n };\n }\n\n protected moveIconFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultObject | string {\n if (!this.checkUsabilityOverride(row, dataContext, grid)) {\n return '';\n } else {\n return { addClasses: `cell-reorder dnd ${this._options.cssClass || ''}`, text: '' };\n }\n }\n\n protected checkUsabilityOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._usabilityOverride === 'function') {\n return this._usabilityOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row moveable.\n * In order word, user can choose which rows to be an available as moveable (or not) by providing his own logic show/hide icon and usability.\n * @param overrideFn: override function callback\n */\n usabilityOverride(overrideFn: UsabilityOverrideFn) {\n this._usabilityOverride = overrideFn;\n }\n\n isHandlerColumn(columnIndex: number | string) {\n return /move|selectAndMove/.test(this._grid.getColumns()[+columnIndex].behavior || '');\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CrossGridRowMoveManager: SlickCrossGridRowMoveManager\n }\n });\n}\n\n"], "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.customtooltip.js.map b/dist/browser/plugins/slick.customtooltip.js.map index e4f270e1a..c96b3f74c 100644 --- a/dist/browser/plugins/slick.customtooltip.js.map +++ b/dist/browser/plugins/slick.customtooltip.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.customtooltip.ts"], - "sourcesContent": ["import type { CancellablePromiseWrapper, Column, CustomTooltipOption, DOMEvent, Formatter, GridOption } from '../models/index';\nimport { SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add Custom Tooltip when hovering a cell, it subscribes to the cell \"onMouseEnter\" and \"onMouseLeave\" events.\n * The \"customTooltip\" is defined in the Column Definition OR Grid Options (the first found will have priority over the second)\n *\n * USAGE:\n *\n * Add the slick.customTooltip.(js|css) files and register it with the grid.\n *\n * To specify a tooltip when hovering a cell, extend the column definition like so:\n * const customTooltipPlugin = new Slick.Plugins.CustomTooltip(columns, grid options);\n *\n * Available plugin options (same options are available in both column definition and/or grid options)\n *\n * Example 1 - via Column Definition\n * const columns = [\n * {\n * id: \"action\", name: \"Action\", field: \"action\", formatter: fakeButtonFormatter,\n * customTooltip: {\n * formatter: tooltipTaskFormatter,\n * usabilityOverride: (args) => !!(args.dataContext.id % 2) // show it only every second row\n * }\n * }\n * ];\n *\n * OR Example 2 - via Grid Options (for all columns), NOTE: the column definition tooltip options will win over the options defined in the grid options\n * const gridOptions = {\n * enableCellNavigation: true,\n * customTooltip: {\n * formatter: tooltipTaskFormatter,\n * usabilityOverride: (args) => !!(args.dataContext.id % 2) // show it only every second row\n * },\n * };\n *\n * Available options that can be defined from either a column definition or in grid options (column definition options as precendence)\n * asyncParamsPropName: defaults to \"__params\", optionally change the property name that will be used to merge the data returned by the async method into the `dataContext` object\n * asyncProcess: Async Post method returning a Promise, it must return an object with 1 or more properties. internally the data that will automatically be merged into the `dataContext` object under the `__params` property so that you can use it in your `asyncPostFormatter` formatter.\n * asyncPostFormatter: Formatter to execute once the async process is completed, to displayed the actual text result (used when dealing with an Async API to get data to display later in the tooltip)\n * hideArrow: defaults to False, should we hide the tooltip pointer arrow?\n * className: defaults to \"slick-custom-tooltip\"\n * formatter: Formatter to execute for displaying the data that will show in the tooltip. NOTE: when using `asyncProcess`, this formatter will be executed first and prior to the actual async process.\n * headerFormatter: Formatter to execute when custom tooltip is over a header column\n * headerRowFormatter: Formatter to execute when custom tooltip is over a heade row column (e.g. filter)\n * maxHeight: optional maximum height number (in pixel) of the tooltip container\n * maxWidth: optional maximum width number (in pixel) of the tooltip container\n * offsetLeft: defaults to 0, optional left offset, it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * offsetRight: defaults to 0, optional right offset, it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * offsetTopBottom: defaults to 4, optional top or bottom offset (depending on which side it shows), it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * position: defaults to \"auto\" (available options: 'auto' | 'top' | 'bottom' | 'left-align' | 'right-align'), allows to align the tooltip to the best logical position in the window, by default it will show on top left but if it calculates that it doesn't have enough space it will use bottom (same goes for each side align)\n * regularTooltipWhiteSpace: defaults to `pre-line`, optionally change the style `white-space` when displaying regular text tooltip. NOTE: when using a formatter it will use the `whiteSpace` setting instead\n * whiteSpace: defaults to `normal`, optionally change the style `white-space` when displaying tooltip with formatter (tooltip or regular formatter)\n * useRegularTooltip: defaults to False, when set to True it will try parse through the regular cell formatter and try to find a `title` attribute to show as a regular tooltip (also note: this has precedence over customTooltip formatter defined)\n * useRegularTooltipFromFormatterOnly: defaults to False, optionally force to retrieve the `title` from the Formatter result instead of the cell itself.\n * for example, when used in combo with the AutoTooltip plugin we might want to force the tooltip to read the `title` attribute from the formatter result first instead of the cell itself,\n * make the cell as a 2nd read, in other words check the formatter prior to the cell which the AutoTooltip might have filled.\n * renderRegularTooltipAsHtml: defaults to false, regular \"title\" tooltip won't be rendered as html unless specified via this flag (also \"\\r\\n\" will be replaced by
)\n * tooltipTextMaxLength: defaults to 700 (characters), when defined the text will be truncated to the max length characters provided\n * usabilityOverride: callback method that user can override the default behavior of showing the tooltip. If it returns False, then the tooltip won't show\n *\n * @param options {Object} Custom Tooltip Options\n * @class Slick.Plugins.CustomTooltip\n * @constructor\n */\n\ntype CellType = 'slick-cell' | 'slick-header-column' | 'slick-headerrow-column';\n\n/**\n * CustomTooltip plugin to show/hide tooltips when columns are too narrow to fit content.\n * @constructor\n * @param {boolean} [options.className=\"slick-custom-tooltip\"] - custom tooltip class name\n * @param {boolean} [options.offsetTop=5] - tooltip offset from the top\n */\nexport class CustomTooltip {\n // --\n // public API\n pluginName = 'CustomTooltip' as const;\n\n // --\n // protected props\n protected _cancellablePromise?: CancellablePromiseWrapper;\n protected _cellNodeElm?: HTMLDivElement;\n protected _dataView?: SlickDataView | null;\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption\n protected _tooltipElm?: HTMLDivElement;\n protected _options!: CustomTooltipOption;\n protected _defaults: CustomTooltipOption = {\n className: 'slick-custom-tooltip',\n offsetLeft: 0,\n offsetRight: 0,\n offsetTopBottom: 4,\n hideArrow: false,\n tooltipTextMaxLength: 700,\n regularTooltipWhiteSpace: 'pre-line',\n whiteSpace: 'normal',\n };\n protected _eventHandler = new SlickEventHandler();\n protected _cellTooltipOptions!: CustomTooltipOption;\n\n constructor(protected readonly tooltipOptions: Partial) { }\n\n /**\n * Initialize plugin.\n */\n init(grid: SlickGrid) {\n this._grid = grid;\n const _data = grid?.getData() || [];\n this._dataView = Array.isArray(_data) ? null : _data as SlickDataView;\n this._gridOptions = (grid.getOptions() || {}) as GridOption;\n this._options = Utils.extend(true, {}, this._defaults, this._gridOptions.customTooltip, this.tooltipOptions);\n this._eventHandler\n .subscribe(grid.onMouseEnter, this.handleOnMouseEnter.bind(this))\n .subscribe(grid.onHeaderMouseEnter, (e, args) => this.handleOnHeaderMouseEnterByType(e, args, 'slick-header-column'))\n .subscribe(grid.onHeaderRowMouseEnter, (e, args) => this.handleOnHeaderMouseEnterByType(e, args, 'slick-headerrow-column'))\n .subscribe(grid.onMouseLeave, () => this.hideTooltip())\n .subscribe(grid.onHeaderMouseLeave, () => this.hideTooltip())\n .subscribe(grid.onHeaderRowMouseLeave, () => this.hideTooltip());\n }\n\n /**\n * Destroy plugin.\n */\n destroy() {\n this.hideTooltip();\n this._eventHandler.unsubscribeAll();\n }\n\n /** depending on the selector type, execute the necessary handler code */\n protected handleOnHeaderMouseEnterByType(e: DOMEvent, args: any, selector: CellType) {\n // before doing anything, let's remove any previous tooltip before\n // and cancel any opened Promise/Observable when using async\n this.hideTooltip();\n\n const cell = {\n row: -1, // negative row to avoid pulling any dataContext while rendering\n cell: this._grid.getColumns().findIndex((col) => args?.column?.id === col.id)\n };\n const columnDef = args.column;\n const item = {};\n const isHeaderRowType = selector === 'slick-headerrow-column';\n\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.cell = cell.cell;\n args.row = cell.row;\n args.columnDef = columnDef;\n args.dataContext = item;\n args.grid = this._grid;\n args.type = isHeaderRowType ? 'header-row' : 'header';\n\n this._cellTooltipOptions = Utils.extend(true, {}, this._options, columnDef.customTooltip);\n if ((columnDef?.disableTooltip) || !this.runOverrideFunctionWhenExists(this._cellTooltipOptions.usabilityOverride, args)) {\n return;\n }\n\n if (columnDef && e.target) {\n this._cellNodeElm = (e.target as HTMLDivElement).closest(`.${selector}`) as HTMLDivElement;\n const formatter = isHeaderRowType ? this._cellTooltipOptions.headerRowFormatter : this._cellTooltipOptions.headerFormatter;\n\n if (this._cellTooltipOptions.useRegularTooltip || !formatter) {\n const formatterOrText = !isHeaderRowType ? columnDef.name : this._cellTooltipOptions.useRegularTooltip ? null : formatter;\n this.renderRegularTooltip(formatterOrText, cell, null, columnDef, item);\n } else if (this._cellNodeElm && typeof formatter === 'function') {\n this.renderTooltipFormatter(formatter, cell, null, columnDef, item);\n }\n }\n }\n\n /**\n * Handle mouse entering grid cell to show tooltip.\n * @param {jQuery.Event} e - The event\n */\n protected handleOnMouseEnter(e: DOMEvent, args: any) {\n // before doing anything, let's remove any previous tooltip before\n // and cancel any opened Promise/Observable when using async\n this.hideTooltip();\n\n if (this._grid && e) {\n // get cell only when it's possible (ie, Composite Editor will not be able to get cell and so it will never show any tooltip)\n const targetClassName = (event?.target as HTMLDivElement)?.closest('.slick-cell')?.className;\n const cell = (targetClassName && /l\\d+/.exec(targetClassName || '')) ? this._grid.getCellFromEvent(e) : null;\n\n if (cell) {\n const item = this._dataView ? this._dataView.getItem(cell.row) : this._grid.getDataItem(cell.row);\n const columnDef = this._grid.getColumns()[cell.cell];\n this._cellNodeElm = this._grid.getCellNode(cell.row, cell.cell) as HTMLDivElement;\n this._cellTooltipOptions = Utils.extend(true, {}, this._options, columnDef.customTooltip);\n\n if (item && columnDef) {\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.cell = cell.cell;\n args.row = cell.row;\n args.columnDef = columnDef;\n args.dataContext = item;\n args.grid = this._grid;\n args.type = 'cell';\n if ((columnDef?.disableTooltip) || !this.runOverrideFunctionWhenExists(this._cellTooltipOptions.usabilityOverride, args)) {\n return;\n }\n\n const value = item.hasOwnProperty(columnDef.field) ? item[columnDef.field] : null;\n\n if (this._cellTooltipOptions.useRegularTooltip || !this._cellTooltipOptions.formatter) {\n this.renderRegularTooltip(columnDef.formatter, cell, value, columnDef, item);\n } else {\n if (typeof this._cellTooltipOptions.formatter === 'function') {\n this.renderTooltipFormatter(this._cellTooltipOptions.formatter, cell, value, columnDef, item);\n }\n if (typeof this._cellTooltipOptions.asyncProcess === 'function') {\n const asyncProcess = this._cellTooltipOptions.asyncProcess(cell.row, cell.cell, value, columnDef, item, this._grid);\n if (!this._cellTooltipOptions.asyncPostFormatter) {\n throw new Error('[SlickGrid] when using \"asyncProcess\", you must also provide an \"asyncPostFormatter\" formatter');\n }\n\n if (asyncProcess instanceof Promise) {\n // create a new cancellable promise which will resolve, unless it's cancelled, with the udpated `dataContext` object that includes the `this._this._params`\n this._cancellablePromise = this.cancellablePromise(asyncProcess);\n this._cancellablePromise.promise\n .then((asyncResult) => {\n this.asyncProcessCallback(asyncResult, cell, value, columnDef, item)\n })\n .catch(function (error) {\n // we will throw back any errors, unless it's a cancelled promise which in that case will be disregarded (thrown by the promise wrapper cancel() call)\n if (!(error.isPromiseCancelled)) {\n throw error;\n }\n });\n }\n }\n }\n }\n }\n }\n }\n\n protected findFirstElementAttribute(inputElm: Element | null | undefined, attributes: string[]): string | null {\n if (inputElm) {\n let outputAttrData: string | null = null;\n attributes.forEach((attribute) => {\n const attrData = inputElm.getAttribute(attribute);\n if (attrData) {\n outputAttrData = attrData;\n }\n });\n return outputAttrData;\n }\n return null;\n }\n\n /**\n * Parse the cell formatter and assume it might be html\n * then create a temporary html element to easily retrieve the first [title=\"\"] attribute text content\n * also clear the \"title\" attribute from the grid div text content so that it won't show also as a 2nd browser tooltip\n */\n protected renderRegularTooltip(formatterOrText: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: any) {\n const tmpDiv = document.createElement('div');\n tmpDiv.innerHTML = this.parseFormatterAndSanitize(formatterOrText, cell, value, columnDef, item);\n let tooltipText = columnDef.toolTip || '';\n let tmpTitleElm;\n\n if (!tooltipText) {\n if ((this._cellNodeElm && (this._cellNodeElm.clientWidth < this._cellNodeElm.scrollWidth)) && !this._cellTooltipOptions.useRegularTooltipFromFormatterOnly) {\n tooltipText = (this._cellNodeElm.textContent || '').trim() || '';\n if (this._cellTooltipOptions.tooltipTextMaxLength && (tooltipText.length > this._cellTooltipOptions.tooltipTextMaxLength)) {\n tooltipText = tooltipText.substring(0, this._cellTooltipOptions.tooltipTextMaxLength - 3) + '...';\n }\n tmpTitleElm = this._cellNodeElm;\n } else {\n if (this._cellTooltipOptions.useRegularTooltipFromFormatterOnly) {\n tmpTitleElm = tmpDiv.querySelector('[title], [data-slick-tooltip]');\n } else {\n tmpTitleElm = this.findFirstElementAttribute(this._cellNodeElm, ['title', 'data-slick-tooltip']) ? this._cellNodeElm : tmpDiv.querySelector('[title], [data-slick-tooltip]');\n if ((!tmpTitleElm || !this.findFirstElementAttribute(tmpTitleElm, ['title', 'data-slick-tooltip'])) && this._cellNodeElm) {\n tmpTitleElm = this._cellNodeElm.querySelector('[title], [data-slick-tooltip]');\n }\n }\n if (!tooltipText || (typeof formatterOrText === 'function' && this._cellTooltipOptions.useRegularTooltipFromFormatterOnly)) {\n tooltipText = this.findFirstElementAttribute(tmpTitleElm, ['title', 'data-slick-tooltip']) || '';\n }\n }\n }\n\n if (tooltipText !== '') {\n this.renderTooltipFormatter(formatterOrText, cell, value, columnDef, item, tooltipText);\n }\n\n // also clear any \"title\" attribute to avoid showing a 2nd browser tooltip\n this.swapAndClearTitleAttribute(tmpTitleElm, tooltipText);\n }\n\n /**\n * swap and copy the \"title\" attribute into a new custom attribute then clear the \"title\" attribute\n * from the grid div text content so that it won't show also as a 2nd browser tooltip\n */\n protected swapAndClearTitleAttribute(inputTitleElm?: Element | null, tooltipText?: string) {\n // the title attribute might be directly on the slick-cell container element (when formatter returns a result object)\n // OR in a child element (most commonly as a custom formatter)\n const titleElm = inputTitleElm || (this._cellNodeElm && ((this._cellNodeElm.hasAttribute('title') && this._cellNodeElm.getAttribute('title')) ? this._cellNodeElm : this._cellNodeElm.querySelector('[title]')));\n\n // flip tooltip text from `title` to `data-slick-tooltip`\n if (titleElm) {\n titleElm.setAttribute('data-slick-tooltip', tooltipText || '');\n if (titleElm.hasAttribute('title')) {\n titleElm.setAttribute('title', '');\n }\n }\n }\n\n protected asyncProcessCallback(asyncResult: any, cell: { row: number, cell: number }, value: any, columnDef: Column, dataContext: any) {\n this.hideTooltip();\n const itemWithAsyncData = Utils.extend(true, {}, dataContext, { [this._cellTooltipOptions.asyncParamsPropName || '__params']: asyncResult });\n this.renderTooltipFormatter(this._cellTooltipOptions.asyncPostFormatter, cell, value, columnDef, itemWithAsyncData);\n }\n\n protected cancellablePromise(inputPromise: Promise): CancellablePromiseWrapper {\n let hasCancelled = false;\n\n if (inputPromise instanceof Promise) {\n return {\n promise: inputPromise.then(function (result) {\n if (hasCancelled) {\n throw { isPromiseCancelled: true };\n }\n return result;\n }),\n cancel: () => hasCancelled = true\n };\n }\n return inputPromise;\n }\n\n protected getHtmlElementOffset(element?: HTMLElement | null) {\n if (!element) {\n return undefined;\n }\n const rect = element.getBoundingClientRect();\n let left = 0;\n let top = 0;\n let bottom = 0;\n let right = 0;\n\n if (rect.top !== undefined && rect.left !== undefined) {\n top = rect.top + window.pageYOffset;\n left = rect.left + window.pageXOffset;\n right = rect.right;\n bottom = rect.bottom;\n }\n return { top: top, left: left, bottom: bottom, right: right };\n }\n\n /**\n * hide (remove) tooltip from the DOM,\n * when using async process, it will also cancel any opened Promise/Observable that might still be opened/pending.\n */\n hideTooltip() {\n this._cancellablePromise?.cancel();\n const prevTooltip = document.body.querySelector(`.${this._cellTooltipOptions?.className ?? this._defaults.className}.${this._grid.getUID()}`);\n prevTooltip?.remove();\n }\n\n /**\n * Reposition the Tooltip to be top-left position over the cell.\n * By default we use an \"auto\" mode which will allow to position the Tooltip to the best logical position in the window, also when we mention position, we are talking about the relative position against the grid cell.\n * We can assume that in 80% of the time the default position is top-right, the default is \"auto\" but we can also override it and use a specific position.\n * Most of the time positioning of the tooltip will be to the \"top-right\" of the cell is ok but if our column is completely on the right side then we'll want to change the position to \"left\" align.\n * Same goes for the top/bottom position, Most of the time positioning the tooltip to the \"top\" but if we are hovering a cell at the top of the grid and there's no room to display it then we might need to reposition to \"bottom\" instead.\n */\n protected reposition(cell: { row: number; cell: number; }) {\n if (this._tooltipElm) {\n this._cellNodeElm = (this._cellNodeElm || this._grid.getCellNode(cell.row, cell.cell)) as HTMLDivElement;\n const cellPosition = this.getHtmlElementOffset(this._cellNodeElm);\n const cellContainerWidth = this._cellNodeElm.offsetWidth;\n const calculatedTooltipHeight = this._tooltipElm.getBoundingClientRect().height;\n const calculatedTooltipWidth = this._tooltipElm.getBoundingClientRect().width;\n const calculatedBodyWidth = document.body.offsetWidth || window.innerWidth;\n\n // first calculate the default (top/left) position\n let newPositionTop = (cellPosition?.top || 0) - this._tooltipElm.offsetHeight - (this._cellTooltipOptions.offsetTopBottom ?? 0);\n let newPositionLeft = (cellPosition?.left || 0) - (this._cellTooltipOptions.offsetRight ?? 0);\n\n // user could explicitely use a \"left-align\" arrow position, (when user knows his column is completely on the right in the grid)\n // or when using \"auto\" and we detect not enough available space then we'll position to the \"left\" of the cell\n const position = this._cellTooltipOptions.position || 'auto';\n if (position === 'center') {\n newPositionLeft += (cellContainerWidth / 2) - (calculatedTooltipWidth / 2) + (this._cellTooltipOptions.offsetRight || 0);\n this._tooltipElm.classList.remove('arrow-left-align');\n this._tooltipElm.classList.remove('arrow-right-align');\n this._tooltipElm.classList.add('arrow-center-align');\n\n } else if (position === 'right-align' || ((position === 'auto' || position !== 'left-align') && (newPositionLeft + calculatedTooltipWidth) > calculatedBodyWidth)) {\n newPositionLeft -= (calculatedTooltipWidth - cellContainerWidth - (this._cellTooltipOptions.offsetLeft || 0));\n this._tooltipElm.classList.remove('arrow-center-align');\n this._tooltipElm.classList.remove('arrow-left-align');\n this._tooltipElm.classList.add('arrow-right-align');\n } else {\n this._tooltipElm.classList.remove('arrow-center-align');\n this._tooltipElm.classList.remove('arrow-right-align');\n this._tooltipElm.classList.add('arrow-left-align');\n }\n\n // do the same calculation/reposition with top/bottom (default is top of the cell or in other word starting from the cell going down)\n if (position === 'bottom' || (position === 'auto' && calculatedTooltipHeight > Utils.calculateAvailableSpace(this._cellNodeElm).top)) {\n newPositionTop = (cellPosition?.top || 0) + (this._gridOptions.rowHeight || 0) + (this._cellTooltipOptions.offsetTopBottom || 0);\n this._tooltipElm.classList.remove('arrow-down');\n this._tooltipElm.classList.add('arrow-up');\n } else {\n this._tooltipElm.classList.add('arrow-down');\n this._tooltipElm.classList.remove('arrow-up');\n }\n\n // reposition the tooltip over the cell (90% of the time this will end up using a position on the \"right\" of the cell)\n this._tooltipElm.style.top = newPositionTop + 'px';\n this._tooltipElm.style.left = newPositionLeft + 'px';\n }\n }\n\n /**\n * Parse the Custom Formatter (when provided) or return directly the text when it is already a string.\n * We will also sanitize the text in both cases before returning it so that it can be used safely.\n */\n protected parseFormatterAndSanitize(formatterOrText: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: unknown): string {\n if (typeof formatterOrText === 'function') {\n const tooltipText = formatterOrText(cell.row, cell.cell, value, columnDef, item, this._grid);\n const formatterText = (typeof tooltipText === 'object' && tooltipText?.text) ? tooltipText.text : (typeof tooltipText === 'string' ? tooltipText : '');\n return this._grid.sanitizeHtmlString(formatterText);\n } else if (typeof formatterOrText === 'string') {\n return this._grid.sanitizeHtmlString(formatterOrText);\n }\n return '';\n }\n\n\n protected renderTooltipFormatter(formatter: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: unknown, tooltipText?: string, inputTitleElm?: Element | null) {\n // create the tooltip DOM element with the text returned by the Formatter\n this._tooltipElm = document.createElement('div');\n this._tooltipElm.className = (this._cellTooltipOptions.className || this._defaults.className) as string;\n this._tooltipElm.classList.add(this._grid.getUID());\n this._tooltipElm.classList.add('l' + cell.cell);\n this._tooltipElm.classList.add('r' + cell.cell);\n let outputText = tooltipText || this.parseFormatterAndSanitize(formatter, cell, value, columnDef, item) || '';\n outputText = (this._cellTooltipOptions.tooltipTextMaxLength && outputText.length > this._cellTooltipOptions.tooltipTextMaxLength) ? outputText.substring(0, this._cellTooltipOptions.tooltipTextMaxLength - 3) + '...' : outputText;\n\n let finalOutputText = '';\n if (!tooltipText || (this._cellTooltipOptions?.renderRegularTooltipAsHtml)) {\n finalOutputText = this._grid.sanitizeHtmlString(outputText);\n this._tooltipElm.innerHTML = finalOutputText;\n this._tooltipElm.style.whiteSpace = this._cellTooltipOptions?.whiteSpace ?? this._defaults.whiteSpace as string;\n } else {\n finalOutputText = outputText || '';\n this._tooltipElm.textContent = finalOutputText;\n this._tooltipElm.style.whiteSpace = this._cellTooltipOptions?.regularTooltipWhiteSpace ?? this._defaults.regularTooltipWhiteSpace as string; // use `pre` so that sequences of white space are collapsed. Lines are broken at newline characters\n }\n\n // optional max height/width of the tooltip container\n if (this._cellTooltipOptions.maxHeight) {\n this._tooltipElm.style.maxHeight = this._cellTooltipOptions.maxHeight + 'px';\n }\n if (this._cellTooltipOptions.maxWidth) {\n this._tooltipElm.style.maxWidth = this._cellTooltipOptions.maxWidth + 'px';\n }\n\n // when do have text to show, then append the new tooltip to the html body & reposition the tooltip\n if (finalOutputText) {\n document.body.appendChild(this._tooltipElm);\n\n // reposition the tooltip on top of the cell that triggered the mouse over event\n this.reposition(cell);\n\n // user could optionally hide the tooltip arrow (we can simply update the CSS variables, that's the only way we have to update CSS pseudo)\n if (!this._cellTooltipOptions.hideArrow) {\n this._tooltipElm.classList.add('tooltip-arrow');\n }\n\n // also clear any \"title\" attribute to avoid showing a 2nd browser tooltip\n this.swapAndClearTitleAttribute(inputTitleElm, outputText);\n }\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n\n setOptions(newOptions: Partial) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n CustomTooltip\n }\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import type { CancellablePromiseWrapper, Column, CustomTooltipOption, DOMEvent, Formatter, GridOption } from '../models/index';\nimport { SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add Custom Tooltip when hovering a cell, it subscribes to the cell \"onMouseEnter\" and \"onMouseLeave\" events.\n * The \"customTooltip\" is defined in the Column Definition OR Grid Options (the first found will have priority over the second)\n *\n * USAGE:\n *\n * Add the slick.customTooltip.(js|css) files and register it with the grid.\n *\n * To specify a tooltip when hovering a cell, extend the column definition like so:\n * const customTooltipPlugin = new Slick.Plugins.CustomTooltip(columns, grid options);\n *\n * Available plugin options (same options are available in both column definition and/or grid options)\n *\n * Example 1 - via Column Definition\n * const columns = [\n * {\n * id: \"action\", name: \"Action\", field: \"action\", formatter: fakeButtonFormatter,\n * customTooltip: {\n * formatter: tooltipTaskFormatter,\n * usabilityOverride: (args) => !!(args.dataContext.id % 2) // show it only every second row\n * }\n * }\n * ];\n *\n * OR Example 2 - via Grid Options (for all columns), NOTE: the column definition tooltip options will win over the options defined in the grid options\n * const gridOptions = {\n * enableCellNavigation: true,\n * customTooltip: {\n * formatter: tooltipTaskFormatter,\n * usabilityOverride: (args) => !!(args.dataContext.id % 2) // show it only every second row\n * },\n * };\n *\n * Available options that can be defined from either a column definition or in grid options (column definition options as precendence)\n * asyncParamsPropName: defaults to \"__params\", optionally change the property name that will be used to merge the data returned by the async method into the `dataContext` object\n * asyncProcess: Async Post method returning a Promise, it must return an object with 1 or more properties. internally the data that will automatically be merged into the `dataContext` object under the `__params` property so that you can use it in your `asyncPostFormatter` formatter.\n * asyncPostFormatter: Formatter to execute once the async process is completed, to displayed the actual text result (used when dealing with an Async API to get data to display later in the tooltip)\n * hideArrow: defaults to False, should we hide the tooltip pointer arrow?\n * className: defaults to \"slick-custom-tooltip\"\n * formatter: Formatter to execute for displaying the data that will show in the tooltip. NOTE: when using `asyncProcess`, this formatter will be executed first and prior to the actual async process.\n * headerFormatter: Formatter to execute when custom tooltip is over a header column\n * headerRowFormatter: Formatter to execute when custom tooltip is over a heade row column (e.g. filter)\n * maxHeight: optional maximum height number (in pixel) of the tooltip container\n * maxWidth: optional maximum width number (in pixel) of the tooltip container\n * offsetLeft: defaults to 0, optional left offset, it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * offsetRight: defaults to 0, optional right offset, it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * offsetTopBottom: defaults to 4, optional top or bottom offset (depending on which side it shows), it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * position: defaults to \"auto\" (available options: 'auto' | 'top' | 'bottom' | 'left-align' | 'right-align'), allows to align the tooltip to the best logical position in the window, by default it will show on top left but if it calculates that it doesn't have enough space it will use bottom (same goes for each side align)\n * regularTooltipWhiteSpace: defaults to `pre-line`, optionally change the style `white-space` when displaying regular text tooltip. NOTE: when using a formatter it will use the `whiteSpace` setting instead\n * whiteSpace: defaults to `normal`, optionally change the style `white-space` when displaying tooltip with formatter (tooltip or regular formatter)\n * useRegularTooltip: defaults to False, when set to True it will try parse through the regular cell formatter and try to find a `title` attribute to show as a regular tooltip (also note: this has precedence over customTooltip formatter defined)\n * useRegularTooltipFromFormatterOnly: defaults to False, optionally force to retrieve the `title` from the Formatter result instead of the cell itself.\n * for example, when used in combo with the AutoTooltip plugin we might want to force the tooltip to read the `title` attribute from the formatter result first instead of the cell itself,\n * make the cell as a 2nd read, in other words check the formatter prior to the cell which the AutoTooltip might have filled.\n * renderRegularTooltipAsHtml: defaults to false, regular \"title\" tooltip won't be rendered as html unless specified via this flag (also \"\\r\\n\" will be replaced by
)\n * tooltipTextMaxLength: defaults to 700 (characters), when defined the text will be truncated to the max length characters provided\n * usabilityOverride: callback method that user can override the default behavior of showing the tooltip. If it returns False, then the tooltip won't show\n *\n * @param options {Object} Custom Tooltip Options\n * @class Slick.Plugins.CustomTooltip\n * @constructor\n */\n\ntype CellType = 'slick-cell' | 'slick-header-column' | 'slick-headerrow-column';\n\n/**\n * CustomTooltip plugin to show/hide tooltips when columns are too narrow to fit content.\n * @constructor\n * @param {boolean} [options.className=\"slick-custom-tooltip\"] - custom tooltip class name\n * @param {boolean} [options.offsetTop=5] - tooltip offset from the top\n */\nexport class CustomTooltip {\n // --\n // public API\n pluginName = 'CustomTooltip' as const;\n\n // --\n // protected props\n protected _cancellablePromise?: CancellablePromiseWrapper;\n protected _cellNodeElm?: HTMLDivElement;\n protected _dataView?: SlickDataView | null;\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _tooltipElm?: HTMLDivElement;\n protected _options!: CustomTooltipOption;\n protected _defaults: CustomTooltipOption = {\n className: 'slick-custom-tooltip',\n offsetLeft: 0,\n offsetRight: 0,\n offsetTopBottom: 4,\n hideArrow: false,\n tooltipTextMaxLength: 700,\n regularTooltipWhiteSpace: 'pre-line',\n whiteSpace: 'normal',\n };\n protected _eventHandler = new SlickEventHandler();\n protected _cellTooltipOptions!: CustomTooltipOption;\n\n constructor(protected readonly tooltipOptions: Partial) { }\n\n /**\n * Initialize plugin.\n */\n init(grid: SlickGrid) {\n this._grid = grid;\n const _data = grid?.getData() || [];\n this._dataView = Array.isArray(_data) ? null : _data as SlickDataView;\n this._gridOptions = (grid.getOptions() || {}) as GridOption;\n this._options = Utils.extend(true, {}, this._defaults, this._gridOptions.customTooltip, this.tooltipOptions);\n this._eventHandler\n .subscribe(grid.onMouseEnter, this.handleOnMouseEnter.bind(this))\n .subscribe(grid.onHeaderMouseEnter, (e, args) => this.handleOnHeaderMouseEnterByType(e, args, 'slick-header-column'))\n .subscribe(grid.onHeaderRowMouseEnter, (e, args) => this.handleOnHeaderMouseEnterByType(e, args, 'slick-headerrow-column'))\n .subscribe(grid.onMouseLeave, () => this.hideTooltip())\n .subscribe(grid.onHeaderMouseLeave, () => this.hideTooltip())\n .subscribe(grid.onHeaderRowMouseLeave, () => this.hideTooltip());\n }\n\n /**\n * Destroy plugin.\n */\n destroy() {\n this.hideTooltip();\n this._eventHandler.unsubscribeAll();\n }\n\n /** depending on the selector type, execute the necessary handler code */\n protected handleOnHeaderMouseEnterByType(e: DOMEvent, args: any, selector: CellType) {\n // before doing anything, let's remove any previous tooltip before\n // and cancel any opened Promise/Observable when using async\n this.hideTooltip();\n\n const cell = {\n row: -1, // negative row to avoid pulling any dataContext while rendering\n cell: this._grid.getColumns().findIndex((col) => args?.column?.id === col.id)\n };\n const columnDef = args.column;\n const item = {};\n const isHeaderRowType = selector === 'slick-headerrow-column';\n\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.cell = cell.cell;\n args.row = cell.row;\n args.columnDef = columnDef;\n args.dataContext = item;\n args.grid = this._grid;\n args.type = isHeaderRowType ? 'header-row' : 'header';\n\n this._cellTooltipOptions = Utils.extend(true, {}, this._options, columnDef.customTooltip);\n if ((columnDef?.disableTooltip) || !this.runOverrideFunctionWhenExists(this._cellTooltipOptions.usabilityOverride, args)) {\n return;\n }\n\n if (columnDef && e.target) {\n this._cellNodeElm = (e.target as HTMLDivElement).closest(`.${selector}`) as HTMLDivElement;\n const formatter = isHeaderRowType ? this._cellTooltipOptions.headerRowFormatter : this._cellTooltipOptions.headerFormatter;\n\n if (this._cellTooltipOptions.useRegularTooltip || !formatter) {\n const formatterOrText = !isHeaderRowType ? columnDef.name : this._cellTooltipOptions.useRegularTooltip ? null : formatter;\n this.renderRegularTooltip(formatterOrText, cell, null, columnDef, item);\n } else if (this._cellNodeElm && typeof formatter === 'function') {\n this.renderTooltipFormatter(formatter, cell, null, columnDef, item);\n }\n }\n }\n\n /**\n * Handle mouse entering grid cell to show tooltip.\n * @param {jQuery.Event} e - The event\n */\n protected handleOnMouseEnter(e: DOMEvent, args: any) {\n // before doing anything, let's remove any previous tooltip before\n // and cancel any opened Promise/Observable when using async\n this.hideTooltip();\n\n if (this._grid && e) {\n // get cell only when it's possible (ie, Composite Editor will not be able to get cell and so it will never show any tooltip)\n const targetClassName = (event?.target as HTMLDivElement)?.closest('.slick-cell')?.className;\n const cell = (targetClassName && /l\\d+/.exec(targetClassName || '')) ? this._grid.getCellFromEvent(e) : null;\n\n if (cell) {\n const item = this._dataView ? this._dataView.getItem(cell.row) : this._grid.getDataItem(cell.row);\n const columnDef = this._grid.getColumns()[cell.cell];\n this._cellNodeElm = this._grid.getCellNode(cell.row, cell.cell) as HTMLDivElement;\n this._cellTooltipOptions = Utils.extend(true, {}, this._options, columnDef.customTooltip);\n\n if (item && columnDef) {\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.cell = cell.cell;\n args.row = cell.row;\n args.columnDef = columnDef;\n args.dataContext = item;\n args.grid = this._grid;\n args.type = 'cell';\n if ((columnDef?.disableTooltip) || !this.runOverrideFunctionWhenExists(this._cellTooltipOptions.usabilityOverride, args)) {\n return;\n }\n\n const value = item.hasOwnProperty(columnDef.field) ? item[columnDef.field] : null;\n\n if (this._cellTooltipOptions.useRegularTooltip || !this._cellTooltipOptions.formatter) {\n this.renderRegularTooltip(columnDef.formatter, cell, value, columnDef, item);\n } else {\n if (typeof this._cellTooltipOptions.formatter === 'function') {\n this.renderTooltipFormatter(this._cellTooltipOptions.formatter, cell, value, columnDef, item);\n }\n if (typeof this._cellTooltipOptions.asyncProcess === 'function') {\n const asyncProcess = this._cellTooltipOptions.asyncProcess(cell.row, cell.cell, value, columnDef, item, this._grid);\n if (!this._cellTooltipOptions.asyncPostFormatter) {\n throw new Error('[SlickGrid] when using \"asyncProcess\", you must also provide an \"asyncPostFormatter\" formatter');\n }\n\n if (asyncProcess instanceof Promise) {\n // create a new cancellable promise which will resolve, unless it's cancelled, with the udpated `dataContext` object that includes the `this._this._params`\n this._cancellablePromise = this.cancellablePromise(asyncProcess);\n this._cancellablePromise.promise\n .then((asyncResult) => {\n this.asyncProcessCallback(asyncResult, cell, value, columnDef, item);\n })\n .catch(function (error) {\n // we will throw back any errors, unless it's a cancelled promise which in that case will be disregarded (thrown by the promise wrapper cancel() call)\n if (!(error.isPromiseCancelled)) {\n throw error;\n }\n });\n }\n }\n }\n }\n }\n }\n }\n\n protected findFirstElementAttribute(inputElm: Element | null | undefined, attributes: string[]): string | null {\n if (inputElm) {\n let outputAttrData: string | null = null;\n attributes.forEach((attribute) => {\n const attrData = inputElm.getAttribute(attribute);\n if (attrData) {\n outputAttrData = attrData;\n }\n });\n return outputAttrData;\n }\n return null;\n }\n\n /**\n * Parse the cell formatter and assume it might be html\n * then create a temporary html element to easily retrieve the first [title=\"\"] attribute text content\n * also clear the \"title\" attribute from the grid div text content so that it won't show also as a 2nd browser tooltip\n */\n protected renderRegularTooltip(formatterOrText: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: any) {\n const tmpDiv = document.createElement('div');\n tmpDiv.innerHTML = this.parseFormatterAndSanitize(formatterOrText, cell, value, columnDef, item);\n let tooltipText = columnDef.toolTip || '';\n let tmpTitleElm;\n\n if (!tooltipText) {\n if ((this._cellNodeElm && (this._cellNodeElm.clientWidth < this._cellNodeElm.scrollWidth)) && !this._cellTooltipOptions.useRegularTooltipFromFormatterOnly) {\n tooltipText = (this._cellNodeElm.textContent || '').trim() || '';\n if (this._cellTooltipOptions.tooltipTextMaxLength && (tooltipText.length > this._cellTooltipOptions.tooltipTextMaxLength)) {\n tooltipText = tooltipText.substring(0, this._cellTooltipOptions.tooltipTextMaxLength - 3) + '...';\n }\n tmpTitleElm = this._cellNodeElm;\n } else {\n if (this._cellTooltipOptions.useRegularTooltipFromFormatterOnly) {\n tmpTitleElm = tmpDiv.querySelector('[title], [data-slick-tooltip]');\n } else {\n tmpTitleElm = this.findFirstElementAttribute(this._cellNodeElm, ['title', 'data-slick-tooltip']) ? this._cellNodeElm : tmpDiv.querySelector('[title], [data-slick-tooltip]');\n if ((!tmpTitleElm || !this.findFirstElementAttribute(tmpTitleElm, ['title', 'data-slick-tooltip'])) && this._cellNodeElm) {\n tmpTitleElm = this._cellNodeElm.querySelector('[title], [data-slick-tooltip]');\n }\n }\n if (!tooltipText || (typeof formatterOrText === 'function' && this._cellTooltipOptions.useRegularTooltipFromFormatterOnly)) {\n tooltipText = this.findFirstElementAttribute(tmpTitleElm, ['title', 'data-slick-tooltip']) || '';\n }\n }\n }\n\n if (tooltipText !== '') {\n this.renderTooltipFormatter(formatterOrText, cell, value, columnDef, item, tooltipText);\n }\n\n // also clear any \"title\" attribute to avoid showing a 2nd browser tooltip\n this.swapAndClearTitleAttribute(tmpTitleElm, tooltipText);\n }\n\n /**\n * swap and copy the \"title\" attribute into a new custom attribute then clear the \"title\" attribute\n * from the grid div text content so that it won't show also as a 2nd browser tooltip\n */\n protected swapAndClearTitleAttribute(inputTitleElm?: Element | null, tooltipText?: string) {\n // the title attribute might be directly on the slick-cell container element (when formatter returns a result object)\n // OR in a child element (most commonly as a custom formatter)\n const titleElm = inputTitleElm || (this._cellNodeElm && ((this._cellNodeElm.hasAttribute('title') && this._cellNodeElm.getAttribute('title')) ? this._cellNodeElm : this._cellNodeElm.querySelector('[title]')));\n\n // flip tooltip text from `title` to `data-slick-tooltip`\n if (titleElm) {\n titleElm.setAttribute('data-slick-tooltip', tooltipText || '');\n if (titleElm.hasAttribute('title')) {\n titleElm.setAttribute('title', '');\n }\n }\n }\n\n protected asyncProcessCallback(asyncResult: any, cell: { row: number, cell: number }, value: any, columnDef: Column, dataContext: any) {\n this.hideTooltip();\n const itemWithAsyncData = Utils.extend(true, {}, dataContext, { [this._cellTooltipOptions.asyncParamsPropName || '__params']: asyncResult });\n this.renderTooltipFormatter(this._cellTooltipOptions.asyncPostFormatter, cell, value, columnDef, itemWithAsyncData);\n }\n\n protected cancellablePromise(inputPromise: Promise): CancellablePromiseWrapper {\n let hasCancelled = false;\n\n if (inputPromise instanceof Promise) {\n return {\n promise: inputPromise.then(function (result) {\n if (hasCancelled) {\n throw { isPromiseCancelled: true };\n }\n return result;\n }),\n cancel: () => hasCancelled = true\n };\n }\n return inputPromise;\n }\n\n protected getHtmlElementOffset(element?: HTMLElement | null) {\n if (!element) {\n return undefined;\n }\n const rect = element.getBoundingClientRect();\n let left = 0;\n let top = 0;\n let bottom = 0;\n let right = 0;\n\n if (rect.top !== undefined && rect.left !== undefined) {\n top = rect.top + window.pageYOffset;\n left = rect.left + window.pageXOffset;\n right = rect.right;\n bottom = rect.bottom;\n }\n return { top, left, bottom, right };\n }\n\n /**\n * hide (remove) tooltip from the DOM,\n * when using async process, it will also cancel any opened Promise/Observable that might still be opened/pending.\n */\n hideTooltip() {\n this._cancellablePromise?.cancel();\n const prevTooltip = document.body.querySelector(`.${this._cellTooltipOptions?.className ?? this._defaults.className}.${this._grid.getUID()}`);\n prevTooltip?.remove();\n }\n\n /**\n * Reposition the Tooltip to be top-left position over the cell.\n * By default we use an \"auto\" mode which will allow to position the Tooltip to the best logical position in the window, also when we mention position, we are talking about the relative position against the grid cell.\n * We can assume that in 80% of the time the default position is top-right, the default is \"auto\" but we can also override it and use a specific position.\n * Most of the time positioning of the tooltip will be to the \"top-right\" of the cell is ok but if our column is completely on the right side then we'll want to change the position to \"left\" align.\n * Same goes for the top/bottom position, Most of the time positioning the tooltip to the \"top\" but if we are hovering a cell at the top of the grid and there's no room to display it then we might need to reposition to \"bottom\" instead.\n */\n protected reposition(cell: { row: number; cell: number; }) {\n if (this._tooltipElm) {\n this._cellNodeElm = (this._cellNodeElm || this._grid.getCellNode(cell.row, cell.cell)) as HTMLDivElement;\n const cellPosition = this.getHtmlElementOffset(this._cellNodeElm);\n const cellContainerWidth = this._cellNodeElm.offsetWidth;\n const calculatedTooltipHeight = this._tooltipElm.getBoundingClientRect().height;\n const calculatedTooltipWidth = this._tooltipElm.getBoundingClientRect().width;\n const calculatedBodyWidth = document.body.offsetWidth || window.innerWidth;\n\n // first calculate the default (top/left) position\n let newPositionTop = (cellPosition?.top || 0) - this._tooltipElm.offsetHeight - (this._cellTooltipOptions.offsetTopBottom ?? 0);\n let newPositionLeft = (cellPosition?.left || 0) - (this._cellTooltipOptions.offsetRight ?? 0);\n\n // user could explicitely use a \"left-align\" arrow position, (when user knows his column is completely on the right in the grid)\n // or when using \"auto\" and we detect not enough available space then we'll position to the \"left\" of the cell\n const position = this._cellTooltipOptions.position || 'auto';\n if (position === 'center') {\n newPositionLeft += (cellContainerWidth / 2) - (calculatedTooltipWidth / 2) + (this._cellTooltipOptions.offsetRight || 0);\n this._tooltipElm.classList.remove('arrow-left-align');\n this._tooltipElm.classList.remove('arrow-right-align');\n this._tooltipElm.classList.add('arrow-center-align');\n\n } else if (position === 'right-align' || ((position === 'auto' || position !== 'left-align') && (newPositionLeft + calculatedTooltipWidth) > calculatedBodyWidth)) {\n newPositionLeft -= (calculatedTooltipWidth - cellContainerWidth - (this._cellTooltipOptions.offsetLeft || 0));\n this._tooltipElm.classList.remove('arrow-center-align');\n this._tooltipElm.classList.remove('arrow-left-align');\n this._tooltipElm.classList.add('arrow-right-align');\n } else {\n this._tooltipElm.classList.remove('arrow-center-align');\n this._tooltipElm.classList.remove('arrow-right-align');\n this._tooltipElm.classList.add('arrow-left-align');\n }\n\n // do the same calculation/reposition with top/bottom (default is top of the cell or in other word starting from the cell going down)\n if (position === 'bottom' || (position === 'auto' && calculatedTooltipHeight > Utils.calculateAvailableSpace(this._cellNodeElm).top)) {\n newPositionTop = (cellPosition?.top || 0) + (this._gridOptions.rowHeight || 0) + (this._cellTooltipOptions.offsetTopBottom || 0);\n this._tooltipElm.classList.remove('arrow-down');\n this._tooltipElm.classList.add('arrow-up');\n } else {\n this._tooltipElm.classList.add('arrow-down');\n this._tooltipElm.classList.remove('arrow-up');\n }\n\n // reposition the tooltip over the cell (90% of the time this will end up using a position on the \"right\" of the cell)\n this._tooltipElm.style.top = newPositionTop + 'px';\n this._tooltipElm.style.left = newPositionLeft + 'px';\n }\n }\n\n /**\n * Parse the Custom Formatter (when provided) or return directly the text when it is already a string.\n * We will also sanitize the text in both cases before returning it so that it can be used safely.\n */\n protected parseFormatterAndSanitize(formatterOrText: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: unknown): string {\n if (typeof formatterOrText === 'function') {\n const tooltipText = formatterOrText(cell.row, cell.cell, value, columnDef, item, this._grid);\n const formatterText = (typeof tooltipText === 'object' && tooltipText?.text) ? tooltipText.text : (typeof tooltipText === 'string' ? tooltipText : '');\n return this._grid.sanitizeHtmlString(formatterText);\n } else if (typeof formatterOrText === 'string') {\n return this._grid.sanitizeHtmlString(formatterOrText);\n }\n return '';\n }\n\n\n protected renderTooltipFormatter(formatter: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: unknown, tooltipText?: string, inputTitleElm?: Element | null) {\n // create the tooltip DOM element with the text returned by the Formatter\n this._tooltipElm = document.createElement('div');\n this._tooltipElm.className = (this._cellTooltipOptions.className || this._defaults.className) as string;\n this._tooltipElm.classList.add(this._grid.getUID());\n this._tooltipElm.classList.add('l' + cell.cell);\n this._tooltipElm.classList.add('r' + cell.cell);\n let outputText = tooltipText || this.parseFormatterAndSanitize(formatter, cell, value, columnDef, item) || '';\n outputText = (this._cellTooltipOptions.tooltipTextMaxLength && outputText.length > this._cellTooltipOptions.tooltipTextMaxLength) ? outputText.substring(0, this._cellTooltipOptions.tooltipTextMaxLength - 3) + '...' : outputText;\n\n let finalOutputText = '';\n if (!tooltipText || (this._cellTooltipOptions?.renderRegularTooltipAsHtml)) {\n finalOutputText = this._grid.sanitizeHtmlString(outputText);\n this._tooltipElm.innerHTML = finalOutputText;\n this._tooltipElm.style.whiteSpace = this._cellTooltipOptions?.whiteSpace ?? this._defaults.whiteSpace as string;\n } else {\n finalOutputText = outputText || '';\n this._tooltipElm.textContent = finalOutputText;\n this._tooltipElm.style.whiteSpace = this._cellTooltipOptions?.regularTooltipWhiteSpace ?? this._defaults.regularTooltipWhiteSpace as string; // use `pre` so that sequences of white space are collapsed. Lines are broken at newline characters\n }\n\n // optional max height/width of the tooltip container\n if (this._cellTooltipOptions.maxHeight) {\n this._tooltipElm.style.maxHeight = this._cellTooltipOptions.maxHeight + 'px';\n }\n if (this._cellTooltipOptions.maxWidth) {\n this._tooltipElm.style.maxWidth = this._cellTooltipOptions.maxWidth + 'px';\n }\n\n // when do have text to show, then append the new tooltip to the html body & reposition the tooltip\n if (finalOutputText) {\n document.body.appendChild(this._tooltipElm);\n\n // reposition the tooltip on top of the cell that triggered the mouse over event\n this.reposition(cell);\n\n // user could optionally hide the tooltip arrow (we can simply update the CSS variables, that's the only way we have to update CSS pseudo)\n if (!this._cellTooltipOptions.hideArrow) {\n this._tooltipElm.classList.add('tooltip-arrow');\n }\n\n // also clear any \"title\" attribute to avoid showing a 2nd browser tooltip\n this.swapAndClearTitleAttribute(inputTitleElm, outputText);\n }\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n\n setOptions(newOptions: Partial) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n CustomTooltip\n }\n }\n });\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.draggablegrouping.js b/dist/browser/plugins/slick.draggablegrouping.js index dce94fef6..6bb537507 100644 --- a/dist/browser/plugins/slick.draggablegrouping.js +++ b/dist/browser/plugins/slick.draggablegrouping.js @@ -155,7 +155,7 @@ let sortArray = (_b = (_a = this._droppableInstance) == null ? void 0 : _a.toArray()) != null ? _b : [], newGroupingOrder = []; for (let i = 0, l = sortArray.length; i < l; i++) for (let a = 0, b = this._columnsGroupBy.length; a < b; a++) - if (this._columnsGroupBy[a].id == sortArray[i]) { + if (this._columnsGroupBy[a].id === sortArray[i]) { newGroupingOrder.push(this._columnsGroupBy[a]); break; } diff --git a/dist/browser/plugins/slick.draggablegrouping.js.map b/dist/browser/plugins/slick.draggablegrouping.js.map index e3ae19492..ebc983417 100644 --- a/dist/browser/plugins/slick.draggablegrouping.js.map +++ b/dist/browser/plugins/slick.draggablegrouping.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.draggablegrouping.ts"], - "sourcesContent": ["// @ts-ignore\nimport type SortableInstance from 'sortablejs';\n\nimport type { Column, DOMMouseOrTouchEvent, DraggableGroupingOption, Grouping, GroupingGetterFunction } from '../models/index';\nimport { BindingEventService as BindingEventService_, SlickEvent as SlickEvent_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n *\n * Draggable Grouping contributed by: Muthukumar Selvarasu\n * muthukumar{dot}se{at}gmail{dot}com\n * github.com/muthukumarse/Slickgrid\n *\n * NOTES:\n * This plugin provides the Draggable Grouping feature\n * A plugin to add Draggable Grouping feature.\n *\n * USAGE:\n *\n * Add the plugin .js & .css files and register it with the grid.\n *\n *\n * The plugin expose the following methods:\n * destroy: used to destroy the plugin\n * setDroppedGroups: provide option to set default grouping on loading\n * clearDroppedGroups: provide option to clear grouping\n * getSetupColumnReorder: its function to setup draggable feature agains Header Column, should be passed on grid option. Also possible to pass custom function\n *\n *\n * The plugin expose the following event(s):\n * onGroupChanged: pass the grouped columns to who subscribed.\n *\n */\nexport class SlickDraggableGrouping {\n // --\n // public API\n pluginName = 'DraggableGrouping' as const;\n onGroupChanged = new SlickEvent<{ caller?: string; groupColumns: Grouping[]; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _gridUid = '';\n protected _gridColumns: Column[] = [];\n protected _dataView!: SlickDataView;\n protected _dropzoneElm!: HTMLDivElement;\n protected _droppableInstance?: SortableInstance;\n protected _dropzonePlaceholder!: HTMLDivElement;\n protected _groupToggler?: HTMLDivElement;\n protected _options: DraggableGroupingOption;\n protected _defaults: DraggableGroupingOption = {\n dropPlaceHolderText: 'Drop a column header here to group by the column',\n hideGroupSortIcons: false,\n hideToggleAllButton: false,\n toggleAllButtonText: '',\n toggleAllPlaceholderText: 'Toggle all Groups',\n };\n protected _bindingEventService = new BindingEventService();\n protected _handler = new SlickEventHandler();\n protected _sortableLeftInstance?: SortableInstance;\n protected _sortableRightInstance?: SortableInstance;\n protected _columnsGroupBy: Column[] = [];\n\n /**\n * @param options {Object} Options:\n * deleteIconCssClass: an extra CSS class to add to the delete button (default undefined), if deleteIconCssClass && deleteIconImage undefined then slick-groupby-remove-image class will be added\n * deleteIconImage: a url to the delete button image (default undefined)\n * groupIconCssClass: an extra CSS class to add to the grouping field hint (default undefined)\n * groupIconImage: a url to the grouping field hint image (default undefined)\n * dropPlaceHolderText: option to specify set own placeholder note text\n */\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n /**\n * Initialize plugin.\n */\n init(grid: SlickGrid) {\n this._grid = grid;\n this._gridUid = this._grid.getUID();\n this._gridColumns = this._grid.getColumns();\n this._dataView = this._grid.getData();\n this._dropzoneElm = this._grid.getPreHeaderPanel();\n this._dropzoneElm.classList.add('slick-dropzone');\n\n const dropPlaceHolderText = this._options.dropPlaceHolderText || 'Drop a column header here to group by the column';\n\n this._dropzonePlaceholder = document.createElement('div')\n this._dropzonePlaceholder.className = 'slick-placeholder';\n this._dropzonePlaceholder.textContent = dropPlaceHolderText;\n\n this._groupToggler = document.createElement('div');\n this._groupToggler.className = 'slick-group-toggle-all expanded';\n this._groupToggler.style.display = 'none';\n\n this._dropzoneElm.appendChild(this._dropzonePlaceholder);\n this._dropzoneElm.appendChild(this._groupToggler);\n\n this.setupColumnDropbox();\n\n\n this._handler.subscribe(this._grid.onHeaderCellRendered, (_e, args) => {\n const column = args.column;\n const node = args.node;\n if (!Utils.isEmptyObject(column.grouping) && node) {\n node.style.cursor = 'pointer'; // add the pointer cursor on each column title\n\n // also optionally add an icon beside each column title that can be dragged\n if (this._options.groupIconCssClass || this._options.groupIconImage) {\n const groupableIconElm = document.createElement('span');\n groupableIconElm.className = 'slick-column-groupable';\n if (this._options.groupIconCssClass) {\n groupableIconElm.classList.add(...this._options.groupIconCssClass.split(' '));\n }\n if (this._options.groupIconImage) {\n groupableIconElm.style.background = `url(${this._options.groupIconImage}) no-repeat center center`;\n }\n node.appendChild(groupableIconElm);\n }\n }\n });\n\n for (let i = 0; i < this._gridColumns.length; i++) {\n const columnId = this._gridColumns[i].field;\n this._grid.updateColumnHeader(columnId);\n }\n }\n\n /**\n * Setup the column reordering\n * NOTE: this function is a standalone function and is called externally and does not have access to `this` instance\n * @param grid - slick grid object\n * @param headers - slick grid column header elements\n * @param _headerColumnWidthDiff - header column width difference\n * @param setColumns - callback to reassign columns\n * @param setupColumnResize - callback to setup the column resize\n * @param columns - columns array\n * @param getColumnIndex - callback to find index of a column\n * @param uid - grid UID\n * @param trigger - callback to execute when triggering a column grouping\n */\n getSetupColumnReorder(grid: SlickGrid, headers: any, _headerColumnWidthDiff: any, setColumns: (columns: Column[]) => void, setupColumnResize: () => void, _columns: Column[], getColumnIndex: (columnId: string) => number, _uid: string, trigger: (slickEvent: SlickEvent_, data?: any) => void) {\n this.destroySortableInstances();\n const dropzoneElm = grid.getPreHeaderPanel();\n const groupTogglerElm = dropzoneElm.querySelector('.slick-group-toggle-all');\n\n const sortableOptions = {\n animation: 50,\n // chosenClass: 'slick-header-column-active',\n ghostClass: 'slick-sortable-placeholder',\n draggable: '.slick-header-column',\n dataIdAttr: 'data-id',\n group: {\n name: 'shared',\n pull: 'clone',\n put: false,\n },\n revertClone: true,\n // filter: function (_e, target) {\n // // block column from being able to be dragged if it's already a grouped column\n // // NOTE: need to disable for now since it also blocks the column reordering\n // return this.columnsGroupBy.some(c => c.id === target.getAttribute('data-id'));\n // },\n onStart: () => {\n dropzoneElm.classList.add('slick-dropzone-hover');\n dropzoneElm.classList.add('slick-dropzone-placeholder-hover');\n const draggablePlaceholderElm = dropzoneElm.querySelector('.slick-placeholder');\n if (draggablePlaceholderElm) {\n draggablePlaceholderElm.style.display = 'inline-block';\n }\n\n const droppedGroupingElms = dropzoneElm.querySelectorAll('.slick-dropped-grouping');\n droppedGroupingElms.forEach(droppedGroupingElm => droppedGroupingElm.style.display = 'none');\n if (groupTogglerElm) {\n groupTogglerElm.style.display = 'none';\n }\n },\n onEnd: (e: Event & { item: any; clone: HTMLElement; }) => {\n const draggablePlaceholderElm = dropzoneElm.querySelector('.slick-placeholder');\n dropzoneElm.classList.remove('slick-dropzone-hover');\n draggablePlaceholderElm?.classList.remove('slick-dropzone-placeholder-hover');\n\n\n if (this._dropzonePlaceholder) {\n this._dropzonePlaceholder.style.display = 'none';\n }\n if (draggablePlaceholderElm) {\n draggablePlaceholderElm.parentElement?.classList.remove('slick-dropzone-placeholder-hover');\n }\n\n const droppedGroupingElms = dropzoneElm.querySelectorAll('.slick-dropped-grouping');\n if (droppedGroupingElms.length) {\n droppedGroupingElms.forEach(droppedGroupingElm => droppedGroupingElm.style.display = 'inline-flex');\n if (draggablePlaceholderElm) {\n draggablePlaceholderElm.style.display = 'none';\n }\n if (groupTogglerElm) {\n groupTogglerElm.style.display = 'inline-block';\n }\n }\n\n if (!grid.getEditorLock().commitCurrentEdit()) {\n return;\n }\n\n const reorderedIds = this._sortableLeftInstance?.toArray() ?? [];\n\n // when frozen columns are used, headers has more than one entry and we need the ids from all of them.\n // though there is only really a left and right header, this will work even if that should change.\n if (headers.length > 1) {\n const ids = this._sortableRightInstance?.toArray() ?? [];\n\n // Note: the loop below could be simplified with:\n // reorderedIds.push.apply(reorderedIds,ids);\n // However, the loop is more in keeping with way-backward compatibility\n for (const id of ids) {\n reorderedIds.push(id);\n }\n }\n\n const finalReorderedColumns: Column[] = [];\n const reorderedColumns = grid.getColumns();\n for (const reorderedId of reorderedIds) {\n finalReorderedColumns.push(reorderedColumns[getColumnIndex.call(grid, reorderedId)]);\n }\n setColumns.call(grid, finalReorderedColumns);\n trigger.call(grid, grid.onColumnsReordered, { grid });\n e.stopPropagation();\n setupColumnResize.call(grid);\n }\n }\n\n this._sortableLeftInstance = Sortable.create(document.querySelector(`.${grid.getUID()} .slick-header-columns.slick-header-columns-left`) as HTMLDivElement, sortableOptions);\n this._sortableRightInstance = Sortable.create(document.querySelector(`.${grid.getUID()} .slick-header-columns.slick-header-columns-right`) as HTMLDivElement, sortableOptions);\n\n return {\n sortableLeftInstance: this._sortableLeftInstance,\n sortableRightInstance: this._sortableRightInstance\n };\n }\n\n /**\n * Destroy plugin.\n */\n destroy() {\n this.destroySortableInstances();\n this.onGroupChanged.unsubscribe();\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n Utils.emptyElement(document.querySelector(`.${this._gridUid} .slick-preheader-panel`));\n }\n\n protected destroySortableInstances() {\n if (this._sortableLeftInstance?.el) {\n this._sortableLeftInstance?.destroy();\n }\n if (this._sortableRightInstance?.el) {\n this._sortableRightInstance?.destroy();\n }\n }\n\n protected addDragOverDropzoneListeners() {\n const draggablePlaceholderElm = this._dropzoneElm.querySelector('.slick-placeholder');\n\n if (draggablePlaceholderElm && this._dropzoneElm) {\n this._bindingEventService.bind(draggablePlaceholderElm, 'dragover', (e) => e.preventDefault());\n this._bindingEventService.bind(draggablePlaceholderElm, 'dragenter', () => this._dropzoneElm.classList.add('slick-dropzone-hover'));\n this._bindingEventService.bind(draggablePlaceholderElm, 'dragleave', () => this._dropzoneElm.classList.remove('slick-dropzone-hover'));\n }\n }\n\n protected setupColumnDropbox() {\n const dropzoneElm = this._dropzoneElm;\n\n this._droppableInstance = Sortable.create(dropzoneElm, {\n group: 'shared',\n // chosenClass: 'slick-header-column-active',\n ghostClass: 'slick-droppable-sortitem-hover',\n draggable: '.slick-dropped-grouping',\n dragoverBubble: true,\n onAdd: (evt: MouseEvent & { item: any; clone: HTMLElement; originalEvent: MouseEvent; }) => {\n const el = evt.item;\n const elId = el.getAttribute('id');\n if (elId?.replace(this._gridUid, '')) {\n this.handleGroupByDrop(dropzoneElm, (Sortable.utils).clone(evt.item));\n }\n evt.clone.style.opacity = '.5';\n el.parentNode?.removeChild(el);\n },\n onUpdate: () => {\n const sortArray = this._droppableInstance?.toArray() ?? [];\n const newGroupingOrder: Column[] = [];\n for (let i = 0, l = sortArray.length; i < l; i++) {\n for (let a = 0, b = this._columnsGroupBy.length; a < b; a++) {\n if (this._columnsGroupBy[a].id == sortArray[i]) {\n newGroupingOrder.push(this._columnsGroupBy[a]);\n break;\n }\n }\n }\n this._columnsGroupBy = newGroupingOrder;\n this.updateGroupBy(\"sort-group\");\n },\n });\n\n // Sortable doesn't have onOver, we need to implement it ourselves\n this.addDragOverDropzoneListeners();\n\n if (this._groupToggler) {\n this._bindingEventService.bind(this._groupToggler, 'click', ((event: DOMMouseOrTouchEvent) => {\n const target = event.target;\n this.toggleGroupToggler(target, target?.classList.contains('expanded'));\n }) as EventListener);\n }\n }\n\n protected handleGroupByDrop(containerElm: HTMLDivElement, headerColumnElm: HTMLDivElement) {\n const headerColDataId = headerColumnElm.getAttribute('data-id');\n const columnId = headerColDataId?.replace(this._gridUid, '');\n let columnAllowed = true;\n for (const colGroupBy of this._columnsGroupBy) {\n if (colGroupBy.id === columnId) {\n columnAllowed = false;\n }\n }\n\n if (columnAllowed) {\n for (const col of this._gridColumns) {\n if (col.id === columnId && col.grouping && !Utils.isEmptyObject(col.grouping)) {\n const columnNameElm = headerColumnElm.querySelector('.slick-column-name');\n const entryElm = document.createElement('div');\n entryElm.id = `${this._gridUid}_${col.id}_entry`;\n entryElm.className = 'slick-dropped-grouping';\n entryElm.dataset.id = `${col.id}`;\n\n const groupTextElm = document.createElement('div');\n groupTextElm.className = 'slick-dropped-grouping-title';\n groupTextElm.style.display = 'inline-flex';\n groupTextElm.textContent = columnNameElm ? columnNameElm.textContent : headerColumnElm.textContent;\n entryElm.appendChild(groupTextElm);\n\n // delete icon\n const groupRemoveIconElm = document.createElement('div');\n groupRemoveIconElm.className = 'slick-groupby-remove';\n if (this._options.deleteIconCssClass) {\n groupRemoveIconElm.classList.add(...this._options.deleteIconCssClass.split(' '));\n }\n if (this._options.deleteIconImage) {\n groupRemoveIconElm.classList.add(...this._options.deleteIconImage.split(' '));\n }\n if (!this._options.deleteIconCssClass) {\n groupRemoveIconElm.classList.add('slick-groupby-remove-icon');\n }\n if (!this._options.deleteIconCssClass && !this._options.deleteIconImage) {\n groupRemoveIconElm.classList.add('slick-groupby-remove-image');\n }\n\n // sorting icons when enabled\n if (this._options?.hideGroupSortIcons !== true && col.sortable) {\n if (col.grouping?.sortAsc === undefined) {\n col.grouping.sortAsc = true;\n }\n }\n\n entryElm.appendChild(groupRemoveIconElm);\n entryElm.appendChild(document.createElement('div'));\n containerElm.appendChild(entryElm);\n\n this.addColumnGroupBy(col);\n this.addGroupByRemoveClickHandler(col.id, groupRemoveIconElm, headerColumnElm, entryElm);\n }\n }\n\n // show the \"Toggle All\" when feature is enabled\n if (this._groupToggler && this._columnsGroupBy.length > 0) {\n this._groupToggler.style.display = 'inline-block';\n }\n }\n }\n\n protected addColumnGroupBy(column: Column) {\n this._columnsGroupBy.push(column);\n this.updateGroupBy(\"add-group\");\n }\n\n protected addGroupByRemoveClickHandler(id: string | number, groupRemoveIconElm: HTMLDivElement, headerColumnElm: HTMLDivElement, entry: any) {\n this._bindingEventService.bind(groupRemoveIconElm, 'click', () => {\n const boundedElms = this._bindingEventService.getBoundedEvents().filter(boundedEvent => boundedEvent.element === groupRemoveIconElm);\n for (const boundedEvent of boundedElms) {\n this._bindingEventService.unbind(boundedEvent.element, 'click', boundedEvent.listener);\n }\n this.removeGroupBy(id, headerColumnElm, entry);\n });\n }\n\n setDroppedGroups(groupingInfo: Array | string) {\n const groupingInfos = Array.isArray(groupingInfo) ? groupingInfo : [groupingInfo];\n this._dropzonePlaceholder.style.display = 'none';\n for (const groupInfo of groupingInfos) {\n const columnElm = this._grid.getHeaderColumn(groupInfo as string);\n this.handleGroupByDrop(this._dropzoneElm, columnElm);\n }\n }\n\n clearDroppedGroups() {\n this._columnsGroupBy = [];\n this.updateGroupBy('clear-all');\n const allDroppedGroupingElms = this._dropzoneElm.querySelectorAll('.slick-dropped-grouping');\n\n for (const groupElm of Array.from(allDroppedGroupingElms)) {\n const groupRemoveBtnElm = this._dropzoneElm.querySelector('.slick-groupby-remove');\n groupRemoveBtnElm?.remove();\n groupElm?.remove();\n }\n\n // show placeholder text & hide the \"Toggle All\" when that later feature is enabled\n this._dropzonePlaceholder.style.display = 'inline-block';\n if (this._groupToggler) {\n this._groupToggler.style.display = 'none';\n }\n }\n\n protected removeFromArray(arrayToModify: any[], itemToRemove: any) {\n if (Array.isArray(arrayToModify)) {\n const itemIdx = arrayToModify.findIndex(a => a.id === itemToRemove.id);\n if (itemIdx >= 0) {\n arrayToModify.splice(itemIdx, 1);\n }\n }\n return arrayToModify;\n }\n\n protected removeGroupBy(id: string | number, _hdrColumnElm: HTMLDivElement, entry: any) {\n entry.remove();\n const groupby: Column[] = [];\n this._gridColumns.forEach((col) => groupby[col.id as any] = col);\n this.removeFromArray(this._columnsGroupBy, groupby[id as any]);\n if (this._columnsGroupBy.length === 0) {\n this._dropzonePlaceholder.style.display = 'block';\n if (this._groupToggler) {\n this._groupToggler.style.display = 'none';\n }\n }\n this.updateGroupBy(\"remove-group\");\n }\n\n protected toggleGroupToggler(targetElm: Element | null, collapsing = true, shouldExecuteDataViewCommand = true) {\n if (targetElm) {\n if (collapsing === true) {\n targetElm.classList.add('collapsed');\n targetElm.classList.remove('expanded');\n if (shouldExecuteDataViewCommand) {\n this._dataView.collapseAllGroups();\n }\n } else {\n targetElm.classList.remove('collapsed');\n targetElm.classList.add('expanded');\n if (shouldExecuteDataViewCommand) {\n this._dataView.expandAllGroups();\n }\n }\n }\n }\n\n protected updateGroupBy(originator: string) {\n if (this._columnsGroupBy.length === 0) {\n this._dataView.setGrouping([]);\n this.onGroupChanged.notify({ caller: originator, groupColumns: [] });\n return;\n }\n const groupingArray: Grouping[] = [];\n this._columnsGroupBy.forEach((element) => groupingArray.push(element.grouping!));\n this._dataView.setGrouping(groupingArray);\n this.onGroupChanged.notify({ caller: originator, groupColumns: groupingArray });\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n DraggableGrouping: SlickDraggableGrouping\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["// @ts-ignore\nimport type SortableInstance from 'sortablejs';\n\nimport type { Column, DOMMouseOrTouchEvent, DraggableGroupingOption, Grouping, GroupingGetterFunction } from '../models/index';\nimport { BindingEventService as BindingEventService_, SlickEvent as SlickEvent_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n *\n * Draggable Grouping contributed by: Muthukumar Selvarasu\n * muthukumar{dot}se{at}gmail{dot}com\n * github.com/muthukumarse/Slickgrid\n *\n * NOTES:\n * This plugin provides the Draggable Grouping feature\n * A plugin to add Draggable Grouping feature.\n *\n * USAGE:\n *\n * Add the plugin .js & .css files and register it with the grid.\n *\n *\n * The plugin expose the following methods:\n * destroy: used to destroy the plugin\n * setDroppedGroups: provide option to set default grouping on loading\n * clearDroppedGroups: provide option to clear grouping\n * getSetupColumnReorder: its function to setup draggable feature agains Header Column, should be passed on grid option. Also possible to pass custom function\n *\n *\n * The plugin expose the following event(s):\n * onGroupChanged: pass the grouped columns to who subscribed.\n *\n */\nexport class SlickDraggableGrouping {\n // --\n // public API\n pluginName = 'DraggableGrouping' as const;\n onGroupChanged = new SlickEvent<{ caller?: string; groupColumns: Grouping[]; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _gridUid = '';\n protected _gridColumns: Column[] = [];\n protected _dataView!: SlickDataView;\n protected _dropzoneElm!: HTMLDivElement;\n protected _droppableInstance?: SortableInstance;\n protected _dropzonePlaceholder!: HTMLDivElement;\n protected _groupToggler?: HTMLDivElement;\n protected _options: DraggableGroupingOption;\n protected _defaults: DraggableGroupingOption = {\n dropPlaceHolderText: 'Drop a column header here to group by the column',\n hideGroupSortIcons: false,\n hideToggleAllButton: false,\n toggleAllButtonText: '',\n toggleAllPlaceholderText: 'Toggle all Groups',\n };\n protected _bindingEventService = new BindingEventService();\n protected _handler = new SlickEventHandler();\n protected _sortableLeftInstance?: SortableInstance;\n protected _sortableRightInstance?: SortableInstance;\n protected _columnsGroupBy: Column[] = [];\n\n /**\n * @param options {Object} Options:\n * deleteIconCssClass: an extra CSS class to add to the delete button (default undefined), if deleteIconCssClass && deleteIconImage undefined then slick-groupby-remove-image class will be added\n * deleteIconImage: a url to the delete button image (default undefined)\n * groupIconCssClass: an extra CSS class to add to the grouping field hint (default undefined)\n * groupIconImage: a url to the grouping field hint image (default undefined)\n * dropPlaceHolderText: option to specify set own placeholder note text\n */\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n /**\n * Initialize plugin.\n */\n init(grid: SlickGrid) {\n this._grid = grid;\n this._gridUid = this._grid.getUID();\n this._gridColumns = this._grid.getColumns();\n this._dataView = this._grid.getData();\n this._dropzoneElm = this._grid.getPreHeaderPanel();\n this._dropzoneElm.classList.add('slick-dropzone');\n\n const dropPlaceHolderText = this._options.dropPlaceHolderText || 'Drop a column header here to group by the column';\n\n this._dropzonePlaceholder = document.createElement('div');\n this._dropzonePlaceholder.className = 'slick-placeholder';\n this._dropzonePlaceholder.textContent = dropPlaceHolderText;\n\n this._groupToggler = document.createElement('div');\n this._groupToggler.className = 'slick-group-toggle-all expanded';\n this._groupToggler.style.display = 'none';\n\n this._dropzoneElm.appendChild(this._dropzonePlaceholder);\n this._dropzoneElm.appendChild(this._groupToggler);\n\n this.setupColumnDropbox();\n\n\n this._handler.subscribe(this._grid.onHeaderCellRendered, (_e, args) => {\n const column = args.column;\n const node = args.node;\n if (!Utils.isEmptyObject(column.grouping) && node) {\n node.style.cursor = 'pointer'; // add the pointer cursor on each column title\n\n // also optionally add an icon beside each column title that can be dragged\n if (this._options.groupIconCssClass || this._options.groupIconImage) {\n const groupableIconElm = document.createElement('span');\n groupableIconElm.className = 'slick-column-groupable';\n if (this._options.groupIconCssClass) {\n groupableIconElm.classList.add(...this._options.groupIconCssClass.split(' '));\n }\n if (this._options.groupIconImage) {\n groupableIconElm.style.background = `url(${this._options.groupIconImage}) no-repeat center center`;\n }\n node.appendChild(groupableIconElm);\n }\n }\n });\n\n for (let i = 0; i < this._gridColumns.length; i++) {\n const columnId = this._gridColumns[i].field;\n this._grid.updateColumnHeader(columnId);\n }\n }\n\n /**\n * Setup the column reordering\n * NOTE: this function is a standalone function and is called externally and does not have access to `this` instance\n * @param grid - slick grid object\n * @param headers - slick grid column header elements\n * @param _headerColumnWidthDiff - header column width difference\n * @param setColumns - callback to reassign columns\n * @param setupColumnResize - callback to setup the column resize\n * @param columns - columns array\n * @param getColumnIndex - callback to find index of a column\n * @param uid - grid UID\n * @param trigger - callback to execute when triggering a column grouping\n */\n getSetupColumnReorder(grid: SlickGrid, headers: any, _headerColumnWidthDiff: any, setColumns: (columns: Column[]) => void, setupColumnResize: () => void, _columns: Column[], getColumnIndex: (columnId: string) => number, _uid: string, trigger: (slickEvent: SlickEvent_, data?: any) => void) {\n this.destroySortableInstances();\n const dropzoneElm = grid.getPreHeaderPanel();\n const groupTogglerElm = dropzoneElm.querySelector('.slick-group-toggle-all');\n\n const sortableOptions = {\n animation: 50,\n // chosenClass: 'slick-header-column-active',\n ghostClass: 'slick-sortable-placeholder',\n draggable: '.slick-header-column',\n dataIdAttr: 'data-id',\n group: {\n name: 'shared',\n pull: 'clone',\n put: false,\n },\n revertClone: true,\n // filter: function (_e, target) {\n // // block column from being able to be dragged if it's already a grouped column\n // // NOTE: need to disable for now since it also blocks the column reordering\n // return this.columnsGroupBy.some(c => c.id === target.getAttribute('data-id'));\n // },\n onStart: () => {\n dropzoneElm.classList.add('slick-dropzone-hover');\n dropzoneElm.classList.add('slick-dropzone-placeholder-hover');\n const draggablePlaceholderElm = dropzoneElm.querySelector('.slick-placeholder');\n if (draggablePlaceholderElm) {\n draggablePlaceholderElm.style.display = 'inline-block';\n }\n\n const droppedGroupingElms = dropzoneElm.querySelectorAll('.slick-dropped-grouping');\n droppedGroupingElms.forEach(droppedGroupingElm => droppedGroupingElm.style.display = 'none');\n if (groupTogglerElm) {\n groupTogglerElm.style.display = 'none';\n }\n },\n onEnd: (e: Event & { item: any; clone: HTMLElement; }) => {\n const draggablePlaceholderElm = dropzoneElm.querySelector('.slick-placeholder');\n dropzoneElm.classList.remove('slick-dropzone-hover');\n draggablePlaceholderElm?.classList.remove('slick-dropzone-placeholder-hover');\n\n\n if (this._dropzonePlaceholder) {\n this._dropzonePlaceholder.style.display = 'none';\n }\n if (draggablePlaceholderElm) {\n draggablePlaceholderElm.parentElement?.classList.remove('slick-dropzone-placeholder-hover');\n }\n\n const droppedGroupingElms = dropzoneElm.querySelectorAll('.slick-dropped-grouping');\n if (droppedGroupingElms.length) {\n droppedGroupingElms.forEach(droppedGroupingElm => droppedGroupingElm.style.display = 'inline-flex');\n if (draggablePlaceholderElm) {\n draggablePlaceholderElm.style.display = 'none';\n }\n if (groupTogglerElm) {\n groupTogglerElm.style.display = 'inline-block';\n }\n }\n\n if (!grid.getEditorLock().commitCurrentEdit()) {\n return;\n }\n\n const reorderedIds = this._sortableLeftInstance?.toArray() ?? [];\n\n // when frozen columns are used, headers has more than one entry and we need the ids from all of them.\n // though there is only really a left and right header, this will work even if that should change.\n if (headers.length > 1) {\n const ids = this._sortableRightInstance?.toArray() ?? [];\n\n // Note: the loop below could be simplified with:\n // reorderedIds.push.apply(reorderedIds,ids);\n // However, the loop is more in keeping with way-backward compatibility\n for (const id of ids) {\n reorderedIds.push(id);\n }\n }\n\n const finalReorderedColumns: Column[] = [];\n const reorderedColumns = grid.getColumns();\n for (const reorderedId of reorderedIds) {\n finalReorderedColumns.push(reorderedColumns[getColumnIndex.call(grid, reorderedId)]);\n }\n setColumns.call(grid, finalReorderedColumns);\n trigger.call(grid, grid.onColumnsReordered, { grid });\n e.stopPropagation();\n setupColumnResize.call(grid);\n }\n };\n\n this._sortableLeftInstance = Sortable.create(document.querySelector(`.${grid.getUID()} .slick-header-columns.slick-header-columns-left`) as HTMLDivElement, sortableOptions);\n this._sortableRightInstance = Sortable.create(document.querySelector(`.${grid.getUID()} .slick-header-columns.slick-header-columns-right`) as HTMLDivElement, sortableOptions);\n\n return {\n sortableLeftInstance: this._sortableLeftInstance,\n sortableRightInstance: this._sortableRightInstance\n };\n }\n\n /**\n * Destroy plugin.\n */\n destroy() {\n this.destroySortableInstances();\n this.onGroupChanged.unsubscribe();\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n Utils.emptyElement(document.querySelector(`.${this._gridUid} .slick-preheader-panel`));\n }\n\n protected destroySortableInstances() {\n if (this._sortableLeftInstance?.el) {\n this._sortableLeftInstance?.destroy();\n }\n if (this._sortableRightInstance?.el) {\n this._sortableRightInstance?.destroy();\n }\n }\n\n protected addDragOverDropzoneListeners() {\n const draggablePlaceholderElm = this._dropzoneElm.querySelector('.slick-placeholder');\n\n if (draggablePlaceholderElm && this._dropzoneElm) {\n this._bindingEventService.bind(draggablePlaceholderElm, 'dragover', (e) => e.preventDefault());\n this._bindingEventService.bind(draggablePlaceholderElm, 'dragenter', () => this._dropzoneElm.classList.add('slick-dropzone-hover'));\n this._bindingEventService.bind(draggablePlaceholderElm, 'dragleave', () => this._dropzoneElm.classList.remove('slick-dropzone-hover'));\n }\n }\n\n protected setupColumnDropbox() {\n const dropzoneElm = this._dropzoneElm;\n\n this._droppableInstance = Sortable.create(dropzoneElm, {\n group: 'shared',\n // chosenClass: 'slick-header-column-active',\n ghostClass: 'slick-droppable-sortitem-hover',\n draggable: '.slick-dropped-grouping',\n dragoverBubble: true,\n onAdd: (evt: MouseEvent & { item: any; clone: HTMLElement; originalEvent: MouseEvent; }) => {\n const el = evt.item;\n const elId = el.getAttribute('id');\n if (elId?.replace(this._gridUid, '')) {\n this.handleGroupByDrop(dropzoneElm, (Sortable.utils).clone(evt.item));\n }\n evt.clone.style.opacity = '.5';\n el.parentNode?.removeChild(el);\n },\n onUpdate: () => {\n const sortArray = this._droppableInstance?.toArray() ?? [];\n const newGroupingOrder: Column[] = [];\n for (let i = 0, l = sortArray.length; i < l; i++) {\n for (let a = 0, b = this._columnsGroupBy.length; a < b; a++) {\n if (this._columnsGroupBy[a].id === sortArray[i]) {\n newGroupingOrder.push(this._columnsGroupBy[a]);\n break;\n }\n }\n }\n this._columnsGroupBy = newGroupingOrder;\n this.updateGroupBy(\"sort-group\");\n },\n });\n\n // Sortable doesn't have onOver, we need to implement it ourselves\n this.addDragOverDropzoneListeners();\n\n if (this._groupToggler) {\n this._bindingEventService.bind(this._groupToggler, 'click', ((event: DOMMouseOrTouchEvent) => {\n const target = event.target;\n this.toggleGroupToggler(target, target?.classList.contains('expanded'));\n }) as EventListener);\n }\n }\n\n protected handleGroupByDrop(containerElm: HTMLDivElement, headerColumnElm: HTMLDivElement) {\n const headerColDataId = headerColumnElm.getAttribute('data-id');\n const columnId = headerColDataId?.replace(this._gridUid, '');\n let columnAllowed = true;\n for (const colGroupBy of this._columnsGroupBy) {\n if (colGroupBy.id === columnId) {\n columnAllowed = false;\n }\n }\n\n if (columnAllowed) {\n for (const col of this._gridColumns) {\n if (col.id === columnId && col.grouping && !Utils.isEmptyObject(col.grouping)) {\n const columnNameElm = headerColumnElm.querySelector('.slick-column-name');\n const entryElm = document.createElement('div');\n entryElm.id = `${this._gridUid}_${col.id}_entry`;\n entryElm.className = 'slick-dropped-grouping';\n entryElm.dataset.id = `${col.id}`;\n\n const groupTextElm = document.createElement('div');\n groupTextElm.className = 'slick-dropped-grouping-title';\n groupTextElm.style.display = 'inline-flex';\n groupTextElm.textContent = columnNameElm ? columnNameElm.textContent : headerColumnElm.textContent;\n entryElm.appendChild(groupTextElm);\n\n // delete icon\n const groupRemoveIconElm = document.createElement('div');\n groupRemoveIconElm.className = 'slick-groupby-remove';\n if (this._options.deleteIconCssClass) {\n groupRemoveIconElm.classList.add(...this._options.deleteIconCssClass.split(' '));\n }\n if (this._options.deleteIconImage) {\n groupRemoveIconElm.classList.add(...this._options.deleteIconImage.split(' '));\n }\n if (!this._options.deleteIconCssClass) {\n groupRemoveIconElm.classList.add('slick-groupby-remove-icon');\n }\n if (!this._options.deleteIconCssClass && !this._options.deleteIconImage) {\n groupRemoveIconElm.classList.add('slick-groupby-remove-image');\n }\n\n // sorting icons when enabled\n if (this._options?.hideGroupSortIcons !== true && col.sortable) {\n if (col.grouping?.sortAsc === undefined) {\n col.grouping.sortAsc = true;\n }\n }\n\n entryElm.appendChild(groupRemoveIconElm);\n entryElm.appendChild(document.createElement('div'));\n containerElm.appendChild(entryElm);\n\n this.addColumnGroupBy(col);\n this.addGroupByRemoveClickHandler(col.id, groupRemoveIconElm, headerColumnElm, entryElm);\n }\n }\n\n // show the \"Toggle All\" when feature is enabled\n if (this._groupToggler && this._columnsGroupBy.length > 0) {\n this._groupToggler.style.display = 'inline-block';\n }\n }\n }\n\n protected addColumnGroupBy(column: Column) {\n this._columnsGroupBy.push(column);\n this.updateGroupBy(\"add-group\");\n }\n\n protected addGroupByRemoveClickHandler(id: string | number, groupRemoveIconElm: HTMLDivElement, headerColumnElm: HTMLDivElement, entry: any) {\n this._bindingEventService.bind(groupRemoveIconElm, 'click', () => {\n const boundedElms = this._bindingEventService.getBoundedEvents().filter(boundedEvent => boundedEvent.element === groupRemoveIconElm);\n for (const boundedEvent of boundedElms) {\n this._bindingEventService.unbind(boundedEvent.element, 'click', boundedEvent.listener);\n }\n this.removeGroupBy(id, headerColumnElm, entry);\n });\n }\n\n setDroppedGroups(groupingInfo: Array | string) {\n const groupingInfos = Array.isArray(groupingInfo) ? groupingInfo : [groupingInfo];\n this._dropzonePlaceholder.style.display = 'none';\n for (const groupInfo of groupingInfos) {\n const columnElm = this._grid.getHeaderColumn(groupInfo as string);\n this.handleGroupByDrop(this._dropzoneElm, columnElm);\n }\n }\n\n clearDroppedGroups() {\n this._columnsGroupBy = [];\n this.updateGroupBy('clear-all');\n const allDroppedGroupingElms = this._dropzoneElm.querySelectorAll('.slick-dropped-grouping');\n\n for (const groupElm of Array.from(allDroppedGroupingElms)) {\n const groupRemoveBtnElm = this._dropzoneElm.querySelector('.slick-groupby-remove');\n groupRemoveBtnElm?.remove();\n groupElm?.remove();\n }\n\n // show placeholder text & hide the \"Toggle All\" when that later feature is enabled\n this._dropzonePlaceholder.style.display = 'inline-block';\n if (this._groupToggler) {\n this._groupToggler.style.display = 'none';\n }\n }\n\n protected removeFromArray(arrayToModify: any[], itemToRemove: any) {\n if (Array.isArray(arrayToModify)) {\n const itemIdx = arrayToModify.findIndex(a => a.id === itemToRemove.id);\n if (itemIdx >= 0) {\n arrayToModify.splice(itemIdx, 1);\n }\n }\n return arrayToModify;\n }\n\n protected removeGroupBy(id: string | number, _hdrColumnElm: HTMLDivElement, entry: any) {\n entry.remove();\n const groupby: Column[] = [];\n this._gridColumns.forEach((col) => groupby[col.id as any] = col);\n this.removeFromArray(this._columnsGroupBy, groupby[id as any]);\n if (this._columnsGroupBy.length === 0) {\n this._dropzonePlaceholder.style.display = 'block';\n if (this._groupToggler) {\n this._groupToggler.style.display = 'none';\n }\n }\n this.updateGroupBy(\"remove-group\");\n }\n\n protected toggleGroupToggler(targetElm: Element | null, collapsing = true, shouldExecuteDataViewCommand = true) {\n if (targetElm) {\n if (collapsing === true) {\n targetElm.classList.add('collapsed');\n targetElm.classList.remove('expanded');\n if (shouldExecuteDataViewCommand) {\n this._dataView.collapseAllGroups();\n }\n } else {\n targetElm.classList.remove('collapsed');\n targetElm.classList.add('expanded');\n if (shouldExecuteDataViewCommand) {\n this._dataView.expandAllGroups();\n }\n }\n }\n }\n\n protected updateGroupBy(originator: string) {\n if (this._columnsGroupBy.length === 0) {\n this._dataView.setGrouping([]);\n this.onGroupChanged.notify({ caller: originator, groupColumns: [] });\n return;\n }\n const groupingArray: Grouping[] = [];\n this._columnsGroupBy.forEach((element) => groupingArray.push(element.grouping!));\n this._dataView.setGrouping(groupingArray);\n this.onGroupChanged.notify({ caller: originator, groupColumns: groupingArray });\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n DraggableGrouping: SlickDraggableGrouping\n }\n });\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.headerbuttons.js.map b/dist/browser/plugins/slick.headerbuttons.js.map index 0001fee03..3018a5b47 100644 --- a/dist/browser/plugins/slick.headerbuttons.js.map +++ b/dist/browser/plugins/slick.headerbuttons.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.headerbuttons.ts"], - "sourcesContent": ["import type {\n Column,\n DOMEvent,\n HeaderButtonItem,\n HeaderButtonOnCommandArgs,\n HeaderButtonOption,\n OnHeaderCellRenderedEventArgs,\n Plugin\n} from '../models/index';\nimport { BindingEventService as BindingEventService_, Event as SlickEvent_, EventHandler as EventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst EventHandler = IIFE_ONLY ? Slick.EventHandler : EventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * A plugin to add custom buttons to column headers.\n *\n * USAGE:\n *\n * Add the plugin .js & .css files and register it with the grid.\n *\n * To specify a custom button in a column header, extend the column definition like so:\n *\n * let columns = [\n * {\n * id: 'myColumn',\n * name: 'My column',\n *\n * // This is the relevant part\n * header: {\n * buttons: [\n * {\n * // button options\n * },\n * {\n * // button options\n * }\n * ]\n * }\n * }\n * ];\n *\n * Available button options:\n * cssClass: CSS class to add to the button.\n * image: Relative button image path.\n * disabled: Whether the item is disabled.\n * tooltip: Button tooltip.\n * showOnHover: Only show the button on hover.\n * handler: Button click handler.\n * command: A command identifier to be passed to the onCommand event handlers.\n *\n * Available menu item options:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * command: A command identifier to be passed to the onCommand event handlers.\n * cssClass: CSS class to add to the button.\n * handler: Button click handler.\n * image: Relative button image path.\n * showOnHover: Only show the button on hover.\n * tooltip: Button tooltip.\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n * The plugin exposes the following events:\n * onCommand: Fired on button click for buttons with 'command' specified.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * command: Button command identified.\n * button: Button options. Note that you can change the button options in your\n * event handler, and the column header will be automatically updated to\n * reflect them. This is useful if you want to implement something like a\n * toggle button.\n *\n *\n * @param options {Object} Options:\n * buttonCssClass: a CSS class to use for buttons (default 'slick-header-button')\n * @class Slick.Plugins.HeaderButtons\n * @constructor\n */\nexport class SlickHeaderButtons implements Plugin {\n // --\n // public API\n pluginName = 'HeaderButtons' as const;\n onCommand = new SlickEvent();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _handler = new EventHandler();\n protected _bindingEventService = new BindingEventService();\n protected _defaults: HeaderButtonOption = {\n buttonCssClass: 'slick-header-button'\n };\n protected _options: HeaderButtonOption;\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._handler\n .subscribe(this._grid.onHeaderCellRendered, this.handleHeaderCellRendered.bind(this))\n .subscribe(this._grid.onBeforeHeaderCellDestroy, this.handleBeforeHeaderCellDestroy.bind(this));\n\n // Force the grid to re-render the header now that the events are hooked up.\n this._grid.setColumns(this._grid.getColumns());\n }\n\n destroy() {\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n }\n\n protected handleHeaderCellRendered(_e: Event, args: OnHeaderCellRenderedEventArgs) {\n const column = args.column;\n\n if (column.header?.buttons) {\n // Append buttons in reverse order since they are floated to the right.\n let i = column.header.buttons.length;\n while (i--) {\n const button = column.header.buttons[i];\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists(button.itemVisibilityOverride, args);\n const isItemUsable = this.runOverrideFunctionWhenExists(button.itemUsabilityOverride, args);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemCommandClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(button, 'itemUsabilityOverride')) {\n button.disabled = isItemUsable ? false : true;\n }\n\n const btn = document.createElement('div');\n btn.className = this._options.buttonCssClass || '';\n btn.ariaLabel = 'Header Button';\n btn.role = 'button';\n\n if (button.disabled) {\n btn.classList.add('slick-header-button-disabled');\n }\n\n if (button.showOnHover) {\n btn.classList.add('slick-header-button-hidden');\n }\n\n if (button.image) {\n btn.style.backgroundImage = `url(${button.image})`;\n }\n\n if (button.cssClass) {\n btn.classList.add(...button.cssClass.split(' '));\n }\n\n if (button.tooltip) {\n btn.title = button.tooltip;\n }\n\n if (button.handler && !button.disabled) {\n this._bindingEventService.bind(btn, 'click', button.handler);\n }\n\n this._bindingEventService.bind(btn, 'click', this.handleButtonClick.bind(this, button, args.column) as EventListener);\n args.node.appendChild(btn);\n }\n }\n }\n\n\n protected handleBeforeHeaderCellDestroy(_e: Event, args: { column: Column; node: HTMLElement; }) {\n const column = args.column;\n\n if (column.header?.buttons) {\n // Removing buttons via jQuery will also clean up any event handlers and data.\n // NOTE: If you attach event handlers directly or using a different framework,\n // you must also clean them up here to avoid memory leaks.\n const buttonCssClass = (this._options.buttonCssClass || '').replace(/(\\s+)/g, '.');\n if (buttonCssClass) {\n args.node.querySelectorAll(`.${buttonCssClass}`).forEach(elm => elm.remove());\n }\n }\n }\n\n protected handleButtonClick(button: HeaderButtonItem, columnDef: Column, e: DOMEvent) {\n const command = button.command || '';\n const callbackArgs = {\n grid: this._grid,\n column: columnDef,\n button: button\n } as HeaderButtonOnCommandArgs;\n\n if (command) {\n callbackArgs.command = command;\n }\n\n // execute action callback when defined\n if (typeof button.action === 'function') {\n button.action.call(this, e, callbackArgs);\n }\n\n if (command && !button.disabled) {\n this.onCommand.notify(callbackArgs, e, this);\n\n // Update the header in case the user updated the button definition in the handler.\n this._grid.updateColumnHeader(columnDef.id);\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n e.preventDefault();\n e.stopPropagation();\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n HeaderButtons: SlickHeaderButtons\n }\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import type {\n Column,\n DOMEvent,\n HeaderButtonItem,\n HeaderButtonOnCommandArgs,\n HeaderButtonOption,\n OnHeaderCellRenderedEventArgs,\n SlickPlugin\n} from '../models/index';\nimport { BindingEventService as BindingEventService_, Event as SlickEvent_, EventHandler as EventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst EventHandler = IIFE_ONLY ? Slick.EventHandler : EventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * A plugin to add custom buttons to column headers.\n *\n * USAGE:\n *\n * Add the plugin .js & .css files and register it with the grid.\n *\n * To specify a custom button in a column header, extend the column definition like so:\n *\n * let columns = [\n * {\n * id: 'myColumn',\n * name: 'My column',\n *\n * // This is the relevant part\n * header: {\n * buttons: [\n * {\n * // button options\n * },\n * {\n * // button options\n * }\n * ]\n * }\n * }\n * ];\n *\n * Available button options:\n * cssClass: CSS class to add to the button.\n * image: Relative button image path.\n * disabled: Whether the item is disabled.\n * tooltip: Button tooltip.\n * showOnHover: Only show the button on hover.\n * handler: Button click handler.\n * command: A command identifier to be passed to the onCommand event handlers.\n *\n * Available menu item options:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * command: A command identifier to be passed to the onCommand event handlers.\n * cssClass: CSS class to add to the button.\n * handler: Button click handler.\n * image: Relative button image path.\n * showOnHover: Only show the button on hover.\n * tooltip: Button tooltip.\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n * The plugin exposes the following events:\n * onCommand: Fired on button click for buttons with 'command' specified.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * command: Button command identified.\n * button: Button options. Note that you can change the button options in your\n * event handler, and the column header will be automatically updated to\n * reflect them. This is useful if you want to implement something like a\n * toggle button.\n *\n *\n * @param options {Object} Options:\n * buttonCssClass: a CSS class to use for buttons (default 'slick-header-button')\n * @class Slick.Plugins.HeaderButtons\n * @constructor\n */\nexport class SlickHeaderButtons implements SlickPlugin {\n // --\n // public API\n pluginName = 'HeaderButtons' as const;\n onCommand = new SlickEvent();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _handler = new EventHandler();\n protected _bindingEventService = new BindingEventService();\n protected _defaults: HeaderButtonOption = {\n buttonCssClass: 'slick-header-button'\n };\n protected _options: HeaderButtonOption;\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._handler\n .subscribe(this._grid.onHeaderCellRendered, this.handleHeaderCellRendered.bind(this))\n .subscribe(this._grid.onBeforeHeaderCellDestroy, this.handleBeforeHeaderCellDestroy.bind(this));\n\n // Force the grid to re-render the header now that the events are hooked up.\n this._grid.setColumns(this._grid.getColumns());\n }\n\n destroy() {\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n }\n\n protected handleHeaderCellRendered(_e: Event, args: OnHeaderCellRenderedEventArgs) {\n const column = args.column;\n\n if (column.header?.buttons) {\n // Append buttons in reverse order since they are floated to the right.\n let i = column.header.buttons.length;\n while (i--) {\n const button = column.header.buttons[i];\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists(button.itemVisibilityOverride, args);\n const isItemUsable = this.runOverrideFunctionWhenExists(button.itemUsabilityOverride, args);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemCommandClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(button, 'itemUsabilityOverride')) {\n button.disabled = isItemUsable ? false : true;\n }\n\n const btn = document.createElement('div');\n btn.className = this._options.buttonCssClass || '';\n btn.ariaLabel = 'Header Button';\n btn.role = 'button';\n\n if (button.disabled) {\n btn.classList.add('slick-header-button-disabled');\n }\n\n if (button.showOnHover) {\n btn.classList.add('slick-header-button-hidden');\n }\n\n if (button.image) {\n btn.style.backgroundImage = `url(${button.image})`;\n }\n\n if (button.cssClass) {\n btn.classList.add(...button.cssClass.split(' '));\n }\n\n if (button.tooltip) {\n btn.title = button.tooltip;\n }\n\n if (button.handler && !button.disabled) {\n this._bindingEventService.bind(btn, 'click', button.handler);\n }\n\n this._bindingEventService.bind(btn, 'click', this.handleButtonClick.bind(this, button, args.column) as EventListener);\n args.node.appendChild(btn);\n }\n }\n }\n\n\n protected handleBeforeHeaderCellDestroy(_e: Event, args: { column: Column; node: HTMLElement; }) {\n const column = args.column;\n\n if (column.header?.buttons) {\n // Removing buttons via jQuery will also clean up any event handlers and data.\n // NOTE: If you attach event handlers directly or using a different framework,\n // you must also clean them up here to avoid memory leaks.\n const buttonCssClass = (this._options.buttonCssClass || '').replace(/(\\s+)/g, '.');\n if (buttonCssClass) {\n args.node.querySelectorAll(`.${buttonCssClass}`).forEach(elm => elm.remove());\n }\n }\n }\n\n protected handleButtonClick(button: HeaderButtonItem, columnDef: Column, e: DOMEvent) {\n const command = button.command || '';\n const callbackArgs = {\n grid: this._grid,\n column: columnDef,\n button\n } as HeaderButtonOnCommandArgs;\n\n if (command) {\n callbackArgs.command = command;\n }\n\n // execute action callback when defined\n if (typeof button.action === 'function') {\n button.action.call(this, e, callbackArgs);\n }\n\n if (command && !button.disabled) {\n this.onCommand.notify(callbackArgs, e, this);\n\n // Update the header in case the user updated the button definition in the handler.\n this._grid.updateColumnHeader(columnDef.id);\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n e.preventDefault();\n e.stopPropagation();\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n HeaderButtons: SlickHeaderButtons\n }\n }\n });\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.headermenu.js b/dist/browser/plugins/slick.headermenu.js index 074bea468..bcaf8b321 100644 --- a/dist/browser/plugins/slick.headermenu.js +++ b/dist/browser/plugins/slick.headermenu.js @@ -16,6 +16,7 @@ // -- // protected props __publicField(this, "_grid"); + __publicField(this, "_gridUid", ""); __publicField(this, "_handler", new SlickEventHandler()); __publicField(this, "_bindingEventService", new BindingEventService()); __publicField(this, "_defaults", { @@ -28,10 +29,11 @@ __publicField(this, "_options"); __publicField(this, "_activeHeaderColumnElm"); __publicField(this, "_menuElm"); - this._options = Utils.extend(!0, {}, this._defaults, options); + __publicField(this, "_subMenuParentId", ""); + this._options = Utils.extend(!0, {}, options, this._defaults); } init(grid) { - this._grid = grid, this._handler.subscribe(this._grid.onHeaderCellRendered, this.handleHeaderCellRendered.bind(this)).subscribe(this._grid.onBeforeHeaderCellDestroy, this.handleBeforeHeaderCellDestroy.bind(this)), this._grid.setColumns(this._grid.getColumns()), this._bindingEventService.bind(document.body, "mousedown", this.handleBodyMouseDown.bind(this)); + this._grid = grid, this._gridUid = (grid == null ? void 0 : grid.getUID()) || "", this._handler.subscribe(this._grid.onHeaderCellRendered, this.handleHeaderCellRendered.bind(this)).subscribe(this._grid.onBeforeHeaderCellDestroy, this.handleBeforeHeaderCellDestroy.bind(this)), this._grid.setColumns(this._grid.getColumns()), this._bindingEventService.bind(document.body, "click", this.handleBodyMouseDown.bind(this)); } setOptions(newOptions) { this._options = Utils.extend(!0, {}, this._options, newOptions); @@ -44,13 +46,23 @@ var _a; this._handler.unsubscribeAll(), this._bindingEventService.unbindAll(), this._menuElm = this._menuElm || document.body.querySelector(`.slick-header-menu${this.getGridUidSelector()}`), (_a = this._menuElm) == null || _a.remove(), this._activeHeaderColumnElm = void 0; } + destroyAllMenus() { + this.destroySubMenus(), document.querySelectorAll(`.slick-header-menu${this.getGridUidSelector()}`).forEach((subElm) => subElm.remove()); + } + /** Close and destroy all previously opened sub-menus */ + destroySubMenus() { + document.querySelectorAll(`.slick-header-menu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => subElm.remove()); + } handleBodyMouseDown(e) { var _a; - (this._menuElm !== e.target && !((_a = this._menuElm) != null && _a.contains(e.target)) || e.target.className === "close") && this.hideMenu(); + let isMenuClicked = !1; + (_a = this._menuElm) != null && _a.contains(e.target) && (isMenuClicked = !0), isMenuClicked || document.querySelectorAll(`.slick-header-menu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => { + subElm.contains(e.target) && (isMenuClicked = !0); + }), (this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented || e.target.className === "close") && this.hideMenu(); } hideMenu() { var _a; - this._menuElm && (this._menuElm.remove(), this._menuElm = void 0), (_a = this._activeHeaderColumnElm) == null || _a.classList.remove("slick-header-column-active"); + this._menuElm && (this._menuElm.remove(), this._menuElm = void 0), (_a = this._activeHeaderColumnElm) == null || _a.classList.remove("slick-header-column-active"), this.destroySubMenus(); } handleHeaderCellRendered(_e, args) { var _a; @@ -63,65 +75,101 @@ let icon = document.createElement("span"); icon.classList.add(...this._options.buttonCssClass.split(" ")), elm.appendChild(icon); } - this._options.buttonImage && (elm.style.backgroundImage = `url(${this._options.buttonImage})`), this._options.tooltip && (elm.title = this._options.tooltip), this._bindingEventService.bind(elm, "click", (e) => this.showMenu(e, menu, args.column)), args.node.appendChild(elm); + this._options.buttonImage && (elm.style.backgroundImage = `url(${this._options.buttonImage})`), this._options.tooltip && (elm.title = this._options.tooltip), this._bindingEventService.bind(elm, "click", (e) => { + this.destroyAllMenus(), this.createParentMenu(e, menu, args.column); + }), args.node.appendChild(elm); } } handleBeforeHeaderCellDestroy(_e, args) { var _a; (_a = args.column.header) != null && _a.menu && args.node.querySelectorAll(".slick-header-menubutton").forEach((elm) => elm.remove()); } - showMenu(event, menu, columnDef) { - var _a, _b, _c, _d, _e, _f; + addSubMenuTitleWhenExists(item, commandMenuElm) { + if (item !== "divider" && (item != null && item.subMenuTitle)) { + let subMenuTitleElm = document.createElement("div"); + subMenuTitleElm.className = "slick-menu-title", subMenuTitleElm.textContent = item.subMenuTitle; + let subMenuTitleClass = item.subMenuTitleCssClass; + subMenuTitleClass && subMenuTitleElm.classList.add(...subMenuTitleClass.split(" ")), commandMenuElm.appendChild(subMenuTitleElm); + } + } + createParentMenu(event, menu, columnDef) { let callbackArgs = { grid: this._grid, column: columnDef, menu }; - if (this.onBeforeMenuShow.notify(callbackArgs, event, this).getReturnValue() == !1) + if (this.onBeforeMenuShow.notify(callbackArgs, event, this).getReturnValue() === !1) return; - if (!this._menuElm) { - this._menuElm = document.createElement("div"), this._menuElm.className = "slick-header-menu", this._menuElm.role = "menu", this._menuElm.style.minWidth = `${this._options.minWidth}px`, this._menuElm.setAttribute("aria-expanded", "true"); - let containerNode = this._grid.getContainerNode(); - containerNode && containerNode.appendChild(this._menuElm); + this._menuElm = this.createMenu(menu.items, columnDef); + let containerNode = this._grid.getContainerNode(); + containerNode && containerNode.appendChild(this._menuElm), this.repositionMenu(event, this._menuElm), this.onAfterMenuShow.notify(callbackArgs, event, this).getReturnValue() !== !1 && (event.preventDefault(), event.stopPropagation()); + } + createMenu(commandItems, columnDef, level = 0, item) { + let subMenuCommand = item == null ? void 0 : item.command, subMenuId = level === 1 && subMenuCommand ? subMenuCommand.replaceAll(" ", "") : ""; + subMenuId && (this._subMenuParentId = subMenuId), level > 1 && (subMenuId = this._subMenuParentId); + let menuClasses = `slick-header-menu slick-menu-level-${level} ${this._gridUid}`, bodyMenuElm = document.body.querySelector(`.slick-header-menu.slick-menu-level-${level}${this.getGridUidSelector()}`); + if (bodyMenuElm) { + if (bodyMenuElm.dataset.subMenuParent === subMenuId) + return bodyMenuElm; + this.destroySubMenus(); } - Utils.emptyElement(this._menuElm); - for (let i = 0; i < menu.items.length; i++) { - let item = menu.items[i], isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, callbackArgs), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, callbackArgs); + let menuElm = document.createElement("div"); + menuElm.className = menuClasses, level > 0 && (menuElm.classList.add("slick-submenu"), subMenuId && (menuElm.dataset.subMenuParent = subMenuId)), menuElm.classList.add(this._gridUid), menuElm.role = "menu", menuElm.ariaLabel = level > 1 ? "SubMenu" : "Header Menu", menuElm.style.minWidth = `${this._options.minWidth}px`, menuElm.setAttribute("aria-expanded", "true"); + let callbackArgs = { + grid: this._grid, + column: columnDef, + menu: { items: commandItems } + }; + item && level > 0 && this.addSubMenuTitleWhenExists(item, menuElm); + for (let i = 0; i < commandItems.length; i++) { + let addClickListener = !0, item2 = commandItems[i], isItemVisible = this.runOverrideFunctionWhenExists(item2.itemVisibilityOverride, callbackArgs), isItemUsable = this.runOverrideFunctionWhenExists(item2.itemUsabilityOverride, callbackArgs); if (!isItemVisible) continue; - Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable); + Object.prototype.hasOwnProperty.call(item2, "itemUsabilityOverride") && (item2.disabled = !isItemUsable); let menuItem = document.createElement("div"); - if (menuItem.className = "slick-header-menuitem", menuItem.role = "menuitem", item.divider || item === "divider") { - menuItem.classList.add("slick-header-menuitem-divider"); - continue; - } - item.disabled && menuItem.classList.add("slick-header-menuitem-disabled"), item.hidden && menuItem.classList.add("slick-header-menuitem-hidden"), item.cssClass && menuItem.classList.add(...item.cssClass.split(" ")), item.tooltip && (menuItem.title = item.tooltip || ""); + menuItem.className = "slick-header-menuitem", menuItem.role = "menuitem", (item2.divider || item2 === "divider") && (menuItem.classList.add("slick-header-menuitem-divider"), addClickListener = !1), item2.disabled && menuItem.classList.add("slick-header-menuitem-disabled"), item2.hidden && menuItem.classList.add("slick-header-menuitem-hidden"), item2.cssClass && menuItem.classList.add(...item2.cssClass.split(" ")), item2.tooltip && (menuItem.title = item2.tooltip || ""); let iconElm = document.createElement("div"); - iconElm.className = "slick-header-menuicon", menuItem.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...item.iconCssClass.split(" ")), item.iconImage && (iconElm.style.backgroundImage = "url(" + item.iconImage + ")"); + iconElm.className = "slick-header-menuicon", menuItem.appendChild(iconElm), item2.iconCssClass && iconElm.classList.add(...item2.iconCssClass.split(" ")), item2.iconImage && (iconElm.style.backgroundImage = "url(" + item2.iconImage + ")"); let textElm = document.createElement("span"); - textElm.className = "slick-header-menucontent", textElm.textContent = item.title || "", menuItem.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), this._menuElm.appendChild(menuItem), this._bindingEventService.bind(menuItem, "click", this.handleMenuItemClick.bind(this, item, columnDef)); - } - let buttonElm = event.target, btnOffset = Utils.offset(buttonElm), menuOffset = Utils.offset(this._menuElm), leftPos = (_a = btnOffset == null ? void 0 : btnOffset.left) != null ? _a : 0; - if (this._options.autoAlign) { - let gridPos = this._grid.getGridPosition(); - leftPos + this._menuElm.offsetWidth >= gridPos.width && (leftPos = leftPos + buttonElm.clientWidth - this._menuElm.clientWidth + (this._options.autoAlignOffset || 0)); + if (textElm.className = "slick-header-menucontent", textElm.textContent = item2.title || "", menuItem.appendChild(textElm), item2.textCssClass && textElm.classList.add(...item2.textCssClass.split(" ")), menuElm.appendChild(menuItem), addClickListener && this._bindingEventService.bind(menuItem, "click", this.handleMenuItemClick.bind(this, item2, columnDef, level)), item2.items) { + let chevronElm = document.createElement("div"); + chevronElm.className = "sub-item-chevron", this._options.subItemChevronClass ? chevronElm.classList.add(...this._options.subItemChevronClass.split(" ")) : chevronElm.textContent = "\u2B9E", menuItem.classList.add("slick-submenu-item"), menuItem.appendChild(chevronElm); + continue; + } } - this._menuElm.style.top = `${(_e = (_b = buttonElm.clientHeight) != null ? _b : btnOffset == null ? void 0 : btnOffset.top) != null ? _e : 0 + ((_d = (_c = this._options) == null ? void 0 : _c.menuOffsetTop) != null ? _d : 0)}px`, this._menuElm.style.left = `${leftPos - ((_f = menuOffset == null ? void 0 : menuOffset.left) != null ? _f : 0)}px`, this._activeHeaderColumnElm = this._menuElm.closest(".slick-header-column"), this._activeHeaderColumnElm && this._activeHeaderColumnElm.classList.add("slick-header-column-active"), this.onAfterMenuShow.notify(callbackArgs, event, this).getReturnValue() != !1 && (event.preventDefault(), event.stopPropagation()); - } - handleMenuItemClick(item, columnDef, e) { - let command = item.command || ""; - if (item.disabled || item.divider || item === "divider") - return !1; - if (command !== null && command !== "") { - let callbackArgs = { - grid: this._grid, - column: columnDef, - command, - item - }; - this.onCommand.notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs); + return menuElm; + } + handleMenuItemClick(item, columnDef, level = 0, e) { + if (item !== "divider" && !item.disabled && !item.divider) { + let command = item.command || ""; + if (command !== void 0 && !item.items) { + let callbackArgs = { + grid: this._grid, + column: columnDef, + command, + item + }; + this.onCommand.notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs), e.defaultPrevented || this.hideMenu(); + } else + item.items ? this.repositionSubMenu(item, columnDef, level, e) : this.destroySubMenus(); } - e.defaultPrevented || this.hideMenu(), e.preventDefault(), e.stopPropagation(); + } + repositionSubMenu(item, columnDef, level, e) { + e.target.classList.contains("slick-header-menubutton") && this.destroySubMenus(); + let subMenuElm = this.createMenu(item.items || [], columnDef, level + 1, item); + document.body.appendChild(subMenuElm), this.repositionMenu(e, subMenuElm); + } + repositionMenu(e, menuElm) { + var _a, _b, _c, _d, _e, _f, _g, _h; + let buttonElm = e.target, isSubMenu = menuElm.classList.contains("slick-submenu"), parentElm = isSubMenu ? e.target.closest(".slick-header-menuitem") : buttonElm, btnOffset = Utils.offset(buttonElm), gridPos = this._grid.getGridPosition(), menuWidth = menuElm.offsetWidth, menuOffset = Utils.offset(this._menuElm), parentOffset = Utils.offset(parentElm), menuOffsetTop = isSubMenu ? (_a = parentOffset == null ? void 0 : parentOffset.top) != null ? _a : 0 : (_e = (_b = buttonElm.clientHeight) != null ? _b : btnOffset == null ? void 0 : btnOffset.top) != null ? _e : 0 + ((_d = (_c = this._options) == null ? void 0 : _c.menuOffsetTop) != null ? _d : 0), menuOffsetLeft = isSubMenu ? (_f = parentOffset == null ? void 0 : parentOffset.left) != null ? _f : 0 : (_g = btnOffset == null ? void 0 : btnOffset.left) != null ? _g : 0; + if (isSubMenu && parentElm) { + let subMenuPosCalc = menuOffsetLeft + Number(menuWidth); + isSubMenu && (subMenuPosCalc += parentElm.clientWidth); + let browserWidth = document.documentElement.clientWidth; + (subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth ? "left" : "right") === "left" ? (menuElm.classList.remove("dropright"), menuElm.classList.add("dropleft"), menuOffsetLeft -= menuWidth) : (menuElm.classList.remove("dropleft"), menuElm.classList.add("dropright"), isSubMenu && (menuOffsetLeft += parentElm.offsetWidth)); + } else + menuOffsetLeft + menuElm.offsetWidth >= gridPos.width && (menuOffsetLeft = menuOffsetLeft + buttonElm.clientWidth - menuElm.clientWidth + (this._options.autoAlignOffset || 0)), menuOffsetLeft -= (_h = menuOffset == null ? void 0 : menuOffset.left) != null ? _h : 0; + menuElm.style.top = `${menuOffsetTop}px`, menuElm.style.left = `${menuOffsetLeft}px`, this._activeHeaderColumnElm = menuElm.closest(".slick-header-column"), this._activeHeaderColumnElm && this._activeHeaderColumnElm.classList.add("slick-header-column-active"); } /** * Method that user can pass to override the default behavior. diff --git a/dist/browser/plugins/slick.headermenu.js.map b/dist/browser/plugins/slick.headermenu.js.map index f0ed46ae0..605732d52 100644 --- a/dist/browser/plugins/slick.headermenu.js.map +++ b/dist/browser/plugins/slick.headermenu.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.headermenu.ts"], - "sourcesContent": ["import { BindingEventService as BindingEventService_, Event as SlickEvent_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type {\n Column,\n DOMEvent,\n HeaderMenuCommandItemCallbackArgs,\n HeaderMenuItems,\n HeaderMenuOption,\n MenuCommandItem,\n MenuCommandItemCallbackArgs,\n Plugin,\n OnHeaderCellRenderedEventArgs\n} from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add drop-down menus to column headers.\n *\n * USAGE:\n *\n * Add the plugin .js & .css files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n *\n * let columns = [\n * {\n * id: 'myColumn',\n * name: 'My column',\n *\n * // This is the relevant part\n * header: {\n * menu: {\n * items: [\n * {\n * // menu item options\n * },\n * {\n * // menu item options\n * }\n * ]\n * }\n * }\n * }\n * ];\n *\n *\n * Available menu options:\n * autoAlign: Auto-align drop menu to the left when not enough viewport space to show on the right\n * autoAlignOffset: When drop menu is aligned to the left, it might not be perfectly aligned with the header menu icon, if that is the case you can add an offset (positive/negative number to move right/left)\n * buttonCssClass: an extra CSS class to add to the menu button (default 'caret')\n * buttonImage: a url to the menu button image\n * menuUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling the menu from being usable (must be combined with a custom formatter)\n * minWidth: Minimum width that the drop menu will have\n *\n *\n * Available menu item options:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * title: Menu item text.\n * divider: Whether the current item is a divider, not an actual command.\n * disabled: Whether the item/command is disabled.\n * hidden: Whether the item/command is hidden.\n * tooltip: Item tooltip.\n * command: A command identifier to be passed to the onCommand event handlers.\n * cssClass: A CSS class to be added to the menu item container.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * iconImage: A url to the icon image.\n * textCssClass: A CSS class to be added to the menu item text.\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n *\n * The plugin exposes the following events:\n\n * onAfterMenuShow: Fired after the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onCommand: Fired on menu item click for buttons with 'command' specified.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * command: Button command identified.\n * button: Button options. Note that you can change the button options in your\n * event handler, and the column header will be automatically updated to\n * reflect them. This is useful if you want to implement something like a\n * toggle button.\n *\n *\n * @param options {Object} Options:\n * buttonCssClass: an extra CSS class to add to the menu button (default 'caret')\n * buttonImage: a url to the menu button image\n * @class Slick.Plugins.HeaderButtons\n */\nexport class SlickHeaderMenu implements Plugin {\n // --\n // public API\n pluginName = 'HeaderMenu' as const;\n onAfterMenuShow = new SlickEvent();\n onBeforeMenuShow = new SlickEvent();\n onCommand = new SlickEvent();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _handler = new SlickEventHandler();\n protected _bindingEventService = new BindingEventService();\n protected _defaults: HeaderMenuOption = {\n buttonCssClass: undefined,\n buttonImage: undefined,\n minWidth: 100,\n autoAlign: true,\n autoAlignOffset: 0\n };\n protected _options: HeaderMenuOption;\n protected _activeHeaderColumnElm?: HTMLDivElement | null;\n protected _menuElm?: HTMLDivElement | null;\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._handler\n .subscribe(this._grid.onHeaderCellRendered, this.handleHeaderCellRendered.bind(this))\n .subscribe(this._grid.onBeforeHeaderCellDestroy, this.handleBeforeHeaderCellDestroy.bind(this));\n\n // Force the grid to re-render the header now that the events are hooked up.\n this._grid.setColumns(this._grid.getColumns());\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n }\n\n setOptions(newOptions: Partial) {\n this._options = Utils.extend(true, {}, this._options, newOptions);\n }\n\n protected getGridUidSelector() {\n const gridUid = this._grid.getUID() || '';\n return gridUid ? `.${gridUid}` : '';\n }\n\n destroy() {\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n this._menuElm = this._menuElm || document.body.querySelector(`.slick-header-menu${this.getGridUidSelector()}`);\n this._menuElm?.remove();\n this._activeHeaderColumnElm = undefined;\n }\n\n protected handleBodyMouseDown(e: DOMEvent) {\n if ((this._menuElm !== e.target && !this._menuElm?.contains(e.target)) || e.target.className === 'close') {\n this.hideMenu();\n }\n }\n\n hideMenu() {\n if (this._menuElm) {\n this._menuElm.remove();\n this._menuElm = undefined;\n }\n this._activeHeaderColumnElm?.classList.remove('slick-header-column-active');\n }\n\n protected handleHeaderCellRendered(_e: Event, args: OnHeaderCellRenderedEventArgs) {\n const column = args.column;\n const menu = column?.header?.menu as HeaderMenuItems;\n\n if (menu) {\n // run the override function (when defined), if the result is false it won't go further\n if (!this.runOverrideFunctionWhenExists(this._options.menuUsabilityOverride, args)) {\n return;\n }\n\n const elm = document.createElement('div');\n elm.className = 'slick-header-menubutton';\n elm.ariaLabel = 'Header Menu';\n elm.role = 'button';\n\n if (!this._options.buttonCssClass && !this._options.buttonImage) {\n this._options.buttonCssClass = 'caret'; // default when nothing is provided\n }\n\n if (this._options.buttonCssClass) {\n // sgi icon with mask requires inner span to work properly\n const icon = document.createElement('span');\n icon.classList.add(...this._options.buttonCssClass.split(' '));\n elm.appendChild(icon);\n }\n\n if (this._options.buttonImage) {\n elm.style.backgroundImage = `url(${this._options.buttonImage})`;\n }\n\n if (this._options.tooltip) {\n elm.title = this._options.tooltip;\n }\n\n this._bindingEventService.bind(elm, 'click', ((e: MouseEvent) => this.showMenu(e, menu, args.column)) as EventListener);\n args.node.appendChild(elm);\n }\n }\n\n protected handleBeforeHeaderCellDestroy(_e: Event, args: { column: Column; node: HTMLElement; }) {\n const column = args.column;\n\n if (column.header?.menu) {\n args.node.querySelectorAll('.slick-header-menubutton').forEach(elm => elm.remove());\n }\n }\n\n\n protected showMenu(event: MouseEvent, menu: HeaderMenuItems, columnDef: Column) {\n // Let the user modify the menu or cancel altogether,\n // or provide alternative menu implementation.\n const callbackArgs = {\n grid: this._grid,\n column: columnDef,\n menu\n } as unknown as HeaderMenuCommandItemCallbackArgs;\n if (this.onBeforeMenuShow.notify(callbackArgs, event, this).getReturnValue() == false) {\n return;\n }\n\n if (!this._menuElm) {\n this._menuElm = document.createElement('div');\n this._menuElm.className = 'slick-header-menu';\n this._menuElm.role = 'menu';\n this._menuElm.style.minWidth = `${this._options.minWidth}px`;\n this._menuElm.setAttribute('aria-expanded', 'true');\n const containerNode = this._grid.getContainerNode();\n if (containerNode) {\n containerNode.appendChild(this._menuElm);\n }\n }\n\n // make sure the menu element is an empty div before adding all list of commands\n Utils.emptyElement(this._menuElm);\n\n // Construct the menu items.\n for (let i = 0; i < menu.items.length; i++) {\n const item = menu.items[i];\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as MenuCommandItem).itemVisibilityOverride, callbackArgs);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as MenuCommandItem).itemUsabilityOverride, callbackArgs);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemCommandClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as MenuCommandItem).disabled = isItemUsable ? false : true;\n }\n\n const menuItem = document.createElement('div');\n menuItem.className = 'slick-header-menuitem';\n menuItem.role = 'menuitem';\n\n if ((item as MenuCommandItem).divider || item === 'divider') {\n menuItem.classList.add('slick-header-menuitem-divider');\n continue;\n }\n\n if ((item as MenuCommandItem).disabled) {\n menuItem.classList.add('slick-header-menuitem-disabled');\n }\n\n if ((item as MenuCommandItem).hidden) {\n menuItem.classList.add('slick-header-menuitem-hidden');\n }\n\n if ((item as MenuCommandItem).cssClass) {\n menuItem.classList.add(...item.cssClass!.split(' '));\n }\n\n if ((item as MenuCommandItem).tooltip) {\n menuItem.title = (item as MenuCommandItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-header-menuicon';\n menuItem.appendChild(iconElm);\n\n if ((item as MenuCommandItem).iconCssClass) {\n iconElm.classList.add(...(item as MenuCommandItem).iconCssClass!.split(' '));\n }\n\n if ((item as MenuCommandItem).iconImage) {\n iconElm.style.backgroundImage = 'url(' + (item as MenuCommandItem).iconImage + ')';\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-header-menucontent';\n textElm.textContent = (item as MenuCommandItem).title || '';\n menuItem.appendChild(textElm);\n\n if ((item as MenuCommandItem).textCssClass) {\n textElm.classList.add(...(item as MenuCommandItem).textCssClass!.split(' '));\n }\n\n this._menuElm.appendChild(menuItem);\n this._bindingEventService.bind(menuItem, 'click', this.handleMenuItemClick.bind(this, item, columnDef) as EventListener);\n }\n\n const buttonElm = event.target as HTMLButtonElement;\n const btnOffset = Utils.offset(buttonElm);\n const menuOffset = Utils.offset(this._menuElm);\n let leftPos = btnOffset?.left ?? 0;\n\n\n // when auto-align is set, it will calculate whether it has enough space in the viewport to show the drop menu on the right (default)\n // if there isn't enough space on the right, it will automatically align the drop menu to the left\n // to simulate an align left, we actually need to know the width of the drop menu\n if (this._options.autoAlign) {\n const gridPos = this._grid.getGridPosition();\n if (leftPos + this._menuElm.offsetWidth >= gridPos.width) {\n leftPos = leftPos + buttonElm.clientWidth - this._menuElm.clientWidth + (this._options.autoAlignOffset || 0);\n }\n }\n\n this._menuElm.style.top = `${(buttonElm.clientHeight ?? btnOffset?.top ?? 0 + (this._options?.menuOffsetTop ?? 0))}px`;\n this._menuElm.style.left = `${leftPos - (menuOffset?.left ?? 0)}px`;\n\n // Mark the header as active to keep the highlighting.\n this._activeHeaderColumnElm = this._menuElm.closest('.slick-header-column');\n if (this._activeHeaderColumnElm) {\n this._activeHeaderColumnElm.classList.add('slick-header-column-active');\n }\n\n if (this.onAfterMenuShow.notify(callbackArgs, event, this).getReturnValue() == false) {\n return;\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n event.preventDefault();\n event.stopPropagation();\n }\n\n protected handleMenuItemClick(item: MenuCommandItem | 'divider', columnDef: Column, e: DOMEvent): boolean | void {\n const command = (item as MenuCommandItem).command || '';\n\n if ((item as MenuCommandItem).disabled || (item as MenuCommandItem).divider || item === 'divider') {\n return false;\n }\n\n if (command !== null && command !== '') {\n const callbackArgs = {\n grid: this._grid,\n column: columnDef,\n command,\n item,\n };\n this.onCommand.notify(callbackArgs, e, this);\n\n // execute action callback when defined\n if (typeof item.action === 'function') {\n item.action.call(this, e, callbackArgs);\n }\n }\n\n if (!e.defaultPrevented) {\n this.hideMenu();\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n e.preventDefault();\n e.stopPropagation();\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n HeaderMenu: SlickHeaderMenu\n }\n }\n });\n}\n\n"], - "mappings": "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", - "names": [] + "sourcesContent": ["import { BindingEventService as BindingEventService_, Event as SlickEvent_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type {\n Column,\n DOMEvent,\n DOMMouseOrTouchEvent,\n HeaderMenuCommandItemCallbackArgs,\n HeaderMenuItems,\n HeaderMenuOption,\n HeaderMenuCommandItem,\n MenuCommandItemCallbackArgs,\n SlickPlugin,\n OnHeaderCellRenderedEventArgs,\n} from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add drop-down menus to column headers.\n *\n * USAGE:\n *\n * Add the plugin .js & .css files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n *\n * let columns = [\n * {\n * id: 'myColumn',\n * name: 'My column',\n *\n * // This is the relevant part\n * header: {\n * menu: {\n * items: [\n * {\n * // menu item options\n * },\n * {\n * // menu item options\n * }\n * ]\n * }\n * }\n * }\n * ];\n *\n *\n * Available menu options:\n * autoAlign: Auto-align drop menu to the left when not enough viewport space to show on the right\n * autoAlignOffset: When drop menu is aligned to the left, it might not be perfectly aligned with the header menu icon, if that is the case you can add an offset (positive/negative number to move right/left)\n * buttonCssClass: an extra CSS class to add to the menu button (default 'caret')\n * buttonImage: a url to the menu button image\n * menuUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling the menu from being usable (must be combined with a custom formatter)\n * minWidth: Minimum width that the drop menu will have\n *\n *\n * Available menu item options:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * title: Menu item text.\n * divider: Whether the current item is a divider, not an actual command.\n * disabled: Whether the item/command is disabled.\n * hidden: Whether the item/command is hidden.\n * tooltip: Item tooltip.\n * command: A command identifier to be passed to the onCommand event handlers.\n * cssClass: A CSS class to be added to the menu item container.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * iconImage: A url to the icon image.\n * textCssClass: A CSS class to be added to the menu item text.\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n *\n * The plugin exposes the following events:\n\n * onAfterMenuShow: Fired after the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onCommand: Fired on menu item click for buttons with 'command' specified.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * command: Button command identified.\n * button: Button options. Note that you can change the button options in your\n * event handler, and the column header will be automatically updated to\n * reflect them. This is useful if you want to implement something like a\n * toggle button.\n *\n *\n * @param options {Object} Options:\n * buttonCssClass: an extra CSS class to add to the menu button (default 'caret')\n * buttonImage: a url to the menu button image\n * @class Slick.Plugins.HeaderButtons\n */\nexport class SlickHeaderMenu implements SlickPlugin {\n // --\n // public API\n pluginName = 'HeaderMenu' as const;\n onAfterMenuShow = new SlickEvent();\n onBeforeMenuShow = new SlickEvent();\n onCommand = new SlickEvent();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _gridUid = '';\n protected _handler = new SlickEventHandler();\n protected _bindingEventService = new BindingEventService();\n protected _defaults: HeaderMenuOption = {\n buttonCssClass: undefined,\n buttonImage: undefined,\n minWidth: 100,\n autoAlign: true,\n autoAlignOffset: 0\n };\n protected _options: HeaderMenuOption;\n protected _activeHeaderColumnElm?: HTMLDivElement | null;\n protected _menuElm?: HTMLDivElement | null;\n protected _subMenuParentId = '';\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, options, this._defaults);\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._gridUid = grid?.getUID() || '';\n this._handler\n .subscribe(this._grid.onHeaderCellRendered, this.handleHeaderCellRendered.bind(this))\n .subscribe(this._grid.onBeforeHeaderCellDestroy, this.handleBeforeHeaderCellDestroy.bind(this));\n\n // Force the grid to re-render the header now that the events are hooked up.\n this._grid.setColumns(this._grid.getColumns());\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'click', this.handleBodyMouseDown.bind(this) as EventListener);\n }\n\n setOptions(newOptions: Partial) {\n this._options = Utils.extend(true, {}, this._options, newOptions);\n }\n\n protected getGridUidSelector() {\n const gridUid = this._grid.getUID() || '';\n return gridUid ? `.${gridUid}` : '';\n }\n\n destroy() {\n this._handler.unsubscribeAll();\n this._bindingEventService.unbindAll();\n this._menuElm = this._menuElm || document.body.querySelector(`.slick-header-menu${this.getGridUidSelector()}`);\n this._menuElm?.remove();\n this._activeHeaderColumnElm = undefined;\n }\n\n destroyAllMenus() {\n this.destroySubMenus();\n document.querySelectorAll(`.slick-header-menu${this.getGridUidSelector()}`)\n .forEach(subElm => subElm.remove());\n }\n\n /** Close and destroy all previously opened sub-menus */\n destroySubMenus() {\n document.querySelectorAll(`.slick-header-menu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => subElm.remove());\n }\n\n protected handleBodyMouseDown(e: DOMEvent) {\n // did we click inside the menu or any of its sub-menu(s)\n let isMenuClicked = false;\n if (this._menuElm?.contains(e.target)) {\n isMenuClicked = true;\n }\n if (!isMenuClicked) {\n document\n .querySelectorAll(`.slick-header-menu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => {\n if (subElm.contains(e.target)) {\n isMenuClicked = true;\n }\n });\n }\n\n if (this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented || e.target.className === 'close') {\n this.hideMenu();\n }\n }\n\n hideMenu() {\n if (this._menuElm) {\n this._menuElm.remove();\n this._menuElm = undefined;\n }\n this._activeHeaderColumnElm?.classList.remove('slick-header-column-active');\n this.destroySubMenus();\n }\n\n protected handleHeaderCellRendered(_e: MouseEvent, args: OnHeaderCellRenderedEventArgs) {\n const column = args.column;\n const menu = column?.header?.menu as HeaderMenuItems;\n\n if (menu) {\n // run the override function (when defined), if the result is false it won't go further\n if (!this.runOverrideFunctionWhenExists(this._options.menuUsabilityOverride, args)) {\n return;\n }\n\n const elm = document.createElement('div');\n elm.className = 'slick-header-menubutton';\n elm.ariaLabel = 'Header Menu';\n elm.role = 'button';\n\n if (!this._options.buttonCssClass && !this._options.buttonImage) {\n this._options.buttonCssClass = 'caret'; // default when nothing is provided\n }\n\n if (this._options.buttonCssClass) {\n // sgi icon with mask requires inner span to work properly\n const icon = document.createElement('span');\n icon.classList.add(...this._options.buttonCssClass.split(' '));\n elm.appendChild(icon);\n }\n\n if (this._options.buttonImage) {\n elm.style.backgroundImage = `url(${this._options.buttonImage})`;\n }\n\n if (this._options.tooltip) {\n elm.title = this._options.tooltip;\n }\n\n this._bindingEventService.bind(elm, 'click', ((e: DOMMouseOrTouchEvent) => {\n this.destroyAllMenus(); // make there's only 1 parent menu opened at a time\n this.createParentMenu(e, menu, args.column);\n }) as EventListener);\n args.node.appendChild(elm);\n }\n }\n\n protected handleBeforeHeaderCellDestroy(_e: Event, args: { column: Column; node: HTMLElement; }) {\n const column = args.column;\n\n if (column.header?.menu) {\n args.node.querySelectorAll('.slick-header-menubutton').forEach(elm => elm.remove());\n }\n }\n\n protected addSubMenuTitleWhenExists(item: HeaderMenuCommandItem | 'divider', commandMenuElm: HTMLDivElement) {\n if (item !== 'divider' && item?.subMenuTitle) {\n const subMenuTitleElm = document.createElement('div');\n subMenuTitleElm.className = 'slick-menu-title';\n subMenuTitleElm.textContent = item.subMenuTitle as string;\n const subMenuTitleClass = item.subMenuTitleCssClass as string;\n if (subMenuTitleClass) {\n subMenuTitleElm.classList.add(...subMenuTitleClass.split(' '));\n }\n\n commandMenuElm.appendChild(subMenuTitleElm);\n }\n }\n\n protected createParentMenu(event: DOMMouseOrTouchEvent, menu: HeaderMenuItems, columnDef: Column) {\n // Let the user modify the menu or cancel altogether,\n // or provide alternative menu implementation.\n const callbackArgs = {\n grid: this._grid,\n column: columnDef,\n menu\n } as unknown as HeaderMenuCommandItemCallbackArgs;\n if (this.onBeforeMenuShow.notify(callbackArgs, event, this).getReturnValue() === false) {\n return;\n }\n\n // create 1st parent menu container & reposition it\n this._menuElm = this.createMenu(menu.items, columnDef);\n const containerNode = this._grid.getContainerNode();\n if (containerNode) {\n containerNode.appendChild(this._menuElm);\n }\n this.repositionMenu(event, this._menuElm);\n\n if (this.onAfterMenuShow.notify(callbackArgs, event, this).getReturnValue() === false) {\n return;\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n event.preventDefault();\n event.stopPropagation();\n }\n\n protected createMenu(commandItems: Array, columnDef: Column, level = 0, item?: HeaderMenuCommandItem | 'divider') {\n // to avoid having multiple sub-menu trees opened,\n // we need to somehow keep trace of which parent menu the tree belongs to\n // and we should keep ref of only the first sub-menu parent, we can use the command name (remove any whitespaces though)\n const subMenuCommand = (item as HeaderMenuCommandItem)?.command;\n let subMenuId = (level === 1 && subMenuCommand) ? subMenuCommand.replaceAll(' ', '') : '';\n if (subMenuId) {\n this._subMenuParentId = subMenuId;\n }\n if (level > 1) {\n subMenuId = this._subMenuParentId;\n }\n\n // return menu/sub-menu if it's already opened unless we are on different sub-menu tree if so close them all\n const menuClasses = `slick-header-menu slick-menu-level-${level} ${this._gridUid}`;\n const bodyMenuElm = document.body.querySelector(`.slick-header-menu.slick-menu-level-${level}${this.getGridUidSelector()}`);\n if (bodyMenuElm) {\n if (bodyMenuElm.dataset.subMenuParent === subMenuId) {\n return bodyMenuElm;\n }\n this.destroySubMenus();\n }\n\n const menuElm = document.createElement('div');\n menuElm.className = menuClasses;\n if (level > 0) {\n menuElm.classList.add('slick-submenu');\n if (subMenuId) {\n menuElm.dataset.subMenuParent = subMenuId;\n }\n }\n menuElm.classList.add(this._gridUid);\n menuElm.role = 'menu';\n menuElm.ariaLabel = level > 1 ? 'SubMenu' : 'Header Menu';\n menuElm.style.minWidth = `${this._options.minWidth}px`;\n menuElm.setAttribute('aria-expanded', 'true');\n\n const callbackArgs = {\n grid: this._grid,\n column: columnDef,\n menu: { items: commandItems }\n } as unknown as HeaderMenuCommandItemCallbackArgs;\n\n // when creating sub-menu add its sub-menu title when exists\n if (item && level > 0) {\n this.addSubMenuTitleWhenExists(item, menuElm); // add sub-menu title when exists\n }\n\n // Construct the menu items.\n for (let i = 0; i < commandItems.length; i++) {\n let addClickListener = true;\n const item = commandItems[i];\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as HeaderMenuCommandItem).itemVisibilityOverride, callbackArgs);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as HeaderMenuCommandItem).itemUsabilityOverride, callbackArgs);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemCommandClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as HeaderMenuCommandItem).disabled = isItemUsable ? false : true;\n }\n\n const menuItem = document.createElement('div');\n menuItem.className = 'slick-header-menuitem';\n menuItem.role = 'menuitem';\n\n if ((item as HeaderMenuCommandItem).divider || item === 'divider') {\n menuItem.classList.add('slick-header-menuitem-divider');\n addClickListener = false;\n }\n\n if ((item as HeaderMenuCommandItem).disabled) {\n menuItem.classList.add('slick-header-menuitem-disabled');\n }\n\n if ((item as HeaderMenuCommandItem).hidden) {\n menuItem.classList.add('slick-header-menuitem-hidden');\n }\n\n if ((item as HeaderMenuCommandItem).cssClass) {\n menuItem.classList.add(...(item as HeaderMenuCommandItem).cssClass!.split(' '));\n }\n\n if ((item as HeaderMenuCommandItem).tooltip) {\n menuItem.title = (item as HeaderMenuCommandItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-header-menuicon';\n menuItem.appendChild(iconElm);\n\n if ((item as HeaderMenuCommandItem).iconCssClass) {\n iconElm.classList.add(...(item as HeaderMenuCommandItem).iconCssClass!.split(' '));\n }\n\n if ((item as HeaderMenuCommandItem).iconImage) {\n iconElm.style.backgroundImage = 'url(' + (item as HeaderMenuCommandItem).iconImage + ')';\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-header-menucontent';\n textElm.textContent = (item as HeaderMenuCommandItem).title || '';\n menuItem.appendChild(textElm);\n\n if ((item as HeaderMenuCommandItem).textCssClass) {\n textElm.classList.add(...(item as HeaderMenuCommandItem).textCssClass!.split(' '));\n }\n menuElm.appendChild(menuItem);\n\n if (addClickListener) {\n this._bindingEventService.bind(menuItem, 'click', this.handleMenuItemClick.bind(this, item, columnDef, level) as EventListener);\n }\n\n // the option/command item could be a sub-menu if it has another list of commands/options\n if ((item as HeaderMenuCommandItem).items) {\n const chevronElm = document.createElement('div');\n chevronElm.className = 'sub-item-chevron';\n if (this._options.subItemChevronClass) {\n chevronElm.classList.add(...this._options.subItemChevronClass.split(' '));\n } else {\n chevronElm.textContent = '\u2B9E'; // \u2B9E or \u25B8\n }\n\n menuItem.classList.add('slick-submenu-item');\n menuItem.appendChild(chevronElm);\n continue;\n }\n }\n\n return menuElm;\n }\n\n protected handleMenuItemClick(item: HeaderMenuCommandItem | 'divider', columnDef: Column, level = 0, e: DOMMouseOrTouchEvent): boolean | void {\n if (item !== 'divider' && !item.disabled && !item.divider) {\n const command = (item as HeaderMenuCommandItem).command || '';\n\n if (command !== undefined && !(item as HeaderMenuCommandItem).items) {\n const callbackArgs = {\n grid: this._grid,\n column: columnDef,\n command,\n item,\n };\n this.onCommand.notify(callbackArgs, e, this);\n\n // execute action callback when defined\n if (typeof item.action === 'function') {\n item.action.call(this, e, callbackArgs);\n }\n\n // unless prevented, close the menu\n if (!e.defaultPrevented) {\n this.hideMenu();\n }\n } else if ((item as HeaderMenuCommandItem).items) {\n this.repositionSubMenu(item as HeaderMenuCommandItem, columnDef, level, e);\n } else {\n this.destroySubMenus();\n }\n }\n }\n\n protected repositionSubMenu(item: HeaderMenuCommandItem, columnDef: Column, level: number, e: DOMMouseOrTouchEvent) {\n // when we're clicking a grid cell OR our last menu type (command/option) differs then we know that we need to start fresh and close any sub-menus that might still be open\n if (e.target.classList.contains('slick-header-menubutton')) {\n this.destroySubMenus();\n }\n\n // creating sub-menu, we'll also pass level & the item object since we might have \"subMenuTitle\" to show\n const subMenuElm = this.createMenu(item.items || [], columnDef, level + 1, item);\n document.body.appendChild(subMenuElm);\n this.repositionMenu(e, subMenuElm);\n }\n\n protected repositionMenu(e: DOMMouseOrTouchEvent, menuElm: HTMLDivElement) {\n const buttonElm = e.target;\n const isSubMenu = menuElm.classList.contains('slick-submenu');\n const parentElm = isSubMenu\n ? e.target.closest('.slick-header-menuitem') as HTMLDivElement\n : buttonElm as HTMLElement;\n\n const btnOffset = Utils.offset(buttonElm);\n const gridPos = this._grid.getGridPosition();\n const menuWidth = menuElm.offsetWidth;\n const menuOffset = Utils.offset(this._menuElm!);\n const parentOffset = Utils.offset(parentElm);\n const menuOffsetTop = isSubMenu\n ? parentOffset?.top ?? 0\n : buttonElm.clientHeight ?? btnOffset?.top ?? 0 + (this._options?.menuOffsetTop ?? 0);\n let menuOffsetLeft = isSubMenu ? parentOffset?.left ?? 0 : btnOffset?.left ?? 0;\n\n // when auto-align is set, it will calculate whether it has enough space in the viewport to show the drop menu on the right (default)\n // if there isn't enough space on the right, it will automatically align the drop menu to the left\n // to simulate an align left, we actually need to know the width of the drop menu\n if (isSubMenu && parentElm) {\n let subMenuPosCalc = menuOffsetLeft + Number(menuWidth); // calculate coordinate at caller element far right\n if (isSubMenu) {\n subMenuPosCalc += parentElm.clientWidth;\n }\n const browserWidth = document.documentElement.clientWidth;\n const dropSide = (subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth) ? 'left' : 'right';\n if (dropSide === 'left') {\n menuElm.classList.remove('dropright');\n menuElm.classList.add('dropleft');\n menuOffsetLeft -= menuWidth;\n } else {\n menuElm.classList.remove('dropleft');\n menuElm.classList.add('dropright');\n if (isSubMenu) {\n menuOffsetLeft += parentElm.offsetWidth;\n }\n }\n } else {\n if (menuOffsetLeft + menuElm.offsetWidth >= gridPos.width) {\n menuOffsetLeft = menuOffsetLeft + buttonElm.clientWidth - menuElm.clientWidth + (this._options.autoAlignOffset || 0);\n }\n menuOffsetLeft -= menuOffset?.left ?? 0;\n }\n\n // ready to reposition the menu\n menuElm.style.top = `${menuOffsetTop}px`;\n menuElm.style.left = `${menuOffsetLeft}px`;\n\n // Mark the header as active to keep the highlighting.\n this._activeHeaderColumnElm = menuElm.closest('.slick-header-column');\n if (this._activeHeaderColumnElm) {\n this._activeHeaderColumnElm.classList.add('slick-header-column-active');\n }\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n HeaderMenu: SlickHeaderMenu\n }\n }\n });\n}\n\n"], + "mappings": "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", + "names": ["item"] } diff --git a/dist/browser/plugins/slick.rowdetailview.js b/dist/browser/plugins/slick.rowdetailview.js index f53c9f668..865ea82fa 100644 --- a/dist/browser/plugins/slick.rowdetailview.js +++ b/dist/browser/plugins/slick.rowdetailview.js @@ -289,7 +289,7 @@ /** The cell Formatter that shows the icon that will be used to toggle the Row Detail */ detailSelectionFormatter(row, _cell, _val, _column, dataContext, grid) { if (this.checkExpandableOverride(row, dataContext, grid)) { - if (dataContext[`${this._keyPrefix}collapsed`] == null && (dataContext[`${this._keyPrefix}collapsed`] = !0, dataContext[`${this._keyPrefix}sizePadding`] = 0, dataContext[`${this._keyPrefix}height`] = 0, dataContext[`${this._keyPrefix}isPadding`] = !1, dataContext[`${this._keyPrefix}parent`] = void 0, dataContext[`${this._keyPrefix}offset`] = 0), !dataContext[`${this._keyPrefix}isPadding`]) + if (dataContext[`${this._keyPrefix}collapsed`] === void 0 && (dataContext[`${this._keyPrefix}collapsed`] = !0, dataContext[`${this._keyPrefix}sizePadding`] = 0, dataContext[`${this._keyPrefix}height`] = 0, dataContext[`${this._keyPrefix}isPadding`] = !1, dataContext[`${this._keyPrefix}parent`] = void 0, dataContext[`${this._keyPrefix}offset`] = 0), !dataContext[`${this._keyPrefix}isPadding`]) if (dataContext[`${this._keyPrefix}collapsed`]) { let collapsedClasses = this._options.cssClass + " expand "; return this._options.collapsedClass && (collapsedClasses += this._options.collapsedClass), '
'; diff --git a/dist/browser/plugins/slick.rowdetailview.js.map b/dist/browser/plugins/slick.rowdetailview.js.map index 69e60470d..d093ab0b7 100644 --- a/dist/browser/plugins/slick.rowdetailview.js.map +++ b/dist/browser/plugins/slick.rowdetailview.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.rowdetailview.ts"], - "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, FormatterResultObject, GridOption, OnAfterRowDetailToggleArgs, OnBeforeRowDetailToggleArgs, OnRowBackToViewportRangeArgs, OnRowDetailAsyncEndUpdateArgs, OnRowDetailAsyncResponseArgs, OnRowOutOfViewportRangeArgs, RowDetailViewOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add row detail panel\n * Original StackOverflow question & article making this possible (thanks to violet313)\n * https://stackoverflow.com/questions/10535164/can-slickgrids-row-height-be-dynamically-altered#29399927\n * http://violet313.org/slickgrids/#intro\n *\n * USAGE:\n * Add the slick.rowDetailView.(js|css) files and register the plugin with the grid.\n *\n * AVAILABLE ROW DETAIL OPTIONS:\n * cssClass: A CSS class to be added to the row detail\n * expandedClass: Extra classes to be added to the expanded Toggle\n * expandableOverride: callback method that user can override the default behavior of making every row an expandable row (the logic to show or not the expandable icon).\n * collapsedClass: Extra classes to be added to the collapse Toggle\n * loadOnce: Defaults to false, when set to True it will load the data once and then reuse it.\n * preTemplate: Template that will be used before the async process (typically used to show a spinner/loading)\n * postTemplate: Template that will be loaded once the async function finishes\n * process: Async server function call\n * panelRows: Row count to use for the template panel\n * singleRowExpand: Defaults to false, limit expanded row to 1 at a time.\n * useRowClick: Boolean flag, when True will open the row detail on a row click (from any column), default to False\n * keyPrefix: Defaults to '_', prefix used for all the plugin metadata added to the item object (meta e.g.: padding, collapsed, parent)\n * collapseAllOnSort: Defaults to true, which will collapse all row detail views when user calls a sort. Unless user implements a sort to deal with padding\n * saveDetailViewOnScroll: Defaults to true, which will save the row detail view in a cache when it detects that it will become out of the viewport buffer\n * useSimpleViewportCalc: Defaults to false, which will use simplified calculation of out or back of viewport visibility\n *\n * AVAILABLE PUBLIC METHODS:\n * init: initiliaze the plugin\n * expandableOverride: callback method that user can override the default behavior of making every row an expandable row (the logic to show or not the expandable icon).\n * destroy: destroy the plugin and it's events\n * collapseAll: collapse all opened row detail panel\n * collapseDetailView: collapse a row by passing the item object (row detail)\n * expandDetailView: expand a row by passing the item object (row detail)\n * getColumnDefinition: get the column definitions\n * getExpandedRows: get all the expanded rows\n * getFilterItem: takes in the item we are filtering and if it is an expanded row returns it's parents row to filter on\n * getOptions: get current plugin options\n * resizeDetailView: resize a row detail view, it will auto-calculate the number of rows it needs\n * saveDetailView: save a row detail view content by passing the row object\n * setOptions: set or change some of the plugin options\n *\n * THE PLUGIN EXPOSES THE FOLLOWING SLICK EVENTS:\n * onAsyncResponse: This event must be used with the \"notify\" by the end user once the Asynchronous Server call returns the item detail\n * Event args:\n * item: Item detail returned from the async server call\n * detailView: An explicit view to use instead of template (Optional)\n *\n * onAsyncEndUpdate: Fired when the async response finished\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n *\n * onBeforeRowDetailToggle: Fired before the row detail gets toggled\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n *\n * onAfterRowDetailToggle: Fired after the row detail gets toggled\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * expandedRows: Array of the Expanded Rows\n *\n * onRowOutOfViewportRange: Fired after a row becomes out of viewport range (user can't see the row anymore)\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * rowId: Id of the Row object (datacontext) in the Grid\n * rowIndex: Index of the Row in the Grid\n * expandedRows: Array of the Expanded Rows\n * rowIdsOutOfViewport: Array of the Out of viewport Range Rows\n *\n * onRowBackToViewportRange: Fired after a row is back to viewport range (user can visually see the row detail)\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * rowId: Id of the Row object (datacontext) in the Grid\n * rowIndex: Index of the Row in the Grid\n * expandedRows: Array of the Expanded Rows\n * rowIdsOutOfViewport: Array of the Out of viewport Range Rows\n */\nexport class SlickRowDetailView {\n // --\n // public API\n pluginName = 'RowDetailView' as const;\n onAsyncResponse = new SlickEvent();\n onAsyncEndUpdate = new SlickEvent();\n onAfterRowDetailToggle = new SlickEvent();\n onBeforeRowDetailToggle = new SlickEvent();\n onRowBackToViewportRange = new SlickEvent();\n onRowOutOfViewportRange = new SlickEvent();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _gridUid = '';\n protected _dataView!: SlickDataView;\n protected _dataViewIdProperty = 'id';\n protected _expandableOverride: UsabilityOverrideFn | null = null;\n protected _lastRange: { bottom: number; top: number; } | null = null;\n protected _expandedRows: any[] = [];\n protected _eventHandler: SlickEventHandler_;\n protected _outsideRange = 5;\n protected _visibleRenderedCellCount = 0;\n protected _options: RowDetailViewOption;\n protected _defaults = {\n columnId: '_detail_selector',\n cssClass: 'detailView-toggle',\n expandedClass: undefined,\n collapsedClass: undefined,\n keyPrefix: '_',\n loadOnce: false,\n collapseAllOnSort: true,\n saveDetailViewOnScroll: true,\n singleRowExpand: false,\n useSimpleViewportCalc: false,\n alwaysRenderColumn: true,\n toolTip: '',\n width: 30,\n maxRows: undefined\n } as RowDetailViewOption;\n protected _keyPrefix = this._defaults.keyPrefix;\n protected _gridRowBuffer = 0;\n protected _rowIdsOutOfViewport: Array = [];\n\n /** Constructor of the Row Detail View Plugin which accepts optional options */\n constructor(options: RowDetailViewOption) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options.expandableOverride === 'function') {\n this.expandableOverride(this._options.expandableOverride);\n }\n }\n\n /**\n * Initialize the plugin, which requires user to pass the SlickGrid Grid object\n * @param grid: SlickGrid Grid object\n */\n init(grid: SlickGrid) {\n if (!grid) {\n throw new Error('RowDetailView Plugin requires the Grid instance to be passed as argument to the \"init()\" method');\n }\n this._grid = grid;\n this._gridUid = grid.getUID();\n this._gridOptions = grid.getOptions() || {};\n this._dataView = this._grid.getData();\n this._keyPrefix = this._options?.keyPrefix ?? '_';\n\n // Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3\n this._gridRowBuffer = this._gridOptions.minRowBuffer || 0;\n this._gridOptions.minRowBuffer = this._options.panelRows + 3;\n\n this._eventHandler\n .subscribe(this._grid.onClick, this.handleClick.bind(this))\n .subscribe(this._grid.onScroll, this.handleScroll.bind(this));\n\n // Sort will, by default, Collapse all of the open items (unless user implements his own onSort which deals with open row and padding)\n if (this._options.collapseAllOnSort) {\n this._eventHandler.subscribe(this._grid.onSort, this.collapseAll.bind(this));\n this._expandedRows = [];\n this._rowIdsOutOfViewport = [];\n }\n\n this._eventHandler.subscribe(this._dataView.onRowCountChanged, () => {\n this._grid.updateRowCount();\n this._grid.render();\n });\n\n this._eventHandler.subscribe(this._dataView.onRowsChanged, (_e, a) => {\n this._grid.invalidateRows(a.rows);\n this._grid.render();\n });\n\n // subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished\n this.subscribeToOnAsyncResponse();\n\n // after data is set, let's get the DataView Id Property name used (defaults to \"id\")\n this._eventHandler.subscribe(this._dataView.onSetItemsCalled, () => {\n this._dataViewIdProperty = this._dataView?.getIdPropertyName() ?? 'id';\n });\n\n // if we use the alternative & simpler calculation of the out of viewport range\n // we will need to know how many rows are rendered on the screen and we need to wait for grid to be rendered\n // unfortunately there is no triggered event for knowing when grid is finished, so we use 250ms delay and it's typically more than enough\n if (this._options.useSimpleViewportCalc) {\n this._eventHandler.subscribe(this._grid.onRendered, (_e, args) => {\n if (args?.endRow) {\n this._visibleRenderedCellCount = args.endRow - args.startRow;\n }\n });\n }\n }\n\n /** destroy the plugin and it's events */\n destroy() {\n this._eventHandler.unsubscribeAll();\n this.onAsyncResponse.unsubscribe();\n this.onAsyncEndUpdate.unsubscribe();\n this.onAfterRowDetailToggle.unsubscribe();\n this.onBeforeRowDetailToggle.unsubscribe();\n this.onRowOutOfViewportRange.unsubscribe();\n this.onRowBackToViewportRange.unsubscribe();\n }\n\n /** Get current plugin options */\n getOptions() {\n return this._options;\n }\n\n /** set or change some of the plugin options */\n setOptions(options: Partial) {\n this._options = Utils.extend(true, {}, this._options, options);\n if (this._options?.singleRowExpand) {\n this.collapseAll();\n }\n }\n\n /** Find a value in an array and return the index when (or -1 when not found) */\n protected arrayFindIndex(sourceArray: any[], value: any) {\n if (Array.isArray(sourceArray)) {\n for (let i = 0; i < sourceArray.length; i++) {\n if (sourceArray[i] === value) {\n return i;\n }\n }\n }\n return -1;\n }\n\n /** Handle mouse click event */\n protected handleClick(e: DOMEvent, args: { row: number; cell: number; }) {\n const dataContext = this._grid.getDataItem(args.row);\n if (!this.checkExpandableOverride(args.row, dataContext, this._grid)) {\n return;\n }\n\n // clicking on a row select checkbox\n if (this._options.useRowClick || this._grid.getColumns()[args.cell]['id'] === this._options.columnId && e.target.classList.contains(this._options.cssClass || '')) {\n // if editing, try to commit\n if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {\n e.preventDefault();\n e.stopImmediatePropagation();\n return;\n }\n\n // trigger an event before toggling\n // user could cancel the Row Detail opening when event is returning false\n if (this.onBeforeRowDetailToggle.notify({ grid: this._grid, item: dataContext }, e, this).getReturnValue() === false) {\n return;\n }\n\n this.toggleRowSelection(args.row, dataContext);\n\n // trigger an event after toggling\n this.onAfterRowDetailToggle.notify({\n grid: this._grid,\n item: dataContext,\n expandedRows: this._expandedRows,\n }, e, this);\n\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n\n /** If we scroll save detail views that go out of cache range */\n protected handleScroll() {\n if (this._options.useSimpleViewportCalc) {\n this.calculateOutOfRangeViewsSimplerVersion();\n } else {\n this.calculateOutOfRangeViews();\n }\n }\n\n /** Calculate when expanded rows become out of view range */\n protected calculateOutOfRangeViews() {\n let scrollDir = ''\n if (this._grid) {\n const renderedRange = this._grid.getRenderedRange();\n // Only check if we have expanded rows\n if (this._expandedRows.length > 0) {\n // Assume scroll direction is down by default.\n scrollDir = 'DOWN';\n if (this._lastRange) {\n // Some scrolling isn't anything as the range is the same\n if (this._lastRange.top === renderedRange.top && this._lastRange.bottom === renderedRange.bottom) {\n return;\n }\n\n // If our new top is smaller we are scrolling up\n if (this._lastRange.top > renderedRange.top ||\n // Or we are at very top but our bottom is increasing\n (this._lastRange.top === 0 && renderedRange.top === 0) && this._lastRange.bottom > renderedRange.bottom) {\n scrollDir = 'UP';\n }\n }\n }\n\n this._expandedRows.forEach((row) => {\n const rowIndex = this._dataView?.getRowById(row[this._dataViewIdProperty]) ?? 0;\n const rowPadding = row[`${this._keyPrefix}sizePadding`];\n const rowOutOfRange = this.arrayFindIndex(this._rowIdsOutOfViewport, row[this._dataViewIdProperty]) >= 0;\n\n if (scrollDir === 'UP') {\n // save the view when asked\n if (this._options.saveDetailViewOnScroll) {\n // If the bottom item within buffer range is an expanded row save it.\n if (rowIndex >= renderedRange.bottom - this._gridRowBuffer) {\n this.saveDetailView(row);\n }\n }\n\n // If the row expanded area is within the buffer notify that it is back in range\n if (rowOutOfRange && rowIndex - this._outsideRange < renderedRange.top && rowIndex >= renderedRange.top) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n }\n\n // if our first expanded row is about to go off the bottom\n else if (!rowOutOfRange && (rowIndex + rowPadding) > renderedRange.bottom) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n }\n else if (scrollDir === 'DOWN') {\n // save the view when asked\n if (this._options.saveDetailViewOnScroll) {\n // If the top item within buffer range is an expanded row save it.\n if (rowIndex <= renderedRange.top + this._gridRowBuffer) {\n this.saveDetailView(row);\n }\n }\n\n // If row index is i higher than bottom with some added value (To ignore top rows off view) and is with view and was our of range\n if (rowOutOfRange && (rowIndex + rowPadding + this._outsideRange) > renderedRange.bottom && rowIndex < rowIndex + rowPadding) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n }\n // if our row is outside top of and the buffering zone but not in the array of outOfVisable range notify it\n else if (!rowOutOfRange && rowIndex < renderedRange.top) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n }\n });\n this._lastRange = renderedRange;\n }\n }\n\n /** This is an alternative & more simpler version of the Calculate when expanded rows become out of view range */\n protected calculateOutOfRangeViewsSimplerVersion() {\n if (this._grid) {\n const renderedRange = this._grid.getRenderedRange();\n\n this._expandedRows.forEach((row) => {\n const rowIndex = this._dataView.getRowById(row[this._dataViewIdProperty]) ?? -1;\n const isOutOfVisibility = this.checkIsRowOutOfViewportRange(rowIndex, renderedRange);\n if (!isOutOfVisibility && this.arrayFindIndex(this._rowIdsOutOfViewport, row[this._dataViewIdProperty]) >= 0) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n } else if (isOutOfVisibility) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n });\n }\n }\n\n /**\n * Check if the row became out of visible range (when user can't see it anymore)\n * @param rowIndex\n * @param renderedRange from SlickGrid\n */\n protected checkIsRowOutOfViewportRange(rowIndex: number, renderedRange: any) {\n if (Math.abs(renderedRange.bottom - this._gridRowBuffer - rowIndex) > this._visibleRenderedCellCount * 2) {\n return true;\n }\n return false;\n }\n\n /** Send a notification, through \"onRowOutOfViewportRange\", that is out of the viewport range */\n protected notifyOutOfViewport(item: any, rowId: number | string) {\n const rowIndex = (item.rowIndex || this._dataView.getRowById(item[this._dataViewIdProperty])) as number;\n\n this.onRowOutOfViewportRange.notify({\n grid: this._grid,\n item,\n rowId,\n rowIndex,\n expandedRows: this._expandedRows,\n rowIdsOutOfViewport: this.syncOutOfViewportArray(rowId, true)\n }, null, this);\n }\n\n /** Send a notification, through \"onRowBackToViewportRange\", that a row came back into the viewport visible range */\n protected notifyBackToViewportWhenDomExist(item: any, rowId: number | string) {\n const rowIndex = (item.rowIndex || this._dataView.getRowById(item[this._dataViewIdProperty])) as number;\n\n setTimeout(() => {\n // make sure View Row DOM Element really exist before notifying that it's a row that is visible again\n if (document.querySelector(`.${this._gridUid} .cellDetailView_${item[this._dataViewIdProperty]}`)) {\n this.onRowBackToViewportRange.notify({\n grid: this._grid,\n item,\n rowId,\n rowIndex,\n expandedRows: this._expandedRows,\n rowIdsOutOfViewport: this.syncOutOfViewportArray(rowId, false)\n }, null, this);\n }\n }, 100);\n }\n\n /**\n * This function will sync the \"out of viewport\" array whenever necessary.\n * The sync can add a detail row (when necessary, no need to add again if it already exist) or delete a row from the array.\n * @param rowId: number\n * @param isAdding: are we adding or removing a row?\n */\n protected syncOutOfViewportArray(rowId: number | string, isAdding: boolean) {\n const arrayRowIndex = this.arrayFindIndex(this._rowIdsOutOfViewport, rowId);\n\n if (isAdding && arrayRowIndex < 0) {\n this._rowIdsOutOfViewport.push(rowId);\n } else if (!isAdding && arrayRowIndex >= 0) {\n this._rowIdsOutOfViewport.splice(arrayRowIndex, 1);\n }\n return this._rowIdsOutOfViewport;\n }\n\n // Toggle between showing or hiding a row\n protected toggleRowSelection(rowNumber: number, dataContext: any) {\n if (!this.checkExpandableOverride(rowNumber, dataContext, this._grid)) {\n return;\n }\n\n this._dataView.beginUpdate();\n this.handleAccordionShowHide(dataContext);\n this._dataView.endUpdate();\n }\n\n /** Collapse all of the open detail rows */\n collapseAll() {\n this._dataView.beginUpdate();\n for (let i = this._expandedRows.length - 1; i >= 0; i--) {\n this.collapseDetailView(this._expandedRows[i], true);\n }\n this._dataView.endUpdate();\n }\n\n /** Collapse a detail row so that it is not longer open */\n collapseDetailView(item: any, isMultipleCollapsing = false) {\n if (!isMultipleCollapsing) {\n this._dataView.beginUpdate();\n }\n // Save the details on the collapse assuming onetime loading\n if (this._options.loadOnce) {\n this.saveDetailView(item);\n }\n\n item[`${this._keyPrefix}collapsed`] = true;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.deleteItem(item[this._dataViewIdProperty] + '.' + idx);\n }\n item[`${this._keyPrefix}sizePadding`] = 0;\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n // Remove the item from the expandedRows\n this._expandedRows = this._expandedRows.filter((r) => {\n return r[this._dataViewIdProperty] !== item[this._dataViewIdProperty];\n });\n\n if (!isMultipleCollapsing) {\n this._dataView.endUpdate();\n }\n }\n\n /** Expand a detail row by providing the dataview item that is to be expanded */\n expandDetailView(item: any) {\n if (this._options?.singleRowExpand) {\n this.collapseAll();\n }\n\n item[`${this._keyPrefix}collapsed`] = false;\n this._expandedRows.push(item);\n\n // In the case something went wrong loading it the first time such a scroll of screen before loaded\n if (!item[`${this._keyPrefix}detailContent`]) item[`${this._keyPrefix}detailViewLoaded`] = false;\n\n // display pre-loading template\n if (!item[`${this._keyPrefix}detailViewLoaded`] || this._options.loadOnce !== true) {\n item[`${this._keyPrefix}detailContent`] = this._options?.preTemplate?.(item);\n } else {\n this.onAsyncResponse.notify({\n item,\n itemDetail: item,\n detailView: item[`${this._keyPrefix}detailContent`]\n }, undefined, this);\n this.applyTemplateNewLineHeight(item);\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n return;\n }\n\n this.applyTemplateNewLineHeight(item);\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n // async server call\n this._options.process(item);\n }\n\n /** Saves the current state of the detail view */\n saveDetailView(item: any) {\n const view = document.querySelector(`.${this._gridUid} .innerDetailView_${item[this._dataViewIdProperty]}`);\n if (view) {\n const html = view.innerHTML;\n if (html !== undefined) {\n item[`${this._keyPrefix}detailContent`] = html;\n }\n }\n }\n\n /**\n * subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished\n * the response has to be as \"args.item\" (or \"args.itemDetail\") with it's data back\n */\n protected subscribeToOnAsyncResponse() {\n this.onAsyncResponse.subscribe((e, args) => {\n if (!args || (!args.item && !args.itemDetail)) {\n throw 'Slick.RowDetailView plugin requires the onAsyncResponse() to supply \"args.item\" property.';\n }\n\n // we accept item/itemDetail, just get the one which has data\n const itemDetail = args.item || args.itemDetail;\n\n // If we just want to load in a view directly we can use detailView property to do so\n if (args.detailView) {\n itemDetail[`${this._keyPrefix}detailContent`] = args.detailView;\n } else {\n itemDetail[`${this._keyPrefix}detailContent`] = this._options?.postTemplate?.(itemDetail);\n }\n\n itemDetail[`${this._keyPrefix}detailViewLoaded`] = true;\n this._dataView.updateItem(itemDetail[this._dataViewIdProperty], itemDetail);\n\n // trigger an event once the post template is finished loading\n this.onAsyncEndUpdate.notify({\n 'grid': this._grid,\n 'item': itemDetail,\n 'itemDetail': itemDetail\n }, e, this);\n });\n }\n\n /** When row is getting toggled, we will handle the action of collapsing/expanding */\n protected handleAccordionShowHide(item: any) {\n if (item) {\n if (!item[`${this._keyPrefix}collapsed`]) {\n this.collapseDetailView(item);\n } else {\n this.expandDetailView(item);\n }\n }\n }\n\n //////////////////////////////////////////////////////////////\n //////////////////////////////////////////////////////////////\n\n /** Get the Row Detail padding (which are the rows dedicated to the detail panel) */\n protected getPaddingItem(parent: any, offset: any) {\n const item: any = {};\n\n for (const prop in this._dataView) {\n item[prop] = null;\n }\n item[this._dataViewIdProperty] = parent[this._dataViewIdProperty] + '.' + offset;\n\n // additional hidden padding metadata fields\n item[`${this._keyPrefix}collapsed`] = true;\n item[`${this._keyPrefix}isPadding`] = true;\n item[`${this._keyPrefix}parent`] = parent;\n item[`${this._keyPrefix}offset`] = offset;\n\n return item;\n };\n\n /** Create the detail ctr node. this belongs to the dev & can be custom-styled as per */\n protected applyTemplateNewLineHeight(item: any) {\n // the height is calculated by the template row count (how many line of items does the template view have)\n const rowCount = this._options.panelRows;\n\n // calculate padding requirements based on detail-content..\n // ie. worst-case: create an invisible dom node now & find it's height.\n const lineHeight = 13; // we know cuz we wrote the custom css init ;)\n item[`${this._keyPrefix}sizePadding`] = Math.ceil(((rowCount * 2) * lineHeight) / this._gridOptions.rowHeight!);\n item[`${this._keyPrefix}height`] = (item[`${this._keyPrefix}sizePadding`] * this._gridOptions.rowHeight!);\n const idxParent = this._dataView.getIdxById(item[this._dataViewIdProperty]) ?? 0;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));\n }\n }\n\n /** Get the Column Definition of the first column dedicated to toggling the Row Detail View */\n getColumnDefinition() {\n return {\n id: this._options.columnId,\n name: '',\n toolTip: this._options.toolTip,\n field: 'sel',\n width: this._options.width,\n resizable: false,\n sortable: false,\n alwaysRenderColumn: this._options.alwaysRenderColumn,\n cssClass: this._options.cssClass,\n formatter: this.detailSelectionFormatter.bind(this)\n };\n }\n\n /** Return the currently expanded rows */\n getExpandedRows() {\n return this._expandedRows;\n }\n\n /** The cell Formatter that shows the icon that will be used to toggle the Row Detail */\n protected detailSelectionFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultObject | string {\n if (!this.checkExpandableOverride(row, dataContext, grid)) {\n return '';\n } else {\n if (dataContext[`${this._keyPrefix}collapsed`] == undefined) {\n dataContext[`${this._keyPrefix}collapsed`] = true;\n dataContext[`${this._keyPrefix}sizePadding`] = 0; //the required number of pading rows\n dataContext[`${this._keyPrefix}height`] = 0; //the actual height in pixels of the detail field\n dataContext[`${this._keyPrefix}isPadding`] = false;\n dataContext[`${this._keyPrefix}parent`] = undefined;\n dataContext[`${this._keyPrefix}offset`] = 0;\n }\n\n if (dataContext[`${this._keyPrefix}isPadding`]) {\n // render nothing\n }\n else if (dataContext[`${this._keyPrefix}collapsed`]) {\n let collapsedClasses = this._options.cssClass + ' expand ';\n if (this._options.collapsedClass) {\n collapsedClasses += this._options.collapsedClass;\n }\n return '
';\n }\n else {\n const html: string[] = [];\n const rowHeight = this._gridOptions.rowHeight;\n let outterHeight = dataContext[`${this._keyPrefix}sizePadding`] * this._gridOptions.rowHeight!;\n\n if (this._options.maxRows !== undefined && dataContext[`${this._keyPrefix}sizePadding`] > this._options.maxRows) {\n outterHeight = this._options.maxRows * rowHeight!;\n dataContext[`${this._keyPrefix}sizePadding`] = this._options.maxRows;\n }\n\n // V313HAX:\n // putting in an extra closing div after the closing toggle div and ommiting a\n // final closing div for the detail ctr div causes the slickgrid renderer to\n // insert our detail div as a new column ;) ~since it wraps whatever we provide\n // in a generic div column container. so our detail becomes a child directly of\n // the row not the cell. nice =) ~no need to apply a css change to the parent\n // slick-cell to escape the cell overflow clipping.\n\n // sneaky extra inserted here-----------------v\n let expandedClasses = this._options.cssClass + ' collapse ';\n if (this._options.expandedClass) {\n expandedClasses += this._options.expandedClass;\n }\n html.push('
');\n\n html.push(`
`); //shift detail below 1st row\n html.push(`
`); //sub ctr for custom styling\n html.push(`
${dataContext[`${this._keyPrefix}detailContent`]}
`);\n // omit a final closing detail container
that would come next\n\n return html.join('');\n }\n }\n return '';\n }\n\n /** Resize the Row Detail View */\n resizeDetailView(item: any) {\n if (!item) {\n return;\n }\n\n // Grad each of the DOM elements\n const mainContainer = document.querySelector(`.${this._gridUid} .detailViewContainer_${item[this._dataViewIdProperty]}`);\n const cellItem = document.querySelector(`.${this._gridUid} .cellDetailView_${item[this._dataViewIdProperty]}`);\n const inner = document.querySelector(`.${this._gridUid} .innerDetailView_${item[this._dataViewIdProperty]}`);\n\n if (!mainContainer || !cellItem || !inner) {\n return;\n }\n\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.deleteItem(`${item[this._dataViewIdProperty]}.${idx}`);\n }\n\n const rowHeight = this._gridOptions.rowHeight; // height of a row\n const lineHeight = 13; // we know cuz we wrote the custom css innit ;)\n\n // remove the height so we can calculate the height\n mainContainer.style.minHeight = '';\n\n // Get the scroll height for the main container so we know the actual size of the view\n const itemHeight = mainContainer.scrollHeight;\n\n // Now work out how many rows\n const rowCount = Math.ceil(itemHeight / rowHeight!);\n\n item[`${this._keyPrefix}sizePadding`] = Math.ceil(((rowCount * 2) * lineHeight) / rowHeight!);\n item[`${this._keyPrefix}height`] = itemHeight;\n\n let outterHeight = (item[`${this._keyPrefix}sizePadding`] * rowHeight!);\n if (this._options.maxRows !== undefined && item[`${this._keyPrefix}sizePadding`] > this._options.maxRows) {\n outterHeight = this._options.maxRows * rowHeight!;\n item[`${this._keyPrefix}sizePadding`] = this._options.maxRows;\n }\n\n // If the padding is now more than the original minRowBuff we need to increase it\n if (this._grid.getOptions().minRowBuffer! < item[`${this._keyPrefix}sizePadding`]) {\n // Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3\n this._grid.getOptions().minRowBuffer = item[`${this._keyPrefix}sizePadding`] + 3;\n }\n\n mainContainer.setAttribute('style', 'min-height: ' + item[`${this._keyPrefix}height`] + 'px');\n if (cellItem) cellItem.setAttribute('style', 'height: ' + outterHeight + 'px; top:' + rowHeight + 'px');\n\n const idxParent = this._dataView.getIdxById(item[this._dataViewIdProperty]) ?? 0;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));\n }\n\n // Lastly save the updated state\n this.saveDetailView(item);\n }\n\n /** Takes in the item we are filtering and if it is an expanded row returns it's parents row to filter on */\n getFilterItem(item: any) {\n if (item[`${this._keyPrefix}isPadding`] && item[`${this._keyPrefix}parent`]) {\n item = item[`${this._keyPrefix}parent`];\n }\n return item;\n }\n\n protected checkExpandableOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._expandableOverride === 'function') {\n return this._expandableOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row an expandable row.\n * In order word, user can choose which rows to be an available row detail (or not) by providing his own logic.\n * @param overrideFn: override function callback\n */\n expandableOverride(overrideFn: UsabilityOverrideFn) {\n this._expandableOverride = overrideFn;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n RowDetailView: SlickRowDetailView\n }\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, FormatterResultObject, GridOption, OnAfterRowDetailToggleArgs, OnBeforeRowDetailToggleArgs, OnRowBackToViewportRangeArgs, OnRowDetailAsyncEndUpdateArgs, OnRowDetailAsyncResponseArgs, OnRowOutOfViewportRangeArgs, RowDetailViewOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add row detail panel\n * Original StackOverflow question & article making this possible (thanks to violet313)\n * https://stackoverflow.com/questions/10535164/can-slickgrids-row-height-be-dynamically-altered#29399927\n * http://violet313.org/slickgrids/#intro\n *\n * USAGE:\n * Add the slick.rowDetailView.(js|css) files and register the plugin with the grid.\n *\n * AVAILABLE ROW DETAIL OPTIONS:\n * cssClass: A CSS class to be added to the row detail\n * expandedClass: Extra classes to be added to the expanded Toggle\n * expandableOverride: callback method that user can override the default behavior of making every row an expandable row (the logic to show or not the expandable icon).\n * collapsedClass: Extra classes to be added to the collapse Toggle\n * loadOnce: Defaults to false, when set to True it will load the data once and then reuse it.\n * preTemplate: Template that will be used before the async process (typically used to show a spinner/loading)\n * postTemplate: Template that will be loaded once the async function finishes\n * process: Async server function call\n * panelRows: Row count to use for the template panel\n * singleRowExpand: Defaults to false, limit expanded row to 1 at a time.\n * useRowClick: Boolean flag, when True will open the row detail on a row click (from any column), default to False\n * keyPrefix: Defaults to '_', prefix used for all the plugin metadata added to the item object (meta e.g.: padding, collapsed, parent)\n * collapseAllOnSort: Defaults to true, which will collapse all row detail views when user calls a sort. Unless user implements a sort to deal with padding\n * saveDetailViewOnScroll: Defaults to true, which will save the row detail view in a cache when it detects that it will become out of the viewport buffer\n * useSimpleViewportCalc: Defaults to false, which will use simplified calculation of out or back of viewport visibility\n *\n * AVAILABLE PUBLIC METHODS:\n * init: initiliaze the plugin\n * expandableOverride: callback method that user can override the default behavior of making every row an expandable row (the logic to show or not the expandable icon).\n * destroy: destroy the plugin and it's events\n * collapseAll: collapse all opened row detail panel\n * collapseDetailView: collapse a row by passing the item object (row detail)\n * expandDetailView: expand a row by passing the item object (row detail)\n * getColumnDefinition: get the column definitions\n * getExpandedRows: get all the expanded rows\n * getFilterItem: takes in the item we are filtering and if it is an expanded row returns it's parents row to filter on\n * getOptions: get current plugin options\n * resizeDetailView: resize a row detail view, it will auto-calculate the number of rows it needs\n * saveDetailView: save a row detail view content by passing the row object\n * setOptions: set or change some of the plugin options\n *\n * THE PLUGIN EXPOSES THE FOLLOWING SLICK EVENTS:\n * onAsyncResponse: This event must be used with the \"notify\" by the end user once the Asynchronous Server call returns the item detail\n * Event args:\n * item: Item detail returned from the async server call\n * detailView: An explicit view to use instead of template (Optional)\n *\n * onAsyncEndUpdate: Fired when the async response finished\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n *\n * onBeforeRowDetailToggle: Fired before the row detail gets toggled\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n *\n * onAfterRowDetailToggle: Fired after the row detail gets toggled\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * expandedRows: Array of the Expanded Rows\n *\n * onRowOutOfViewportRange: Fired after a row becomes out of viewport range (user can't see the row anymore)\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * rowId: Id of the Row object (datacontext) in the Grid\n * rowIndex: Index of the Row in the Grid\n * expandedRows: Array of the Expanded Rows\n * rowIdsOutOfViewport: Array of the Out of viewport Range Rows\n *\n * onRowBackToViewportRange: Fired after a row is back to viewport range (user can visually see the row detail)\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * rowId: Id of the Row object (datacontext) in the Grid\n * rowIndex: Index of the Row in the Grid\n * expandedRows: Array of the Expanded Rows\n * rowIdsOutOfViewport: Array of the Out of viewport Range Rows\n */\nexport class SlickRowDetailView {\n // --\n // public API\n pluginName = 'RowDetailView' as const;\n onAsyncResponse = new SlickEvent();\n onAsyncEndUpdate = new SlickEvent();\n onAfterRowDetailToggle = new SlickEvent();\n onBeforeRowDetailToggle = new SlickEvent();\n onRowBackToViewportRange = new SlickEvent();\n onRowOutOfViewportRange = new SlickEvent();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _gridUid = '';\n protected _dataView!: SlickDataView;\n protected _dataViewIdProperty = 'id';\n protected _expandableOverride: UsabilityOverrideFn | null = null;\n protected _lastRange: { bottom: number; top: number; } | null = null;\n protected _expandedRows: any[] = [];\n protected _eventHandler: SlickEventHandler_;\n protected _outsideRange = 5;\n protected _visibleRenderedCellCount = 0;\n protected _options: RowDetailViewOption;\n protected _defaults = {\n columnId: '_detail_selector',\n cssClass: 'detailView-toggle',\n expandedClass: undefined,\n collapsedClass: undefined,\n keyPrefix: '_',\n loadOnce: false,\n collapseAllOnSort: true,\n saveDetailViewOnScroll: true,\n singleRowExpand: false,\n useSimpleViewportCalc: false,\n alwaysRenderColumn: true,\n toolTip: '',\n width: 30,\n maxRows: undefined\n } as RowDetailViewOption;\n protected _keyPrefix = this._defaults.keyPrefix;\n protected _gridRowBuffer = 0;\n protected _rowIdsOutOfViewport: Array = [];\n\n /** Constructor of the Row Detail View Plugin which accepts optional options */\n constructor(options: RowDetailViewOption) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options.expandableOverride === 'function') {\n this.expandableOverride(this._options.expandableOverride);\n }\n }\n\n /**\n * Initialize the plugin, which requires user to pass the SlickGrid Grid object\n * @param grid: SlickGrid Grid object\n */\n init(grid: SlickGrid) {\n if (!grid) {\n throw new Error('RowDetailView Plugin requires the Grid instance to be passed as argument to the \"init()\" method');\n }\n this._grid = grid;\n this._gridUid = grid.getUID();\n this._gridOptions = grid.getOptions() || {};\n this._dataView = this._grid.getData();\n this._keyPrefix = this._options?.keyPrefix ?? '_';\n\n // Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3\n this._gridRowBuffer = this._gridOptions.minRowBuffer || 0;\n this._gridOptions.minRowBuffer = this._options.panelRows + 3;\n\n this._eventHandler\n .subscribe(this._grid.onClick, this.handleClick.bind(this))\n .subscribe(this._grid.onScroll, this.handleScroll.bind(this));\n\n // Sort will, by default, Collapse all of the open items (unless user implements his own onSort which deals with open row and padding)\n if (this._options.collapseAllOnSort) {\n this._eventHandler.subscribe(this._grid.onSort, this.collapseAll.bind(this));\n this._expandedRows = [];\n this._rowIdsOutOfViewport = [];\n }\n\n this._eventHandler.subscribe(this._dataView.onRowCountChanged, () => {\n this._grid.updateRowCount();\n this._grid.render();\n });\n\n this._eventHandler.subscribe(this._dataView.onRowsChanged, (_e, a) => {\n this._grid.invalidateRows(a.rows);\n this._grid.render();\n });\n\n // subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished\n this.subscribeToOnAsyncResponse();\n\n // after data is set, let's get the DataView Id Property name used (defaults to \"id\")\n this._eventHandler.subscribe(this._dataView.onSetItemsCalled, () => {\n this._dataViewIdProperty = this._dataView?.getIdPropertyName() ?? 'id';\n });\n\n // if we use the alternative & simpler calculation of the out of viewport range\n // we will need to know how many rows are rendered on the screen and we need to wait for grid to be rendered\n // unfortunately there is no triggered event for knowing when grid is finished, so we use 250ms delay and it's typically more than enough\n if (this._options.useSimpleViewportCalc) {\n this._eventHandler.subscribe(this._grid.onRendered, (_e, args) => {\n if (args?.endRow) {\n this._visibleRenderedCellCount = args.endRow - args.startRow;\n }\n });\n }\n }\n\n /** destroy the plugin and it's events */\n destroy() {\n this._eventHandler.unsubscribeAll();\n this.onAsyncResponse.unsubscribe();\n this.onAsyncEndUpdate.unsubscribe();\n this.onAfterRowDetailToggle.unsubscribe();\n this.onBeforeRowDetailToggle.unsubscribe();\n this.onRowOutOfViewportRange.unsubscribe();\n this.onRowBackToViewportRange.unsubscribe();\n }\n\n /** Get current plugin options */\n getOptions() {\n return this._options;\n }\n\n /** set or change some of the plugin options */\n setOptions(options: Partial) {\n this._options = Utils.extend(true, {}, this._options, options);\n if (this._options?.singleRowExpand) {\n this.collapseAll();\n }\n }\n\n /** Find a value in an array and return the index when (or -1 when not found) */\n protected arrayFindIndex(sourceArray: any[], value: any) {\n if (Array.isArray(sourceArray)) {\n for (let i = 0; i < sourceArray.length; i++) {\n if (sourceArray[i] === value) {\n return i;\n }\n }\n }\n return -1;\n }\n\n /** Handle mouse click event */\n protected handleClick(e: DOMEvent, args: { row: number; cell: number; }) {\n const dataContext = this._grid.getDataItem(args.row);\n if (!this.checkExpandableOverride(args.row, dataContext, this._grid)) {\n return;\n }\n\n // clicking on a row select checkbox\n if (this._options.useRowClick || this._grid.getColumns()[args.cell]['id'] === this._options.columnId && e.target.classList.contains(this._options.cssClass || '')) {\n // if editing, try to commit\n if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {\n e.preventDefault();\n e.stopImmediatePropagation();\n return;\n }\n\n // trigger an event before toggling\n // user could cancel the Row Detail opening when event is returning false\n if (this.onBeforeRowDetailToggle.notify({ grid: this._grid, item: dataContext }, e, this).getReturnValue() === false) {\n return;\n }\n\n this.toggleRowSelection(args.row, dataContext);\n\n // trigger an event after toggling\n this.onAfterRowDetailToggle.notify({\n grid: this._grid,\n item: dataContext,\n expandedRows: this._expandedRows,\n }, e, this);\n\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n\n /** If we scroll save detail views that go out of cache range */\n protected handleScroll() {\n if (this._options.useSimpleViewportCalc) {\n this.calculateOutOfRangeViewsSimplerVersion();\n } else {\n this.calculateOutOfRangeViews();\n }\n }\n\n /** Calculate when expanded rows become out of view range */\n protected calculateOutOfRangeViews() {\n let scrollDir = '';\n if (this._grid) {\n const renderedRange = this._grid.getRenderedRange();\n // Only check if we have expanded rows\n if (this._expandedRows.length > 0) {\n // Assume scroll direction is down by default.\n scrollDir = 'DOWN';\n if (this._lastRange) {\n // Some scrolling isn't anything as the range is the same\n if (this._lastRange.top === renderedRange.top && this._lastRange.bottom === renderedRange.bottom) {\n return;\n }\n\n // If our new top is smaller we are scrolling up\n if (this._lastRange.top > renderedRange.top ||\n // Or we are at very top but our bottom is increasing\n (this._lastRange.top === 0 && renderedRange.top === 0) && this._lastRange.bottom > renderedRange.bottom) {\n scrollDir = 'UP';\n }\n }\n }\n\n this._expandedRows.forEach((row) => {\n const rowIndex = this._dataView?.getRowById(row[this._dataViewIdProperty]) ?? 0;\n const rowPadding = row[`${this._keyPrefix}sizePadding`];\n const rowOutOfRange = this.arrayFindIndex(this._rowIdsOutOfViewport, row[this._dataViewIdProperty]) >= 0;\n\n if (scrollDir === 'UP') {\n // save the view when asked\n if (this._options.saveDetailViewOnScroll) {\n // If the bottom item within buffer range is an expanded row save it.\n if (rowIndex >= renderedRange.bottom - this._gridRowBuffer) {\n this.saveDetailView(row);\n }\n }\n\n // If the row expanded area is within the buffer notify that it is back in range\n if (rowOutOfRange && rowIndex - this._outsideRange < renderedRange.top && rowIndex >= renderedRange.top) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n }\n\n // if our first expanded row is about to go off the bottom\n else if (!rowOutOfRange && (rowIndex + rowPadding) > renderedRange.bottom) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n }\n else if (scrollDir === 'DOWN') {\n // save the view when asked\n if (this._options.saveDetailViewOnScroll) {\n // If the top item within buffer range is an expanded row save it.\n if (rowIndex <= renderedRange.top + this._gridRowBuffer) {\n this.saveDetailView(row);\n }\n }\n\n // If row index is i higher than bottom with some added value (To ignore top rows off view) and is with view and was our of range\n if (rowOutOfRange && (rowIndex + rowPadding + this._outsideRange) > renderedRange.bottom && rowIndex < rowIndex + rowPadding) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n }\n // if our row is outside top of and the buffering zone but not in the array of outOfVisable range notify it\n else if (!rowOutOfRange && rowIndex < renderedRange.top) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n }\n });\n this._lastRange = renderedRange;\n }\n }\n\n /** This is an alternative & more simpler version of the Calculate when expanded rows become out of view range */\n protected calculateOutOfRangeViewsSimplerVersion() {\n if (this._grid) {\n const renderedRange = this._grid.getRenderedRange();\n\n this._expandedRows.forEach((row) => {\n const rowIndex = this._dataView.getRowById(row[this._dataViewIdProperty]) ?? -1;\n const isOutOfVisibility = this.checkIsRowOutOfViewportRange(rowIndex, renderedRange);\n if (!isOutOfVisibility && this.arrayFindIndex(this._rowIdsOutOfViewport, row[this._dataViewIdProperty]) >= 0) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n } else if (isOutOfVisibility) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n });\n }\n }\n\n /**\n * Check if the row became out of visible range (when user can't see it anymore)\n * @param rowIndex\n * @param renderedRange from SlickGrid\n */\n protected checkIsRowOutOfViewportRange(rowIndex: number, renderedRange: any) {\n if (Math.abs(renderedRange.bottom - this._gridRowBuffer - rowIndex) > this._visibleRenderedCellCount * 2) {\n return true;\n }\n return false;\n }\n\n /** Send a notification, through \"onRowOutOfViewportRange\", that is out of the viewport range */\n protected notifyOutOfViewport(item: any, rowId: number | string) {\n const rowIndex = (item.rowIndex || this._dataView.getRowById(item[this._dataViewIdProperty])) as number;\n\n this.onRowOutOfViewportRange.notify({\n grid: this._grid,\n item,\n rowId,\n rowIndex,\n expandedRows: this._expandedRows,\n rowIdsOutOfViewport: this.syncOutOfViewportArray(rowId, true)\n }, null, this);\n }\n\n /** Send a notification, through \"onRowBackToViewportRange\", that a row came back into the viewport visible range */\n protected notifyBackToViewportWhenDomExist(item: any, rowId: number | string) {\n const rowIndex = (item.rowIndex || this._dataView.getRowById(item[this._dataViewIdProperty])) as number;\n\n setTimeout(() => {\n // make sure View Row DOM Element really exist before notifying that it's a row that is visible again\n if (document.querySelector(`.${this._gridUid} .cellDetailView_${item[this._dataViewIdProperty]}`)) {\n this.onRowBackToViewportRange.notify({\n grid: this._grid,\n item,\n rowId,\n rowIndex,\n expandedRows: this._expandedRows,\n rowIdsOutOfViewport: this.syncOutOfViewportArray(rowId, false)\n }, null, this);\n }\n }, 100);\n }\n\n /**\n * This function will sync the \"out of viewport\" array whenever necessary.\n * The sync can add a detail row (when necessary, no need to add again if it already exist) or delete a row from the array.\n * @param rowId: number\n * @param isAdding: are we adding or removing a row?\n */\n protected syncOutOfViewportArray(rowId: number | string, isAdding: boolean) {\n const arrayRowIndex = this.arrayFindIndex(this._rowIdsOutOfViewport, rowId);\n\n if (isAdding && arrayRowIndex < 0) {\n this._rowIdsOutOfViewport.push(rowId);\n } else if (!isAdding && arrayRowIndex >= 0) {\n this._rowIdsOutOfViewport.splice(arrayRowIndex, 1);\n }\n return this._rowIdsOutOfViewport;\n }\n\n // Toggle between showing or hiding a row\n protected toggleRowSelection(rowNumber: number, dataContext: any) {\n if (!this.checkExpandableOverride(rowNumber, dataContext, this._grid)) {\n return;\n }\n\n this._dataView.beginUpdate();\n this.handleAccordionShowHide(dataContext);\n this._dataView.endUpdate();\n }\n\n /** Collapse all of the open detail rows */\n collapseAll() {\n this._dataView.beginUpdate();\n for (let i = this._expandedRows.length - 1; i >= 0; i--) {\n this.collapseDetailView(this._expandedRows[i], true);\n }\n this._dataView.endUpdate();\n }\n\n /** Collapse a detail row so that it is not longer open */\n collapseDetailView(item: any, isMultipleCollapsing = false) {\n if (!isMultipleCollapsing) {\n this._dataView.beginUpdate();\n }\n // Save the details on the collapse assuming onetime loading\n if (this._options.loadOnce) {\n this.saveDetailView(item);\n }\n\n item[`${this._keyPrefix}collapsed`] = true;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.deleteItem(item[this._dataViewIdProperty] + '.' + idx);\n }\n item[`${this._keyPrefix}sizePadding`] = 0;\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n // Remove the item from the expandedRows\n this._expandedRows = this._expandedRows.filter((r) => {\n return r[this._dataViewIdProperty] !== item[this._dataViewIdProperty];\n });\n\n if (!isMultipleCollapsing) {\n this._dataView.endUpdate();\n }\n }\n\n /** Expand a detail row by providing the dataview item that is to be expanded */\n expandDetailView(item: any) {\n if (this._options?.singleRowExpand) {\n this.collapseAll();\n }\n\n item[`${this._keyPrefix}collapsed`] = false;\n this._expandedRows.push(item);\n\n // In the case something went wrong loading it the first time such a scroll of screen before loaded\n if (!item[`${this._keyPrefix}detailContent`]) {\n item[`${this._keyPrefix}detailViewLoaded`] = false;\n }\n // display pre-loading template\n if (!item[`${this._keyPrefix}detailViewLoaded`] || this._options.loadOnce !== true) {\n item[`${this._keyPrefix}detailContent`] = this._options?.preTemplate?.(item);\n } else {\n this.onAsyncResponse.notify({\n item,\n itemDetail: item,\n detailView: item[`${this._keyPrefix}detailContent`]\n }, undefined, this);\n this.applyTemplateNewLineHeight(item);\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n return;\n }\n\n this.applyTemplateNewLineHeight(item);\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n // async server call\n this._options.process(item);\n }\n\n /** Saves the current state of the detail view */\n saveDetailView(item: any) {\n const view = document.querySelector(`.${this._gridUid} .innerDetailView_${item[this._dataViewIdProperty]}`);\n if (view) {\n const html = view.innerHTML;\n if (html !== undefined) {\n item[`${this._keyPrefix}detailContent`] = html;\n }\n }\n }\n\n /**\n * subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished\n * the response has to be as \"args.item\" (or \"args.itemDetail\") with it's data back\n */\n protected subscribeToOnAsyncResponse() {\n this.onAsyncResponse.subscribe((e, args) => {\n if (!args || (!args.item && !args.itemDetail)) {\n throw 'Slick.RowDetailView plugin requires the onAsyncResponse() to supply \"args.item\" property.';\n }\n\n // we accept item/itemDetail, just get the one which has data\n const itemDetail = args.item || args.itemDetail;\n\n // If we just want to load in a view directly we can use detailView property to do so\n if (args.detailView) {\n itemDetail[`${this._keyPrefix}detailContent`] = args.detailView;\n } else {\n itemDetail[`${this._keyPrefix}detailContent`] = this._options?.postTemplate?.(itemDetail);\n }\n\n itemDetail[`${this._keyPrefix}detailViewLoaded`] = true;\n this._dataView.updateItem(itemDetail[this._dataViewIdProperty], itemDetail);\n\n // trigger an event once the post template is finished loading\n this.onAsyncEndUpdate.notify({\n grid: this._grid,\n item: itemDetail,\n itemDetail\n }, e, this);\n });\n }\n\n /** When row is getting toggled, we will handle the action of collapsing/expanding */\n protected handleAccordionShowHide(item: any) {\n if (item) {\n if (!item[`${this._keyPrefix}collapsed`]) {\n this.collapseDetailView(item);\n } else {\n this.expandDetailView(item);\n }\n }\n }\n\n //////////////////////////////////////////////////////////////\n //////////////////////////////////////////////////////////////\n\n /** Get the Row Detail padding (which are the rows dedicated to the detail panel) */\n protected getPaddingItem(parent: any, offset: any) {\n const item: any = {};\n\n for (const prop in this._dataView) {\n item[prop] = null;\n }\n item[this._dataViewIdProperty] = parent[this._dataViewIdProperty] + '.' + offset;\n\n // additional hidden padding metadata fields\n item[`${this._keyPrefix}collapsed`] = true;\n item[`${this._keyPrefix}isPadding`] = true;\n item[`${this._keyPrefix}parent`] = parent;\n item[`${this._keyPrefix}offset`] = offset;\n\n return item;\n };\n\n /** Create the detail ctr node. this belongs to the dev & can be custom-styled as per */\n protected applyTemplateNewLineHeight(item: any) {\n // the height is calculated by the template row count (how many line of items does the template view have)\n const rowCount = this._options.panelRows;\n\n // calculate padding requirements based on detail-content..\n // ie. worst-case: create an invisible dom node now & find it's height.\n const lineHeight = 13; // we know cuz we wrote the custom css init ;)\n item[`${this._keyPrefix}sizePadding`] = Math.ceil(((rowCount * 2) * lineHeight) / this._gridOptions.rowHeight!);\n item[`${this._keyPrefix}height`] = (item[`${this._keyPrefix}sizePadding`] * this._gridOptions.rowHeight!);\n const idxParent = this._dataView.getIdxById(item[this._dataViewIdProperty]) ?? 0;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));\n }\n }\n\n /** Get the Column Definition of the first column dedicated to toggling the Row Detail View */\n getColumnDefinition() {\n return {\n id: this._options.columnId,\n name: '',\n toolTip: this._options.toolTip,\n field: 'sel',\n width: this._options.width,\n resizable: false,\n sortable: false,\n alwaysRenderColumn: this._options.alwaysRenderColumn,\n cssClass: this._options.cssClass,\n formatter: this.detailSelectionFormatter.bind(this)\n };\n }\n\n /** Return the currently expanded rows */\n getExpandedRows() {\n return this._expandedRows;\n }\n\n /** The cell Formatter that shows the icon that will be used to toggle the Row Detail */\n protected detailSelectionFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultObject | string {\n if (!this.checkExpandableOverride(row, dataContext, grid)) {\n return '';\n } else {\n if (dataContext[`${this._keyPrefix}collapsed`] === undefined) {\n dataContext[`${this._keyPrefix}collapsed`] = true;\n dataContext[`${this._keyPrefix}sizePadding`] = 0; //the required number of pading rows\n dataContext[`${this._keyPrefix}height`] = 0; //the actual height in pixels of the detail field\n dataContext[`${this._keyPrefix}isPadding`] = false;\n dataContext[`${this._keyPrefix}parent`] = undefined;\n dataContext[`${this._keyPrefix}offset`] = 0;\n }\n\n if (dataContext[`${this._keyPrefix}isPadding`]) {\n // render nothing\n }\n else if (dataContext[`${this._keyPrefix}collapsed`]) {\n let collapsedClasses = this._options.cssClass + ' expand ';\n if (this._options.collapsedClass) {\n collapsedClasses += this._options.collapsedClass;\n }\n return '
';\n }\n else {\n const html: string[] = [];\n const rowHeight = this._gridOptions.rowHeight;\n let outterHeight = dataContext[`${this._keyPrefix}sizePadding`] * this._gridOptions.rowHeight!;\n\n if (this._options.maxRows !== undefined && dataContext[`${this._keyPrefix}sizePadding`] > this._options.maxRows) {\n outterHeight = this._options.maxRows * rowHeight!;\n dataContext[`${this._keyPrefix}sizePadding`] = this._options.maxRows;\n }\n\n // V313HAX:\n // putting in an extra closing div after the closing toggle div and ommiting a\n // final closing div for the detail ctr div causes the slickgrid renderer to\n // insert our detail div as a new column ;) ~since it wraps whatever we provide\n // in a generic div column container. so our detail becomes a child directly of\n // the row not the cell. nice =) ~no need to apply a css change to the parent\n // slick-cell to escape the cell overflow clipping.\n\n // sneaky extra inserted here-----------------v\n let expandedClasses = this._options.cssClass + ' collapse ';\n if (this._options.expandedClass) {\n expandedClasses += this._options.expandedClass;\n }\n html.push('
');\n\n html.push(`
`); //shift detail below 1st row\n html.push(`
`); //sub ctr for custom styling\n html.push(`
${dataContext[`${this._keyPrefix}detailContent`]}
`);\n // omit a final closing detail container
that would come next\n\n return html.join('');\n }\n }\n return '';\n }\n\n /** Resize the Row Detail View */\n resizeDetailView(item: any) {\n if (!item) {\n return;\n }\n\n // Grad each of the DOM elements\n const mainContainer = document.querySelector(`.${this._gridUid} .detailViewContainer_${item[this._dataViewIdProperty]}`);\n const cellItem = document.querySelector(`.${this._gridUid} .cellDetailView_${item[this._dataViewIdProperty]}`);\n const inner = document.querySelector(`.${this._gridUid} .innerDetailView_${item[this._dataViewIdProperty]}`);\n\n if (!mainContainer || !cellItem || !inner) {\n return;\n }\n\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.deleteItem(`${item[this._dataViewIdProperty]}.${idx}`);\n }\n\n const rowHeight = this._gridOptions.rowHeight; // height of a row\n const lineHeight = 13; // we know cuz we wrote the custom css innit ;)\n\n // remove the height so we can calculate the height\n mainContainer.style.minHeight = '';\n\n // Get the scroll height for the main container so we know the actual size of the view\n const itemHeight = mainContainer.scrollHeight;\n\n // Now work out how many rows\n const rowCount = Math.ceil(itemHeight / rowHeight!);\n\n item[`${this._keyPrefix}sizePadding`] = Math.ceil(((rowCount * 2) * lineHeight) / rowHeight!);\n item[`${this._keyPrefix}height`] = itemHeight;\n\n let outterHeight = (item[`${this._keyPrefix}sizePadding`] * rowHeight!);\n if (this._options.maxRows !== undefined && item[`${this._keyPrefix}sizePadding`] > this._options.maxRows) {\n outterHeight = this._options.maxRows * rowHeight!;\n item[`${this._keyPrefix}sizePadding`] = this._options.maxRows;\n }\n\n // If the padding is now more than the original minRowBuff we need to increase it\n if (this._grid.getOptions().minRowBuffer! < item[`${this._keyPrefix}sizePadding`]) {\n // Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3\n this._grid.getOptions().minRowBuffer = item[`${this._keyPrefix}sizePadding`] + 3;\n }\n\n mainContainer.setAttribute('style', 'min-height: ' + item[`${this._keyPrefix}height`] + 'px');\n if (cellItem) {\n cellItem.setAttribute('style', 'height: ' + outterHeight + 'px; top:' + rowHeight + 'px');\n }\n\n const idxParent = this._dataView.getIdxById(item[this._dataViewIdProperty]) ?? 0;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));\n }\n\n // Lastly save the updated state\n this.saveDetailView(item);\n }\n\n /** Takes in the item we are filtering and if it is an expanded row returns it's parents row to filter on */\n getFilterItem(item: any) {\n if (item[`${this._keyPrefix}isPadding`] && item[`${this._keyPrefix}parent`]) {\n item = item[`${this._keyPrefix}parent`];\n }\n return item;\n }\n\n protected checkExpandableOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._expandableOverride === 'function') {\n return this._expandableOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row an expandable row.\n * In order word, user can choose which rows to be an available row detail (or not) by providing his own logic.\n * @param overrideFn: override function callback\n */\n expandableOverride(overrideFn: UsabilityOverrideFn) {\n this._expandableOverride = overrideFn;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n RowDetailView: SlickRowDetailView\n }\n }\n });\n}\n\n"], + "mappings": "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", "names": ["_a", "_b"] } diff --git a/dist/browser/plugins/slick.rowmovemanager.js b/dist/browser/plugins/slick.rowmovemanager.js index eb7adc9f0..b72933c42 100644 --- a/dist/browser/plugins/slick.rowmovemanager.js +++ b/dist/browser/plugins/slick.rowmovemanager.js @@ -113,7 +113,10 @@ }; } moveIconFormatter(row, _cell, _val, _column, dataContext, grid) { - return this.checkUsabilityOverride(row, dataContext, grid) ? { addClasses: `cell-reorder dnd ${this._options.cssClass || ""}`, text: "" } : ""; + return this.checkUsabilityOverride(row, dataContext, grid) ? { + addClasses: `cell-reorder dnd ${this._options.containerCssClass || ""}`, + text: `
` + } : ""; } checkUsabilityOverride(row, dataContext, grid) { return typeof this._usabilityOverride == "function" ? this._usabilityOverride(row, dataContext, grid) : !0; diff --git a/dist/browser/plugins/slick.rowmovemanager.js.map b/dist/browser/plugins/slick.rowmovemanager.js.map index 46983bdef..e19d47973 100644 --- a/dist/browser/plugins/slick.rowmovemanager.js.map +++ b/dist/browser/plugins/slick.rowmovemanager.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.rowmovemanager.ts"], - "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, DragRowMove, FormatterResultObject, RowMoveManagerOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * Row Move Manager options:\n * cssClass: A CSS class to be added to the menu item container.\n * columnId: Column definition id (defaults to \"_move\")\n * cancelEditOnDrag: Do we want to cancel any Editing while dragging a row (defaults to false)\n * disableRowSelection: Do we want to disable the row selection? (defaults to false)\n * hideRowMoveShadow: Do we want to hide the row move shadow clone? (defaults to true)\n * rowMoveShadowMarginTop: When row move shadow is shown, optional margin-top (defaults to 0)\n * rowMoveShadowMarginLeft: When row move shadow is shown, optional margin-left (defaults to 0)\n * rowMoveShadowOpacity: When row move shadow is shown, what is its opacity? (defaults to 0.95)\n * rowMoveShadowScale: When row move shadow is shown, what is its size scale? (default to 0.75)\n * singleRowMove: Do we want a single row move? Setting this to false means that it's a multple row move (defaults to false)\n * width: Width of the column\n * usabilityOverride: Callback method that user can override the default behavior of the row being moveable or not\n *\n */\n\nexport class SlickRowMoveManager {\n // --\n // public API\n pluginName = 'RowMoveManager' as const;\n onBeforeMoveRows = new SlickEvent<{ grid: SlickGrid; rows: number[]; insertBefore: number; }>();\n onMoveRows = new SlickEvent<{ grid: SlickGrid; rows: number[]; insertBefore: number; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _canvas!: HTMLElement;\n protected _dragging = false;\n protected _eventHandler: SlickEventHandler_;\n protected _usabilityOverride?: UsabilityOverrideFn;\n protected _options: RowMoveManagerOption;\n protected _defaults: RowMoveManagerOption = {\n columnId: '_move',\n cssClass: undefined,\n cancelEditOnDrag: false,\n disableRowSelection: false,\n hideRowMoveShadow: true,\n rowMoveShadowMarginTop: 0,\n rowMoveShadowMarginLeft: 0,\n rowMoveShadowOpacity: 0.95,\n rowMoveShadowScale: 0.75,\n singleRowMove: false,\n width: 40,\n };\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n }\n\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._canvas = this._grid.getCanvasNode();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options?.usabilityOverride === 'function') {\n this.usabilityOverride(this._options.usabilityOverride);\n }\n\n this._eventHandler\n .subscribe(this._grid.onDragInit, this.handleDragInit.bind(this))\n .subscribe(this._grid.onDragStart, this.handleDragStart.bind(this))\n .subscribe(this._grid.onDrag, this.handleDrag.bind(this))\n .subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));\n }\n\n destroy() {\n this._eventHandler.unsubscribeAll();\n }\n\n setOptions(newOptions: Partial) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n\n protected handleDragInit(e: SlickEventData_) {\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n }\n\n protected handleDragStart(e: DOMEvent, dd: DragRowMove): boolean | void {\n const cell = this._grid.getCellFromEvent(e) || { cell: -1, row: -1 };\n const currentRow = cell?.row;\n const dataContext = this._grid.getDataItem(currentRow);\n\n if (!this.checkUsabilityOverride(currentRow, dataContext, this._grid)) {\n return;\n }\n\n if (this._options.cancelEditOnDrag && this._grid.getEditorLock().isActive()) {\n this._grid.getEditorLock().cancelCurrentEdit();\n }\n\n if (this._grid.getEditorLock().isActive() || !this.isHandlerColumn(cell.cell)) {\n return false;\n }\n\n this._dragging = true;\n e.stopImmediatePropagation();\n\n // optionally create a shadow element of the row so that we can see all the time which row exactly we're dragging\n if (!this._options.hideRowMoveShadow) {\n const slickRowElm = this._grid.getCellNode(cell.row, cell.cell)?.closest('.slick-row');\n if (slickRowElm) {\n dd.clonedSlickRow = slickRowElm.cloneNode(true) as HTMLDivElement;\n dd.clonedSlickRow.classList.add('slick-reorder-shadow-row');\n dd.clonedSlickRow.style.display = 'none';\n dd.clonedSlickRow.style.marginLeft = Number(this._options.rowMoveShadowMarginLeft || 0) + 'px';\n dd.clonedSlickRow.style.marginTop = Number(this._options.rowMoveShadowMarginTop || 0) + 'px';\n dd.clonedSlickRow.style.opacity = `${this._options.rowMoveShadowOpacity || 0.95}`;\n dd.clonedSlickRow.style.transform = `scale(${this._options.rowMoveShadowScale || 0.75})`;\n this._canvas.appendChild(dd.clonedSlickRow);\n }\n }\n\n let selectedRows = this._options.singleRowMove ? [cell.row] : this._grid.getSelectedRows();\n if (selectedRows.length === 0 || !selectedRows.some(selectedRow => selectedRow === cell.row)) {\n selectedRows = [cell.row];\n if (!this._options.disableRowSelection) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n const rowHeight = this._grid.getOptions().rowHeight;\n\n dd.selectedRows = selectedRows;\n\n dd.selectionProxy = document.createElement('div');\n dd.selectionProxy.className = 'slick-reorder-proxy';\n dd.selectionProxy.style.display = 'none';\n dd.selectionProxy.style.position = 'absolute';\n dd.selectionProxy.style.zIndex = '99999';\n dd.selectionProxy.style.width = `${this._canvas.clientWidth}px`;\n dd.selectionProxy.style.height = `${rowHeight! * selectedRows.length}px`;\n this._canvas.appendChild(dd.selectionProxy);\n\n dd.guide = document.createElement('div');\n dd.guide.className = 'slick-reorder-guide';\n dd.guide.style.position = 'absolute';\n dd.guide.style.zIndex = '99999';\n dd.guide.style.width = `${this._canvas.clientWidth}px`;\n dd.guide.style.top = `-1000px`;\n this._canvas.appendChild(dd.guide);\n\n dd.insertBefore = -1;\n }\n\n protected handleDrag(evt: SlickEventData_, dd: DragRowMove): boolean | void {\n if (!this._dragging) {\n return;\n }\n\n evt.stopImmediatePropagation();\n const e = evt.getNativeEvent();\n\n const targetEvent = (e as TouchEvent)?.touches?.[0] ?? e;\n const top = targetEvent.pageY - (Utils.offset(this._canvas)?.top ?? 0);\n dd.selectionProxy.style.top = `${top - 5}px`;\n dd.selectionProxy.style.display = 'block';\n\n // if the row move shadow is enabled, we'll also make it follow the mouse cursor\n if (dd.clonedSlickRow) {\n dd.clonedSlickRow.style.top = `${top - 6}px`;\n dd.clonedSlickRow.style.display = 'block';\n }\n\n const insertBefore = Math.max(0, Math.min(Math.round(top / this._grid.getOptions().rowHeight!), this._grid.getDataLength()));\n if (insertBefore !== dd.insertBefore) {\n const eventData = {\n grid: this._grid,\n rows: dd.selectedRows,\n insertBefore\n };\n\n if (this.onBeforeMoveRows.notify(eventData).getReturnValue() === false) {\n dd.canMove = false;\n } else {\n dd.canMove = true;\n }\n\n // if there's a UsabilityOverride defined, we also need to verify that the condition is valid\n if (this._usabilityOverride && dd.canMove) {\n const insertBeforeDataContext = this._grid.getDataItem(insertBefore);\n dd.canMove = this.checkUsabilityOverride(insertBefore, insertBeforeDataContext, this._grid);\n }\n\n // if the new target is possible we'll display the dark blue bar (representin the acceptability) at the target position\n // else it won't show up (it will be off the screen)\n if (!dd.canMove) {\n dd.guide.style.top = '-1000px';\n } else {\n dd.guide.style.top = `${insertBefore * (this._grid.getOptions().rowHeight || 0)}px`;\n }\n\n dd.insertBefore = insertBefore;\n }\n }\n\n protected handleDragEnd(e: SlickEventData_, dd: DragRowMove) {\n if (!this._dragging) {\n return;\n }\n this._dragging = false;\n e.stopImmediatePropagation();\n\n dd.guide?.remove();\n dd.selectionProxy?.remove();\n dd.clonedSlickRow?.remove();\n\n if (dd.canMove) {\n const eventData = {\n grid: this._grid,\n rows: dd.selectedRows,\n insertBefore: dd.insertBefore\n };\n // TODO: this._grid.remapCellCssClasses ?\n this.onMoveRows.notify(eventData);\n }\n }\n\n getColumnDefinition(): Column {\n const columnId = String(this._options?.columnId ?? this._defaults.columnId);\n\n return {\n id: columnId,\n name: '',\n field: 'move',\n behavior: 'selectAndMove',\n excludeFromColumnPicker: true,\n excludeFromGridMenu: true,\n excludeFromHeaderMenu: true,\n resizable: false,\n selectable: false,\n width: this._options.width || 40,\n formatter: this.moveIconFormatter.bind(this)\n };\n }\n\n protected moveIconFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultObject | string {\n if (!this.checkUsabilityOverride(row, dataContext, grid)) {\n return '';\n } else {\n return { addClasses: `cell-reorder dnd ${this._options.cssClass || ''}`, text: '' };\n }\n }\n\n protected checkUsabilityOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._usabilityOverride === 'function') {\n return this._usabilityOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row moveable.\n * In order word, user can choose which rows to be an available as moveable (or not) by providing his own logic show/hide icon and usability.\n * @param overrideFn: override function callback\n */\n usabilityOverride(overrideFn: UsabilityOverrideFn) {\n this._usabilityOverride = overrideFn;\n }\n\n isHandlerColumn(columnIndex: number | string) {\n return /move|selectAndMove/.test(this._grid.getColumns()[+columnIndex].behavior || '');\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n RowMoveManager: SlickRowMoveManager\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, DragRowMove, FormatterResultObject, RowMoveManagerOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * Row Move Manager options:\n * containerCssClass: A CSS class to be added to the cell container.\n * cssClass: A CSS class to be added to the div of the cell formatter.\n * columnId: Column definition id (defaults to \"_move\")\n * cancelEditOnDrag: Do we want to cancel any Editing while dragging a row (defaults to false)\n * disableRowSelection: Do we want to disable the row selection? (defaults to false)\n * hideRowMoveShadow: Do we want to hide the row move shadow clone? (defaults to true)\n * rowMoveShadowMarginTop: When row move shadow is shown, optional margin-top (defaults to 0)\n * rowMoveShadowMarginLeft: When row move shadow is shown, optional margin-left (defaults to 0)\n * rowMoveShadowOpacity: When row move shadow is shown, what is its opacity? (defaults to 0.95)\n * rowMoveShadowScale: When row move shadow is shown, what is its size scale? (default to 0.75)\n * singleRowMove: Do we want a single row move? Setting this to false means that it's a multple row move (defaults to false)\n * width: Width of the column\n * usabilityOverride: Callback method that user can override the default behavior of the row being moveable or not\n *\n */\n\nexport class SlickRowMoveManager {\n // --\n // public API\n pluginName = 'RowMoveManager' as const;\n onBeforeMoveRows = new SlickEvent<{ grid: SlickGrid; rows: number[]; insertBefore: number; }>();\n onMoveRows = new SlickEvent<{ grid: SlickGrid; rows: number[]; insertBefore: number; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _canvas!: HTMLElement;\n protected _dragging = false;\n protected _eventHandler: SlickEventHandler_;\n protected _usabilityOverride?: UsabilityOverrideFn;\n protected _options: RowMoveManagerOption;\n protected _defaults: RowMoveManagerOption = {\n columnId: '_move',\n cssClass: undefined,\n cancelEditOnDrag: false,\n disableRowSelection: false,\n hideRowMoveShadow: true,\n rowMoveShadowMarginTop: 0,\n rowMoveShadowMarginLeft: 0,\n rowMoveShadowOpacity: 0.95,\n rowMoveShadowScale: 0.75,\n singleRowMove: false,\n width: 40,\n };\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n }\n\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._canvas = this._grid.getCanvasNode();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options?.usabilityOverride === 'function') {\n this.usabilityOverride(this._options.usabilityOverride);\n }\n\n this._eventHandler\n .subscribe(this._grid.onDragInit, this.handleDragInit.bind(this))\n .subscribe(this._grid.onDragStart, this.handleDragStart.bind(this))\n .subscribe(this._grid.onDrag, this.handleDrag.bind(this))\n .subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));\n }\n\n destroy() {\n this._eventHandler.unsubscribeAll();\n }\n\n setOptions(newOptions: Partial) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n\n protected handleDragInit(e: SlickEventData_) {\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n }\n\n protected handleDragStart(e: DOMEvent, dd: DragRowMove): boolean | void {\n const cell = this._grid.getCellFromEvent(e) || { cell: -1, row: -1 };\n const currentRow = cell?.row;\n const dataContext = this._grid.getDataItem(currentRow);\n\n if (!this.checkUsabilityOverride(currentRow, dataContext, this._grid)) {\n return;\n }\n\n if (this._options.cancelEditOnDrag && this._grid.getEditorLock().isActive()) {\n this._grid.getEditorLock().cancelCurrentEdit();\n }\n\n if (this._grid.getEditorLock().isActive() || !this.isHandlerColumn(cell.cell)) {\n return false;\n }\n\n this._dragging = true;\n e.stopImmediatePropagation();\n\n // optionally create a shadow element of the row so that we can see all the time which row exactly we're dragging\n if (!this._options.hideRowMoveShadow) {\n const slickRowElm = this._grid.getCellNode(cell.row, cell.cell)?.closest('.slick-row');\n if (slickRowElm) {\n dd.clonedSlickRow = slickRowElm.cloneNode(true) as HTMLDivElement;\n dd.clonedSlickRow.classList.add('slick-reorder-shadow-row');\n dd.clonedSlickRow.style.display = 'none';\n dd.clonedSlickRow.style.marginLeft = Number(this._options.rowMoveShadowMarginLeft || 0) + 'px';\n dd.clonedSlickRow.style.marginTop = Number(this._options.rowMoveShadowMarginTop || 0) + 'px';\n dd.clonedSlickRow.style.opacity = `${this._options.rowMoveShadowOpacity || 0.95}`;\n dd.clonedSlickRow.style.transform = `scale(${this._options.rowMoveShadowScale || 0.75})`;\n this._canvas.appendChild(dd.clonedSlickRow);\n }\n }\n\n let selectedRows = this._options.singleRowMove ? [cell.row] : this._grid.getSelectedRows();\n if (selectedRows.length === 0 || !selectedRows.some(selectedRow => selectedRow === cell.row)) {\n selectedRows = [cell.row];\n if (!this._options.disableRowSelection) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n const rowHeight = this._grid.getOptions().rowHeight;\n\n dd.selectedRows = selectedRows;\n\n dd.selectionProxy = document.createElement('div');\n dd.selectionProxy.className = 'slick-reorder-proxy';\n dd.selectionProxy.style.display = 'none';\n dd.selectionProxy.style.position = 'absolute';\n dd.selectionProxy.style.zIndex = '99999';\n dd.selectionProxy.style.width = `${this._canvas.clientWidth}px`;\n dd.selectionProxy.style.height = `${rowHeight! * selectedRows.length}px`;\n this._canvas.appendChild(dd.selectionProxy);\n\n dd.guide = document.createElement('div');\n dd.guide.className = 'slick-reorder-guide';\n dd.guide.style.position = 'absolute';\n dd.guide.style.zIndex = '99999';\n dd.guide.style.width = `${this._canvas.clientWidth}px`;\n dd.guide.style.top = `-1000px`;\n this._canvas.appendChild(dd.guide);\n\n dd.insertBefore = -1;\n }\n\n protected handleDrag(evt: SlickEventData_, dd: DragRowMove): boolean | void {\n if (!this._dragging) {\n return;\n }\n\n evt.stopImmediatePropagation();\n const e = evt.getNativeEvent();\n\n const targetEvent = (e as TouchEvent)?.touches?.[0] ?? e;\n const top = targetEvent.pageY - (Utils.offset(this._canvas)?.top ?? 0);\n dd.selectionProxy.style.top = `${top - 5}px`;\n dd.selectionProxy.style.display = 'block';\n\n // if the row move shadow is enabled, we'll also make it follow the mouse cursor\n if (dd.clonedSlickRow) {\n dd.clonedSlickRow.style.top = `${top - 6}px`;\n dd.clonedSlickRow.style.display = 'block';\n }\n\n const insertBefore = Math.max(0, Math.min(Math.round(top / this._grid.getOptions().rowHeight!), this._grid.getDataLength()));\n if (insertBefore !== dd.insertBefore) {\n const eventData = {\n grid: this._grid,\n rows: dd.selectedRows,\n insertBefore\n };\n\n if (this.onBeforeMoveRows.notify(eventData).getReturnValue() === false) {\n dd.canMove = false;\n } else {\n dd.canMove = true;\n }\n\n // if there's a UsabilityOverride defined, we also need to verify that the condition is valid\n if (this._usabilityOverride && dd.canMove) {\n const insertBeforeDataContext = this._grid.getDataItem(insertBefore);\n dd.canMove = this.checkUsabilityOverride(insertBefore, insertBeforeDataContext, this._grid);\n }\n\n // if the new target is possible we'll display the dark blue bar (representin the acceptability) at the target position\n // else it won't show up (it will be off the screen)\n if (!dd.canMove) {\n dd.guide.style.top = '-1000px';\n } else {\n dd.guide.style.top = `${insertBefore * (this._grid.getOptions().rowHeight || 0)}px`;\n }\n\n dd.insertBefore = insertBefore;\n }\n }\n\n protected handleDragEnd(e: SlickEventData_, dd: DragRowMove) {\n if (!this._dragging) {\n return;\n }\n this._dragging = false;\n e.stopImmediatePropagation();\n\n dd.guide?.remove();\n dd.selectionProxy?.remove();\n dd.clonedSlickRow?.remove();\n\n if (dd.canMove) {\n const eventData = {\n grid: this._grid,\n rows: dd.selectedRows,\n insertBefore: dd.insertBefore\n };\n // TODO: this._grid.remapCellCssClasses ?\n this.onMoveRows.notify(eventData);\n }\n }\n\n getColumnDefinition(): Column {\n const columnId = String(this._options?.columnId ?? this._defaults.columnId);\n\n return {\n id: columnId,\n name: '',\n field: 'move',\n behavior: 'selectAndMove',\n excludeFromColumnPicker: true,\n excludeFromGridMenu: true,\n excludeFromHeaderMenu: true,\n resizable: false,\n selectable: false,\n width: this._options.width || 40,\n formatter: this.moveIconFormatter.bind(this)\n };\n }\n\n protected moveIconFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultObject | string {\n if (!this.checkUsabilityOverride(row, dataContext, grid)) {\n return '';\n } else {\n return {\n addClasses: `cell-reorder dnd ${this._options.containerCssClass || ''}`,\n text: `
`\n };\n }\n }\n\n protected checkUsabilityOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._usabilityOverride === 'function') {\n return this._usabilityOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row moveable.\n * In order word, user can choose which rows to be an available as moveable (or not) by providing his own logic show/hide icon and usability.\n * @param overrideFn: override function callback\n */\n usabilityOverride(overrideFn: UsabilityOverrideFn) {\n this._usabilityOverride = overrideFn;\n }\n\n isHandlerColumn(columnIndex: number | string) {\n return /move|selectAndMove/.test(this._grid.getColumns()[+columnIndex].behavior || '');\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n RowMoveManager: SlickRowMoveManager\n }\n });\n}\n\n"], + "mappings": ";;;;;;;AAKA,MAAM,aAAyB,MAAM,OAC/B,oBAAgC,MAAM,cACtC,QAAoB,MAAM,OAoBnB,sBAAN,MAA0B;AAAA,IA6B/B,YAAY,SAAwC;AA1BpD;AAAA;AAAA,wCAAa;AACb,8CAAmB,IAAI,WAAuE;AAC9F,wCAAa,IAAI,WAAuE;AAIxF;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU,aAAY;AACtB,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU,aAAkC;AAAA,QAC1C,UAAU;AAAA,QACV,UAAU;AAAA,QACV,kBAAkB;AAAA,QAClB,qBAAqB;AAAA,QACrB,mBAAmB;AAAA,QACnB,wBAAwB;AAAA,QACxB,yBAAyB;AAAA,QACzB,sBAAsB;AAAA,QACtB,oBAAoB;AAAA,QACpB,eAAe;AAAA,QACf,OAAO;AAAA,MACT;AAGE,WAAK,WAAW,MAAM,OAAO,IAAM,CAAC,GAAG,KAAK,WAAW,OAAO,GAC9D,KAAK,gBAAgB,IAAI,kBAAkB;AAAA,IAC7C;AAAA,IAGA,KAAK,MAAiB;AA9DxB;AA+DI,WAAK,QAAQ,MACb,KAAK,UAAU,KAAK,MAAM,cAAc,GAGpC,SAAO,UAAK,aAAL,mBAAe,sBAAsB,cAC9C,KAAK,kBAAkB,KAAK,SAAS,iBAAiB,GAGxD,KAAK,cACF,UAAU,KAAK,MAAM,YAAY,KAAK,eAAe,KAAK,IAAI,CAAC,EAC/D,UAAU,KAAK,MAAM,aAAa,KAAK,gBAAgB,KAAK,IAAI,CAAC,EACjE,UAAU,KAAK,MAAM,QAAQ,KAAK,WAAW,KAAK,IAAI,CAAC,EACvD,UAAU,KAAK,MAAM,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,IAClE;AAAA,IAEA,UAAU;AACR,WAAK,cAAc,eAAe;AAAA,IACpC;AAAA,IAEA,WAAW,YAA2C;AACpD,WAAK,WAAW,MAAM,OAAO,CAAC,GAAG,KAAK,UAAU,UAAU;AAAA,IAC5D;AAAA,IAEU,eAAe,GAAoB;AAE3C,QAAE,yBAAyB;AAAA,IAC7B;AAAA,IAEU,gBAAgB,GAA6B,IAAiC;AA3F1F;AA4FI,UAAM,OAAO,KAAK,MAAM,iBAAiB,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,GAAG,GAC7D,aAAa,6BAAM,KACnB,cAAc,KAAK,MAAM,YAAY,UAAU;AAErD,UAAI,CAAC,KAAK,uBAAuB,YAAY,aAAa,KAAK,KAAK;AAClE;AAOF,UAJI,KAAK,SAAS,oBAAoB,KAAK,MAAM,cAAc,EAAE,SAAS,KACxE,KAAK,MAAM,cAAc,EAAE,kBAAkB,GAG3C,KAAK,MAAM,cAAc,EAAE,SAAS,KAAK,CAAC,KAAK,gBAAgB,KAAK,IAAI;AAC1E,eAAO;AAOT,UAJA,KAAK,YAAY,IACjB,EAAE,yBAAyB,GAGvB,CAAC,KAAK,SAAS,mBAAmB;AACpC,YAAM,eAAc,UAAK,MAAM,YAAY,KAAK,KAAK,KAAK,IAAI,MAA1C,mBAA6C,QAAwB;AACzF,QAAI,gBACF,GAAG,iBAAiB,YAAY,UAAU,EAAI,GAC9C,GAAG,eAAe,UAAU,IAAI,0BAA0B,GAC1D,GAAG,eAAe,MAAM,UAAU,QAClC,GAAG,eAAe,MAAM,aAAa,OAAO,KAAK,SAAS,2BAA2B,CAAC,IAAI,MAC1F,GAAG,eAAe,MAAM,YAAY,OAAO,KAAK,SAAS,0BAA0B,CAAC,IAAI,MACxF,GAAG,eAAe,MAAM,UAAU,GAAG,KAAK,SAAS,wBAAwB,IAAI,IAC/E,GAAG,eAAe,MAAM,YAAY,SAAS,KAAK,SAAS,sBAAsB,IAAI,KACrF,KAAK,QAAQ,YAAY,GAAG,cAAc;AAAA,MAE9C;AAEA,UAAI,eAAe,KAAK,SAAS,gBAAgB,CAAC,KAAK,GAAG,IAAI,KAAK,MAAM,gBAAgB;AACzF,OAAI,aAAa,WAAW,KAAK,CAAC,aAAa,KAAK,iBAAe,gBAAgB,KAAK,GAAG,OACzF,eAAe,CAAC,KAAK,GAAG,GACnB,KAAK,SAAS,uBACjB,KAAK,MAAM,gBAAgB,YAAY;AAI3C,UAAM,YAAY,KAAK,MAAM,WAAW,EAAE;AAE1C,SAAG,eAAe,cAElB,GAAG,iBAAiB,SAAS,cAAc,KAAK,GAChD,GAAG,eAAe,YAAY,uBAC9B,GAAG,eAAe,MAAM,UAAU,QAClC,GAAG,eAAe,MAAM,WAAW,YACnC,GAAG,eAAe,MAAM,SAAS,SACjC,GAAG,eAAe,MAAM,QAAQ,GAAG,KAAK,QAAQ,WAAW,MAC3D,GAAG,eAAe,MAAM,SAAS,GAAG,YAAa,aAAa,MAAM,MACpE,KAAK,QAAQ,YAAY,GAAG,cAAc,GAE1C,GAAG,QAAQ,SAAS,cAAc,KAAK,GACvC,GAAG,MAAM,YAAY,uBACrB,GAAG,MAAM,MAAM,WAAW,YAC1B,GAAG,MAAM,MAAM,SAAS,SACxB,GAAG,MAAM,MAAM,QAAQ,GAAG,KAAK,QAAQ,WAAW,MAClD,GAAG,MAAM,MAAM,MAAM,WACrB,KAAK,QAAQ,YAAY,GAAG,KAAK,GAEjC,GAAG,eAAe;AAAA,IACpB;AAAA,IAEU,WAAW,KAAsB,IAAiC;AA9J9E;AA+JI,UAAI,CAAC,KAAK;AACR;AAGF,UAAI,yBAAyB;AAC7B,UAAM,IAAI,IAAI,eAAwC,GAGhD,QADe,kCAAkB,YAAlB,mBAA4B,OAA5B,YAAkC,GAC/B,UAAS,iBAAM,OAAO,KAAK,OAAO,MAAzB,mBAA4B,QAA5B,YAAmC;AACpE,SAAG,eAAe,MAAM,MAAM,GAAG,MAAM,CAAC,MACxC,GAAG,eAAe,MAAM,UAAU,SAG9B,GAAG,mBACL,GAAG,eAAe,MAAM,MAAM,GAAG,MAAM,CAAC,MACxC,GAAG,eAAe,MAAM,UAAU;AAGpC,UAAM,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAM,MAAM,KAAK,MAAM,WAAW,EAAE,SAAU,GAAG,KAAK,MAAM,cAAc,CAAC,CAAC;AAC3H,UAAI,iBAAiB,GAAG,cAAc;AACpC,YAAM,YAAY;AAAA,UAChB,MAAM,KAAK;AAAA,UACX,MAAM,GAAG;AAAA,UACT;AAAA,QACF;AASA,YAPI,KAAK,iBAAiB,OAAO,SAAS,EAAE,eAAe,MAAM,KAC/D,GAAG,UAAU,KAEb,GAAG,UAAU,IAIX,KAAK,sBAAsB,GAAG,SAAS;AACzC,cAAM,0BAA0B,KAAK,MAAM,YAAY,YAAY;AACnE,aAAG,UAAU,KAAK,uBAAuB,cAAc,yBAAyB,KAAK,KAAK;AAAA,QAC5F;AAIA,QAAK,GAAG,UAGN,GAAG,MAAM,MAAM,MAAM,GAAG,gBAAgB,KAAK,MAAM,WAAW,EAAE,aAAa,EAAE,OAF/E,GAAG,MAAM,MAAM,MAAM,WAKvB,GAAG,eAAe;AAAA,MACpB;AAAA,IACF;AAAA,IAEU,cAAc,GAAoB,IAAiB;AAjN/D;AAkNI,UAAK,KAAK,cAGV,KAAK,YAAY,IACjB,EAAE,yBAAyB,IAE3B,QAAG,UAAH,WAAU,WACV,QAAG,mBAAH,WAAmB,WACnB,QAAG,mBAAH,WAAmB,UAEf,GAAG,UAAS;AACd,YAAM,YAAY;AAAA,UAChB,MAAM,KAAK;AAAA,UACX,MAAM,GAAG;AAAA,UACT,cAAc,GAAG;AAAA,QACnB;AAEA,aAAK,WAAW,OAAO,SAAS;AAAA,MAClC;AAAA,IACF;AAAA,IAEA,sBAA8B;AAvOhC;AA0OI,aAAO;AAAA,QACL,IAHe,QAAO,gBAAK,aAAL,mBAAe,aAAf,YAA2B,KAAK,UAAU,QAAQ;AAAA,QAIxE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,yBAAyB;AAAA,QACzB,qBAAqB;AAAA,QACrB,uBAAuB;AAAA,QACvB,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,OAAO,KAAK,SAAS,SAAS;AAAA,QAC9B,WAAW,KAAK,kBAAkB,KAAK,IAAI;AAAA,MAC7C;AAAA,IACF;AAAA,IAEU,kBAAkB,KAAa,OAAe,MAAW,SAAiB,aAAkB,MAAiD;AACrJ,aAAK,KAAK,uBAAuB,KAAK,aAAa,IAAI,IAG9C;AAAA,QACL,YAAY,oBAAoB,KAAK,SAAS,qBAAqB,EAAE;AAAA,QACrE,MAAM,eAAe,KAAK,SAAS,QAAQ;AAAA,MAC7C,IALO;AAAA,IAOX;AAAA,IAEU,uBAAuB,KAAa,aAAkB,MAAiB;AAC/E,aAAI,OAAO,KAAK,sBAAuB,aAC9B,KAAK,mBAAmB,KAAK,aAAa,IAAI,IAEhD;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,kBAAkB,YAAiC;AACjD,WAAK,qBAAqB;AAAA,IAC5B;AAAA,IAEA,gBAAgB,aAA8B;AAC5C,aAAO,qBAAqB,KAAK,KAAK,MAAM,WAAW,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE;AAAA,IACvF;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,gBAAgB;AAAA,IAClB;AAAA,EACF,CAAC;", "names": [] } diff --git a/dist/browser/plugins/slick.rowselectionmodel.js b/dist/browser/plugins/slick.rowselectionmodel.js index 12050bc9e..65ee663d7 100644 --- a/dist/browser/plugins/slick.rowselectionmodel.js +++ b/dist/browser/plugins/slick.rowselectionmodel.js @@ -91,17 +91,17 @@ this.setSelectedRows(this.getSelectedRows()); } handleActiveCellChange(_e, args) { - this._options.selectActiveRow && args.row != null && this.setSelectedRanges([new SlickRange(args.row, 0, args.row, this._grid.getColumns().length - 1)]); + this._options.selectActiveRow && Utils.isDefined(args.row) && this.setSelectedRanges([new SlickRange(args.row, 0, args.row, this._grid.getColumns().length - 1)]); } handleKeyDown(e) { let activeRow = this._grid.getActiveCell(); - if (this._grid.getOptions().multiSelect && activeRow && e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey && (e.which == keyCode.UP || e.which == keyCode.DOWN)) { + if (this._grid.getOptions().multiSelect && activeRow && e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey && (e.which === keyCode.UP || e.which === keyCode.DOWN)) { let selectedRows = this.getSelectedRows(); selectedRows.sort(function(x, y) { return x - y; }), selectedRows.length || (selectedRows = [activeRow.row]); let top = selectedRows[0], bottom = selectedRows[selectedRows.length - 1], active; - if (e.which == keyCode.DOWN ? active = activeRow.row < bottom || top == bottom ? ++bottom : ++top : active = activeRow.row < bottom ? --bottom : --top, active >= 0 && active < this._grid.getDataLength()) { + if (e.which === keyCode.DOWN ? active = activeRow.row < bottom || top === bottom ? ++bottom : ++top : active = activeRow.row < bottom ? --bottom : --top, active >= 0 && active < this._grid.getDataLength()) { this._grid.scrollRowIntoView(active); let tempRanges = this.rowsToRanges(this.getRowsRange(top, bottom)); this.setSelectedRanges(tempRanges); diff --git a/dist/browser/plugins/slick.rowselectionmodel.js.map b/dist/browser/plugins/slick.rowselectionmodel.js.map index 391937c3f..ff830c046 100644 --- a/dist/browser/plugins/slick.rowselectionmodel.js.map +++ b/dist/browser/plugins/slick.rowselectionmodel.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.rowselectionmodel.ts"], - "sourcesContent": ["import { keyCode as keyCode_, SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickEventHandler as SlickEventHandler_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\nimport { Draggable as Draggable_ } from '../slick.interactions';\nimport { SlickCellRangeDecorator as SlickCellRangeDecorator_ } from './slick.cellrangedecorator';\nimport { SlickCellRangeSelector as SlickCellRangeSelector_ } from './slick.cellrangeselector';\nimport type { SlickCrossGridRowMoveManager as SlickCrossGridRowMoveManager_ } from './slick.crossgridrowmovemanager';\nimport type { SlickRowMoveManager as SlickRowMoveManager_ } from './slick.rowmovemanager';\nimport type { CellRange, OnActiveCellChangedEventArgs, RowSelectionModelOption } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Draggable = IIFE_ONLY ? Slick.Draggable : Draggable_;\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\nconst SlickCellRangeDecorator = IIFE_ONLY ? Slick.CellRangeDecorator : SlickCellRangeDecorator_;\nconst SlickCellRangeSelector = IIFE_ONLY ? Slick.CellRangeSelector : SlickCellRangeSelector_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport class SlickRowSelectionModel {\n // --\n // public API\n pluginName = 'RowSelectionModel' as const;\n onSelectedRangesChanged = new SlickEvent();\n // _handler, _inHandler, _isRowMoveManagerHandler, _options, wrapHandler\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _ranges: CellRange[] = [];\n protected _eventHandler = new SlickEventHandler();\n protected _inHandler = false;\n protected _selector?: SlickCellRangeSelector_;\n protected _isRowMoveManagerHandler: any;\n protected _options: RowSelectionModelOption;\n protected _defaults: RowSelectionModelOption = {\n selectActiveRow: true,\n dragToSelect: false,\n autoScrollWhenDrag: true,\n cellRangeSelector: undefined\n };\n\n constructor(options?: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n init(grid: SlickGrid) {\n if (Draggable === undefined) {\n throw new Error('Slick.Draggable is undefined, make sure to import \"slick.interactions.js\"');\n }\n\n this._selector = this._options.cellRangeSelector;\n this._grid = grid;\n\n if (!this._selector && this._options.dragToSelect) {\n if (!SlickCellRangeDecorator) {\n throw new Error('Slick.CellRangeDecorator is required when option dragToSelect set to true');\n }\n this._selector = new SlickCellRangeSelector({\n selectionCss: { border: 'none' } as CSSStyleDeclaration,\n autoScroll: this._options.autoScrollWhenDrag\n });\n }\n\n this._eventHandler.subscribe(this._grid.onActiveCellChanged, this.wrapHandler(this.handleActiveCellChange).bind(this));\n this._eventHandler.subscribe(this._grid.onKeyDown, this.wrapHandler(this.handleKeyDown).bind(this));\n this._eventHandler.subscribe(this._grid.onClick, this.wrapHandler(this.handleClick).bind(this));\n if (this._selector) {\n grid.registerPlugin(this._selector);\n this._selector.onCellRangeSelecting.subscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onCellRangeSelected.subscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onBeforeCellRangeSelected.subscribe(this.handleBeforeCellRangeSelected.bind(this));\n }\n }\n\n destroy() {\n this._eventHandler.unsubscribeAll();\n if (this._selector) {\n this._selector.onCellRangeSelecting.unsubscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onCellRangeSelected.unsubscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onBeforeCellRangeSelected.unsubscribe(this.handleBeforeCellRangeSelected.bind(this));\n this._grid.unregisterPlugin(this._selector);\n if (this._selector.destroy) {\n this._selector.destroy();\n }\n }\n }\n\n protected wrapHandler(handler: (...args: any) => void) {\n return (...args: any) => {\n if (!this._inHandler) {\n this._inHandler = true;\n handler.apply(this, args);\n this._inHandler = false;\n }\n };\n }\n\n protected rangesToRows(ranges: CellRange[]): number[] {\n const rows: number[] = [];\n for (let i = 0; i < ranges.length; i++) {\n for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n rows.push(j);\n }\n }\n return rows;\n }\n\n protected rowsToRanges(rows: number[]) {\n const ranges: SlickRange_[] = [];\n const lastCell = this._grid.getColumns().length - 1;\n for (let i = 0; i < rows.length; i++) {\n ranges.push(new SlickRange(rows[i], 0, rows[i], lastCell));\n }\n return ranges;\n }\n\n protected getRowsRange(from: number, to: number) {\n let i;\n const rows: number[] = [];\n for (i = from; i <= to; i++) {\n rows.push(i);\n }\n for (i = to; i < from; i++) {\n rows.push(i);\n }\n return rows;\n }\n\n getSelectedRows() {\n return this.rangesToRows(this._ranges);\n }\n\n setSelectedRows(rows: number[]) {\n this.setSelectedRanges(this.rowsToRanges(rows), 'SlickRowSelectionModel.setSelectedRows');\n }\n\n setSelectedRanges(ranges: CellRange[], caller = 'SlickRowSelectionModel.setSelectedRanges') {\n // simple check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n if ((!this._ranges || this._ranges.length === 0) && (!ranges || ranges.length === 0)) {\n return;\n }\n this._ranges = ranges;\n\n // provide extra \"caller\" argument through SlickEventData to avoid breaking pubsub event that only accepts an array of selected range\n const eventData = new SlickEventData(null, this._ranges);\n Object.defineProperty(eventData, 'detail', { writable: true, configurable: true, value: { caller: caller || \"SlickRowSelectionModel.setSelectedRanges\" } });\n this.onSelectedRangesChanged.notify(this._ranges, eventData);\n }\n\n getSelectedRanges() {\n return this._ranges;\n }\n\n refreshSelections() {\n this.setSelectedRows(this.getSelectedRows());\n }\n\n protected handleActiveCellChange(_e: SlickEventData_, args: OnActiveCellChangedEventArgs) {\n if (this._options.selectActiveRow && args.row != null) {\n this.setSelectedRanges([new SlickRange(args.row, 0, args.row, this._grid.getColumns().length - 1)]);\n }\n }\n\n protected handleKeyDown(e: KeyboardEvent) {\n const activeRow = this._grid.getActiveCell();\n if (this._grid.getOptions().multiSelect && activeRow\n && e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey\n && (e.which == keyCode.UP || e.which == keyCode.DOWN)) {\n let selectedRows = this.getSelectedRows();\n selectedRows.sort(function (x, y) {\n return x - y;\n });\n\n if (!selectedRows.length) {\n selectedRows = [activeRow.row];\n }\n\n let top = selectedRows[0];\n let bottom = selectedRows[selectedRows.length - 1];\n let active: number;\n\n if (e.which == keyCode.DOWN) {\n active = activeRow.row < bottom || top == bottom ? ++bottom : ++top;\n } else {\n active = activeRow.row < bottom ? --bottom : --top;\n }\n\n if (active >= 0 && active < this._grid.getDataLength()) {\n this._grid.scrollRowIntoView(active);\n const tempRanges = this.rowsToRanges(this.getRowsRange(top, bottom));\n this.setSelectedRanges(tempRanges);\n }\n\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n protected handleClick(e: MouseEvent): boolean | void {\n const cell = this._grid.getCellFromEvent(e);\n if (!cell || !this._grid.canCellBeActive(cell.row, cell.cell)) {\n return false;\n }\n\n if (!this._grid.getOptions().multiSelect || (\n !e.ctrlKey && !e.shiftKey && !e.metaKey)) {\n return false;\n }\n\n let selection = this.rangesToRows(this._ranges);\n const idx = selection.indexOf(cell.row);\n\n if (idx === -1 && (e.ctrlKey || e.metaKey)) {\n selection.push(cell.row);\n this._grid.setActiveCell(cell.row, cell.cell);\n } else if (idx !== -1 && (e.ctrlKey || e.metaKey)) {\n selection = selection.filter((o) => o !== cell.row);\n this._grid.setActiveCell(cell.row, cell.cell);\n } else if (selection.length && e.shiftKey) {\n const last = selection.pop() as number;\n const from = Math.min(cell.row, last);\n const to = Math.max(cell.row, last);\n selection = [];\n for (let i = from; i <= to; i++) {\n if (i !== last) {\n selection.push(i);\n }\n }\n selection.push(last);\n this._grid.setActiveCell(cell.row, cell.cell);\n }\n\n const tempRanges = this.rowsToRanges(selection);\n this.setSelectedRanges(tempRanges);\n e.stopImmediatePropagation();\n\n return true;\n }\n\n protected handleBeforeCellRangeSelected(e: SlickEventData_, cell: { row: number; cell: number; }): boolean | void {\n if (!this._isRowMoveManagerHandler) {\n const rowMoveManager = this._grid.getPluginByName('RowMoveManager') || this._grid.getPluginByName('CrossGridRowMoveManager');\n this._isRowMoveManagerHandler = rowMoveManager ? rowMoveManager.isHandlerColumn : Utils.noop;\n }\n if (this._grid.getEditorLock().isActive() || this._isRowMoveManagerHandler(cell.cell)) {\n e.stopPropagation();\n return false;\n }\n this._grid.setActiveCell(cell.row, cell.cell);\n }\n\n protected handleCellRangeSelected(_e: SlickEventData_, args: { range: CellRange; }): boolean | void {\n if (!this._grid.getOptions().multiSelect || !this._options.selectActiveRow) {\n return false;\n }\n this.setSelectedRanges([new SlickRange(args.range.fromRow, 0, args.range.toRow, this._grid.getColumns().length - 1)])\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n RowSelectionModel: SlickRowSelectionModel\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import { keyCode as keyCode_, SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickEventHandler as SlickEventHandler_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\nimport { Draggable as Draggable_ } from '../slick.interactions';\nimport { SlickCellRangeDecorator as SlickCellRangeDecorator_ } from './slick.cellrangedecorator';\nimport { SlickCellRangeSelector as SlickCellRangeSelector_ } from './slick.cellrangeselector';\nimport type { SlickCrossGridRowMoveManager as SlickCrossGridRowMoveManager_ } from './slick.crossgridrowmovemanager';\nimport type { SlickRowMoveManager as SlickRowMoveManager_ } from './slick.rowmovemanager';\nimport type { CellRange, OnActiveCellChangedEventArgs, RowSelectionModelOption } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Draggable = IIFE_ONLY ? Slick.Draggable : Draggable_;\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\nconst SlickCellRangeDecorator = IIFE_ONLY ? Slick.CellRangeDecorator : SlickCellRangeDecorator_;\nconst SlickCellRangeSelector = IIFE_ONLY ? Slick.CellRangeSelector : SlickCellRangeSelector_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport class SlickRowSelectionModel {\n // --\n // public API\n pluginName = 'RowSelectionModel' as const;\n onSelectedRangesChanged = new SlickEvent();\n // _handler, _inHandler, _isRowMoveManagerHandler, _options, wrapHandler\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _ranges: CellRange[] = [];\n protected _eventHandler = new SlickEventHandler();\n protected _inHandler = false;\n protected _selector?: SlickCellRangeSelector_;\n protected _isRowMoveManagerHandler: any;\n protected _options: RowSelectionModelOption;\n protected _defaults: RowSelectionModelOption = {\n selectActiveRow: true,\n dragToSelect: false,\n autoScrollWhenDrag: true,\n cellRangeSelector: undefined\n };\n\n constructor(options?: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n init(grid: SlickGrid) {\n if (Draggable === undefined) {\n throw new Error('Slick.Draggable is undefined, make sure to import \"slick.interactions.js\"');\n }\n\n this._selector = this._options.cellRangeSelector;\n this._grid = grid;\n\n if (!this._selector && this._options.dragToSelect) {\n if (!SlickCellRangeDecorator) {\n throw new Error('Slick.CellRangeDecorator is required when option dragToSelect set to true');\n }\n this._selector = new SlickCellRangeSelector({\n selectionCss: { border: 'none' } as CSSStyleDeclaration,\n autoScroll: this._options.autoScrollWhenDrag\n });\n }\n\n this._eventHandler.subscribe(this._grid.onActiveCellChanged, this.wrapHandler(this.handleActiveCellChange).bind(this));\n this._eventHandler.subscribe(this._grid.onKeyDown, this.wrapHandler(this.handleKeyDown).bind(this));\n this._eventHandler.subscribe(this._grid.onClick, this.wrapHandler(this.handleClick).bind(this));\n if (this._selector) {\n grid.registerPlugin(this._selector);\n this._selector.onCellRangeSelecting.subscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onCellRangeSelected.subscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onBeforeCellRangeSelected.subscribe(this.handleBeforeCellRangeSelected.bind(this));\n }\n }\n\n destroy() {\n this._eventHandler.unsubscribeAll();\n if (this._selector) {\n this._selector.onCellRangeSelecting.unsubscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onCellRangeSelected.unsubscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onBeforeCellRangeSelected.unsubscribe(this.handleBeforeCellRangeSelected.bind(this));\n this._grid.unregisterPlugin(this._selector);\n if (this._selector.destroy) {\n this._selector.destroy();\n }\n }\n }\n\n protected wrapHandler(handler: (...args: any) => void) {\n return (...args: any) => {\n if (!this._inHandler) {\n this._inHandler = true;\n handler.apply(this, args);\n this._inHandler = false;\n }\n };\n }\n\n protected rangesToRows(ranges: CellRange[]): number[] {\n const rows: number[] = [];\n for (let i = 0; i < ranges.length; i++) {\n for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n rows.push(j);\n }\n }\n return rows;\n }\n\n protected rowsToRanges(rows: number[]) {\n const ranges: SlickRange_[] = [];\n const lastCell = this._grid.getColumns().length - 1;\n for (let i = 0; i < rows.length; i++) {\n ranges.push(new SlickRange(rows[i], 0, rows[i], lastCell));\n }\n return ranges;\n }\n\n protected getRowsRange(from: number, to: number) {\n let i;\n const rows: number[] = [];\n for (i = from; i <= to; i++) {\n rows.push(i);\n }\n for (i = to; i < from; i++) {\n rows.push(i);\n }\n return rows;\n }\n\n getSelectedRows() {\n return this.rangesToRows(this._ranges);\n }\n\n setSelectedRows(rows: number[]) {\n this.setSelectedRanges(this.rowsToRanges(rows), 'SlickRowSelectionModel.setSelectedRows');\n }\n\n setSelectedRanges(ranges: CellRange[], caller = 'SlickRowSelectionModel.setSelectedRanges') {\n // simple check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n if ((!this._ranges || this._ranges.length === 0) && (!ranges || ranges.length === 0)) {\n return;\n }\n this._ranges = ranges;\n\n // provide extra \"caller\" argument through SlickEventData to avoid breaking pubsub event that only accepts an array of selected range\n const eventData = new SlickEventData(null, this._ranges);\n Object.defineProperty(eventData, 'detail', { writable: true, configurable: true, value: { caller: caller || \"SlickRowSelectionModel.setSelectedRanges\" } });\n this.onSelectedRangesChanged.notify(this._ranges, eventData);\n }\n\n getSelectedRanges() {\n return this._ranges;\n }\n\n refreshSelections() {\n this.setSelectedRows(this.getSelectedRows());\n }\n\n protected handleActiveCellChange(_e: SlickEventData_, args: OnActiveCellChangedEventArgs) {\n if (this._options.selectActiveRow && Utils.isDefined(args.row)) {\n this.setSelectedRanges([new SlickRange(args.row, 0, args.row, this._grid.getColumns().length - 1)]);\n }\n }\n\n protected handleKeyDown(e: KeyboardEvent) {\n const activeRow = this._grid.getActiveCell();\n if (this._grid.getOptions().multiSelect && activeRow\n && e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey\n && (e.which === keyCode.UP || e.which === keyCode.DOWN)) {\n let selectedRows = this.getSelectedRows();\n selectedRows.sort(function (x, y) {\n return x - y;\n });\n\n if (!selectedRows.length) {\n selectedRows = [activeRow.row];\n }\n\n let top = selectedRows[0];\n let bottom = selectedRows[selectedRows.length - 1];\n let active: number;\n\n if (e.which === keyCode.DOWN) {\n active = activeRow.row < bottom || top === bottom ? ++bottom : ++top;\n } else {\n active = activeRow.row < bottom ? --bottom : --top;\n }\n\n if (active >= 0 && active < this._grid.getDataLength()) {\n this._grid.scrollRowIntoView(active);\n const tempRanges = this.rowsToRanges(this.getRowsRange(top, bottom));\n this.setSelectedRanges(tempRanges);\n }\n\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n protected handleClick(e: MouseEvent): boolean | void {\n const cell = this._grid.getCellFromEvent(e);\n if (!cell || !this._grid.canCellBeActive(cell.row, cell.cell)) {\n return false;\n }\n\n if (!this._grid.getOptions().multiSelect || (\n !e.ctrlKey && !e.shiftKey && !e.metaKey)) {\n return false;\n }\n\n let selection = this.rangesToRows(this._ranges);\n const idx = selection.indexOf(cell.row);\n\n if (idx === -1 && (e.ctrlKey || e.metaKey)) {\n selection.push(cell.row);\n this._grid.setActiveCell(cell.row, cell.cell);\n } else if (idx !== -1 && (e.ctrlKey || e.metaKey)) {\n selection = selection.filter((o) => o !== cell.row);\n this._grid.setActiveCell(cell.row, cell.cell);\n } else if (selection.length && e.shiftKey) {\n const last = selection.pop() as number;\n const from = Math.min(cell.row, last);\n const to = Math.max(cell.row, last);\n selection = [];\n for (let i = from; i <= to; i++) {\n if (i !== last) {\n selection.push(i);\n }\n }\n selection.push(last);\n this._grid.setActiveCell(cell.row, cell.cell);\n }\n\n const tempRanges = this.rowsToRanges(selection);\n this.setSelectedRanges(tempRanges);\n e.stopImmediatePropagation();\n\n return true;\n }\n\n protected handleBeforeCellRangeSelected(e: SlickEventData_, cell: { row: number; cell: number; }): boolean | void {\n if (!this._isRowMoveManagerHandler) {\n const rowMoveManager = this._grid.getPluginByName('RowMoveManager') || this._grid.getPluginByName('CrossGridRowMoveManager');\n this._isRowMoveManagerHandler = rowMoveManager ? rowMoveManager.isHandlerColumn : Utils.noop;\n }\n if (this._grid.getEditorLock().isActive() || this._isRowMoveManagerHandler(cell.cell)) {\n e.stopPropagation();\n return false;\n }\n this._grid.setActiveCell(cell.row, cell.cell);\n }\n\n protected handleCellRangeSelected(_e: SlickEventData_, args: { range: CellRange; }): boolean | void {\n if (!this._grid.getOptions().multiSelect || !this._options.selectActiveRow) {\n return false;\n }\n this.setSelectedRanges([new SlickRange(args.range.fromRow, 0, args.range.toRow, this._grid.getColumns().length - 1)]);\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n RowSelectionModel: SlickRowSelectionModel\n }\n });\n}\n\n"], + "mappings": ";;;;;;;AAUA,MAAM,YAAwB,MAAM,WAC9B,UAAsB,MAAM,SAC5B,0BAAsC,MAAM,oBAC5C,yBAAqC,MAAM,mBAC3C,aAAyB,MAAM,OAC/B,iBAA6B,MAAM,WACnC,oBAAgC,MAAM,cACtC,aAAyB,MAAM,OAC/B,QAAoB,MAAM,OAEnB,yBAAN,MAA6B;AAAA,IAsBlC,YAAY,SAA4C;AAnBxD;AAAA;AAAA,wCAAa;AACb,qDAA0B,IAAI,WAAwB;AAItD;AAAA;AAAA;AAAA,0BAAU;AACV,0BAAU,WAAuB,CAAC;AAClC,0BAAU,iBAAgB,IAAI,kBAAkB;AAChD,0BAAU,cAAa;AACvB,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU,aAAqC;AAAA,QAC7C,iBAAiB;AAAA,QACjB,cAAc;AAAA,QACd,oBAAoB;AAAA,QACpB,mBAAmB;AAAA,MACrB;AAGE,WAAK,WAAW,MAAM,OAAO,IAAM,CAAC,GAAG,KAAK,WAAW,OAAO;AAAA,IAChE;AAAA,IAEA,KAAK,MAAiB;AACpB,UAAI,cAAc;AAChB,cAAM,IAAI,MAAM,2EAA2E;AAM7F,UAHA,KAAK,YAAY,KAAK,SAAS,mBAC/B,KAAK,QAAQ,MAET,CAAC,KAAK,aAAa,KAAK,SAAS,cAAc;AACjD,YAAI,CAAC;AACH,gBAAM,IAAI,MAAM,2EAA2E;AAE7F,aAAK,YAAY,IAAI,uBAAuB;AAAA,UAC1C,cAAc,EAAE,QAAQ,OAAO;AAAA,UAC/B,YAAY,KAAK,SAAS;AAAA,QAC5B,CAAC;AAAA,MACH;AAEA,WAAK,cAAc,UAAU,KAAK,MAAM,qBAAqB,KAAK,YAAY,KAAK,sBAAsB,EAAE,KAAK,IAAI,CAAC,GACrH,KAAK,cAAc,UAAU,KAAK,MAAM,WAAW,KAAK,YAAY,KAAK,aAAa,EAAE,KAAK,IAAI,CAAC,GAClG,KAAK,cAAc,UAAU,KAAK,MAAM,SAAS,KAAK,YAAY,KAAK,WAAW,EAAE,KAAK,IAAI,CAAC,GAC1F,KAAK,cACP,KAAK,eAAe,KAAK,SAAS,GAClC,KAAK,UAAU,qBAAqB,UAAU,KAAK,wBAAwB,KAAK,IAAI,CAAC,GACrF,KAAK,UAAU,oBAAoB,UAAU,KAAK,wBAAwB,KAAK,IAAI,CAAC,GACpF,KAAK,UAAU,0BAA0B,UAAU,KAAK,8BAA8B,KAAK,IAAI,CAAC;AAAA,IAEpG;AAAA,IAEA,UAAU;AACR,WAAK,cAAc,eAAe,GAC9B,KAAK,cACP,KAAK,UAAU,qBAAqB,YAAY,KAAK,wBAAwB,KAAK,IAAI,CAAC,GACvF,KAAK,UAAU,oBAAoB,YAAY,KAAK,wBAAwB,KAAK,IAAI,CAAC,GACtF,KAAK,UAAU,0BAA0B,YAAY,KAAK,8BAA8B,KAAK,IAAI,CAAC,GAClG,KAAK,MAAM,iBAAiB,KAAK,SAAS,GACtC,KAAK,UAAU,WACjB,KAAK,UAAU,QAAQ;AAAA,IAG7B;AAAA,IAEU,YAAY,SAAiC;AACrD,aAAO,IAAI,SAAc;AACvB,QAAK,KAAK,eACR,KAAK,aAAa,IAClB,QAAQ,MAAM,MAAM,IAAI,GACxB,KAAK,aAAa;AAAA,MAEtB;AAAA,IACF;AAAA,IAEU,aAAa,QAA+B;AACpD,UAAM,OAAiB,CAAC;AACxB,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ;AACjC,iBAAS,IAAI,OAAO,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC,EAAE,OAAO;AACpD,eAAK,KAAK,CAAC;AAGf,aAAO;AAAA,IACT;AAAA,IAEU,aAAa,MAAgB;AACrC,UAAM,SAAwB,CAAC,GACzB,WAAW,KAAK,MAAM,WAAW,EAAE,SAAS;AAClD,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ;AAC/B,eAAO,KAAK,IAAI,WAAW,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC;AAE3D,aAAO;AAAA,IACT;AAAA,IAEU,aAAa,MAAc,IAAY;AAC/C,UAAI,GACE,OAAiB,CAAC;AACxB,WAAK,IAAI,MAAM,KAAK,IAAI;AACtB,aAAK,KAAK,CAAC;AAEb,WAAK,IAAI,IAAI,IAAI,MAAM;AACrB,aAAK,KAAK,CAAC;AAEb,aAAO;AAAA,IACT;AAAA,IAEA,kBAAkB;AAChB,aAAO,KAAK,aAAa,KAAK,OAAO;AAAA,IACvC;AAAA,IAEA,gBAAgB,MAAgB;AAC9B,WAAK,kBAAkB,KAAK,aAAa,IAAI,GAAG,wCAAwC;AAAA,IAC1F;AAAA,IAEA,kBAAkB,QAAqB,SAAS,4CAA4C;AAE1F,WAAK,CAAC,KAAK,WAAW,KAAK,QAAQ,WAAW,OAAO,CAAC,UAAU,OAAO,WAAW;AAChF;AAEF,WAAK,UAAU;AAGf,UAAM,YAAY,IAAI,eAAe,MAAM,KAAK,OAAO;AACvD,aAAO,eAAe,WAAW,UAAU,EAAE,UAAU,IAAM,cAAc,IAAM,OAAO,EAAE,QAAQ,UAAU,2CAA2C,EAAE,CAAC,GAC1J,KAAK,wBAAwB,OAAO,KAAK,SAAS,SAAS;AAAA,IAC7D;AAAA,IAEA,oBAAoB;AAClB,aAAO,KAAK;AAAA,IACd;AAAA,IAEA,oBAAoB;AAClB,WAAK,gBAAgB,KAAK,gBAAgB,CAAC;AAAA,IAC7C;AAAA,IAEU,uBAAuB,IAAqB,MAAoC;AACxF,MAAI,KAAK,SAAS,mBAAmB,MAAM,UAAU,KAAK,GAAG,KAC3D,KAAK,kBAAkB,CAAC,IAAI,WAAW,KAAK,KAAK,GAAG,KAAK,KAAK,KAAK,MAAM,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;AAAA,IAEtG;AAAA,IAEU,cAAc,GAAkB;AACxC,UAAM,YAAY,KAAK,MAAM,cAAc;AAC3C,UAAI,KAAK,MAAM,WAAW,EAAE,eAAe,aACtC,EAAE,YAAY,CAAC,EAAE,WAAW,CAAC,EAAE,UAAU,CAAC,EAAE,YAC3C,EAAE,UAAU,QAAQ,MAAM,EAAE,UAAU,QAAQ,OAAO;AACzD,YAAI,eAAe,KAAK,gBAAgB;AACxC,qBAAa,KAAK,SAAU,GAAG,GAAG;AAChC,iBAAO,IAAI;AAAA,QACb,CAAC,GAEI,aAAa,WAChB,eAAe,CAAC,UAAU,GAAG;AAG/B,YAAI,MAAM,aAAa,CAAC,GACpB,SAAS,aAAa,aAAa,SAAS,CAAC,GAC7C;AAQJ,YANI,EAAE,UAAU,QAAQ,OACtB,SAAS,UAAU,MAAM,UAAU,QAAQ,SAAS,EAAE,SAAS,EAAE,MAEjE,SAAS,UAAU,MAAM,SAAS,EAAE,SAAS,EAAE,KAG7C,UAAU,KAAK,SAAS,KAAK,MAAM,cAAc,GAAG;AACtD,eAAK,MAAM,kBAAkB,MAAM;AACnC,cAAM,aAAa,KAAK,aAAa,KAAK,aAAa,KAAK,MAAM,CAAC;AACnE,eAAK,kBAAkB,UAAU;AAAA,QACnC;AAEA,UAAE,eAAe,GACjB,EAAE,gBAAgB;AAAA,MACpB;AAAA,IACF;AAAA,IAEU,YAAY,GAA+B;AACnD,UAAM,OAAO,KAAK,MAAM,iBAAiB,CAAC;AAK1C,UAJI,CAAC,QAAQ,CAAC,KAAK,MAAM,gBAAgB,KAAK,KAAK,KAAK,IAAI,KAIxD,CAAC,KAAK,MAAM,WAAW,EAAE,eAC3B,CAAC,EAAE,WAAW,CAAC,EAAE,YAAY,CAAC,EAAE;AAChC,eAAO;AAGT,UAAI,YAAY,KAAK,aAAa,KAAK,OAAO,GACxC,MAAM,UAAU,QAAQ,KAAK,GAAG;AAEtC,UAAI,QAAQ,OAAO,EAAE,WAAW,EAAE;AAChC,kBAAU,KAAK,KAAK,GAAG,GACvB,KAAK,MAAM,cAAc,KAAK,KAAK,KAAK,IAAI;AAAA,eACnC,QAAQ,OAAO,EAAE,WAAW,EAAE;AACvC,oBAAY,UAAU,OAAO,CAAC,MAAM,MAAM,KAAK,GAAG,GAClD,KAAK,MAAM,cAAc,KAAK,KAAK,KAAK,IAAI;AAAA,eACnC,UAAU,UAAU,EAAE,UAAU;AACzC,YAAM,OAAO,UAAU,IAAI,GACrB,OAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAC9B,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI;AAClC,oBAAY,CAAC;AACb,iBAAS,IAAI,MAAM,KAAK,IAAI;AAC1B,UAAI,MAAM,QACR,UAAU,KAAK,CAAC;AAGpB,kBAAU,KAAK,IAAI,GACnB,KAAK,MAAM,cAAc,KAAK,KAAK,KAAK,IAAI;AAAA,MAC9C;AAEA,UAAM,aAAa,KAAK,aAAa,SAAS;AAC9C,kBAAK,kBAAkB,UAAU,GACjC,EAAE,yBAAyB,GAEpB;AAAA,IACT;AAAA,IAEU,8BAA8B,GAAoB,MAAsD;AAChH,UAAI,CAAC,KAAK,0BAA0B;AAClC,YAAM,iBAAiB,KAAK,MAAM,gBAAsC,gBAAgB,KAAK,KAAK,MAAM,gBAA+C,yBAAyB;AAChL,aAAK,2BAA2B,iBAAiB,eAAe,kBAAkB,MAAM;AAAA,MAC1F;AACA,UAAI,KAAK,MAAM,cAAc,EAAE,SAAS,KAAK,KAAK,yBAAyB,KAAK,IAAI;AAClF,iBAAE,gBAAgB,GACX;AAET,WAAK,MAAM,cAAc,KAAK,KAAK,KAAK,IAAI;AAAA,IAC9C;AAAA,IAEU,wBAAwB,IAAqB,MAA6C;AAClG,UAAI,CAAC,KAAK,MAAM,WAAW,EAAE,eAAe,CAAC,KAAK,SAAS;AACzD,eAAO;AAET,WAAK,kBAAkB,CAAC,IAAI,WAAW,KAAK,MAAM,SAAS,GAAG,KAAK,MAAM,OAAO,KAAK,MAAM,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;AAAA,IACtH;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,mBAAmB;AAAA,IACrB;AAAA,EACF,CAAC;", "names": [] } diff --git a/dist/browser/plugins/slick.state.js.map b/dist/browser/plugins/slick.state.js.map index 374a2a57e..f05a072b4 100644 --- a/dist/browser/plugins/slick.state.js.map +++ b/dist/browser/plugins/slick.state.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.state.ts"], - "sourcesContent": ["import { SlickEvent as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { Column, ColumnSort, Plugin } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport interface SlickStateOption {\n /** optional grid state clientId */\n cid: string;\n\n /** default columns when loadnig the grid */\n defaultColumns: Column[];\n\n /** local storage key prefix */\n key_prefix: string;\n\n /** should we scroll the grid into view? */\n scrollRowIntoView: boolean;\n\n /** local storage wrapper */\n storage: LocalStorageWrapper;\n}\n\nexport interface CurrentState {\n columns: Array<{ id: string | number; width: number | undefined; }>;\n sortcols: ColumnSort[];\n userData: any;\n viewport: { top: number; bottom: number; leftPx: number; rightPx: number; };\n}\n\nclass LocalStorageWrapper {\n protected localStorage = window.localStorage;\n\n constructor() {\n if (typeof localStorage === 'undefined') {\n console.error('localStorage is not available. slickgrid statepersistor disabled.');\n }\n }\n\n get(key: string) {\n return new Promise((resolve, reject) => {\n if (!localStorage) {\n reject('missing localStorage');\n return\n }\n try {\n const d = localStorage.getItem(key);\n if (d) {\n return resolve(JSON.parse(d) as T);\n }\n resolve({} as T);\n } catch (exc) {\n reject(exc);\n }\n });\n }\n\n set(key: string, obj: any) {\n if (!localStorage) return;\n if (typeof obj !== 'undefined') {\n obj = JSON.stringify(obj);\n }\n localStorage.setItem(key, obj);\n }\n};\n\nexport class SlickState implements Plugin {\n // --\n // public API\n pluginName = 'State' as const;\n onStateChanged = new SlickEvent();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _cid = '';\n protected _store: LocalStorageWrapper;\n protected _options: SlickStateOption;\n protected _state?: CurrentState;\n protected _userData = {\n state: null,\n current: null\n };\n\n constructor(options: Partial) {\n const defaults = {\n key_prefix: 'slickgrid:',\n storage: new LocalStorageWrapper(),\n scrollRowIntoView: true\n };\n this._options = Utils.extend(true, {}, defaults, options);\n this._store = this._options.storage;\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._cid = grid.cid || this._options.cid;\n if (this._cid) {\n this._grid.onColumnsResized.subscribe(this.save.bind(this));\n this._grid.onColumnsReordered.subscribe(this.save.bind(this));\n this._grid.onSort.subscribe(this.save.bind(this));\n } else {\n console.warn('grid has no client id. state persisting is disabled.');\n }\n }\n\n destroy() {\n this._grid.onSort.unsubscribe(this.save.bind(this));\n this._grid.onColumnsReordered.unsubscribe(this.save.bind(this));\n this._grid.onColumnsResized.unsubscribe(this.save.bind(this));\n this.save();\n }\n\n save() {\n if (this._cid && this._store) {\n this._state = {\n sortcols: this.getSortColumns(),\n viewport: this._grid.getViewport(),\n columns: this.getColumns(),\n userData: null\n };\n this._state.userData = this._userData.current;\n this.setUserDataFromState(this._state.userData);\n this.onStateChanged.notify(this._state);\n\n return this._store.set(this._options.key_prefix + this._cid, this._state);\n }\n }\n\n restore() {\n return new Promise((resolve, reject) => {\n if (!this._cid) {\n reject('missing client id');\n return;\n }\n if (!this._store) {\n reject('missing store');\n return;\n }\n\n this._store.get(this._options.key_prefix + this._cid)\n .then((state) => {\n if (state) {\n if (state.sortcols) {\n this._grid.setSortColumns(state.sortcols || []);\n }\n if (state.viewport && this._options.scrollRowIntoView) {\n this._grid.scrollRowIntoView(state.viewport.top, true);\n }\n if (state.columns) {\n const defaultColumns = this._options.defaultColumns;\n if (defaultColumns) {\n const defaultColumnsLookup: Record = {};\n defaultColumns.forEach((colDef) => defaultColumnsLookup[colDef.id] = colDef);\n\n const cols: Array<{ id: string | number; width: number | undefined; }> = [];\n (state.columns || []).forEach((columnDef) => {\n if (defaultColumnsLookup[columnDef.id]) {\n cols.push(Utils.extend(true, {}, defaultColumnsLookup[columnDef.id], {\n width: columnDef.width,\n headerCssClass: (columnDef as Column).headerCssClass\n }));\n }\n });\n\n state.columns = cols;\n }\n\n this._grid.setColumns(state.columns as Column[]);\n }\n this.setUserDataFromState(state.userData);\n }\n resolve(state);\n })\n .catch((e) => {\n reject(e);\n })\n });\n }\n\n /**\n * allows users to add their own data to the grid state\n * this function does not trigger the save() function, so the actual act of writing the state happens in save()\n * therefore, it's necessary to call save() function after setting user-data\n *\n * @param data\n * @return {State}\n */\n setUserData(data: any) {\n this._userData.current = data;\n return this;\n }\n\n /**\n *\n * @internal\n * @param data\n * @return {State}\n */\n setUserDataFromState(data: any) {\n this._userData.state = data;\n return this.setUserData(data);\n }\n\n /**\n * returns current value of user-data\n * @return {Object}\n */\n getUserData() {\n return this._userData.current;\n }\n\n /**\n * returns user-data found in saved state\n *\n * @return {Object}\n */\n getStateUserData() {\n return this._userData.state;\n }\n\n /**\n * Sets user-data to the value read from state\n * @return {State}\n */\n resetUserData() {\n this._userData.current = this._userData.state;\n return this;\n }\n\n getColumns() {\n return this._grid.getColumns().map((col) => ({\n id: col.id,\n width: col.width\n }));\n }\n\n getSortColumns() {\n return this._grid.getSortColumns();\n }\n\n reset() {\n this._store.set(this._options.key_prefix + this._cid, {});\n this.setUserDataFromState(null);\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n State: SlickState\n }\n });\n}\n\n"], - "mappings": ";;;;;;;AAKA,MAAM,aAAyB,MAAM,OAC/B,QAAoB,MAAM,OA0B1B,sBAAN,MAA0B;AAAA,IAGxB,cAAc;AAFd,0BAAU,gBAAe,OAAO;AAG9B,MAAI,OAAO,gBAAiB,eAC1B,QAAQ,MAAM,mEAAmE;AAAA,IAErF;AAAA,IAEA,IAAa,KAAa;AACxB,aAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACzC,YAAI,CAAC,cAAc;AACjB,iBAAO,sBAAsB;AAC7B;AAAA,QACF;AACA,YAAI;AACF,cAAM,IAAI,aAAa,QAAQ,GAAG;AAClC,cAAI;AACF,mBAAO,QAAQ,KAAK,MAAM,CAAC,CAAM;AAEnC,kBAAQ,CAAC,CAAM;AAAA,QACjB,SAAS,KAAK;AACZ,iBAAO,GAAG;AAAA,QACZ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,IAAI,KAAa,KAAU;AACzB,MAAK,iBACD,OAAO,OAAQ,gBACjB,MAAM,KAAK,UAAU,GAAG,IAE1B,aAAa,QAAQ,KAAK,GAAG;AAAA,IAC/B;AAAA,EACF,GAEa,aAAN,MAAmC;AAAA,IAkBxC,YAAY,SAAoC;AAfhD;AAAA;AAAA,wCAAa;AACb,4CAAiB,IAAI,WAAyB;AAI9C;AAAA;AAAA,0BAAU;AACV,0BAAU,QAAO;AACjB,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU,aAAY;AAAA,QACpB,OAAO;AAAA,QACP,SAAS;AAAA,MACX;AAGE,UAAM,WAAW;AAAA,QACf,YAAY;AAAA,QACZ,SAAS,IAAI,oBAAoB;AAAA,QACjC,mBAAmB;AAAA,MACrB;AACA,WAAK,WAAW,MAAM,OAAO,IAAM,CAAC,GAAG,UAAU,OAAO,GACxD,KAAK,SAAS,KAAK,SAAS;AAAA,IAC9B;AAAA,IAEA,KAAK,MAAiB;AACpB,WAAK,QAAQ,MACb,KAAK,OAAO,KAAK,OAAO,KAAK,SAAS,KAClC,KAAK,QACP,KAAK,MAAM,iBAAiB,UAAU,KAAK,KAAK,KAAK,IAAI,CAAC,GAC1D,KAAK,MAAM,mBAAmB,UAAU,KAAK,KAAK,KAAK,IAAI,CAAC,GAC5D,KAAK,MAAM,OAAO,UAAU,KAAK,KAAK,KAAK,IAAI,CAAC,KAEhD,QAAQ,KAAK,sDAAsD;AAAA,IAEvE;AAAA,IAEA,UAAU;AACR,WAAK,MAAM,OAAO,YAAY,KAAK,KAAK,KAAK,IAAI,CAAC,GAClD,KAAK,MAAM,mBAAmB,YAAY,KAAK,KAAK,KAAK,IAAI,CAAC,GAC9D,KAAK,MAAM,iBAAiB,YAAY,KAAK,KAAK,KAAK,IAAI,CAAC,GAC5D,KAAK,KAAK;AAAA,IACZ;AAAA,IAEA,OAAO;AACL,UAAI,KAAK,QAAQ,KAAK;AACpB,oBAAK,SAAS;AAAA,UACZ,UAAU,KAAK,eAAe;AAAA,UAC9B,UAAU,KAAK,MAAM,YAAY;AAAA,UACjC,SAAS,KAAK,WAAW;AAAA,UACzB,UAAU;AAAA,QACZ,GACA,KAAK,OAAO,WAAW,KAAK,UAAU,SACtC,KAAK,qBAAqB,KAAK,OAAO,QAAQ,GAC9C,KAAK,eAAe,OAAO,KAAK,MAAM,GAE/B,KAAK,OAAO,IAAI,KAAK,SAAS,aAAa,KAAK,MAAM,KAAK,MAAM;AAAA,IAE5E;AAAA,IAEA,UAAU;AACR,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAI,CAAC,KAAK,MAAM;AACd,iBAAO,mBAAmB;AAC1B;AAAA,QACF;AACA,YAAI,CAAC,KAAK,QAAQ;AAChB,iBAAO,eAAe;AACtB;AAAA,QACF;AAEA,aAAK,OAAO,IAAkB,KAAK,SAAS,aAAa,KAAK,IAAI,EAC/D,KAAK,CAAC,UAAU;AACf,cAAI,OAAO;AAOT,gBANI,MAAM,YACR,KAAK,MAAM,eAAe,MAAM,YAAY,CAAC,CAAC,GAE5C,MAAM,YAAY,KAAK,SAAS,qBAClC,KAAK,MAAM,kBAAkB,MAAM,SAAS,KAAK,EAAI,GAEnD,MAAM,SAAS;AACjB,kBAAM,iBAAiB,KAAK,SAAS;AACrC,kBAAI,gBAAgB;AAClB,oBAAM,uBAAwD,CAAC;AAC/D,+BAAe,QAAQ,CAAC,WAAW,qBAAqB,OAAO,EAAE,IAAI,MAAM;AAE3E,oBAAM,OAAmE,CAAC;AAC1E,iBAAC,MAAM,WAAW,CAAC,GAAG,QAAQ,CAAC,cAAc;AAC3C,kBAAI,qBAAqB,UAAU,EAAE,KACnC,KAAK,KAAK,MAAM,OAAO,IAAM,CAAC,GAAG,qBAAqB,UAAU,EAAE,GAAG;AAAA,oBACnE,OAAO,UAAU;AAAA,oBACjB,gBAAiB,UAAqB;AAAA,kBACxC,CAAC,CAAC;AAAA,gBAEN,CAAC,GAED,MAAM,UAAU;AAAA,cAClB;AAEA,mBAAK,MAAM,WAAW,MAAM,OAAmB;AAAA,YACjD;AACA,iBAAK,qBAAqB,MAAM,QAAQ;AAAA,UAC1C;AACA,kBAAQ,KAAK;AAAA,QACf,CAAC,EACA,MAAM,CAAC,MAAM;AACZ,iBAAO,CAAC;AAAA,QACV,CAAC;AAAA,MACL,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,YAAY,MAAW;AACrB,kBAAK,UAAU,UAAU,MAClB;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,qBAAqB,MAAW;AAC9B,kBAAK,UAAU,QAAQ,MAChB,KAAK,YAAY,IAAI;AAAA,IAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,cAAc;AACZ,aAAO,KAAK,UAAU;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,mBAAmB;AACjB,aAAO,KAAK,UAAU;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,gBAAgB;AACd,kBAAK,UAAU,UAAU,KAAK,UAAU,OACjC;AAAA,IACT;AAAA,IAEA,aAAa;AACX,aAAO,KAAK,MAAM,WAAW,EAAE,IAAI,CAAC,SAAS;AAAA,QAC3C,IAAI,IAAI;AAAA,QACR,OAAO,IAAI;AAAA,MACb,EAAE;AAAA,IACJ;AAAA,IAEA,iBAAiB;AACf,aAAO,KAAK,MAAM,eAAe;AAAA,IACnC;AAAA,IAEA,QAAQ;AACN,WAAK,OAAO,IAAI,KAAK,SAAS,aAAa,KAAK,MAAM,CAAC,CAAC,GACxD,KAAK,qBAAqB,IAAI;AAAA,IAChC;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,OAAO;AAAA,IACT;AAAA,EACF,CAAC;", + "sourcesContent": ["import { SlickEvent as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { Column, ColumnSort, SlickPlugin } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport interface SlickStateOption {\n /** optional grid state clientId */\n cid: string;\n\n /** default columns when loadnig the grid */\n defaultColumns: Column[];\n\n /** local storage key prefix */\n key_prefix: string;\n\n /** should we scroll the grid into view? */\n scrollRowIntoView: boolean;\n\n /** local storage wrapper */\n storage: LocalStorageWrapper;\n}\n\nexport interface CurrentState {\n columns: Array<{ id: string | number; width: number | undefined; }>;\n sortcols: ColumnSort[];\n userData: any;\n viewport: { top: number; bottom: number; leftPx: number; rightPx: number; };\n}\n\nclass LocalStorageWrapper {\n protected localStorage = window.localStorage;\n\n constructor() {\n if (typeof localStorage === 'undefined') {\n console.error('localStorage is not available. slickgrid statepersistor disabled.');\n }\n }\n\n get(key: string) {\n return new Promise((resolve, reject) => {\n if (!localStorage) {\n reject('missing localStorage');\n return;\n }\n try {\n const d = localStorage.getItem(key);\n if (d) {\n return resolve(JSON.parse(d) as T);\n }\n resolve({} as T);\n } catch (exc) {\n reject(exc);\n }\n });\n }\n\n set(key: string, obj: any) {\n if (!localStorage) { return; }\n if (typeof obj !== 'undefined') {\n obj = JSON.stringify(obj);\n }\n localStorage.setItem(key, obj);\n }\n};\n\nexport class SlickState implements SlickPlugin {\n // --\n // public API\n pluginName = 'State' as const;\n onStateChanged = new SlickEvent();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _cid = '';\n protected _store: LocalStorageWrapper;\n protected _options: SlickStateOption;\n protected _state?: CurrentState;\n protected _userData = {\n state: null,\n current: null\n };\n\n constructor(options: Partial) {\n const defaults = {\n key_prefix: 'slickgrid:',\n storage: new LocalStorageWrapper(),\n scrollRowIntoView: true\n };\n this._options = Utils.extend(true, {}, defaults, options);\n this._store = this._options.storage;\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._cid = grid.cid || this._options.cid;\n if (this._cid) {\n this._grid.onColumnsResized.subscribe(this.save.bind(this));\n this._grid.onColumnsReordered.subscribe(this.save.bind(this));\n this._grid.onSort.subscribe(this.save.bind(this));\n } else {\n console.warn('grid has no client id. state persisting is disabled.');\n }\n }\n\n destroy() {\n this._grid.onSort.unsubscribe(this.save.bind(this));\n this._grid.onColumnsReordered.unsubscribe(this.save.bind(this));\n this._grid.onColumnsResized.unsubscribe(this.save.bind(this));\n this.save();\n }\n\n save() {\n if (this._cid && this._store) {\n this._state = {\n sortcols: this.getSortColumns(),\n viewport: this._grid.getViewport(),\n columns: this.getColumns(),\n userData: null\n };\n this._state.userData = this._userData.current;\n this.setUserDataFromState(this._state.userData);\n this.onStateChanged.notify(this._state);\n\n return this._store.set(this._options.key_prefix + this._cid, this._state);\n }\n }\n\n restore() {\n return new Promise((resolve, reject) => {\n if (!this._cid) {\n reject('missing client id');\n return;\n }\n if (!this._store) {\n reject('missing store');\n return;\n }\n\n this._store.get(this._options.key_prefix + this._cid)\n .then((state) => {\n if (state) {\n if (state.sortcols) {\n this._grid.setSortColumns(state.sortcols || []);\n }\n if (state.viewport && this._options.scrollRowIntoView) {\n this._grid.scrollRowIntoView(state.viewport.top, true);\n }\n if (state.columns) {\n const defaultColumns = this._options.defaultColumns;\n if (defaultColumns) {\n const defaultColumnsLookup: Record = {};\n defaultColumns.forEach((colDef) => defaultColumnsLookup[colDef.id] = colDef);\n\n const cols: Array<{ id: string | number; width: number | undefined; }> = [];\n (state.columns || []).forEach((columnDef) => {\n if (defaultColumnsLookup[columnDef.id]) {\n cols.push(Utils.extend(true, {}, defaultColumnsLookup[columnDef.id], {\n width: columnDef.width,\n headerCssClass: (columnDef as Column).headerCssClass\n }));\n }\n });\n\n state.columns = cols;\n }\n\n this._grid.setColumns(state.columns as Column[]);\n }\n this.setUserDataFromState(state.userData);\n }\n resolve(state);\n })\n .catch((e) => {\n reject(e);\n });\n });\n }\n\n /**\n * allows users to add their own data to the grid state\n * this function does not trigger the save() function, so the actual act of writing the state happens in save()\n * therefore, it's necessary to call save() function after setting user-data\n *\n * @param data\n * @return {State}\n */\n setUserData(data: any) {\n this._userData.current = data;\n return this;\n }\n\n /**\n *\n * @internal\n * @param data\n * @return {State}\n */\n setUserDataFromState(data: any) {\n this._userData.state = data;\n return this.setUserData(data);\n }\n\n /**\n * returns current value of user-data\n * @return {Object}\n */\n getUserData() {\n return this._userData.current;\n }\n\n /**\n * returns user-data found in saved state\n *\n * @return {Object}\n */\n getStateUserData() {\n return this._userData.state;\n }\n\n /**\n * Sets user-data to the value read from state\n * @return {State}\n */\n resetUserData() {\n this._userData.current = this._userData.state;\n return this;\n }\n\n getColumns() {\n return this._grid.getColumns().map((col) => ({\n id: col.id,\n width: col.width\n }));\n }\n\n getSortColumns() {\n return this._grid.getSortColumns();\n }\n\n reset() {\n this._store.set(this._options.key_prefix + this._cid, {});\n this.setUserDataFromState(null);\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n State: SlickState\n }\n });\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/slick.compositeeditor.js.map b/dist/browser/slick.compositeeditor.js.map index aed65958e..025c1b6cf 100644 --- a/dist/browser/slick.compositeeditor.js.map +++ b/dist/browser/slick.compositeeditor.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.compositeeditor.ts"], - "sourcesContent": ["import type { Column, CompositeEditorOption, Editor, EditorArguments, HtmlElementPosition } from './models/index';\nimport { Utils as Utils_ } from './slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A composite SlickGrid editor factory.\n * Generates an editor that is composed of multiple editors for given columns.\n * Individual editors are provided given containers instead of the original cell.\n * Validation will be performed on all editors individually and the results will be aggregated into one\n * validation result.\n *\n *\n * The returned editor will have its prototype set to CompositeEditor, so you can use the \"instanceof\" check.\n *\n * NOTE: This doesn't work for detached editors since they will be created and positioned relative to the\n * active cell and not the provided container.\n *\n * @namespace Slick\n * @class CompositeEditor\n * @constructor\n * @param columns {Array} Column definitions from which editors will be pulled.\n * @param containers {Array} Container HTMLElements in which editors will be placed.\n * @param options {Object} Options hash:\n * validationFailedMsg - A generic failed validation message set on the aggregated validation resuls.\n * validationMsgPrefix - Add an optional prefix to each validation message (only the ones shown in the modal form, not the ones in the \"errors\")\n * modalType - Defaults to \"edit\", modal type can 1 of these 3: (create, edit, mass, mass-selection)\n * hide - A function to be called when the grid asks the editor to hide itself.\n * show - A function to be called when the grid asks the editor to show itself.\n * position - A function to be called when the grid asks the editor to reposition itself.\n * destroy - A function to be called when the editor is destroyed.\n */\nexport function SlickCompositeEditor(columns: Column[], containers: Array, options: CompositeEditorOption) {\n const defaultOptions = {\n modalType: 'edit', // available type (create, edit, mass)\n validationFailedMsg: 'Some of the fields have failed validation',\n validationMsgPrefix: null,\n show: null,\n hide: null,\n position: null,\n destroy: null,\n formValues: {},\n editors: {}\n };\n\n const noop = function () { };\n\n let firstInvalidEditor: Editor | null = null;\n\n options = Slick.Utils.extend({}, defaultOptions, options);\n\n function getContainerBox(i: number) {\n const c = containers[i];\n const offset = Slick.Utils.offset(c);\n const w = Slick.Utils.width(c);\n const h = Slick.Utils.height(c);\n\n return {\n top: (offset?.top ?? 0),\n left: (offset?.left ?? 0),\n bottom: (offset?.top ?? 0) + (h || 0),\n right: (offset?.left ?? 0) + (w || 0),\n width: w,\n height: h,\n visible: true\n };\n }\n\n function editor(args: any[]) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const context: any = this;\n let editors: Array = [];\n\n function init() {\n let newArgs: any = {};\n let idx = 0;\n while (idx < columns.length) {\n if (columns[idx].editor) {\n const column = columns[idx];\n newArgs = Slick.Utils.extend(false, {}, args);\n newArgs.container = containers[idx];\n newArgs.column = column;\n newArgs.position = getContainerBox(idx);\n newArgs.commitChanges = noop;\n newArgs.cancelChanges = noop;\n newArgs.compositeEditorOptions = options;\n newArgs.formValues = {};\n\n const currentEditor = new (column.editor as any)(newArgs) as Editor & { args: EditorArguments };\n options.editors[column.id] = currentEditor; // add every Editor instance refs\n editors.push(currentEditor);\n }\n idx++;\n }\n\n // focus on first input\n setTimeout(function () {\n if (Array.isArray(editors) && editors.length > 0 && typeof editors[0].focus === 'function') {\n editors[0].focus();\n }\n }, 0);\n }\n\n context.destroy = () => {\n let idx = 0;\n while (idx < editors.length) {\n editors[idx].destroy();\n idx++;\n }\n\n options.destroy?.();\n editors = [];\n };\n\n\n context.focus = () => {\n // if validation has failed, set the focus to the first invalid editor\n (firstInvalidEditor || editors[0]).focus();\n };\n\n context.isValueChanged = () => {\n let idx = 0;\n while (idx < editors.length) {\n if (editors[idx].isValueChanged()) {\n return true;\n }\n idx++;\n }\n return false;\n };\n\n context.serializeValue = () => {\n const serializedValue: any[] = [];\n let idx = 0;\n while (idx < editors.length) {\n serializedValue[idx] = editors[idx].serializeValue();\n idx++;\n }\n return serializedValue;\n };\n\n context.applyValue = (item: any, state: any) => {\n let idx = 0;\n while (idx < editors.length) {\n editors[idx].applyValue(item, state[idx]);\n idx++;\n }\n };\n\n context.loadValue = (item: any) => {\n let idx = 0;\n\n while (idx < editors.length) {\n editors[idx].loadValue(item);\n idx++;\n }\n };\n\n context.validate = (target: HTMLElement | null) => {\n let validationResults;\n const errors: any[] = [];\n let targetElm = target ? target : null;\n\n firstInvalidEditor = null;\n\n let idx = 0;\n while (idx < editors.length) {\n const columnDef = editors[idx].args?.column ?? {};\n if (columnDef) {\n let validationElm = document.querySelector(`.item-details-validation.editor-${columnDef.id}`);\n let labelElm = document.querySelector(`.item-details-label.editor-${columnDef.id}`);\n let editorElm = document.querySelector(`[data-editorid=${columnDef.id}]`);\n const validationMsgPrefix = options?.validationMsgPrefix || '';\n\n if (!targetElm || Slick.Utils.contains(editorElm as HTMLElement, targetElm)) {\n validationResults = editors[idx].validate();\n\n if (!validationResults.valid) {\n firstInvalidEditor = editors[idx];\n errors.push({\n index: idx,\n editor: editors[idx],\n container: containers[idx],\n msg: validationResults.msg\n });\n\n if (validationElm) {\n validationElm.textContent = validationMsgPrefix + validationResults.msg;\n labelElm?.classList.add('invalid');\n editorElm?.classList.add('invalid');\n }\n } else if (validationElm) {\n validationElm.textContent = '';\n editorElm?.classList.remove('invalid');\n labelElm?.classList.remove('invalid');\n }\n }\n validationElm = null;\n labelElm = null;\n editorElm = null;\n }\n idx++;\n }\n targetElm = null;\n\n if (errors.length) {\n return {\n valid: false,\n msg: options.validationFailedMsg,\n errors: errors\n };\n } else {\n return {\n valid: true,\n msg: ''\n };\n }\n };\n\n context.hide = () => {\n let idx = 0;\n while (idx < editors.length) {\n editors[idx]?.hide?.();\n idx++;\n }\n options?.hide?.();\n };\n\n context.show = () => {\n let idx = 0;\n while (idx < editors.length) {\n editors[idx]?.show?.();\n idx++;\n }\n options?.show?.();\n };\n\n context.position = (box: HtmlElementPosition) => {\n options?.position?.(box);\n };\n\n init();\n }\n\n // so we can do \"editor instanceof Slick.CompositeEditor\n // @ts-ignore\n editor.prototype = this;\n return editor;\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(Slick, {\n CompositeEditor: SlickCompositeEditor\n });\n}\n"], + "sourcesContent": ["import type { Column, CompositeEditorOption, Editor, EditorArguments, HtmlElementPosition } from './models/index';\nimport { Utils as Utils_ } from './slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A composite SlickGrid editor factory.\n * Generates an editor that is composed of multiple editors for given columns.\n * Individual editors are provided given containers instead of the original cell.\n * Validation will be performed on all editors individually and the results will be aggregated into one\n * validation result.\n *\n *\n * The returned editor will have its prototype set to CompositeEditor, so you can use the \"instanceof\" check.\n *\n * NOTE: This doesn't work for detached editors since they will be created and positioned relative to the\n * active cell and not the provided container.\n *\n * @namespace Slick\n * @class CompositeEditor\n * @constructor\n * @param columns {Array} Column definitions from which editors will be pulled.\n * @param containers {Array} Container HTMLElements in which editors will be placed.\n * @param options {Object} Options hash:\n * validationFailedMsg - A generic failed validation message set on the aggregated validation resuls.\n * validationMsgPrefix - Add an optional prefix to each validation message (only the ones shown in the modal form, not the ones in the \"errors\")\n * modalType - Defaults to \"edit\", modal type can 1 of these 3: (create, edit, mass, mass-selection)\n * hide - A function to be called when the grid asks the editor to hide itself.\n * show - A function to be called when the grid asks the editor to show itself.\n * position - A function to be called when the grid asks the editor to reposition itself.\n * destroy - A function to be called when the editor is destroyed.\n */\nexport function SlickCompositeEditor(columns: Column[], containers: Array, options: CompositeEditorOption) {\n const defaultOptions = {\n modalType: 'edit', // available type (create, edit, mass)\n validationFailedMsg: 'Some of the fields have failed validation',\n validationMsgPrefix: null,\n show: null,\n hide: null,\n position: null,\n destroy: null,\n formValues: {},\n editors: {}\n };\n\n const noop = function () { };\n\n let firstInvalidEditor: Editor | null = null;\n\n options = Slick.Utils.extend({}, defaultOptions, options);\n\n function getContainerBox(i: number) {\n const c = containers[i];\n const offset = Slick.Utils.offset(c);\n const w = Slick.Utils.width(c);\n const h = Slick.Utils.height(c);\n\n return {\n top: (offset?.top ?? 0),\n left: (offset?.left ?? 0),\n bottom: (offset?.top ?? 0) + (h || 0),\n right: (offset?.left ?? 0) + (w || 0),\n width: w,\n height: h,\n visible: true\n };\n }\n\n function editor(args: any[]) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const context: any = this;\n let editors: Array = [];\n\n function init() {\n let newArgs: any = {};\n let idx = 0;\n while (idx < columns.length) {\n if (columns[idx].editor) {\n const column = columns[idx];\n newArgs = Slick.Utils.extend(false, {}, args);\n newArgs.container = containers[idx];\n newArgs.column = column;\n newArgs.position = getContainerBox(idx);\n newArgs.commitChanges = noop;\n newArgs.cancelChanges = noop;\n newArgs.compositeEditorOptions = options;\n newArgs.formValues = {};\n\n const currentEditor = new (column.editor as any)(newArgs) as Editor & { args: EditorArguments };\n options.editors[column.id] = currentEditor; // add every Editor instance refs\n editors.push(currentEditor);\n }\n idx++;\n }\n\n // focus on first input\n setTimeout(function () {\n if (Array.isArray(editors) && editors.length > 0 && typeof editors[0].focus === 'function') {\n editors[0].focus();\n }\n }, 0);\n }\n\n context.destroy = () => {\n let idx = 0;\n while (idx < editors.length) {\n editors[idx].destroy();\n idx++;\n }\n\n options.destroy?.();\n editors = [];\n };\n\n\n context.focus = () => {\n // if validation has failed, set the focus to the first invalid editor\n (firstInvalidEditor || editors[0]).focus();\n };\n\n context.isValueChanged = () => {\n let idx = 0;\n while (idx < editors.length) {\n if (editors[idx].isValueChanged()) {\n return true;\n }\n idx++;\n }\n return false;\n };\n\n context.serializeValue = () => {\n const serializedValue: any[] = [];\n let idx = 0;\n while (idx < editors.length) {\n serializedValue[idx] = editors[idx].serializeValue();\n idx++;\n }\n return serializedValue;\n };\n\n context.applyValue = (item: any, state: any) => {\n let idx = 0;\n while (idx < editors.length) {\n editors[idx].applyValue(item, state[idx]);\n idx++;\n }\n };\n\n context.loadValue = (item: any) => {\n let idx = 0;\n\n while (idx < editors.length) {\n editors[idx].loadValue(item);\n idx++;\n }\n };\n\n context.validate = (target: HTMLElement | null) => {\n let validationResults;\n const errors: any[] = [];\n let targetElm = target ? target : null;\n\n firstInvalidEditor = null;\n\n let idx = 0;\n while (idx < editors.length) {\n const columnDef = editors[idx].args?.column ?? {};\n if (columnDef) {\n let validationElm = document.querySelector(`.item-details-validation.editor-${columnDef.id}`);\n let labelElm = document.querySelector(`.item-details-label.editor-${columnDef.id}`);\n let editorElm = document.querySelector(`[data-editorid=${columnDef.id}]`);\n const validationMsgPrefix = options?.validationMsgPrefix || '';\n\n if (!targetElm || Slick.Utils.contains(editorElm as HTMLElement, targetElm)) {\n validationResults = editors[idx].validate();\n\n if (!validationResults.valid) {\n firstInvalidEditor = editors[idx];\n errors.push({\n index: idx,\n editor: editors[idx],\n container: containers[idx],\n msg: validationResults.msg\n });\n\n if (validationElm) {\n validationElm.textContent = validationMsgPrefix + validationResults.msg;\n labelElm?.classList.add('invalid');\n editorElm?.classList.add('invalid');\n }\n } else if (validationElm) {\n validationElm.textContent = '';\n editorElm?.classList.remove('invalid');\n labelElm?.classList.remove('invalid');\n }\n }\n validationElm = null;\n labelElm = null;\n editorElm = null;\n }\n idx++;\n }\n targetElm = null;\n\n if (errors.length) {\n return {\n valid: false,\n msg: options.validationFailedMsg,\n errors\n };\n } else {\n return {\n valid: true,\n msg: ''\n };\n }\n };\n\n context.hide = () => {\n let idx = 0;\n while (idx < editors.length) {\n editors[idx]?.hide?.();\n idx++;\n }\n options?.hide?.();\n };\n\n context.show = () => {\n let idx = 0;\n while (idx < editors.length) {\n editors[idx]?.show?.();\n idx++;\n }\n options?.show?.();\n };\n\n context.position = (box: HtmlElementPosition) => {\n options?.position?.(box);\n };\n\n init();\n }\n\n // so we can do \"editor instanceof Slick.CompositeEditor\n // @ts-ignore\n editor.prototype = this;\n return editor;\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(Slick, {\n CompositeEditor: SlickCompositeEditor\n });\n}\n"], "mappings": "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", "names": [] } diff --git a/dist/browser/slick.core.js b/dist/browser/slick.core.js index 91d011dc4..f92f8db59 100644 --- a/dist/browser/slick.core.js +++ b/dist/browser/slick.core.js @@ -208,7 +208,7 @@ var Slick = (() => { __publicField(this, "fromCell"); __publicField(this, "toCell"); __publicField(this, "toRow"); - toRow === void 0 && toCell === void 0 && (toRow = fromRow, toCell = fromCell), this.fromRow = Math.min(fromRow, toRow), this.fromCell = Math.min(fromCell, toCell), this.toRow = Math.max(fromRow, toRow), this.toCell = Math.max(fromCell, toCell); + toRow === void 0 && toCell === void 0 && (toRow = fromRow, toCell = fromCell), this.fromRow = Math.min(fromRow, toRow), this.fromCell = Math.min(fromCell, toCell), this.toCell = Math.max(fromCell, toCell), this.toRow = Math.max(fromRow, toRow); } /** * Returns whether a range represents a single row. @@ -216,7 +216,7 @@ var Slick = (() => { * @return {Boolean} */ isSingleRow() { - return this.fromRow == this.toRow; + return this.fromRow === this.toRow; } /** * Returns whether a range represents a single cell. @@ -224,7 +224,7 @@ var Slick = (() => { * @return {Boolean} */ isSingleCell() { - return this.fromRow == this.toRow && this.fromCell == this.toCell; + return this.fromRow === this.toRow && this.fromCell === this.toCell; } /** * Returns whether a range contains a given cell. @@ -463,7 +463,7 @@ var Slick = (() => { static extend(...args) { let options, name, src, copy, copyIsArray, clone, target = args[0], i = 1, deep = !1, length = args.length; for (typeof target == "boolean" ? (deep = target, target = args[i] || {}, i++) : target = target || {}, typeof target != "object" && !_Utils.isFunction(target) && (target = {}), i === length && (target = this, i--); i < length; i++) - if ((options = args[i]) != null) + if (_Utils.isDefined(options = args[i])) for (name in options) copy = options[name], !(name === "__proto__" || target === copy) && (deep && copy && (_Utils.isPlainObject(copy) || (copyIsArray = Array.isArray(copy))) ? (src = target[name], copyIsArray && !Array.isArray(src) ? clone = [] : !copyIsArray && !_Utils.isPlainObject(src) ? clone = {} : clone = src, copyIsArray = !1, target[name] = _Utils.extend(deep, clone, copy)) : copy !== void 0 && (target[name] = copy)); return target; @@ -503,6 +503,9 @@ var Slick = (() => { } return size; } + static isDefined(value) { + return value != null; + } static getElementProp(elm, property) { return elm != null && elm.getComputedStyle ? window.getComputedStyle(elm, null).getPropertyValue(property) : null; } @@ -544,13 +547,13 @@ var Slick = (() => { typeof val == "function" ? val = val() : typeof val == "string" ? el.style[style] = val : el.style[style] = val + "px"; } static contains(parent, child) { - return !parent || !child ? !1 : !_Utils.parents(child).every((p) => parent != p); + return !parent || !child ? !1 : !_Utils.parents(child).every((p) => parent !== p); } static isHidden(el) { return el.offsetWidth === 0 && el.offsetHeight === 0; } static parents(el, selector) { - let parents = [], visible = selector == ":visible", hidden = selector == ":hidden"; + let parents = [], visible = selector === ":visible", hidden = selector === ":hidden"; for (; (el = el.parentNode) && el !== document && !(!el || !el.parentNode); ) hidden ? _Utils.isHidden(el) && parents.push(el) : visible ? _Utils.isHidden(el) || parents.push(el) : (!selector || el.matches(selector)) && parents.push(el); return parents; @@ -589,13 +592,16 @@ var Slick = (() => { __publicField(_Utils, "getProto", Object.getPrototypeOf), __publicField(_Utils, "class2type", {}), __publicField(_Utils, "toString", _Utils.class2type.toString), __publicField(_Utils, "hasOwn", _Utils.class2type.hasOwnProperty), __publicField(_Utils, "fnToString", _Utils.hasOwn.toString), __publicField(_Utils, "ObjectFunctionString", _Utils.fnToString.call(Object)), __publicField(_Utils, "storage", { // https://stackoverflow.com/questions/29222027/vanilla-alternative-to-jquery-data-function-any-native-javascript-alternati _storage: /* @__PURE__ */ new WeakMap(), + // eslint-disable-next-line object-shorthand put: function(element, key, obj) { this._storage.has(element) || this._storage.set(element, /* @__PURE__ */ new Map()), this._storage.get(element).set(key, obj); }, + // eslint-disable-next-line object-shorthand get: function(element, key) { let el = this._storage.get(element); return el ? el.get(key) : null; }, + // eslint-disable-next-line object-shorthand remove: function(element, key) { let ret = this._storage.get(element).delete(key); return this._storage.get(element).size !== 0 && this._storage.delete(element), ret; diff --git a/dist/browser/slick.core.js.map b/dist/browser/slick.core.js.map index 508dafc63..5abbd4b2d 100644 --- a/dist/browser/slick.core.js.map +++ b/dist/browser/slick.core.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.core.ts"], - "sourcesContent": ["/**\n * Contains core SlickGrid classes.\n * @module Core\n * @namespace Slick\n */\n\nimport type {\n CSSStyleDeclarationWritable,\n EditController,\n ElementEventListener,\n Handler,\n InferDOMType,\n MergeTypes\n} from './models/index';\n\n/**\n * An event object for passing data to event handlers and letting them control propagation.\n *

This is pretty much identical to how W3C and jQuery implement events.

\n * @class EventData\n * @constructor\n */\nexport class SlickEventData {\n protected _isPropagationStopped = false;\n protected _isImmediatePropagationStopped = false;\n protected _isDefaultPrevented = false;\n protected returnValues: string[] = [];\n protected returnValue: any = undefined;\n protected target?: EventTarget | null;\n protected nativeEvent?: Event | null;\n protected arguments_: any;\n\n constructor(protected event?: Event | null, protected args?: any) {\n this.nativeEvent = event;\n this.arguments_ = args;\n\n // when we already have an event, we want to keep some of the event properties\n // looping through some props is the only way to keep and sync these properties to the returned EventData\n if (event) {\n const eventProps = [\n 'altKey', 'ctrlKey', 'metaKey', 'shiftKey', 'key', 'keyCode',\n 'clientX', 'clientY', 'offsetX', 'offsetY', 'pageX', 'pageY',\n 'bubbles', 'type', 'which', 'x', 'y'\n ];\n for (const key of eventProps) {\n (this as any)[key] = event[key as keyof Event];\n }\n }\n this.target = this.nativeEvent ? this.nativeEvent.target : undefined;\n }\n\n /**\n * Stops event from propagating up the DOM tree.\n * @method stopPropagation\n */\n stopPropagation() {\n this._isPropagationStopped = true;\n this.nativeEvent?.stopPropagation();\n }\n\n /**\n * Returns whether stopPropagation was called on this event object.\n * @method isPropagationStopped\n * @return {Boolean}\n */\n isPropagationStopped() {\n return this._isPropagationStopped;\n }\n\n /**\n * Prevents the rest of the handlers from being executed.\n * @method stopImmediatePropagation\n */\n stopImmediatePropagation() {\n this._isImmediatePropagationStopped = true;\n if (this.nativeEvent) {\n this.nativeEvent.stopImmediatePropagation();\n }\n };\n\n /**\n * Returns whether stopImmediatePropagation was called on this event object.\\\n * @method isImmediatePropagationStopped\n * @return {Boolean}\n */\n isImmediatePropagationStopped() {\n return this._isImmediatePropagationStopped;\n };\n\n getNativeEvent() {\n return this.nativeEvent as E;\n }\n\n preventDefault() {\n if (this.nativeEvent) {\n this.nativeEvent.preventDefault();\n }\n this._isDefaultPrevented = true;\n }\n\n isDefaultPrevented() {\n if (this.nativeEvent) {\n return this.nativeEvent.defaultPrevented;\n }\n return this._isDefaultPrevented;\n }\n\n addReturnValue(value: any) {\n this.returnValues.push(value);\n if (this.returnValue === undefined && value !== undefined) {\n this.returnValue = value;\n }\n }\n\n getReturnValue() {\n return this.returnValue;\n }\n\n getArguments() {\n return this.arguments_;\n }\n}\n\n/**\n * A simple publisher-subscriber implementation.\n * @class Event\n * @constructor\n */\nexport class SlickEvent {\n protected handlers: Handler[] = [];\n\n /**\n * Adds an event handler to be called when the event is fired.\n *

Event handler will receive two arguments - an EventData and the data\n * object the event was fired with.

\n * @method subscribe\n * @param fn {Function} Event handler.\n */\n subscribe(fn: Handler) {\n this.handlers.push(fn);\n }\n\n /**\n * Removes an event handler added with subscribe(fn).\n * @method unsubscribe\n * @param fn {Function} Event handler to be removed.\n */\n unsubscribe(fn?: Handler) {\n for (let i = this.handlers.length - 1; i >= 0; i--) {\n if (this.handlers[i] === fn) {\n this.handlers.splice(i, 1);\n }\n }\n }\n\n /**\n * Fires an event notifying all subscribers.\n * @method notify\n * @param args {Object} Additional data object to be passed to all handlers.\n * @param e {EventData}\n * Optional.\n * An EventData object to be passed to all handlers.\n * For DOM events, an existing W3C event object can be passed in.\n * @param scope {Object}\n * Optional.\n * The scope (\"this\") within which the handler will be executed.\n * If not specified, the scope will be set to the Event instance.\n */\n notify(args: ArgType, evt?: SlickEventData | Event | MergeTypes | null, scope?: any) {\n const sed: SlickEventData = evt instanceof SlickEventData\n ? evt\n : new SlickEventData(evt, args);\n scope = scope || this;\n\n for (let i = 0; i < this.handlers.length && !(sed.isPropagationStopped() || sed.isImmediatePropagationStopped()); i++) {\n const returnValue = this.handlers[i].call(scope, sed as SlickEvent | SlickEventData, args);\n sed.addReturnValue(returnValue);\n }\n\n return sed;\n }\n}\n\nexport class SlickEventHandler {\n protected handlers: Array<{ event: SlickEvent; handler: Handler; }> = [];\n\n subscribe(event: SlickEvent, handler: Handler) {\n this.handlers.push({ event, handler });\n event.subscribe(handler);\n\n return this; // allow chaining\n }\n\n unsubscribe(event: SlickEvent, handler: Handler) {\n let i = this.handlers.length;\n while (i--) {\n if (this.handlers[i].event === event &&\n this.handlers[i].handler === handler) {\n this.handlers.splice(i, 1);\n event.unsubscribe(handler);\n return;\n }\n }\n\n return this; // allow chaining\n }\n\n unsubscribeAll() {\n let i = this.handlers.length;\n while (i--) {\n this.handlers[i].event.unsubscribe(this.handlers[i].handler);\n }\n this.handlers = [];\n\n return this; // allow chaining\n }\n}\n\n/**\n * A structure containing a range of cells.\n * @class Range\n * @constructor\n * @param fromRow {Integer} Starting row.\n * @param fromCell {Integer} Starting cell.\n * @param toRow {Integer} Optional. Ending row. Defaults to fromRow.\n * @param toCell {Integer} Optional. Ending cell. Defaults to fromCell.\n */\nexport class SlickRange {\n fromRow: number;\n fromCell: number;\n toCell: number;\n toRow: number;\n\n constructor(fromRow: number, fromCell: number, toRow?: number, toCell?: number) {\n if (toRow === undefined && toCell === undefined) {\n toRow = fromRow;\n toCell = fromCell;\n }\n\n /**\n * @property fromRow\n * @type {Integer}\n */\n this.fromRow = Math.min(fromRow, toRow as number);\n\n /**\n * @property fromCell\n * @type {Integer}\n */\n this.fromCell = Math.min(fromCell, toCell as number);\n\n /**\n * @property toRow\n * @type {Integer}\n */\n this.toRow = Math.max(fromRow, toRow as number);\n\n /**\n * @property toCell\n * @type {Integer}\n */\n this.toCell = Math.max(fromCell, toCell as number);\n }\n\n\n /**\n * Returns whether a range represents a single row.\n * @method isSingleRow\n * @return {Boolean}\n */\n isSingleRow() {\n return this.fromRow == this.toRow;\n }\n\n /**\n * Returns whether a range represents a single cell.\n * @method isSingleCell\n * @return {Boolean}\n */\n isSingleCell() {\n return this.fromRow == this.toRow && this.fromCell == this.toCell;\n }\n\n /**\n * Returns whether a range contains a given cell.\n * @method contains\n * @param row {Integer}\n * @param cell {Integer}\n * @return {Boolean}\n */\n contains(row: number, cell: number) {\n return row >= this.fromRow && row <= this.toRow &&\n cell >= this.fromCell && cell <= this.toCell;\n }\n\n /**\n * Returns a readable representation of a range.\n * @method toString\n * @return {String}\n */\n toString() {\n if (this.isSingleCell()) {\n return `(${this.fromRow}:${this.fromCell})`;\n }\n else {\n return `(${this.fromRow}:${this.fromCell} - ${this.toRow}:${this.toCell})`;\n }\n };\n}\n\n\n/**\n * A base class that all special / non-data rows (like Group and GroupTotals) derive from.\n * @class NonDataItem\n * @constructor\n */\nexport class SlickNonDataItem {\n __nonDataRow = true;\n}\n\n\n/**\n * Information about a group of rows.\n * @class Group\n * @extends Slick.NonDataItem\n * @constructor\n */\nexport class SlickGroup extends SlickNonDataItem {\n __group = true;\n\n /**\n * Grouping level, starting with 0.\n * @property level\n * @type {Number}\n */\n level = 0;\n\n /**\n * Number of rows in the group.\n * @property count\n * @type {Integer}\n */\n count = 0;\n\n /**\n * Grouping value.\n * @property value\n * @type {Object}\n */\n value = null;\n\n /**\n * Formatted display value of the group.\n * @property title\n * @type {String}\n */\n title: string | null = null;\n\n /**\n * Whether a group is collapsed.\n * @property collapsed\n * @type {Boolean}\n */\n collapsed: boolean | number = false;\n\n /**\n * Whether a group selection checkbox is checked.\n * @property selectChecked\n * @type {Boolean}\n */\n selectChecked = false;\n\n /**\n * GroupTotals, if any.\n * @property totals\n * @type {GroupTotals}\n */\n totals: SlickGroupTotals = null as any;\n\n /**\n * Rows that are part of the group.\n * @property rows\n * @type {Array}\n */\n rows: number[] = [];\n\n /**\n * Sub-groups that are part of the group.\n * @property groups\n * @type {Array}\n */\n groups: any[] = null as any;\n\n /**\n * A unique key used to identify the group. This key can be used in calls to DataView\n * collapseGroup() or expandGroup().\n * @property groupingKey\n * @type {Object}\n */\n groupingKey: any = null;\n\n constructor() {\n super();\n }\n /**\n * Compares two Group instances.\n * @method equals\n * @return {Boolean}\n * @param group {Group} Group instance to compare to.\n */\n equals(group: SlickGroup): boolean {\n return this.value === group.value &&\n this.count === group.count &&\n this.collapsed === group.collapsed &&\n this.title === group.title;\n };\n}\n\n/**\n * Information about group totals.\n * An instance of GroupTotals will be created for each totals row and passed to the aggregators\n * so that they can store arbitrary data in it. That data can later be accessed by group totals\n * formatters during the display.\n * @class GroupTotals\n * @extends Slick.NonDataItem\n * @constructor\n */\nexport class SlickGroupTotals extends SlickNonDataItem {\n __groupTotals = true;\n\n /**\n * Parent Group.\n * @param group\n * @type {Group}\n */\n group: SlickGroup = null as any;\n\n /**\n * Whether the totals have been fully initialized / calculated.\n * Will be set to false for lazy-calculated group totals.\n * @param initialized\n * @type {Boolean}\n */\n initialized = false;\n\n constructor() {\n super();\n }\n}\n\n/**\n * A locking helper to track the active edit controller and ensure that only a single controller\n * can be active at a time. This prevents a whole class of state and validation synchronization\n * issues. An edit controller (such as SlickGrid) can query if an active edit is in progress\n * and attempt a commit or cancel before proceeding.\n * @class EditorLock\n * @constructor\n */\nexport class SlickEditorLock {\n activeEditController: any = null;\n\n /**\n * Returns true if a specified edit controller is active (has the edit lock).\n * If the parameter is not specified, returns true if any edit controller is active.\n * @method isActive\n * @param editController {EditController}\n * @return {Boolean}\n */\n isActive(editController?: EditController): boolean {\n return (editController ? this.activeEditController === editController : this.activeEditController !== null);\n };\n\n /**\n * Sets the specified edit controller as the active edit controller (acquire edit lock).\n * If another edit controller is already active, and exception will be throw new Error(.\n * @method activate\n * @param editController {EditController} edit controller acquiring the lock\n */\n activate(editController: EditController) {\n if (editController === this.activeEditController) { // already activated?\n return;\n }\n if (this.activeEditController !== null) {\n throw new Error(`Slick.EditorLock.activate: an editController is still active, can't activate another editController`);\n }\n if (!editController.commitCurrentEdit) {\n throw new Error('Slick.EditorLock.activate: editController must implement .commitCurrentEdit()');\n }\n if (!editController.cancelCurrentEdit) {\n throw new Error('Slick.EditorLock.activate: editController must implement .cancelCurrentEdit()');\n }\n this.activeEditController = editController;\n };\n\n /**\n * Unsets the specified edit controller as the active edit controller (release edit lock).\n * If the specified edit controller is not the active one, an exception will be throw new Error(.\n * @method deactivate\n * @param editController {EditController} edit controller releasing the lock\n */\n deactivate(editController: EditController) {\n if (!this.activeEditController) {\n return;\n }\n if (this.activeEditController !== editController) {\n throw new Error('Slick.EditorLock.deactivate: specified editController is not the currently active one');\n }\n this.activeEditController = null;\n };\n\n /**\n * Attempts to commit the current edit by calling \"commitCurrentEdit\" method on the active edit\n * controller and returns whether the commit attempt was successful (commit may fail due to validation\n * errors, etc.). Edit controller's \"commitCurrentEdit\" must return true if the commit has succeeded\n * and false otherwise. If no edit controller is active, returns true.\n * @method commitCurrentEdit\n * @return {Boolean}\n */\n commitCurrentEdit(): boolean {\n return (this.activeEditController ? this.activeEditController.commitCurrentEdit() : true);\n };\n\n /**\n * Attempts to cancel the current edit by calling \"cancelCurrentEdit\" method on the active edit\n * controller and returns whether the edit was successfully cancelled. If no edit controller is\n * active, returns true.\n * @method cancelCurrentEdit\n * @return {Boolean}\n */\n cancelCurrentEdit(): boolean {\n return (this.activeEditController ? this.activeEditController.cancelCurrentEdit() : true);\n };\n}\n\nfunction regexSanitizer(dirtyHtml: string) {\n return dirtyHtml.replace(/(\\b)(on[a-z]+)(\\s*)=|javascript:([^>]*)[^>]*|(<\\s*)(\\/*)script([<>]*).*(<\\s*)(\\/*)script(>*)|(<)(\\/*)(script|script defer)(.*)(>|>\">)/gi, '');\n}\n\n/**\n * A simple binding event service to keep track of all JavaScript events with callback listeners,\n * it allows us to unbind event(s) and their listener(s) by calling a simple unbind method call.\n * Unbinding is a necessary step to make sure that all event listeners are removed to avoid memory leaks when destroing the grid\n */\nexport class BindingEventService {\n protected _boundedEvents: ElementEventListener[] = [];\n\n getBoundedEvents() {\n return this._boundedEvents;\n }\n\n destroy() {\n this.unbindAll();\n }\n\n /** Bind an event listener to any element */\n bind(element: Element | Window, eventName: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) {\n element.addEventListener(eventName, listener, options);\n this._boundedEvents.push({ element, eventName, listener });\n }\n\n /** Unbind all will remove every every event handlers that were bounded earlier */\n unbind(element: Element | Window, eventName: string, listener: EventListenerOrEventListenerObject) {\n if (element?.removeEventListener) {\n element.removeEventListener(eventName, listener);\n }\n }\n\n unbindByEventName(element: Element | Window, eventName: string) {\n const boundedEvent = this._boundedEvents.find(e => e.element === element && e.eventName === eventName);\n if (boundedEvent) {\n this.unbind(boundedEvent.element, boundedEvent.eventName, boundedEvent.listener);\n }\n }\n\n /** Unbind all will remove every every event handlers that were bounded earlier */\n unbindAll() {\n while (this._boundedEvents.length > 0) {\n const boundedEvent = this._boundedEvents.pop() as ElementEventListener;\n this.unbind(boundedEvent.element, boundedEvent.eventName, boundedEvent.listener);\n }\n }\n}\n\nexport class Utils {\n // jQuery's extend\n private static getProto = Object.getPrototypeOf;\n private static class2type: any = {};\n private static toString = Utils.class2type.toString;\n private static hasOwn = Utils.class2type.hasOwnProperty;\n private static fnToString = Utils.hasOwn.toString;\n private static ObjectFunctionString = Utils.fnToString.call(Object);\n public static storage = {\n // https://stackoverflow.com/questions/29222027/vanilla-alternative-to-jquery-data-function-any-native-javascript-alternati\n _storage: new WeakMap(),\n put: function (element: any, key: string, obj: any) {\n if (!this._storage.has(element)) {\n this._storage.set(element, new Map());\n }\n this._storage.get(element).set(key, obj);\n },\n get: function (element: any, key: string) {\n const el = this._storage.get(element);\n if (el) {\n return el.get(key);\n }\n return null;\n },\n remove: function (element: any, key: string) {\n const ret = this._storage.get(element).delete(key);\n if (!(this._storage.get(element).size === 0)) {\n this._storage.delete(element);\n }\n return ret;\n }\n }\n\n public static isFunction(obj: any) {\n return typeof obj === 'function' && typeof obj.nodeType !== 'number' &&\n typeof obj.item !== 'function';\n }\n\n public static isPlainObject(obj: any) {\n if (!obj || Utils.toString.call(obj) !== '[object Object]') {\n return false;\n }\n\n const proto = Utils.getProto(obj);\n if (!proto) {\n return true;\n }\n const Ctor = Utils.hasOwn.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor === 'function' && Utils.fnToString.call(Ctor) === Utils.ObjectFunctionString;\n }\n\n public static calculateAvailableSpace(element: HTMLElement) {\n let bottom = 0, top = 0, left = 0, right = 0;\n\n const windowHeight = window.innerHeight || 0;\n const windowWidth = window.innerWidth || 0;\n const scrollPosition = Utils.windowScrollPosition();\n const pageScrollTop = scrollPosition.top;\n const pageScrollLeft = scrollPosition.left;\n const elmOffset = Utils.offset(element);\n\n if (elmOffset) {\n const elementOffsetTop = elmOffset.top || 0;\n const elementOffsetLeft = elmOffset.left || 0;\n top = elementOffsetTop - pageScrollTop;\n bottom = windowHeight - (elementOffsetTop - pageScrollTop);\n left = elementOffsetLeft - pageScrollLeft;\n right = windowWidth - (elementOffsetLeft - pageScrollLeft);\n }\n\n return { top, bottom, left, right };\n }\n\n public static extend(...args: any[]): T {\n let options, name, src, copy, copyIsArray, clone,\n target = args[0],\n i = 1,\n deep = false;\n const length = args.length;\n\n if (typeof target === 'boolean') {\n deep = target;\n target = args[i] || {};\n i++;\n } else {\n target = target || {};\n }\n if (typeof target !== 'object' && !Utils.isFunction(target)) {\n target = {};\n }\n if (i === length) {\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n target = this;\n i--;\n }\n for (; i < length; i++) {\n if ((options = args[i]) != null) {\n for (name in options) {\n copy = options[name];\n if (name === '__proto__' || target === copy) {\n continue;\n }\n if (deep && copy && (Utils.isPlainObject(copy) ||\n (copyIsArray = Array.isArray(copy)))) {\n src = target[name];\n if (copyIsArray && !Array.isArray(src)) {\n clone = [];\n } else if (!copyIsArray && !Utils.isPlainObject(src)) {\n clone = {};\n } else {\n clone = src;\n }\n copyIsArray = false;\n target[name] = Utils.extend(deep, clone, copy);\n } else if (copy !== undefined) {\n target[name] = copy;\n }\n }\n }\n }\n return target as T;\n }\n\n /**\n * Create a DOM Element with any optional attributes or properties.\n * It will only accept valid DOM element properties that `createElement` would accept.\n * For example: `createDomElement('div', { className: 'my-css-class' })`,\n * for style or dataset you need to use nested object `{ style: { display: 'none' }}\n * The last argument is to optionally append the created element to a parent container element.\n * @param {String} tagName - html tag\n * @param {Object} options - element properties\n * @param {[HTMLElement]} appendToParent - parent element to append to\n */\n public static createDomElement(\n tagName: T,\n elementOptions?: null | { [P in K]: InferDOMType },\n appendToParent?: Element\n ): HTMLElementTagNameMap[T] {\n const elm = document.createElement(tagName);\n\n if (elementOptions) {\n Object.keys(elementOptions).forEach((elmOptionKey) => {\n const elmValue = elementOptions[elmOptionKey as keyof typeof elementOptions];\n if (typeof elmValue === 'object') {\n Object.assign(elm[elmOptionKey as K] as object, elmValue);\n } else {\n elm[elmOptionKey as K] = (elementOptions as any)[elmOptionKey as keyof typeof elementOptions];\n }\n });\n }\n if (appendToParent?.appendChild) {\n appendToParent.appendChild(elm);\n }\n return elm;\n }\n\n public static emptyElement(element: HTMLElement | null) {\n if (element?.firstChild) {\n while (element.firstChild) {\n if (element.lastChild) {\n element.removeChild(element.lastChild);\n }\n }\n }\n return element;\n }\n\n public static innerSize(elm: HTMLElement, type: 'height' | 'width') {\n let size = 0;\n\n if (elm) {\n const clientSize = type === 'height' ? 'clientHeight' : 'clientWidth';\n const sides = type === 'height' ? ['top', 'bottom'] : ['left', 'right'];\n size = elm[clientSize];\n for (const side of sides) {\n const sideSize = (parseFloat(Utils.getElementProp(elm, `padding-${side}`) || '') || 0);\n size -= sideSize;\n }\n }\n return size;\n }\n\n public static getElementProp(elm: HTMLElement & { getComputedStyle?: () => CSSStyleDeclaration }, property: string) {\n if (elm?.getComputedStyle) {\n return window.getComputedStyle(elm, null).getPropertyValue(property);\n }\n return null;\n }\n\n public static isEmptyObject(obj: any) {\n if (obj === null || obj === undefined) {\n return true;\n }\n return Object.entries(obj).length === 0;\n }\n\n public static noop() { }\n\n public static offset(el: HTMLElement | null) {\n if (!el || !el.getBoundingClientRect) {\n return undefined;\n }\n const box = el.getBoundingClientRect();\n const docElem = document.documentElement;\n\n return {\n top: box.top + window.pageYOffset - docElem.clientTop,\n left: box.left + window.pageXOffset - docElem.clientLeft\n };\n }\n\n public static windowScrollPosition() {\n return {\n left: window.pageXOffset || document.documentElement.scrollLeft || 0,\n top: window.pageYOffset || document.documentElement.scrollTop || 0,\n };\n }\n\n public static width(el: HTMLElement, value?: number | string): number | void {\n if (!el || !el.getBoundingClientRect) return;\n if (value === undefined) {\n return el.getBoundingClientRect().width;\n }\n Utils.setStyleSize(el, 'width', value);\n }\n\n public static height(el: HTMLElement, value?: number | string): number | void {\n if (!el) return;\n if (value === undefined) {\n return el.getBoundingClientRect().height;\n }\n Utils.setStyleSize(el, 'height', value);\n }\n\n public static setStyleSize(el: HTMLElement, style: string, val?: number | string | Function) {\n if (typeof val === 'function') {\n val = val();\n } else if (typeof val === 'string') {\n el.style[style as CSSStyleDeclarationWritable] = val;\n } else {\n el.style[style as CSSStyleDeclarationWritable] = val + 'px';\n }\n }\n\n public static contains(parent: HTMLElement, child: HTMLElement) {\n if (!parent || !child) {\n return false;\n }\n\n const parentList = Utils.parents(child);\n return !parentList.every((p) => {\n if (parent == p) {\n return false;\n }\n return true;\n });\n }\n\n public static isHidden(el: HTMLElement) {\n return el.offsetWidth === 0 && el.offsetHeight === 0;\n }\n\n public static parents(el: HTMLElement | ParentNode, selector?: string) {\n const parents: Array = [];\n const visible = selector == ':visible';\n const hidden = selector == ':hidden';\n\n while ((el = el.parentNode as ParentNode) && el !== document) {\n if (!el || !el.parentNode) {\n break;\n }\n if (hidden) {\n if (Utils.isHidden(el as HTMLElement)) {\n parents.push(el);\n }\n } else if (visible) {\n if (!Utils.isHidden(el as HTMLElement)) {\n parents.push(el);\n }\n } else if (!selector || (el as any).matches(selector)) {\n parents.push(el);\n }\n }\n return parents;\n }\n\n public static toFloat(value: string | number) {\n const x = parseFloat(value as string);\n if (isNaN(x)) {\n return 0;\n }\n return x;\n }\n\n public static show(el: HTMLElement | HTMLElement[], type = '') {\n if (Array.isArray(el)) {\n el.forEach((e) => e.style.display = type)\n } else {\n el.style.display = type;\n }\n }\n\n public static hide(el: HTMLElement | HTMLElement[]) {\n if (Array.isArray(el)) {\n el.forEach(function (e) {\n e.style.display = 'none';\n });\n } else {\n el.style.display = 'none';\n }\n }\n\n public static slideUp(el: HTMLElement | HTMLElement[], callback: Function) {\n return Utils.slideAnimation(el, 'slideUp', callback);\n }\n\n public static slideDown(el: HTMLElement | HTMLElement[], callback: Function) {\n return Utils.slideAnimation(el, 'slideDown', callback);\n }\n\n public static slideAnimation(el: HTMLElement | HTMLElement[], slideDirection: 'slideDown' | 'slideUp', callback: Function) {\n if ((window as any).jQuery !== undefined) {\n (window as any).jQuery(el)[slideDirection]('fast', callback);\n return;\n }\n (slideDirection === 'slideUp') ? Utils.hide(el) : Utils.show(el);\n callback();\n }\n\n public static applyDefaults(targetObj: any, srcObj: any) {\n for (const key in srcObj) {\n if (srcObj.hasOwnProperty(key) && !targetObj.hasOwnProperty(key)) {\n targetObj[key] = srcObj[key];\n }\n }\n }\n}\n\nexport const SlickGlobalEditorLock = new SlickEditorLock();\n\n// export Slick namespace on both global & window objects\nconst SlickCore = {\n Event: SlickEvent,\n EventData: SlickEventData,\n EventHandler: SlickEventHandler,\n Range: SlickRange,\n NonDataRow: SlickNonDataItem,\n Group: SlickGroup,\n GroupTotals: SlickGroupTotals,\n EditorLock: SlickEditorLock,\n RegexSanitizer: regexSanitizer,\n\n /**\n * A global singleton editor lock.\n * @class GlobalEditorLock\n * @static\n * @constructor\n */\n GlobalEditorLock: SlickGlobalEditorLock,\n\n keyCode: {\n SPACE: 8,\n BACKSPACE: 8,\n DELETE: 46,\n DOWN: 40,\n END: 35,\n ENTER: 13,\n ESCAPE: 27,\n HOME: 36,\n INSERT: 45,\n LEFT: 37,\n PAGE_DOWN: 34,\n PAGE_UP: 33,\n RIGHT: 39,\n TAB: 9,\n UP: 38,\n A: 65\n },\n preClickClassName: 'slick-edit-preclick',\n\n GridAutosizeColsMode: {\n None: 'NOA',\n LegacyOff: 'LOF',\n LegacyForceFit: 'LFF',\n IgnoreViewport: 'IGV',\n FitColsToViewport: 'FCV',\n FitViewportToCols: 'FVC'\n },\n\n 'ColAutosizeMode': {\n Locked: 'LCK',\n Guide: 'GUI',\n Content: 'CON',\n ContentExpandOnly: 'CXO',\n ContentIntelligent: 'CTI'\n },\n\n 'RowSelectionMode': {\n FirstRow: 'FS1',\n FirstNRows: 'FSN',\n AllRows: 'ALL',\n LastRow: 'LS1'\n },\n\n 'ValueFilterMode': {\n None: 'NONE',\n DeDuplicate: 'DEDP',\n GetGreatestAndSub: 'GR8T',\n GetLongestTextAndSub: 'LNSB',\n GetLongestText: 'LNSC'\n },\n\n WidthEvalMode: {\n Auto: 'AUTO',\n TextOnly: 'CANV',\n HTML: 'HTML'\n }\n}\n\nexport const {\n EditorLock, Event, EventData, EventHandler, Group, GroupTotals, NonDataRow, Range,\n RegexSanitizer, GlobalEditorLock, keyCode, preClickClassName, GridAutosizeColsMode, ColAutosizeMode,\n RowSelectionMode, ValueFilterMode, WidthEvalMode\n} = SlickCore;\n\n/* eslint-disable no-undef */\n// also add to global object when exist\nif (IIFE_ONLY && typeof global !== 'undefined' && window.Slick) {\n global.Slick = window.Slick;\n}\n/* eslint-enable no-undef */\n"], - "mappings": "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", + "sourcesContent": ["/**\n * Contains core SlickGrid classes.\n * @module Core\n * @namespace Slick\n */\n\nimport type {\n CSSStyleDeclarationWritable,\n EditController,\n ElementEventListener,\n Handler,\n InferDOMType,\n MergeTypes\n} from './models/index';\n\n/**\n * An event object for passing data to event handlers and letting them control propagation.\n *

This is pretty much identical to how W3C and jQuery implement events.

\n * @class EventData\n * @constructor\n */\nexport class SlickEventData {\n protected _isPropagationStopped = false;\n protected _isImmediatePropagationStopped = false;\n protected _isDefaultPrevented = false;\n protected returnValues: string[] = [];\n protected returnValue: any = undefined;\n protected target?: EventTarget | null;\n protected nativeEvent?: Event | null;\n protected arguments_: any;\n\n constructor(protected event?: Event | null, protected args?: any) {\n this.nativeEvent = event;\n this.arguments_ = args;\n\n // when we already have an event, we want to keep some of the event properties\n // looping through some props is the only way to keep and sync these properties to the returned EventData\n if (event) {\n const eventProps = [\n 'altKey', 'ctrlKey', 'metaKey', 'shiftKey', 'key', 'keyCode',\n 'clientX', 'clientY', 'offsetX', 'offsetY', 'pageX', 'pageY',\n 'bubbles', 'type', 'which', 'x', 'y'\n ];\n for (const key of eventProps) {\n (this as any)[key] = event[key as keyof Event];\n }\n }\n this.target = this.nativeEvent ? this.nativeEvent.target : undefined;\n }\n\n /**\n * Stops event from propagating up the DOM tree.\n * @method stopPropagation\n */\n stopPropagation() {\n this._isPropagationStopped = true;\n this.nativeEvent?.stopPropagation();\n }\n\n /**\n * Returns whether stopPropagation was called on this event object.\n * @method isPropagationStopped\n * @return {Boolean}\n */\n isPropagationStopped() {\n return this._isPropagationStopped;\n }\n\n /**\n * Prevents the rest of the handlers from being executed.\n * @method stopImmediatePropagation\n */\n stopImmediatePropagation() {\n this._isImmediatePropagationStopped = true;\n if (this.nativeEvent) {\n this.nativeEvent.stopImmediatePropagation();\n }\n };\n\n /**\n * Returns whether stopImmediatePropagation was called on this event object.\\\n * @method isImmediatePropagationStopped\n * @return {Boolean}\n */\n isImmediatePropagationStopped() {\n return this._isImmediatePropagationStopped;\n };\n\n getNativeEvent() {\n return this.nativeEvent as E;\n }\n\n preventDefault() {\n if (this.nativeEvent) {\n this.nativeEvent.preventDefault();\n }\n this._isDefaultPrevented = true;\n }\n\n isDefaultPrevented() {\n if (this.nativeEvent) {\n return this.nativeEvent.defaultPrevented;\n }\n return this._isDefaultPrevented;\n }\n\n addReturnValue(value: any) {\n this.returnValues.push(value);\n if (this.returnValue === undefined && value !== undefined) {\n this.returnValue = value;\n }\n }\n\n getReturnValue() {\n return this.returnValue;\n }\n\n getArguments() {\n return this.arguments_;\n }\n}\n\n/**\n * A simple publisher-subscriber implementation.\n * @class Event\n * @constructor\n */\nexport class SlickEvent {\n protected handlers: Handler[] = [];\n\n /**\n * Adds an event handler to be called when the event is fired.\n *

Event handler will receive two arguments - an EventData and the data\n * object the event was fired with.

\n * @method subscribe\n * @param fn {Function} Event handler.\n */\n subscribe(fn: Handler) {\n this.handlers.push(fn);\n }\n\n /**\n * Removes an event handler added with subscribe(fn).\n * @method unsubscribe\n * @param fn {Function} Event handler to be removed.\n */\n unsubscribe(fn?: Handler) {\n for (let i = this.handlers.length - 1; i >= 0; i--) {\n if (this.handlers[i] === fn) {\n this.handlers.splice(i, 1);\n }\n }\n }\n\n /**\n * Fires an event notifying all subscribers.\n * @method notify\n * @param args {Object} Additional data object to be passed to all handlers.\n * @param e {EventData}\n * Optional.\n * An EventData object to be passed to all handlers.\n * For DOM events, an existing W3C event object can be passed in.\n * @param scope {Object}\n * Optional.\n * The scope (\"this\") within which the handler will be executed.\n * If not specified, the scope will be set to the Event instance.\n */\n notify(args: ArgType, evt?: SlickEventData | Event | MergeTypes | null, scope?: any) {\n const sed: SlickEventData = evt instanceof SlickEventData\n ? evt\n : new SlickEventData(evt, args);\n scope = scope || this;\n\n for (let i = 0; i < this.handlers.length && !(sed.isPropagationStopped() || sed.isImmediatePropagationStopped()); i++) {\n const returnValue = this.handlers[i].call(scope, sed as SlickEvent | SlickEventData, args);\n sed.addReturnValue(returnValue);\n }\n\n return sed;\n }\n}\n\nexport class SlickEventHandler {\n protected handlers: Array<{ event: SlickEvent; handler: Handler; }> = [];\n\n subscribe(event: SlickEvent, handler: Handler) {\n this.handlers.push({ event, handler });\n event.subscribe(handler);\n\n return this; // allow chaining\n }\n\n unsubscribe(event: SlickEvent, handler: Handler) {\n let i = this.handlers.length;\n while (i--) {\n if (this.handlers[i].event === event &&\n this.handlers[i].handler === handler) {\n this.handlers.splice(i, 1);\n event.unsubscribe(handler);\n return;\n }\n }\n\n return this; // allow chaining\n }\n\n unsubscribeAll() {\n let i = this.handlers.length;\n while (i--) {\n this.handlers[i].event.unsubscribe(this.handlers[i].handler);\n }\n this.handlers = [];\n\n return this; // allow chaining\n }\n}\n\n/**\n * A structure containing a range of cells.\n * @class Range\n * @constructor\n * @param fromRow {Integer} Starting row.\n * @param fromCell {Integer} Starting cell.\n * @param toRow {Integer} Optional. Ending row. Defaults to fromRow.\n * @param toCell {Integer} Optional. Ending cell. Defaults to fromCell.\n */\nexport class SlickRange {\n fromRow: number;\n fromCell: number;\n toCell: number;\n toRow: number;\n\n constructor(fromRow: number, fromCell: number, toRow?: number, toCell?: number) {\n if (toRow === undefined && toCell === undefined) {\n toRow = fromRow;\n toCell = fromCell;\n }\n\n /**\n * @property fromRow\n * @type {Integer}\n */\n this.fromRow = Math.min(fromRow, toRow as number);\n\n /**\n * @property fromCell\n * @type {Integer}\n */\n this.fromCell = Math.min(fromCell, toCell as number);\n\n /**\n * @property toCell\n * @type {Integer}\n */\n this.toCell = Math.max(fromCell, toCell as number);\n\n /**\n * @property toRow\n * @type {Integer}\n */\n this.toRow = Math.max(fromRow, toRow as number);\n }\n\n\n /**\n * Returns whether a range represents a single row.\n * @method isSingleRow\n * @return {Boolean}\n */\n isSingleRow() {\n return this.fromRow === this.toRow;\n }\n\n /**\n * Returns whether a range represents a single cell.\n * @method isSingleCell\n * @return {Boolean}\n */\n isSingleCell() {\n return this.fromRow === this.toRow && this.fromCell === this.toCell;\n }\n\n /**\n * Returns whether a range contains a given cell.\n * @method contains\n * @param row {Integer}\n * @param cell {Integer}\n * @return {Boolean}\n */\n contains(row: number, cell: number) {\n return row >= this.fromRow && row <= this.toRow &&\n cell >= this.fromCell && cell <= this.toCell;\n }\n\n /**\n * Returns a readable representation of a range.\n * @method toString\n * @return {String}\n */\n toString() {\n if (this.isSingleCell()) {\n return `(${this.fromRow}:${this.fromCell})`;\n }\n else {\n return `(${this.fromRow}:${this.fromCell} - ${this.toRow}:${this.toCell})`;\n }\n };\n}\n\n\n/**\n * A base class that all special / non-data rows (like Group and GroupTotals) derive from.\n * @class NonDataItem\n * @constructor\n */\nexport class SlickNonDataItem {\n __nonDataRow = true;\n}\n\n\n/**\n * Information about a group of rows.\n * @class Group\n * @extends Slick.NonDataItem\n * @constructor\n */\nexport class SlickGroup extends SlickNonDataItem {\n __group = true;\n\n /**\n * Grouping level, starting with 0.\n * @property level\n * @type {Number}\n */\n level = 0;\n\n /**\n * Number of rows in the group.\n * @property count\n * @type {Integer}\n */\n count = 0;\n\n /**\n * Grouping value.\n * @property value\n * @type {Object}\n */\n value = null;\n\n /**\n * Formatted display value of the group.\n * @property title\n * @type {String}\n */\n title: string | null = null;\n\n /**\n * Whether a group is collapsed.\n * @property collapsed\n * @type {Boolean}\n */\n collapsed: boolean | number = false;\n\n /**\n * Whether a group selection checkbox is checked.\n * @property selectChecked\n * @type {Boolean}\n */\n selectChecked = false;\n\n /**\n * GroupTotals, if any.\n * @property totals\n * @type {GroupTotals}\n */\n totals: SlickGroupTotals = null as any;\n\n /**\n * Rows that are part of the group.\n * @property rows\n * @type {Array}\n */\n rows: number[] = [];\n\n /**\n * Sub-groups that are part of the group.\n * @property groups\n * @type {Array}\n */\n groups: any[] = null as any;\n\n /**\n * A unique key used to identify the group. This key can be used in calls to DataView\n * collapseGroup() or expandGroup().\n * @property groupingKey\n * @type {Object}\n */\n groupingKey: any = null;\n\n constructor() {\n super();\n }\n /**\n * Compares two Group instances.\n * @method equals\n * @return {Boolean}\n * @param group {Group} Group instance to compare to.\n */\n equals(group: SlickGroup): boolean {\n return this.value === group.value &&\n this.count === group.count &&\n this.collapsed === group.collapsed &&\n this.title === group.title;\n };\n}\n\n/**\n * Information about group totals.\n * An instance of GroupTotals will be created for each totals row and passed to the aggregators\n * so that they can store arbitrary data in it. That data can later be accessed by group totals\n * formatters during the display.\n * @class GroupTotals\n * @extends Slick.NonDataItem\n * @constructor\n */\nexport class SlickGroupTotals extends SlickNonDataItem {\n __groupTotals = true;\n\n /**\n * Parent Group.\n * @param group\n * @type {Group}\n */\n group: SlickGroup = null as any;\n\n /**\n * Whether the totals have been fully initialized / calculated.\n * Will be set to false for lazy-calculated group totals.\n * @param initialized\n * @type {Boolean}\n */\n initialized = false;\n\n constructor() {\n super();\n }\n}\n\n/**\n * A locking helper to track the active edit controller and ensure that only a single controller\n * can be active at a time. This prevents a whole class of state and validation synchronization\n * issues. An edit controller (such as SlickGrid) can query if an active edit is in progress\n * and attempt a commit or cancel before proceeding.\n * @class EditorLock\n * @constructor\n */\nexport class SlickEditorLock {\n activeEditController: any = null;\n\n /**\n * Returns true if a specified edit controller is active (has the edit lock).\n * If the parameter is not specified, returns true if any edit controller is active.\n * @method isActive\n * @param editController {EditController}\n * @return {Boolean}\n */\n isActive(editController?: EditController): boolean {\n return (editController ? this.activeEditController === editController : this.activeEditController !== null);\n };\n\n /**\n * Sets the specified edit controller as the active edit controller (acquire edit lock).\n * If another edit controller is already active, and exception will be throw new Error(.\n * @method activate\n * @param editController {EditController} edit controller acquiring the lock\n */\n activate(editController: EditController) {\n if (editController === this.activeEditController) { // already activated?\n return;\n }\n if (this.activeEditController !== null) {\n throw new Error(`Slick.EditorLock.activate: an editController is still active, can't activate another editController`);\n }\n if (!editController.commitCurrentEdit) {\n throw new Error('Slick.EditorLock.activate: editController must implement .commitCurrentEdit()');\n }\n if (!editController.cancelCurrentEdit) {\n throw new Error('Slick.EditorLock.activate: editController must implement .cancelCurrentEdit()');\n }\n this.activeEditController = editController;\n };\n\n /**\n * Unsets the specified edit controller as the active edit controller (release edit lock).\n * If the specified edit controller is not the active one, an exception will be throw new Error(.\n * @method deactivate\n * @param editController {EditController} edit controller releasing the lock\n */\n deactivate(editController: EditController) {\n if (!this.activeEditController) {\n return;\n }\n if (this.activeEditController !== editController) {\n throw new Error('Slick.EditorLock.deactivate: specified editController is not the currently active one');\n }\n this.activeEditController = null;\n };\n\n /**\n * Attempts to commit the current edit by calling \"commitCurrentEdit\" method on the active edit\n * controller and returns whether the commit attempt was successful (commit may fail due to validation\n * errors, etc.). Edit controller's \"commitCurrentEdit\" must return true if the commit has succeeded\n * and false otherwise. If no edit controller is active, returns true.\n * @method commitCurrentEdit\n * @return {Boolean}\n */\n commitCurrentEdit(): boolean {\n return (this.activeEditController ? this.activeEditController.commitCurrentEdit() : true);\n };\n\n /**\n * Attempts to cancel the current edit by calling \"cancelCurrentEdit\" method on the active edit\n * controller and returns whether the edit was successfully cancelled. If no edit controller is\n * active, returns true.\n * @method cancelCurrentEdit\n * @return {Boolean}\n */\n cancelCurrentEdit(): boolean {\n return (this.activeEditController ? this.activeEditController.cancelCurrentEdit() : true);\n };\n}\n\nfunction regexSanitizer(dirtyHtml: string) {\n return dirtyHtml.replace(/(\\b)(on[a-z]+)(\\s*)=|javascript:([^>]*)[^>]*|(<\\s*)(\\/*)script([<>]*).*(<\\s*)(\\/*)script(>*)|(<)(\\/*)(script|script defer)(.*)(>|>\">)/gi, '');\n}\n\n/**\n * A simple binding event service to keep track of all JavaScript events with callback listeners,\n * it allows us to unbind event(s) and their listener(s) by calling a simple unbind method call.\n * Unbinding is a necessary step to make sure that all event listeners are removed to avoid memory leaks when destroing the grid\n */\nexport class BindingEventService {\n protected _boundedEvents: ElementEventListener[] = [];\n\n getBoundedEvents() {\n return this._boundedEvents;\n }\n\n destroy() {\n this.unbindAll();\n }\n\n /** Bind an event listener to any element */\n bind(element: Element | Window, eventName: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) {\n element.addEventListener(eventName, listener, options);\n this._boundedEvents.push({ element, eventName, listener });\n }\n\n /** Unbind all will remove every every event handlers that were bounded earlier */\n unbind(element: Element | Window, eventName: string, listener: EventListenerOrEventListenerObject) {\n if (element?.removeEventListener) {\n element.removeEventListener(eventName, listener);\n }\n }\n\n unbindByEventName(element: Element | Window, eventName: string) {\n const boundedEvent = this._boundedEvents.find(e => e.element === element && e.eventName === eventName);\n if (boundedEvent) {\n this.unbind(boundedEvent.element, boundedEvent.eventName, boundedEvent.listener);\n }\n }\n\n /** Unbind all will remove every every event handlers that were bounded earlier */\n unbindAll() {\n while (this._boundedEvents.length > 0) {\n const boundedEvent = this._boundedEvents.pop() as ElementEventListener;\n this.unbind(boundedEvent.element, boundedEvent.eventName, boundedEvent.listener);\n }\n }\n}\n\nexport class Utils {\n // jQuery's extend\n private static getProto = Object.getPrototypeOf;\n private static class2type: any = {};\n private static toString = Utils.class2type.toString;\n private static hasOwn = Utils.class2type.hasOwnProperty;\n private static fnToString = Utils.hasOwn.toString;\n private static ObjectFunctionString = Utils.fnToString.call(Object);\n public static storage = {\n // https://stackoverflow.com/questions/29222027/vanilla-alternative-to-jquery-data-function-any-native-javascript-alternati\n _storage: new WeakMap(),\n // eslint-disable-next-line object-shorthand\n put: function (element: any, key: string, obj: any) {\n if (!this._storage.has(element)) {\n this._storage.set(element, new Map());\n }\n this._storage.get(element).set(key, obj);\n },\n // eslint-disable-next-line object-shorthand\n get: function (element: any, key: string) {\n const el = this._storage.get(element);\n if (el) {\n return el.get(key);\n }\n return null;\n },\n // eslint-disable-next-line object-shorthand\n remove: function (element: any, key: string) {\n const ret = this._storage.get(element).delete(key);\n if (!(this._storage.get(element).size === 0)) {\n this._storage.delete(element);\n }\n return ret;\n }\n };\n\n public static isFunction(obj: any) {\n return typeof obj === 'function' && typeof obj.nodeType !== 'number' &&\n typeof obj.item !== 'function';\n }\n\n public static isPlainObject(obj: any) {\n if (!obj || Utils.toString.call(obj) !== '[object Object]') {\n return false;\n }\n\n const proto = Utils.getProto(obj);\n if (!proto) {\n return true;\n }\n const Ctor = Utils.hasOwn.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor === 'function' && Utils.fnToString.call(Ctor) === Utils.ObjectFunctionString;\n }\n\n public static calculateAvailableSpace(element: HTMLElement) {\n let bottom = 0, top = 0, left = 0, right = 0;\n\n const windowHeight = window.innerHeight || 0;\n const windowWidth = window.innerWidth || 0;\n const scrollPosition = Utils.windowScrollPosition();\n const pageScrollTop = scrollPosition.top;\n const pageScrollLeft = scrollPosition.left;\n const elmOffset = Utils.offset(element);\n\n if (elmOffset) {\n const elementOffsetTop = elmOffset.top || 0;\n const elementOffsetLeft = elmOffset.left || 0;\n top = elementOffsetTop - pageScrollTop;\n bottom = windowHeight - (elementOffsetTop - pageScrollTop);\n left = elementOffsetLeft - pageScrollLeft;\n right = windowWidth - (elementOffsetLeft - pageScrollLeft);\n }\n\n return { top, bottom, left, right };\n }\n\n public static extend(...args: any[]): T {\n let options, name, src, copy, copyIsArray, clone,\n target = args[0],\n i = 1,\n deep = false;\n const length = args.length;\n\n if (typeof target === 'boolean') {\n deep = target;\n target = args[i] || {};\n i++;\n } else {\n target = target || {};\n }\n if (typeof target !== 'object' && !Utils.isFunction(target)) {\n target = {};\n }\n if (i === length) {\n // @ts-ignore\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n target = this;\n i--;\n }\n for (; i < length; i++) {\n if (Utils.isDefined(options = args[i])) {\n for (name in options) {\n copy = options[name];\n if (name === '__proto__' || target === copy) {\n continue;\n }\n if (deep && copy && (Utils.isPlainObject(copy) ||\n (copyIsArray = Array.isArray(copy)))) {\n src = target[name];\n if (copyIsArray && !Array.isArray(src)) {\n clone = [];\n } else if (!copyIsArray && !Utils.isPlainObject(src)) {\n clone = {};\n } else {\n clone = src;\n }\n copyIsArray = false;\n target[name] = Utils.extend(deep, clone, copy);\n } else if (copy !== undefined) {\n target[name] = copy;\n }\n }\n }\n }\n return target as T;\n }\n\n /**\n * Create a DOM Element with any optional attributes or properties.\n * It will only accept valid DOM element properties that `createElement` would accept.\n * For example: `createDomElement('div', { className: 'my-css-class' })`,\n * for style or dataset you need to use nested object `{ style: { display: 'none' }}\n * The last argument is to optionally append the created element to a parent container element.\n * @param {String} tagName - html tag\n * @param {Object} options - element properties\n * @param {[HTMLElement]} appendToParent - parent element to append to\n */\n public static createDomElement(\n tagName: T,\n elementOptions?: null | { [P in K]: InferDOMType },\n appendToParent?: Element\n ): HTMLElementTagNameMap[T] {\n const elm = document.createElement(tagName);\n\n if (elementOptions) {\n Object.keys(elementOptions).forEach((elmOptionKey) => {\n const elmValue = elementOptions[elmOptionKey as keyof typeof elementOptions];\n if (typeof elmValue === 'object') {\n Object.assign(elm[elmOptionKey as K] as object, elmValue);\n } else {\n elm[elmOptionKey as K] = (elementOptions as any)[elmOptionKey as keyof typeof elementOptions];\n }\n });\n }\n if (appendToParent?.appendChild) {\n appendToParent.appendChild(elm);\n }\n return elm;\n }\n\n public static emptyElement(element: HTMLElement | null) {\n if (element?.firstChild) {\n while (element.firstChild) {\n if (element.lastChild) {\n element.removeChild(element.lastChild);\n }\n }\n }\n return element;\n }\n\n public static innerSize(elm: HTMLElement, type: 'height' | 'width') {\n let size = 0;\n\n if (elm) {\n const clientSize = type === 'height' ? 'clientHeight' : 'clientWidth';\n const sides = type === 'height' ? ['top', 'bottom'] : ['left', 'right'];\n size = elm[clientSize];\n for (const side of sides) {\n const sideSize = (parseFloat(Utils.getElementProp(elm, `padding-${side}`) || '') || 0);\n size -= sideSize;\n }\n }\n return size;\n }\n\n public static isDefined(value: T | undefined | null): value is T {\n return value !== undefined && value !== null;\n }\n\n public static getElementProp(elm: HTMLElement & { getComputedStyle?: () => CSSStyleDeclaration }, property: string) {\n if (elm?.getComputedStyle) {\n return window.getComputedStyle(elm, null).getPropertyValue(property);\n }\n return null;\n }\n\n public static isEmptyObject(obj: any) {\n if (obj === null || obj === undefined) {\n return true;\n }\n return Object.entries(obj).length === 0;\n }\n\n public static noop() { }\n\n public static offset(el: HTMLElement | null) {\n if (!el || !el.getBoundingClientRect) {\n return undefined;\n }\n const box = el.getBoundingClientRect();\n const docElem = document.documentElement;\n\n return {\n top: box.top + window.pageYOffset - docElem.clientTop,\n left: box.left + window.pageXOffset - docElem.clientLeft\n };\n }\n\n public static windowScrollPosition() {\n return {\n left: window.pageXOffset || document.documentElement.scrollLeft || 0,\n top: window.pageYOffset || document.documentElement.scrollTop || 0,\n };\n }\n\n public static width(el: HTMLElement, value?: number | string): number | void {\n if (!el || !el.getBoundingClientRect) { return; }\n if (value === undefined) {\n return el.getBoundingClientRect().width;\n }\n Utils.setStyleSize(el, 'width', value);\n }\n\n public static height(el: HTMLElement, value?: number | string): number | void {\n if (!el) { return; }\n if (value === undefined) {\n return el.getBoundingClientRect().height;\n }\n Utils.setStyleSize(el, 'height', value);\n }\n\n public static setStyleSize(el: HTMLElement, style: string, val?: number | string | Function) {\n if (typeof val === 'function') {\n val = val();\n } else if (typeof val === 'string') {\n el.style[style as CSSStyleDeclarationWritable] = val;\n } else {\n el.style[style as CSSStyleDeclarationWritable] = val + 'px';\n }\n }\n\n public static contains(parent: HTMLElement, child: HTMLElement) {\n if (!parent || !child) {\n return false;\n }\n\n const parentList = Utils.parents(child);\n return !parentList.every((p) => {\n if (parent === p) {\n return false;\n }\n return true;\n });\n }\n\n public static isHidden(el: HTMLElement) {\n return el.offsetWidth === 0 && el.offsetHeight === 0;\n }\n\n public static parents(el: HTMLElement | ParentNode, selector?: string) {\n const parents: Array = [];\n const visible = selector === ':visible';\n const hidden = selector === ':hidden';\n\n while ((el = el.parentNode as ParentNode) && el !== document) {\n if (!el || !el.parentNode) {\n break;\n }\n if (hidden) {\n if (Utils.isHidden(el as HTMLElement)) {\n parents.push(el);\n }\n } else if (visible) {\n if (!Utils.isHidden(el as HTMLElement)) {\n parents.push(el);\n }\n } else if (!selector || (el as any).matches(selector)) {\n parents.push(el);\n }\n }\n return parents;\n }\n\n public static toFloat(value: string | number) {\n const x = parseFloat(value as string);\n if (isNaN(x)) {\n return 0;\n }\n return x;\n }\n\n public static show(el: HTMLElement | HTMLElement[], type = '') {\n if (Array.isArray(el)) {\n el.forEach((e) => e.style.display = type);\n } else {\n el.style.display = type;\n }\n }\n\n public static hide(el: HTMLElement | HTMLElement[]) {\n if (Array.isArray(el)) {\n el.forEach(function (e) {\n e.style.display = 'none';\n });\n } else {\n el.style.display = 'none';\n }\n }\n\n public static slideUp(el: HTMLElement | HTMLElement[], callback: Function) {\n return Utils.slideAnimation(el, 'slideUp', callback);\n }\n\n public static slideDown(el: HTMLElement | HTMLElement[], callback: Function) {\n return Utils.slideAnimation(el, 'slideDown', callback);\n }\n\n public static slideAnimation(el: HTMLElement | HTMLElement[], slideDirection: 'slideDown' | 'slideUp', callback: Function) {\n if ((window as any).jQuery !== undefined) {\n (window as any).jQuery(el)[slideDirection]('fast', callback);\n return;\n }\n (slideDirection === 'slideUp') ? Utils.hide(el) : Utils.show(el);\n callback();\n }\n\n public static applyDefaults(targetObj: any, srcObj: any) {\n for (const key in srcObj) {\n if (srcObj.hasOwnProperty(key) && !targetObj.hasOwnProperty(key)) {\n targetObj[key] = srcObj[key];\n }\n }\n }\n}\n\nexport const SlickGlobalEditorLock = new SlickEditorLock();\n\n// export Slick namespace on both global & window objects\nconst SlickCore = {\n Event: SlickEvent,\n EventData: SlickEventData,\n EventHandler: SlickEventHandler,\n Range: SlickRange,\n NonDataRow: SlickNonDataItem,\n Group: SlickGroup,\n GroupTotals: SlickGroupTotals,\n EditorLock: SlickEditorLock,\n RegexSanitizer: regexSanitizer,\n\n /**\n * A global singleton editor lock.\n * @class GlobalEditorLock\n * @static\n * @constructor\n */\n GlobalEditorLock: SlickGlobalEditorLock,\n\n keyCode: {\n SPACE: 8,\n BACKSPACE: 8,\n DELETE: 46,\n DOWN: 40,\n END: 35,\n ENTER: 13,\n ESCAPE: 27,\n HOME: 36,\n INSERT: 45,\n LEFT: 37,\n PAGE_DOWN: 34,\n PAGE_UP: 33,\n RIGHT: 39,\n TAB: 9,\n UP: 38,\n A: 65\n },\n preClickClassName: 'slick-edit-preclick',\n\n GridAutosizeColsMode: {\n None: 'NOA',\n LegacyOff: 'LOF',\n LegacyForceFit: 'LFF',\n IgnoreViewport: 'IGV',\n FitColsToViewport: 'FCV',\n FitViewportToCols: 'FVC'\n },\n\n 'ColAutosizeMode': {\n Locked: 'LCK',\n Guide: 'GUI',\n Content: 'CON',\n ContentExpandOnly: 'CXO',\n ContentIntelligent: 'CTI'\n },\n\n 'RowSelectionMode': {\n FirstRow: 'FS1',\n FirstNRows: 'FSN',\n AllRows: 'ALL',\n LastRow: 'LS1'\n },\n\n 'ValueFilterMode': {\n None: 'NONE',\n DeDuplicate: 'DEDP',\n GetGreatestAndSub: 'GR8T',\n GetLongestTextAndSub: 'LNSB',\n GetLongestText: 'LNSC'\n },\n\n WidthEvalMode: {\n Auto: 'AUTO',\n TextOnly: 'CANV',\n HTML: 'HTML'\n }\n};\n\nexport const {\n EditorLock, Event, EventData, EventHandler, Group, GroupTotals, NonDataRow, Range,\n RegexSanitizer, GlobalEditorLock, keyCode, preClickClassName, GridAutosizeColsMode, ColAutosizeMode,\n RowSelectionMode, ValueFilterMode, WidthEvalMode\n} = SlickCore;\n\n/* eslint-disable no-undef */\n// also add to global object when exist\nif (IIFE_ONLY && typeof global !== 'undefined' && window.Slick) {\n global.Slick = window.Slick;\n}\n/* eslint-enable no-undef */\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/slick.dataview.js b/dist/browser/slick.dataview.js index 1f58a4d50..ea11509d0 100644 --- a/dist/browser/slick.dataview.js +++ b/dist/browser/slick.dataview.js @@ -156,7 +156,7 @@ } /** Set Paging Options */ setPagingOptions(args) { - this.onBeforePagingInfoChanged.notify(this.getPagingInfo(), null, this).getReturnValue() !== !1 && (args.pageSize != null && (this.pagesize = args.pageSize, this.pagenum = this.pagesize ? Math.min(this.pagenum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1)) : 0), args.pageNum != null && (this.pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1))), this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this), this.refresh()); + this.onBeforePagingInfoChanged.notify(this.getPagingInfo(), null, this).getReturnValue() !== !1 && (Utils.isDefined(args.pageSize) && (this.pagesize = args.pageSize, this.pagenum = this.pagesize ? Math.min(this.pagenum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1)) : 0), Utils.isDefined(args.pageNum) && (this.pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1))), this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this), this.refresh()); } /** Get Paging Options */ getPagingInfo() { @@ -256,7 +256,7 @@ this.ensureRowsByIdCache(); for (let i = 0, l = itemArray.length; i < l; i++) { let row = (_a2 = this.rowsById) == null ? void 0 : _a2[itemArray[i][this.idProperty]]; - row != null && (rows[rows.length] = row); + Utils.isDefined(row) && (rows[rows.length] = row); } return rows; } @@ -267,7 +267,7 @@ this.ensureRowsByIdCache(); for (let i = 0, l = idArray.length; i < l; i++) { let row = (_a2 = this.rowsById) == null ? void 0 : _a2[idArray[i]]; - row != null && (rows[rows.length] = row); + Utils.isDefined(row) && (rows[rows.length] = row); } return rows; } @@ -294,7 +294,7 @@ throw new Error("[SlickGrid DataView] Invalid id"); if (id !== item[this.idProperty]) { let newId = item[this.idProperty]; - if (newId == null) + if (!Utils.isDefined(newId)) throw new Error("[SlickGrid DataView] Cannot update item to associate with a null id"); if (this.idxById.has(newId)) throw new Error("[SlickGrid DataView] Cannot update item to associate with a non-unique id"); @@ -444,11 +444,11 @@ return item === void 0 ? null : item.__group ? this._options.groupItemMetadataProvider.getGroupRowMetadata(item) : item.__groupTotals ? this._options.groupItemMetadataProvider.getTotalsRowMetadata(item) : null; } expandCollapseAllGroups(level, collapse) { - if (level == null) + if (Utils.isDefined(level)) + this.toggledGroupsByLevel[level] = {}, this.groupingInfos[level].collapsed = collapse, collapse === !0 ? this.onGroupCollapsed.notify({ level, groupingKey: null }) : this.onGroupExpanded.notify({ level, groupingKey: null }); + else for (let i = 0; i < this.groupingInfos.length; i++) this.toggledGroupsByLevel[i] = {}, this.groupingInfos[i].collapsed = collapse, collapse === !0 ? this.onGroupCollapsed.notify({ level: i, groupingKey: null }) : this.onGroupExpanded.notify({ level: i, groupingKey: null }); - else - this.toggledGroupsByLevel[level] = {}, this.groupingInfos[level].collapsed = collapse, collapse === !0 ? this.onGroupCollapsed.notify({ level, groupingKey: null }) : this.onGroupExpanded.notify({ level, groupingKey: null }); this.refresh(); } /** @@ -653,11 +653,11 @@ i >= rl ? diff[diff.length] = i : (item = newRows[i], r = rows[i], (!item || this.groupingInfos.length && (eitherIsNonData = item.__nonDataRow || r.__nonDataRow) && item.__group !== r.__group || item.__group && !item.equals(r) || eitherIsNonData && // no good way to compare totals since they are arbitrary DTOs // deep object comparison is pretty expensive // always considering them 'dirty' seems easier for the time being - (item.__groupTotals || r.__groupTotals) || item[this.idProperty] != r[this.idProperty] || (_c = this.updated) != null && _c[item[this.idProperty]]) && (diff[diff.length] = i)); + (item.__groupTotals || r.__groupTotals) || item[this.idProperty] !== r[this.idProperty] || (_c = this.updated) != null && _c[item[this.idProperty]]) && (diff[diff.length] = i)); return diff; } recalc(_items) { - this.rowsById = void 0, (this.refreshHints.isFilterNarrowing != this.prevRefreshHints.isFilterNarrowing || this.refreshHints.isFilterExpanding != this.prevRefreshHints.isFilterExpanding) && (this.filterCache = []); + this.rowsById = void 0, (this.refreshHints.isFilterNarrowing !== this.prevRefreshHints.isFilterNarrowing || this.refreshHints.isFilterExpanding !== this.prevRefreshHints.isFilterExpanding) && (this.filterCache = []); let filteredItems = this.getFilteredAndPagedItems(_items); this.totalRows = filteredItems.totalRows; let newRows = filteredItems.rows; @@ -823,13 +823,13 @@ let newHash = {}; for (let id in hashById) { let row = (_a2 = this.rowsById) == null ? void 0 : _a2[id]; - row != null && (newHash[row] = hashById[id]); + Utils.isDefined(row) && (newHash[row] = hashById[id]); } grid.setCellCssStyles(key, newHash), inHandler = !1; } }; grid.onCellCssStylesChanged.subscribe((_e, args) => { - inHandler || key == args.key && (args.hash ? storeCellCssStyles(args.hash) : (grid.onCellCssStylesChanged.unsubscribe(), this.onRowsOrCountChanged.unsubscribe(update))); + inHandler || key === args.key && (args.hash ? storeCellCssStyles(args.hash) : (grid.onCellCssStylesChanged.unsubscribe(), this.onRowsOrCountChanged.unsubscribe(update))); }), this.onRowsOrCountChanged.subscribe(update.bind(this)); } }, AvgAggregator = class { diff --git a/dist/browser/slick.dataview.js.map b/dist/browser/slick.dataview.js.map index 280552172..697190333 100644 --- a/dist/browser/slick.dataview.js.map +++ b/dist/browser/slick.dataview.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.dataview.ts"], - "sourcesContent": ["import type {\n Aggregator,\n CssStyleHash,\n CustomDataView,\n Grouping,\n GroupingFormatterItem,\n ItemMetadata,\n OnGroupCollapsedEventArgs,\n OnGroupExpandedEventArgs,\n OnRowCountChangedEventArgs,\n OnRowsChangedEventArgs,\n OnRowsOrCountChangedEventArgs,\n OnSelectedRowIdsChangedEventArgs,\n OnSetItemsCalledEventArgs,\n PagingInfo,\n} from './models/index';\nimport {\n SlickEvent as SlickEvent_,\n SlickEventData as SlickEventData_,\n SlickGroup as SlickGroup_,\n SlickGroupTotals as SlickGroupTotals_,\n Utils as Utils_,\n SlickNonDataItem,\n} from './slick.core';\nimport type { SlickGrid } from './slick.grid';\nimport { SlickGroupItemMetadataProvider as SlickGroupItemMetadataProvider_ } from './slick.groupitemmetadataprovider';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst SlickGroup = IIFE_ONLY ? Slick.Group : SlickGroup_;\nconst SlickGroupTotals = IIFE_ONLY ? Slick.GroupTotals : SlickGroupTotals_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\nconst SlickGroupItemMetadataProvider = IIFE_ONLY ? Slick.Data?.GroupItemMetadataProvider ?? {} : SlickGroupItemMetadataProvider_;\n\nexport interface DataViewOption {\n groupItemMetadataProvider: SlickGroupItemMetadataProvider_ | null;\n inlineFilters: boolean;\n}\nexport type FilterFn = (item: T, args: any) => boolean;\nexport type DataIdType = number | string;\nexport type SlickDataItem = SlickNonDataItem | SlickGroup_ | SlickGroupTotals_ | any;\n\n/**\n * A sample Model implementation.\n * Provides a filtered view of the underlying data.\n *\n * Relies on the data item having an \"id\" property uniquely identifying it.\n */\nexport class SlickDataView implements CustomDataView {\n protected defaults: DataViewOption = {\n groupItemMetadataProvider: null,\n inlineFilters: false\n };\n\n // private\n protected idProperty = 'id'; // property holding a unique row id\n protected items: TData[] = []; // data by index\n protected rows: TData[] = []; // data by row\n protected idxById = new Map(); // indexes by id\n protected rowsById: { [id: DataIdType]: number } | undefined = undefined; // rows by id; lazy-calculated\n protected filter: FilterFn | null = null; // filter function\n protected updated: ({ [id: DataIdType]: boolean }) | null = null; // updated item ids\n protected suspend = false; // suspends the recalculation\n protected isBulkSuspend = false; // delays protectedious operations like the\n // index update and delete to efficient\n // versions at endUpdate\n protected bulkDeleteIds = new Map();\n protected sortAsc: boolean | undefined = true;\n protected fastSortField?: string | null | (() => string);\n protected sortComparer!: ((a: TData, b: TData) => number);\n protected refreshHints: any = {};\n protected prevRefreshHints: any = {};\n protected filterArgs: any;\n protected filteredItems: TData[] = [];\n protected compiledFilter?: FilterFn | null;\n protected compiledFilterWithCaching?: FilterFn | null;\n protected filterCache: any[] = [];\n protected _grid?: SlickGrid; // grid object will be defined only after using \"syncGridSelection()\" method\"\n\n // grouping\n protected groupingInfoDefaults: Grouping = {\n getter: undefined,\n formatter: undefined,\n comparer: (a: { value: any; }, b: { value: any; }) => (a.value === b.value ? 0 : (a.value > b.value ? 1 : -1)),\n predefinedValues: [],\n aggregators: [],\n aggregateEmpty: false,\n aggregateCollapsed: false,\n aggregateChildGroups: false,\n collapsed: false,\n displayTotalsRow: true,\n lazyTotalsCalculation: false\n };\n protected groupingInfos: Array = [];\n protected groups: SlickGroup_[] = [];\n protected toggledGroupsByLevel: any[] = [];\n protected groupingDelimiter = ':|:';\n protected selectedRowIds: DataIdType[] = [];\n protected preSelectedRowIdsChangeFn?: Function;\n\n protected pagesize = 0;\n protected pagenum = 0;\n protected totalRows = 0;\n protected _options: DataViewOption;\n\n // public events\n onBeforePagingInfoChanged = new SlickEvent();\n onGroupExpanded = new SlickEvent();\n onGroupCollapsed = new SlickEvent();\n onPagingInfoChanged = new SlickEvent();\n onRowCountChanged = new SlickEvent();\n onRowsChanged = new SlickEvent();\n onRowsOrCountChanged = new SlickEvent();\n onSelectedRowIdsChanged = new SlickEvent();\n onSetItemsCalled = new SlickEvent();\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this.defaults, options);\n }\n\n /**\n * Begins a bached update of the items in the data view.\n * including deletes and the related events are postponed to the endUpdate call.\n * As certain operations are postponed during this update, some methods might not\n * deliver fully consistent information.\n * @param {Boolean} [bulkUpdate] - if set to true, most data view modifications\n */\n beginUpdate(bulkUpdate?: boolean) {\n this.suspend = true;\n this.isBulkSuspend = bulkUpdate === true;\n }\n\n endUpdate() {\n const wasBulkSuspend = this.isBulkSuspend;\n this.isBulkSuspend = false;\n this.suspend = false;\n if (wasBulkSuspend) {\n this.processBulkDelete();\n this.ensureIdUniqueness();\n }\n this.refresh();\n }\n\n destroy() {\n this.items = [];\n this.idxById = null as any;\n this.rowsById = null as any;\n this.filter = null as any;\n this.updated = null as any;\n this.sortComparer = null as any;\n this.filterCache = [];\n this.filteredItems = [];\n this.compiledFilter = null;\n this.compiledFilterWithCaching = null;\n\n if (this._grid && this._grid.onSelectedRowsChanged && this._grid.onCellCssStylesChanged) {\n this._grid.onSelectedRowsChanged.unsubscribe();\n this._grid.onCellCssStylesChanged.unsubscribe();\n }\n if (this.onRowsOrCountChanged) {\n this.onRowsOrCountChanged.unsubscribe();\n }\n }\n\n setRefreshHints(hints: any) {\n this.refreshHints = hints;\n }\n\n setFilterArgs(args: any) {\n this.filterArgs = args;\n }\n\n /**\n * Processes all delete requests placed during bulk update\n * by recomputing the items and idxById members.\n */\n protected processBulkDelete() {\n if (!this.idxById) return;\n\n // the bulk update is processed by\n // recomputing the whole items array and the index lookup in one go.\n // this is done by placing the not-deleted items\n // from left to right into the array and shrink the array the the new\n // size afterwards.\n // see https://github.com/6pac/SlickGrid/issues/571 for further details.\n\n let id: DataIdType, item, newIdx = 0;\n for (let i = 0, l = this.items.length; i < l; i++) {\n item = this.items[i];\n id = item[this.idProperty as keyof TData] as DataIdType;\n if (id === undefined) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n\n // if items have been marked as deleted we skip them for the new final items array\n // and we remove them from the lookup table.\n if (this.bulkDeleteIds.has(id)) {\n this.idxById.delete(id);\n } else {\n // for items which are not deleted, we add them to the\n // next free position in the array and register the index in the lookup.\n this.items[newIdx] = item;\n this.idxById.set(id, newIdx);\n ++newIdx;\n }\n }\n\n // here we shrink down the full item array to the ones actually\n // inserted in the cleanup loop above.\n this.items.length = newIdx;\n // and finally cleanup the deleted ids to start cleanly on the next update.\n this.bulkDeleteIds = new Map();\n }\n\n protected updateIdxById(startingIndex?: number) {\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\n return;\n }\n startingIndex = startingIndex || 0;\n let id: DataIdType;\n for (let i = startingIndex, l = this.items.length; i < l; i++) {\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\n if (id === undefined) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n this.idxById.set(id, i);\n }\n }\n\n protected ensureIdUniqueness() {\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\n return;\n }\n let id: DataIdType;\n for (let i = 0, l = this.items.length; i < l; i++) {\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\n if (id === undefined || this.idxById.get(id) !== i) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n }\n }\n\n /** Get all DataView Items */\n getItems() {\n return this.items;\n }\n\n /** Get the DataView Id property name to use (defaults to \"Id\" but could be customized to something else when instantiating the DataView) */\n getIdPropertyName() {\n return this.idProperty;\n }\n\n /**\n * Set the Items with a new Dataset and optionally pass a different Id property name\n * @param {Array<*>} data - array of data\n * @param {String} [objectIdProperty] - optional id property to use as primary id\n */\n setItems(data: TData[], objectIdProperty?: string) {\n if (objectIdProperty !== undefined) {\n this.idProperty = objectIdProperty;\n }\n this.items = this.filteredItems = data;\n this.onSetItemsCalled.notify({ idProperty: this.idProperty, itemCount: this.items.length }, null, this);\n this.idxById = new Map();\n this.updateIdxById();\n this.ensureIdUniqueness();\n this.refresh();\n }\n\n /** Set Paging Options */\n setPagingOptions(args: Partial) {\n if (this.onBeforePagingInfoChanged.notify(this.getPagingInfo(), null, this).getReturnValue() !== false) {\n if (args.pageSize != undefined) {\n this.pagesize = args.pageSize;\n this.pagenum = this.pagesize ? Math.min(this.pagenum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1)) : 0;\n }\n\n if (args.pageNum != undefined) {\n this.pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1));\n }\n\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\n\n this.refresh();\n }\n }\n\n /** Get Paging Options */\n getPagingInfo(): PagingInfo {\n const totalPages = this.pagesize ? Math.max(1, Math.ceil(this.totalRows / this.pagesize)) : 1;\n return { pageSize: this.pagesize, pageNum: this.pagenum, totalRows: this.totalRows, totalPages: totalPages, dataView: this as SlickDataView };\n }\n\n /** Sort Method to use by the DataView */\n sort(comparer: (a: TData, b: TData) => number, ascending?: boolean) {\n this.sortAsc = ascending;\n this.sortComparer = comparer;\n this.fastSortField = null;\n if (ascending === false) {\n this.items.reverse();\n }\n this.items.sort(comparer);\n if (ascending === false) {\n this.items.reverse();\n }\n this.idxById = new Map();\n this.updateIdxById();\n this.refresh();\n }\n\n /**\n * Provides a workaround for the extremely slow sorting in IE.\n * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString\n * to return the value of that field and then doing a native Array.sort().\n */\n fastSort(field: string | (() => string), ascending?: boolean) {\n this.sortAsc = ascending;\n this.fastSortField = field;\n this.sortComparer = null as any;\n const oldToString = Object.prototype.toString;\n Object.prototype.toString = (typeof field === 'function') ? field : function () {\n // @ts-ignore\n return this[field];\n };\n // an extra reversal for descending sort keeps the sort stable\n // (assuming a stable native sort implementation, which isn't true in some cases)\n if (ascending === false) {\n this.items.reverse();\n }\n this.items.sort();\n Object.prototype.toString = oldToString;\n if (ascending === false) {\n this.items.reverse();\n }\n this.idxById = new Map();\n this.updateIdxById();\n this.refresh();\n }\n\n /** Re-Sort the dataset */\n reSort() {\n if (this.sortComparer) {\n this.sort(this.sortComparer, this.sortAsc);\n } else if (this.fastSortField) {\n this.fastSort(this.fastSortField, this.sortAsc);\n }\n }\n\n /** Get only the DataView filtered items */\n getFilteredItems() {\n return this.filteredItems as T[];\n }\n\n /** Get the array length (count) of only the DataView filtered items */\n getFilteredItemCount() {\n return this.filteredItems.length;\n }\n\n /** Get current Filter used by the DataView */\n getFilter() {\n return this.filter;\n }\n\n /**\n * Set a Filter that will be used by the DataView\n * @param {Function} fn - filter callback function\n */\n setFilter(filterFn: FilterFn) {\n this.filter = filterFn;\n if (this._options.inlineFilters) {\n this.compiledFilter = this.compileFilter();\n this.compiledFilterWithCaching = this.compileFilterWithCaching();\n }\n this.refresh();\n }\n\n /** Get current Grouping info */\n getGrouping(): Grouping[] {\n return this.groupingInfos;\n }\n\n /** Set some Grouping */\n setGrouping(groupingInfo: Grouping | Grouping[]) {\n if (!this._options.groupItemMetadataProvider) {\n this._options.groupItemMetadataProvider = new SlickGroupItemMetadataProvider();\n }\n\n this.groups = [];\n this.toggledGroupsByLevel = [];\n groupingInfo = groupingInfo || [];\n this.groupingInfos = ((groupingInfo instanceof Array) ? groupingInfo : [groupingInfo]) as any;\n\n for (let i = 0; i < this.groupingInfos.length; i++) {\n const gi = this.groupingInfos[i] = Utils.extend(true, {}, this.groupingInfoDefaults, this.groupingInfos[i]);\n gi.getterIsAFn = typeof gi.getter === 'function';\n\n // pre-compile accumulator loops\n gi.compiledAccumulators = [];\n let idx = gi.aggregators.length;\n while (idx--) {\n gi.compiledAccumulators[idx] = this.compileAccumulatorLoop(gi.aggregators[idx]);\n }\n\n this.toggledGroupsByLevel[i] = {};\n }\n\n this.refresh();\n }\n\n /** Get an item in the DataView by its row index */\n getItemByIdx(i: number) {\n return this.items[i] as T;\n }\n\n /** Get row index in the DataView by its Id */\n getIdxById(id: DataIdType) {\n return this.idxById?.get(id);\n }\n\n protected ensureRowsByIdCache() {\n if (!this.rowsById) {\n this.rowsById = {};\n for (let i = 0, l = this.rows.length; i < l; i++) {\n this.rowsById[this.rows[i][this.idProperty as keyof TData] as DataIdType] = i;\n }\n }\n }\n\n /** Get row number in the grid by its item object */\n getRowByItem(item: TData) {\n this.ensureRowsByIdCache();\n return this.rowsById?.[item[this.idProperty as keyof TData] as DataIdType];\n }\n\n /** Get row number in the grid by its Id */\n getRowById(id: DataIdType) {\n this.ensureRowsByIdCache();\n return this.rowsById?.[id];\n }\n\n /** Get an item in the DataView by its Id */\n getItemById(id: DataIdType) {\n return this.items[(this.idxById.get(id) as number)] as T;\n }\n\n /** From the items array provided, return the mapped rows */\n mapItemsToRows(itemArray: TData[]) {\n const rows: number[] = [];\n this.ensureRowsByIdCache();\n for (let i = 0, l = itemArray.length; i < l; i++) {\n const row = this.rowsById?.[itemArray[i][this.idProperty as keyof TData] as DataIdType];\n if (row != null) {\n rows[rows.length] = row;\n }\n }\n return rows;\n }\n\n /** From the Ids array provided, return the mapped rows */\n mapIdsToRows(idArray: DataIdType[]) {\n const rows: number[] = [];\n this.ensureRowsByIdCache();\n for (let i = 0, l = idArray.length; i < l; i++) {\n const row = this.rowsById?.[idArray[i]];\n if (row != null) {\n rows[rows.length] = row;\n }\n }\n return rows;\n }\n\n /** From the rows array provided, return the mapped Ids */\n mapRowsToIds(rowArray: number[]) {\n const ids: DataIdType[] = [];\n for (let i = 0, l = rowArray.length; i < l; i++) {\n if (rowArray[i] < this.rows.length) {\n const rowItem = this.rows[rowArray[i]];\n ids[ids.length] = rowItem![this.idProperty as keyof TData] as DataIdType;\n }\n }\n return ids;\n }\n\n /**\n * Performs the update operations of a single item by id without\n * triggering any events or refresh operations.\n * @param id The new id of the item.\n * @param item The item which should be the new value for the given id.\n */\n updateSingleItem(id: DataIdType, item: TData) {\n if (!this.idxById) return;\n\n // see also https://github.com/mleibman/SlickGrid/issues/1082\n if (!this.idxById.has(id)) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n\n // What if the specified item also has an updated idProperty?\n // Then we'll have to update the index as well, and possibly the `updated` cache too.\n if (id !== item[this.idProperty as keyof TData]) {\n // make sure the new id is unique:\n const newId = item[this.idProperty as keyof TData] as DataIdType;\n if (newId == null) {\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a null id');\n }\n if (this.idxById.has(newId)) {\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a non-unique id');\n }\n this.idxById.set(newId, this.idxById.get(id) as number);\n this.idxById.delete(id);\n\n // Also update the `updated` hashtable/markercache? Yes, `recalc()` inside `refresh()` needs that one!\n if (this.updated?.[id]) {\n delete this.updated[id];\n }\n\n // Also update the row indexes? no need since the `refresh()`, further down, blows away the `rowsById[]` cache!\n\n id = newId;\n }\n this.items[this.idxById.get(id) as number] = item;\n\n // Also update the rows? no need since the `refresh()`, further down, blows away the `rows[]` cache and recalculates it via `recalc()`!\n\n if (!this.updated) {\n this.updated = {};\n }\n this.updated[id] = true;\n }\n\n /**\n * Updates a single item in the data view given the id and new value.\n * @param id The new id of the item.\n * @param item The item which should be the new value for the given id.\n */\n updateItem(id: DataIdType, item: T) {\n this.updateSingleItem(id, item);\n this.refresh();\n }\n\n /**\n * Updates multiple items in the data view given the new ids and new values.\n * @param id {Array} The array of new ids which is in the same order as the items.\n * @param newItems {Array} The new items that should be set in the data view for the given ids.\n */\n updateItems(ids: DataIdType[], newItems: T[]) {\n if (ids.length !== newItems.length) {\n throw new Error(\"[SlickGrid DataView] Mismatch on the length of ids and items provided to update\");\n }\n for (let i = 0, l = newItems.length; i < l; i++) {\n this.updateSingleItem(ids[i], newItems[i]);\n }\n this.refresh();\n }\n\n /**\n * Inserts a single item into the data view at the given position.\n * @param insertBefore {Number} The 0-based index before which the item should be inserted.\n * @param item The item to insert.\n */\n insertItem(insertBefore: number, item: TData) {\n this.items.splice(insertBefore, 0, item);\n this.updateIdxById(insertBefore);\n this.refresh();\n }\n\n /**\n * Inserts multiple items into the data view at the given position.\n * @param insertBefore {Number} The 0-based index before which the items should be inserted.\n * @param newItems {Array} The items to insert.\n */\n insertItems(insertBefore: number, newItems: TData[]) {\n // @ts-ignore\n Array.prototype.splice.apply(this.items, [insertBefore, 0].concat(newItems));\n this.updateIdxById(insertBefore);\n this.refresh();\n }\n\n /**\n * Adds a single item at the end of the data view.\n * @param item The item to add at the end.\n */\n addItem(item: TData) {\n this.items.push(item);\n this.updateIdxById(this.items.length - 1);\n this.refresh();\n }\n\n /**\n * Adds multiple items at the end of the data view.\n * @param {Array} newItems The items to add at the end.\n */\n addItems(newItems: TData[]) {\n this.items = this.items.concat(newItems);\n this.updateIdxById(this.items.length - newItems.length);\n this.refresh();\n }\n\n /**\n * Deletes a single item identified by the given id from the data view.\n * @param {String|Number} id The id identifying the object to delete.\n */\n deleteItem(id: DataIdType) {\n if (!this.idxById) return;\n if (this.isBulkSuspend) {\n this.bulkDeleteIds.set(id, true);\n } else {\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.idxById.delete(id);\n this.items.splice(idx, 1);\n this.updateIdxById(idx);\n this.refresh();\n }\n }\n\n /**\n * Deletes multiple item identified by the given ids from the data view.\n * @param {Array} ids The ids of the items to delete.\n */\n deleteItems(ids: DataIdType[]) {\n if (ids.length === 0 || !this.idxById) {\n return;\n }\n\n if (this.isBulkSuspend) {\n for (let i = 0, l = ids.length; i < l; i++) {\n const id = ids[i];\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.bulkDeleteIds.set(id, true);\n }\n } else {\n // collect all indexes\n const indexesToDelete: number[] = [];\n for (let i = 0, l = ids.length; i < l; i++) {\n const id = ids[i];\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.idxById.delete(id);\n indexesToDelete.push(idx);\n }\n\n // Remove from back to front\n indexesToDelete.sort();\n for (let i = indexesToDelete.length - 1; i >= 0; --i) {\n this.items.splice(indexesToDelete[i], 1);\n }\n\n // update lookup from front to back\n this.updateIdxById(indexesToDelete[0]);\n this.refresh();\n }\n }\n\n /** Add an item in a sorted dataset (a Sort function must be defined) */\n sortedAddItem(item: TData) {\n if (!this.sortComparer) {\n throw new Error('[SlickGrid DataView] sortedAddItem() requires a sort comparer, use sort()');\n }\n this.insertItem(this.sortedIndex(item), item);\n }\n\n /** Update an item in a sorted dataset (a Sort function must be defined) */\n sortedUpdateItem(id: string | number, item: TData) {\n if (!this.idxById) return;\n if (!this.idxById.has(id) || id !== item[this.idProperty as keyof TData]) {\n throw new Error('[SlickGrid DataView] Invalid or non-matching id ' + this.idxById.get(id));\n }\n if (!this.sortComparer) {\n throw new Error(\"[SlickGrid DataView] sortedUpdateItem() requires a sort comparer, use sort()\");\n }\n const oldItem = this.getItemById(id);\n if (this.sortComparer(oldItem, item) !== 0) {\n // item affects sorting -> must use sorted add\n this.deleteItem(id);\n this.sortedAddItem(item);\n } else { // update does not affect sorting -> regular update works fine\n this.updateItem(id, item);\n }\n }\n\n protected sortedIndex(searchItem: TData) {\n let low = 0;\n let high = this.items.length;\n\n while (low < high) {\n const mid = low + high >>> 1;\n if (this.sortComparer(this.items[mid], searchItem) === -1) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return low;\n }\n\n /** Get item count, that is the full dataset lenght of the DataView */\n getItemCount() {\n return this.items.length;\n }\n\n /** Get row count (rows displayed in current page) */\n getLength() {\n return this.rows.length;\n }\n\n /** Retrieve an item from the DataView at specific index */\n getItem(i: number) {\n const item = this.rows[i] as T;\n\n // if this is a group row, make sure totals are calculated and update the title\n if ((item as SlickGroup_)?.__group && (item as SlickGroup_).totals && !(item as SlickGroup_).totals?.initialized) {\n const gi = this.groupingInfos[(item as SlickGroup_).level];\n if (!gi.displayTotalsRow) {\n this.calculateTotals((item as SlickGroup_).totals);\n (item as SlickGroup_).title = gi.formatter ? gi.formatter((item as SlickGroup_)) : (item as SlickGroup_).value;\n }\n }\n // if this is a totals row, make sure it's calculated\n else if ((item as SlickGroupTotals_)?.__groupTotals && !(item as SlickGroupTotals_).initialized) {\n this.calculateTotals(item as SlickGroupTotals_);\n }\n\n return item;\n }\n\n getItemMetadata(i: number): ItemMetadata | null {\n const item = this.rows[i];\n if (item === undefined) {\n return null;\n }\n\n // overrides for grouping rows\n if ((item as SlickGroup_).__group) {\n return this._options.groupItemMetadataProvider!.getGroupRowMetadata(item as GroupingFormatterItem);\n }\n\n // overrides for totals rows\n if ((item as SlickGroupTotals_).__groupTotals) {\n return this._options.groupItemMetadataProvider!.getTotalsRowMetadata(item as { group: GroupingFormatterItem });\n }\n\n return null;\n }\n\n protected expandCollapseAllGroups(level?: number, collapse?: boolean) {\n if (level == null) {\n for (let i = 0; i < this.groupingInfos.length; i++) {\n this.toggledGroupsByLevel[i] = {};\n this.groupingInfos[i].collapsed = collapse;\n\n if (collapse === true) {\n this.onGroupCollapsed.notify({ level: i, groupingKey: null });\n } else {\n this.onGroupExpanded.notify({ level: i, groupingKey: null });\n }\n }\n } else {\n this.toggledGroupsByLevel[level] = {};\n this.groupingInfos[level].collapsed = collapse;\n\n if (collapse === true) {\n this.onGroupCollapsed.notify({ level: level, groupingKey: null });\n } else {\n this.onGroupExpanded.notify({ level: level, groupingKey: null });\n }\n }\n this.refresh();\n }\n\n /**\n * @param {Number} [level] Optional level to collapse. If not specified, applies to all levels.\n */\n collapseAllGroups(level?: number) {\n this.expandCollapseAllGroups(level, true);\n }\n\n /**\n * @param {Number} [level] Optional level to expand. If not specified, applies to all levels.\n */\n expandAllGroups(level?: number) {\n this.expandCollapseAllGroups(level, false);\n }\n\n expandCollapseGroup(level: number, groupingKey: string, collapse?: boolean) {\n // @ts-ignore\n this.toggledGroupsByLevel[level][groupingKey] = this.groupingInfos[level].collapsed ^ collapse;\n this.refresh();\n }\n\n /**\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\n * variable argument list of grouping values denoting a unique path to the row. For\n * example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of\n * the 'high' group.\n */\n collapseGroup(...args: any) {\n const calledArgs = Array.prototype.slice.call(args);\n const arg0 = calledArgs[0];\n let groupingKey;\n let level;\n\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\n groupingKey = arg0;\n level = arg0.split(this.groupingDelimiter).length - 1;\n } else {\n groupingKey = args.join(this.groupingDelimiter);\n level = args.length - 1;\n }\n\n this.expandCollapseGroup(level, groupingKey, true);\n this.onGroupCollapsed.notify({ level: level, groupingKey: groupingKey });\n }\n\n /**\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\n * variable argument list of grouping values denoting a unique path to the row. For\n * example, calling expandGroup('high', '10%') will expand the '10%' subgroup of\n * the 'high' group.\n */\n expandGroup(...args: any) {\n const calledArgs = Array.prototype.slice.call(args);\n const arg0 = calledArgs[0];\n let groupingKey;\n let level;\n\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\n level = arg0.split(this.groupingDelimiter).length - 1;\n groupingKey = arg0;\n } else {\n level = args.length - 1;\n groupingKey = args.join(this.groupingDelimiter);\n }\n\n this.expandCollapseGroup(level, groupingKey, false);\n this.onGroupExpanded.notify({ level: level, groupingKey: groupingKey });\n }\n\n getGroups() {\n return this.groups;\n }\n\n protected extractGroups(rows: any[], parentGroup?: SlickGroup_) {\n let group;\n let val;\n const groups: SlickGroup_[] = [];\n const groupsByVal: any = {};\n let r;\n const level = parentGroup ? parentGroup.level + 1 : 0;\n const gi = this.groupingInfos[level];\n\n for (let i = 0, l = gi.predefinedValues?.length ?? 0; i < l; i++) {\n val = gi.predefinedValues?.[i];\n group = groupsByVal[val];\n if (!group) {\n group = new SlickGroup();\n group.value = val;\n group.level = level;\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\n groups[groups.length] = group;\n groupsByVal[val] = group;\n }\n }\n\n for (let i = 0, l = rows.length; i < l; i++) {\n r = rows[i];\n val = gi.getterIsAFn ? (gi.getter as Function)(r) : r[gi.getter as keyof TData];\n group = groupsByVal[val];\n if (!group) {\n group = new SlickGroup();\n group.value = val;\n group.level = level;\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\n groups[groups.length] = group;\n groupsByVal[val] = group;\n }\n\n group.rows[group.count++] = r;\n }\n\n if (level < this.groupingInfos.length - 1) {\n for (let i = 0; i < groups.length; i++) {\n group = groups[i];\n group.groups = this.extractGroups(group.rows, group);\n }\n }\n\n if (groups.length) {\n this.addTotals(groups, level);\n }\n\n groups.sort(this.groupingInfos[level].comparer);\n\n return groups;\n }\n\n protected calculateTotals(totals: SlickGroupTotals_) {\n const group = totals.group;\n const gi = this.groupingInfos[group.level ?? 0];\n const isLeafLevel = (group.level === this.groupingInfos.length);\n let agg: Aggregator, idx = gi.aggregators.length;\n\n if (!isLeafLevel && gi.aggregateChildGroups) {\n // make sure all the subgroups are calculated\n let i = group.groups?.length ?? 0;\n while (i--) {\n if (!group.groups[i].totals.initialized) {\n this.calculateTotals(group.groups[i].totals);\n }\n }\n }\n\n while (idx--) {\n agg = gi.aggregators[idx];\n agg.init();\n if (!isLeafLevel && gi.aggregateChildGroups) {\n gi.compiledAccumulators[idx].call(agg, group.groups);\n } else {\n gi.compiledAccumulators[idx].call(agg, group.rows);\n }\n agg.storeResult(totals);\n }\n totals.initialized = true;\n }\n\n protected addGroupTotals(group: SlickGroup_) {\n const gi = this.groupingInfos[group.level];\n const totals = new SlickGroupTotals();\n totals.group = group;\n group.totals = totals;\n if (!gi.lazyTotalsCalculation) {\n this.calculateTotals(totals);\n }\n }\n\n protected addTotals(groups: SlickGroup_[], level?: number) {\n level = level || 0;\n const gi = this.groupingInfos[level];\n const groupCollapsed = gi.collapsed;\n const toggledGroups = this.toggledGroupsByLevel[level];\n let idx = groups.length, g;\n while (idx--) {\n g = groups[idx];\n\n if (g.collapsed && !gi.aggregateCollapsed) {\n continue;\n }\n\n // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.\n if (g.groups) {\n this.addTotals(g.groups, level + 1);\n }\n\n if (gi.aggregators?.length && (\n gi.aggregateEmpty || g.rows.length || g.groups?.length)) {\n this.addGroupTotals(g);\n }\n\n g.collapsed = (groupCollapsed as any) ^ toggledGroups[g.groupingKey];\n g.title = gi.formatter ? gi.formatter(g) : g.value;\n }\n }\n\n protected flattenGroupedRows(groups: SlickGroup_[], level?: number) {\n level = level || 0;\n const gi = this.groupingInfos[level];\n const groupedRows: any[] = [];\n let rows: any[], gl = 0, g;\n for (let i = 0, l = groups.length; i < l; i++) {\n g = groups[i];\n groupedRows[gl++] = g;\n\n if (!g.collapsed) {\n rows = g.groups ? this.flattenGroupedRows(g.groups, level + 1) : g.rows;\n for (let j = 0, jj = rows.length; j < jj; j++) {\n groupedRows[gl++] = rows[j];\n }\n }\n\n if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)) {\n groupedRows[gl++] = g.totals;\n }\n }\n return groupedRows;\n }\n\n protected getFunctionInfo(fn: Function) {\n const fnStr = fn.toString();\n const usingEs5 = fnStr.indexOf('function') >= 0; // with ES6, the word function is not present\n const fnRegex = usingEs5 ? /^function[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/ : /^[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/;\n const matches = fn.toString().match(fnRegex) || [];\n return {\n params: matches[1].split(\",\"),\n body: matches[2]\n };\n }\n\n protected compileAccumulatorLoop(aggregator: Aggregator) {\n if (aggregator.accumulate) {\n const accumulatorInfo = this.getFunctionInfo(aggregator.accumulate);\n const fn: any = new Function(\n \"_items\",\n \"for (var \" + accumulatorInfo.params[0] + \", _i=0, _il=_items.length; _i<_il; _i++) {\" +\n accumulatorInfo.params[0] + \" = _items[_i]; \" +\n accumulatorInfo.body +\n \"}\"\n );\n const fnName = \"compiledAccumulatorLoop\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n } else {\n return function noAccumulator() { }\n }\n }\n\n protected compileFilter(): FilterFn {\n const filterInfo = this.getFunctionInfo(this.filter as Function);\n\n const filterPath1 = \"{ continue _coreloop; }$1\";\n const filterPath2 = \"{ _retval[_idx++] = $item$; continue _coreloop; }$1\";\n // make some allowances for minification - there's only so far we can go with RegEx\n const filterBody = filterInfo.body\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\n \"{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2\");\n\n // This preserves the function template code after JS compression,\n // so that replace() commands still work as expected.\n let tpl = [\n //\"function(_items, _args) { \",\n \"var _retval = [], _idx = 0; \",\n \"var $item$, $args$ = _args; \",\n \"_coreloop: \",\n \"for (var _i = 0, _il = _items.length; _i < _il; _i++) { \",\n \"$item$ = _items[_i]; \",\n \"$filter$; \",\n \"} \",\n \"return _retval; \"\n //\"}\"\n ].join(\"\");\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\n const fn: any = new Function(\"_items,_args\", tpl);\n const fnName = \"compiledFilter\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n }\n\n protected compileFilterWithCaching() {\n const filterInfo = this.getFunctionInfo(this.filter as Function);\n\n const filterPath1 = \"{ continue _coreloop; }$1\";\n const filterPath2 = \"{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1\";\n // make some allowances for minification - there's only so far we can go with RegEx\n const filterBody = filterInfo.body\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\n \"{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2\");\n\n // This preserves the function template code after JS compression,\n // so that replace() commands still work as expected.\n let tpl = [\n //\"function(_items, _args, _cache) { \",\n \"var _retval = [], _idx = 0; \",\n \"var $item$, $args$ = _args; \",\n \"_coreloop: \",\n \"for (var _i = 0, _il = _items.length; _i < _il; _i++) { \",\n \"$item$ = _items[_i]; \",\n \"if (_cache[_i]) { \",\n \"_retval[_idx++] = $item$; \",\n \"continue _coreloop; \",\n \"} \",\n \"$filter$; \",\n \"} \",\n \"return _retval; \"\n //\"}\"\n ].join(\"\");\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\n const fn: any = new Function(\"_items,_args,_cache\", tpl);\n const fnName = \"compiledFilterWithCaching\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n }\n\n /**\n * In ES5 we could set the function name on the fly but in ES6 this is forbidden and we need to set it through differently\n * We can use Object.defineProperty and set it the property to writable, see MDN for reference\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n * @param {*} fn\n * @param {string} fnName\n */\n protected setFunctionName(fn: any, fnName: string) {\n try {\n Object.defineProperty(fn, 'name', {\n writable: true,\n value: fnName\n });\n } catch (err) {\n fn.name = fnName;\n }\n }\n\n protected uncompiledFilter(items: TData[], args: any) {\n const retval: any[] = [];\n let idx = 0;\n\n for (let i = 0, ii = items.length; i < ii; i++) {\n if (this.filter?.(items[i], args)) {\n retval[idx++] = items[i];\n }\n }\n\n return retval;\n }\n\n protected uncompiledFilterWithCaching(items: TData[], args: any, cache: any) {\n const retval: any[] = [];\n let idx = 0,\n item: TData;\n\n for (let i = 0, ii = items.length; i < ii; i++) {\n item = items[i];\n if (cache[i]) {\n retval[idx++] = item;\n } else if (this.filter?.(item, args)) {\n retval[idx++] = item;\n cache[i] = true;\n }\n }\n\n return retval;\n }\n\n protected getFilteredAndPagedItems(items: TData[]) {\n if (this.filter) {\n const batchFilter = (this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter) as Function;\n const batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching) as Function;\n\n if (this.refreshHints.isFilterNarrowing) {\n this.filteredItems = batchFilter.call(this, this.filteredItems, this.filterArgs);\n } else if (this.refreshHints.isFilterExpanding) {\n this.filteredItems = batchFilterWithCaching.call(this, items, this.filterArgs, this.filterCache);\n } else if (!this.refreshHints.isFilterUnchanged) {\n this.filteredItems = batchFilter.call(this, items, this.filterArgs);\n }\n } else {\n // special case: if not filtering and not paging, the resulting\n // rows collection needs to be a copy so that changes due to sort\n // can be caught\n this.filteredItems = this.pagesize ? items : items.concat();\n }\n\n // get the current page\n let paged: TData[];\n if (this.pagesize) {\n if (this.filteredItems.length <= this.pagenum * this.pagesize) {\n if (this.filteredItems.length === 0) {\n this.pagenum = 0;\n } else {\n this.pagenum = Math.floor((this.filteredItems.length - 1) / this.pagesize);\n }\n }\n paged = this.filteredItems.slice(this.pagesize * this.pagenum, this.pagesize * this.pagenum + this.pagesize);\n } else {\n paged = this.filteredItems;\n }\n return { totalRows: this.filteredItems.length, rows: paged };\n }\n\n protected getRowDiffs(rows: TData[], newRows: TData[]) {\n let item: any, r, eitherIsNonData;\n const diff: number[] = [];\n let from = 0, to = Math.max(newRows.length, rows.length);\n\n if (this.refreshHints?.ignoreDiffsBefore) {\n from = Math.max(0,\n Math.min(newRows.length, this.refreshHints.ignoreDiffsBefore));\n }\n\n if (this.refreshHints?.ignoreDiffsAfter) {\n to = Math.min(newRows.length,\n Math.max(0, this.refreshHints.ignoreDiffsAfter));\n }\n\n for (let i = from, rl = rows.length; i < to; i++) {\n if (i >= rl) {\n diff[diff.length] = i;\n } else {\n item = newRows[i];\n r = rows[i];\n\n if (!item || (this.groupingInfos.length && (eitherIsNonData = ((item as SlickNonDataItem).__nonDataRow) || ((r as SlickNonDataItem).__nonDataRow)) &&\n (item as SlickGroup_).__group !== (r as SlickGroup_).__group ||\n (item as SlickGroup_).__group && !(item as SlickGroup_).equals(r as SlickGroup_))\n || (eitherIsNonData &&\n // no good way to compare totals since they are arbitrary DTOs\n // deep object comparison is pretty expensive\n // always considering them 'dirty' seems easier for the time being\n ((item as SlickGroupTotals_).__groupTotals || (r as SlickGroupTotals_).__groupTotals))\n || item[this.idProperty as keyof TData] != r[this.idProperty as keyof TData]\n || (this.updated?.[item[this.idProperty as keyof TData]])\n ) {\n diff[diff.length] = i;\n }\n }\n }\n return diff;\n }\n\n protected recalc(_items: TData[]) {\n this.rowsById = undefined;\n\n if (this.refreshHints.isFilterNarrowing != this.prevRefreshHints.isFilterNarrowing ||\n this.refreshHints.isFilterExpanding != this.prevRefreshHints.isFilterExpanding) {\n this.filterCache = [];\n }\n\n const filteredItems = this.getFilteredAndPagedItems(_items);\n this.totalRows = filteredItems.totalRows;\n let newRows: TData[] = filteredItems.rows;\n\n this.groups = [];\n if (this.groupingInfos.length) {\n this.groups = this.extractGroups(newRows);\n if (this.groups.length) {\n newRows = this.flattenGroupedRows(this.groups);\n }\n }\n\n const diff = this.getRowDiffs(this.rows, newRows as TData[]);\n\n this.rows = newRows as TData[];\n\n return diff;\n }\n\n refresh() {\n if (this.suspend) {\n return;\n }\n\n const previousPagingInfo = Utils.extend(true, {}, this.getPagingInfo());\n\n const countBefore = this.rows.length;\n const totalRowsBefore = this.totalRows;\n\n let diff = this.recalc(this.items); // pass as direct refs to avoid closure perf hit\n\n // if the current page is no longer valid, go to last page and recalc\n // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized\n if (this.pagesize && this.totalRows < this.pagenum * this.pagesize) {\n this.pagenum = Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1);\n diff = this.recalc(this.items);\n }\n\n this.updated = null;\n this.prevRefreshHints = this.refreshHints;\n this.refreshHints = {};\n\n if (totalRowsBefore !== this.totalRows) {\n // use the previously saved paging info\n if (this.onBeforePagingInfoChanged.notify(previousPagingInfo, null, this).getReturnValue() !== false) {\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\n }\n }\n if (countBefore !== this.rows.length) {\n this.onRowCountChanged.notify({ previous: countBefore, current: this.rows.length, itemCount: this.items.length, dataView: this, callingOnRowsChanged: (diff.length > 0) }, null, this);\n }\n if (diff.length > 0) {\n this.onRowsChanged.notify({ rows: diff, itemCount: this.items.length, dataView: this, calledOnRowCountChanged: (countBefore !== this.rows.length) }, null, this);\n }\n if (countBefore !== this.rows.length || diff.length > 0) {\n this.onRowsOrCountChanged.notify({\n rowsDiff: diff, previousRowCount: countBefore, currentRowCount: this.rows.length, itemCount: this.items.length,\n rowCountChanged: countBefore !== this.rows.length, rowsChanged: diff.length > 0, dataView: this\n }, null, this);\n }\n }\n\n /**\n * Wires the grid and the DataView together to keep row selection tied to item ids.\n * This is useful since, without it, the grid only knows about rows, so if the items\n * move around, the same rows stay selected instead of the selection moving along\n * with the items.\n *\n * NOTE: This doesn't work with cell selection model.\n *\n * @param {SlickGrid} grid - The grid to sync selection with.\n * @param {Boolean} preserveHidden - Whether to keep selected items that go out of the\n * view due to them getting filtered out.\n * @param {Boolean} [preserveHiddenOnSelectionChange] - Whether to keep selected items\n * that are currently out of the view (see preserveHidden) as selected when selection\n * changes.\n * @return {Event} An event that notifies when an internal list of selected row ids\n * changes. This is useful since, in combination with the above two options, it allows\n * access to the full list selected row ids, and not just the ones visible to the grid.\n * @method syncGridSelection\n */\n syncGridSelection(grid: SlickGrid, preserveHidden: boolean, preserveHiddenOnSelectionChange?: boolean) {\n this._grid = grid;\n let inHandler: boolean;\n this.selectedRowIds = this.mapRowsToIds(grid.getSelectedRows());\n\n /** @param {Array} rowIds */\n const setSelectedRowIds = (rowIds: DataIdType[] | false) => {\n if (rowIds === false) {\n this.selectedRowIds = [];\n } else {\n if (this.selectedRowIds!.sort().join(',') !== rowIds.sort().join(',')) {\n this.selectedRowIds = rowIds;\n }\n }\n }\n\n const update = () => {\n if ((this.selectedRowIds || []).length > 0 && !inHandler) {\n inHandler = true;\n const selectedRows = this.mapIdsToRows(this.selectedRowIds || []);\n if (!preserveHidden) {\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: this.mapRowsToIds(selectedRows),\n rows: selectedRows,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n grid.setSelectedRows(selectedRows);\n inHandler = false;\n }\n }\n\n grid.onSelectedRowsChanged.subscribe((_e: Event, args: { rows: number[]; }) => {\n if (!inHandler) {\n const newSelectedRowIds = this.mapRowsToIds(args.rows);\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: newSelectedRowIds,\n rows: args.rows,\n added: true,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n });\n\n this.preSelectedRowIdsChangeFn = (args: { ids: DataIdType[]; added?: boolean; }) => {\n if (!inHandler) {\n inHandler = true;\n const overwrite = (typeof args.added === typeof undefined);\n\n if (overwrite) {\n setSelectedRowIds(args.ids);\n } else {\n let rowIds: DataIdType[];\n if (args.added) {\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\n // find the ones that are hidden\n const hiddenSelectedRowIds = this.selectedRowIds?.filter((id) => this.getRowById(id) === undefined);\n // add the newly selected ones\n rowIds = hiddenSelectedRowIds!.concat(args.ids);\n } else {\n rowIds = args.ids;\n }\n } else {\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\n // remove rows whose id is on the list\n rowIds = this.selectedRowIds!.filter((id) => args.ids.indexOf(id) === -1);\n } else {\n rowIds = [];\n }\n }\n setSelectedRowIds(rowIds);\n }\n inHandler = false;\n }\n };\n\n this.onRowsOrCountChanged.subscribe(update.bind(this));\n\n return this.onSelectedRowIdsChanged;\n }\n\n /**\n * Get all selected IDs\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedIds() {\n return this.selectedRowIds;\n }\n\n /**\n * Get all selected filtered IDs (similar to \"getAllSelectedIds\" but only return filtered data)\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedFilteredIds() {\n return this.getAllSelectedFilteredItems().map((item) => item[this.idProperty as keyof TData]);\n }\n\n /**\n * Set current row selected IDs array (regardless of Pagination)\n * NOTE: This will NOT change the selection in the grid, if you need to do that then you still need to call\n * \"grid.setSelectedRows(rows)\"\n * @param {Array} selectedIds - list of IDs which have been selected for this action\n * @param {Object} options\n * - `isRowBeingAdded`: defaults to true, are the new selected IDs being added (or removed) as new row selections\n * - `shouldTriggerEvent`: defaults to true, should we trigger `onSelectedRowIdsChanged` event\n * - `applyRowSelectionToGrid`: defaults to true, should we apply the row selections to the grid in the UI\n */\n setSelectedIds(selectedIds: Array, options?: Partial<{ isRowBeingAdded: boolean; shouldTriggerEvent: boolean; applyRowSelectionToGrid: boolean; }>) {\n let isRowBeingAdded = options?.isRowBeingAdded;\n const shouldTriggerEvent = options?.shouldTriggerEvent;\n const applyRowSelectionToGrid = options?.applyRowSelectionToGrid;\n\n if (isRowBeingAdded !== false) {\n isRowBeingAdded = true;\n }\n const selectedRows = this.mapIdsToRows(selectedIds);\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: selectedIds,\n rows: selectedRows,\n added: isRowBeingAdded,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn?.(selectedRowsChangedArgs);\n\n if (shouldTriggerEvent !== false) {\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n\n // should we also apply the row selection in to the grid (UI) as well?\n if (applyRowSelectionToGrid !== false && this._grid) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n /**\n * Get all selected dataContext items\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedItems() {\n const selectedData: TData[] = [];\n const selectedIds = this.getAllSelectedIds();\n selectedIds!.forEach((id) => {\n selectedData.push(this.getItemById(id));\n });\n return selectedData as T[];\n }\n\n /**\n * Get all selected filtered dataContext items (similar to \"getAllSelectedItems\" but only return filtered data)\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedFilteredItems() {\n if (!Array.isArray(this.selectedRowIds)) {\n return [];\n }\n\n const intersection = this.filteredItems.filter((a) => this.selectedRowIds!.some((b) => a[this.idProperty as keyof TData] === b));\n return (intersection || []) as T[];\n }\n\n syncGridCellCssStyles(grid: SlickGrid, key: string) {\n let hashById: any;\n let inHandler: boolean;\n\n const storeCellCssStyles = (hash: CssStyleHash) => {\n hashById = {};\n for (const row in hash) {\n const id = this.rows[row as any][this.idProperty as keyof TData];\n hashById[id] = hash[row];\n }\n }\n\n // since this method can be called after the cell styles have been set,\n // get the existing ones right away\n storeCellCssStyles(grid.getCellCssStyles(key));\n\n const update = () => {\n if (hashById) {\n inHandler = true;\n this.ensureRowsByIdCache();\n const newHash: CssStyleHash = {};\n for (const id in hashById) {\n const row = this.rowsById?.[id];\n if (row != undefined) {\n newHash[row] = hashById[id];\n }\n }\n grid.setCellCssStyles(key, newHash);\n inHandler = false;\n }\n }\n\n grid.onCellCssStylesChanged.subscribe((_e, args) => {\n if (inHandler) { return; }\n if (key != args.key) { return; }\n if (args.hash) {\n storeCellCssStyles(args.hash);\n } else {\n grid.onCellCssStylesChanged.unsubscribe();\n this.onRowsOrCountChanged.unsubscribe(update);\n }\n });\n\n this.onRowsOrCountChanged.subscribe(update.bind(this));\n }\n}\n\nexport class AvgAggregator implements Aggregator {\n private _nonNullCount = 0;\n private _sum = 0;\n private _field: number | string;\n private _type = 'avg' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n this._nonNullCount = 0;\n this._sum = 0;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n this._nonNullCount++;\n this._sum += parseFloat(val);\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { avg: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n (groupTotals as any)[this._type] = {};\n }\n if (this._nonNullCount !== 0) {\n groupTotals[this._type][this._field] = this._sum / this._nonNullCount;\n }\n }\n}\n\nexport class MinAggregator implements Aggregator {\n private _min: number | null = null;\n private _field: number | string;\n private _type = 'min' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init() {\n this._min = null;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n if (this._min === null || val < this._min) {\n this._min = parseFloat(val);\n }\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { min: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._min;\n }\n}\n\nexport class MaxAggregator implements Aggregator {\n private _max: number | null = null;\n private _field: number | string;\n private _type = 'max' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n this._max = null;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n if (this._max === null || val > this._max) {\n this._max = parseFloat(val);\n }\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { max: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._max;\n }\n}\n\nexport class SumAggregator implements Aggregator {\n private _sum = 0;\n private _field: number | string;\n private _type = 'sum' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init() {\n this._sum = 0;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n this._sum += parseFloat(val);\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { sum: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._sum;\n }\n}\n\nexport class CountAggregator implements Aggregator {\n private _field: number | string;\n private _type = 'count' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { count: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = groupTotals.group.rows.length;\n }\n}\n\n// TODO: add more built-in aggregators\n// TODO: merge common aggregators in one to prevent needless iterating\n\nexport const Aggregators = {\n Avg: AvgAggregator,\n Min: MinAggregator,\n Max: MaxAggregator,\n Sum: SumAggregator,\n Count: CountAggregator\n};\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Data = window.Slick.Data || {};\n window.Slick.Data.DataView = SlickDataView;\n window.Slick.Data.Aggregators = Aggregators;\n}"], - "mappings": "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", + "sourcesContent": ["import type {\n Aggregator,\n CssStyleHash,\n CustomDataView,\n Grouping,\n GroupingFormatterItem,\n ItemMetadata,\n OnGroupCollapsedEventArgs,\n OnGroupExpandedEventArgs,\n OnRowCountChangedEventArgs,\n OnRowsChangedEventArgs,\n OnRowsOrCountChangedEventArgs,\n OnSelectedRowIdsChangedEventArgs,\n OnSetItemsCalledEventArgs,\n PagingInfo,\n} from './models/index';\nimport {\n SlickEvent as SlickEvent_,\n SlickEventData as SlickEventData_,\n SlickGroup as SlickGroup_,\n SlickGroupTotals as SlickGroupTotals_,\n Utils as Utils_,\n SlickNonDataItem,\n} from './slick.core';\nimport type { SlickGrid } from './slick.grid';\nimport { SlickGroupItemMetadataProvider as SlickGroupItemMetadataProvider_ } from './slick.groupitemmetadataprovider';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst SlickGroup = IIFE_ONLY ? Slick.Group : SlickGroup_;\nconst SlickGroupTotals = IIFE_ONLY ? Slick.GroupTotals : SlickGroupTotals_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\nconst SlickGroupItemMetadataProvider = IIFE_ONLY ? Slick.Data?.GroupItemMetadataProvider ?? {} : SlickGroupItemMetadataProvider_;\n\nexport interface DataViewOption {\n groupItemMetadataProvider: SlickGroupItemMetadataProvider_ | null;\n inlineFilters: boolean;\n}\nexport type FilterFn = (item: T, args: any) => boolean;\nexport type DataIdType = number | string;\nexport type SlickDataItem = SlickNonDataItem | SlickGroup_ | SlickGroupTotals_ | any;\n\n/**\n * A sample Model implementation.\n * Provides a filtered view of the underlying data.\n *\n * Relies on the data item having an \"id\" property uniquely identifying it.\n */\nexport class SlickDataView implements CustomDataView {\n protected defaults: DataViewOption = {\n groupItemMetadataProvider: null,\n inlineFilters: false\n };\n\n // private\n protected idProperty = 'id'; // property holding a unique row id\n protected items: TData[] = []; // data by index\n protected rows: TData[] = []; // data by row\n protected idxById = new Map(); // indexes by id\n protected rowsById: { [id: DataIdType]: number } | undefined = undefined; // rows by id; lazy-calculated\n protected filter: FilterFn | null = null; // filter function\n protected updated: ({ [id: DataIdType]: boolean }) | null = null; // updated item ids\n protected suspend = false; // suspends the recalculation\n protected isBulkSuspend = false; // delays protectedious operations like the\n // index update and delete to efficient\n // versions at endUpdate\n protected bulkDeleteIds = new Map();\n protected sortAsc: boolean | undefined = true;\n protected fastSortField?: string | null | (() => string);\n protected sortComparer!: ((a: TData, b: TData) => number);\n protected refreshHints: any = {};\n protected prevRefreshHints: any = {};\n protected filterArgs: any;\n protected filteredItems: TData[] = [];\n protected compiledFilter?: FilterFn | null;\n protected compiledFilterWithCaching?: FilterFn | null;\n protected filterCache: any[] = [];\n protected _grid?: SlickGrid; // grid object will be defined only after using \"syncGridSelection()\" method\"\n\n // grouping\n protected groupingInfoDefaults: Grouping = {\n getter: undefined,\n formatter: undefined,\n comparer: (a: { value: any; }, b: { value: any; }) => (a.value === b.value ? 0 : (a.value > b.value ? 1 : -1)),\n predefinedValues: [],\n aggregators: [],\n aggregateEmpty: false,\n aggregateCollapsed: false,\n aggregateChildGroups: false,\n collapsed: false,\n displayTotalsRow: true,\n lazyTotalsCalculation: false\n };\n protected groupingInfos: Array = [];\n protected groups: SlickGroup_[] = [];\n protected toggledGroupsByLevel: any[] = [];\n protected groupingDelimiter = ':|:';\n protected selectedRowIds: DataIdType[] = [];\n protected preSelectedRowIdsChangeFn?: Function;\n\n protected pagesize = 0;\n protected pagenum = 0;\n protected totalRows = 0;\n protected _options: DataViewOption;\n\n // public events\n onBeforePagingInfoChanged = new SlickEvent();\n onGroupExpanded = new SlickEvent();\n onGroupCollapsed = new SlickEvent();\n onPagingInfoChanged = new SlickEvent();\n onRowCountChanged = new SlickEvent();\n onRowsChanged = new SlickEvent();\n onRowsOrCountChanged = new SlickEvent();\n onSelectedRowIdsChanged = new SlickEvent();\n onSetItemsCalled = new SlickEvent();\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this.defaults, options);\n }\n\n /**\n * Begins a bached update of the items in the data view.\n * including deletes and the related events are postponed to the endUpdate call.\n * As certain operations are postponed during this update, some methods might not\n * deliver fully consistent information.\n * @param {Boolean} [bulkUpdate] - if set to true, most data view modifications\n */\n beginUpdate(bulkUpdate?: boolean) {\n this.suspend = true;\n this.isBulkSuspend = bulkUpdate === true;\n }\n\n endUpdate() {\n const wasBulkSuspend = this.isBulkSuspend;\n this.isBulkSuspend = false;\n this.suspend = false;\n if (wasBulkSuspend) {\n this.processBulkDelete();\n this.ensureIdUniqueness();\n }\n this.refresh();\n }\n\n destroy() {\n this.items = [];\n this.idxById = null as any;\n this.rowsById = null as any;\n this.filter = null as any;\n this.updated = null as any;\n this.sortComparer = null as any;\n this.filterCache = [];\n this.filteredItems = [];\n this.compiledFilter = null;\n this.compiledFilterWithCaching = null;\n\n if (this._grid && this._grid.onSelectedRowsChanged && this._grid.onCellCssStylesChanged) {\n this._grid.onSelectedRowsChanged.unsubscribe();\n this._grid.onCellCssStylesChanged.unsubscribe();\n }\n if (this.onRowsOrCountChanged) {\n this.onRowsOrCountChanged.unsubscribe();\n }\n }\n\n setRefreshHints(hints: any) {\n this.refreshHints = hints;\n }\n\n setFilterArgs(args: any) {\n this.filterArgs = args;\n }\n\n /**\n * Processes all delete requests placed during bulk update\n * by recomputing the items and idxById members.\n */\n protected processBulkDelete() {\n if (!this.idxById) { return; }\n\n // the bulk update is processed by\n // recomputing the whole items array and the index lookup in one go.\n // this is done by placing the not-deleted items\n // from left to right into the array and shrink the array the the new\n // size afterwards.\n // see https://github.com/6pac/SlickGrid/issues/571 for further details.\n\n let id: DataIdType, item, newIdx = 0;\n for (let i = 0, l = this.items.length; i < l; i++) {\n item = this.items[i];\n id = item[this.idProperty as keyof TData] as DataIdType;\n if (id === undefined) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n\n // if items have been marked as deleted we skip them for the new final items array\n // and we remove them from the lookup table.\n if (this.bulkDeleteIds.has(id)) {\n this.idxById.delete(id);\n } else {\n // for items which are not deleted, we add them to the\n // next free position in the array and register the index in the lookup.\n this.items[newIdx] = item;\n this.idxById.set(id, newIdx);\n ++newIdx;\n }\n }\n\n // here we shrink down the full item array to the ones actually\n // inserted in the cleanup loop above.\n this.items.length = newIdx;\n // and finally cleanup the deleted ids to start cleanly on the next update.\n this.bulkDeleteIds = new Map();\n }\n\n protected updateIdxById(startingIndex?: number) {\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\n return;\n }\n startingIndex = startingIndex || 0;\n let id: DataIdType;\n for (let i = startingIndex, l = this.items.length; i < l; i++) {\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\n if (id === undefined) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n this.idxById.set(id, i);\n }\n }\n\n protected ensureIdUniqueness() {\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\n return;\n }\n let id: DataIdType;\n for (let i = 0, l = this.items.length; i < l; i++) {\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\n if (id === undefined || this.idxById.get(id) !== i) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n }\n }\n\n /** Get all DataView Items */\n getItems() {\n return this.items;\n }\n\n /** Get the DataView Id property name to use (defaults to \"Id\" but could be customized to something else when instantiating the DataView) */\n getIdPropertyName() {\n return this.idProperty;\n }\n\n /**\n * Set the Items with a new Dataset and optionally pass a different Id property name\n * @param {Array<*>} data - array of data\n * @param {String} [objectIdProperty] - optional id property to use as primary id\n */\n setItems(data: TData[], objectIdProperty?: string) {\n if (objectIdProperty !== undefined) {\n this.idProperty = objectIdProperty;\n }\n this.items = this.filteredItems = data;\n this.onSetItemsCalled.notify({ idProperty: this.idProperty, itemCount: this.items.length }, null, this);\n this.idxById = new Map();\n this.updateIdxById();\n this.ensureIdUniqueness();\n this.refresh();\n }\n\n /** Set Paging Options */\n setPagingOptions(args: Partial) {\n if (this.onBeforePagingInfoChanged.notify(this.getPagingInfo(), null, this).getReturnValue() !== false) {\n if (Utils.isDefined(args.pageSize)) {\n this.pagesize = args.pageSize;\n this.pagenum = this.pagesize ? Math.min(this.pagenum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1)) : 0;\n }\n\n if (Utils.isDefined(args.pageNum)) {\n this.pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1));\n }\n\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\n\n this.refresh();\n }\n }\n\n /** Get Paging Options */\n getPagingInfo(): PagingInfo {\n const totalPages = this.pagesize ? Math.max(1, Math.ceil(this.totalRows / this.pagesize)) : 1;\n return { pageSize: this.pagesize, pageNum: this.pagenum, totalRows: this.totalRows, totalPages, dataView: this as SlickDataView };\n }\n\n /** Sort Method to use by the DataView */\n sort(comparer: (a: TData, b: TData) => number, ascending?: boolean) {\n this.sortAsc = ascending;\n this.sortComparer = comparer;\n this.fastSortField = null;\n if (ascending === false) {\n this.items.reverse();\n }\n this.items.sort(comparer);\n if (ascending === false) {\n this.items.reverse();\n }\n this.idxById = new Map();\n this.updateIdxById();\n this.refresh();\n }\n\n /**\n * Provides a workaround for the extremely slow sorting in IE.\n * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString\n * to return the value of that field and then doing a native Array.sort().\n */\n fastSort(field: string | (() => string), ascending?: boolean) {\n this.sortAsc = ascending;\n this.fastSortField = field;\n this.sortComparer = null as any;\n const oldToString = Object.prototype.toString;\n Object.prototype.toString = (typeof field === 'function') ? field : function () {\n // @ts-ignore\n return this[field];\n };\n // an extra reversal for descending sort keeps the sort stable\n // (assuming a stable native sort implementation, which isn't true in some cases)\n if (ascending === false) {\n this.items.reverse();\n }\n this.items.sort();\n Object.prototype.toString = oldToString;\n if (ascending === false) {\n this.items.reverse();\n }\n this.idxById = new Map();\n this.updateIdxById();\n this.refresh();\n }\n\n /** Re-Sort the dataset */\n reSort() {\n if (this.sortComparer) {\n this.sort(this.sortComparer, this.sortAsc);\n } else if (this.fastSortField) {\n this.fastSort(this.fastSortField, this.sortAsc);\n }\n }\n\n /** Get only the DataView filtered items */\n getFilteredItems() {\n return this.filteredItems as T[];\n }\n\n /** Get the array length (count) of only the DataView filtered items */\n getFilteredItemCount() {\n return this.filteredItems.length;\n }\n\n /** Get current Filter used by the DataView */\n getFilter() {\n return this.filter;\n }\n\n /**\n * Set a Filter that will be used by the DataView\n * @param {Function} fn - filter callback function\n */\n setFilter(filterFn: FilterFn) {\n this.filter = filterFn;\n if (this._options.inlineFilters) {\n this.compiledFilter = this.compileFilter();\n this.compiledFilterWithCaching = this.compileFilterWithCaching();\n }\n this.refresh();\n }\n\n /** Get current Grouping info */\n getGrouping(): Grouping[] {\n return this.groupingInfos;\n }\n\n /** Set some Grouping */\n setGrouping(groupingInfo: Grouping | Grouping[]) {\n if (!this._options.groupItemMetadataProvider) {\n this._options.groupItemMetadataProvider = new SlickGroupItemMetadataProvider();\n }\n\n this.groups = [];\n this.toggledGroupsByLevel = [];\n groupingInfo = groupingInfo || [];\n this.groupingInfos = ((groupingInfo instanceof Array) ? groupingInfo : [groupingInfo]) as any;\n\n for (let i = 0; i < this.groupingInfos.length; i++) {\n const gi = this.groupingInfos[i] = Utils.extend(true, {}, this.groupingInfoDefaults, this.groupingInfos[i]);\n gi.getterIsAFn = typeof gi.getter === 'function';\n\n // pre-compile accumulator loops\n gi.compiledAccumulators = [];\n let idx = gi.aggregators.length;\n while (idx--) {\n gi.compiledAccumulators[idx] = this.compileAccumulatorLoop(gi.aggregators[idx]);\n }\n\n this.toggledGroupsByLevel[i] = {};\n }\n\n this.refresh();\n }\n\n /** Get an item in the DataView by its row index */\n getItemByIdx(i: number) {\n return this.items[i] as T;\n }\n\n /** Get row index in the DataView by its Id */\n getIdxById(id: DataIdType) {\n return this.idxById?.get(id);\n }\n\n protected ensureRowsByIdCache() {\n if (!this.rowsById) {\n this.rowsById = {};\n for (let i = 0, l = this.rows.length; i < l; i++) {\n this.rowsById[this.rows[i][this.idProperty as keyof TData] as DataIdType] = i;\n }\n }\n }\n\n /** Get row number in the grid by its item object */\n getRowByItem(item: TData) {\n this.ensureRowsByIdCache();\n return this.rowsById?.[item[this.idProperty as keyof TData] as DataIdType];\n }\n\n /** Get row number in the grid by its Id */\n getRowById(id: DataIdType) {\n this.ensureRowsByIdCache();\n return this.rowsById?.[id];\n }\n\n /** Get an item in the DataView by its Id */\n getItemById(id: DataIdType) {\n return this.items[(this.idxById.get(id) as number)] as T;\n }\n\n /** From the items array provided, return the mapped rows */\n mapItemsToRows(itemArray: TData[]) {\n const rows: number[] = [];\n this.ensureRowsByIdCache();\n for (let i = 0, l = itemArray.length; i < l; i++) {\n const row = this.rowsById?.[itemArray[i][this.idProperty as keyof TData] as DataIdType];\n if (Utils.isDefined(row)) {\n rows[rows.length] = row;\n }\n }\n return rows;\n }\n\n /** From the Ids array provided, return the mapped rows */\n mapIdsToRows(idArray: DataIdType[]) {\n const rows: number[] = [];\n this.ensureRowsByIdCache();\n for (let i = 0, l = idArray.length; i < l; i++) {\n const row = this.rowsById?.[idArray[i]];\n if (Utils.isDefined(row)) {\n rows[rows.length] = row;\n }\n }\n return rows;\n }\n\n /** From the rows array provided, return the mapped Ids */\n mapRowsToIds(rowArray: number[]) {\n const ids: DataIdType[] = [];\n for (let i = 0, l = rowArray.length; i < l; i++) {\n if (rowArray[i] < this.rows.length) {\n const rowItem = this.rows[rowArray[i]];\n ids[ids.length] = rowItem![this.idProperty as keyof TData] as DataIdType;\n }\n }\n return ids;\n }\n\n /**\n * Performs the update operations of a single item by id without\n * triggering any events or refresh operations.\n * @param id The new id of the item.\n * @param item The item which should be the new value for the given id.\n */\n updateSingleItem(id: DataIdType, item: TData) {\n if (!this.idxById) { return; }\n\n // see also https://github.com/mleibman/SlickGrid/issues/1082\n if (!this.idxById.has(id)) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n\n // What if the specified item also has an updated idProperty?\n // Then we'll have to update the index as well, and possibly the `updated` cache too.\n if (id !== item[this.idProperty as keyof TData]) {\n // make sure the new id is unique:\n const newId = item[this.idProperty as keyof TData] as DataIdType;\n if (!Utils.isDefined(newId)) {\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a null id');\n }\n if (this.idxById.has(newId)) {\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a non-unique id');\n }\n this.idxById.set(newId, this.idxById.get(id) as number);\n this.idxById.delete(id);\n\n // Also update the `updated` hashtable/markercache? Yes, `recalc()` inside `refresh()` needs that one!\n if (this.updated?.[id]) {\n delete this.updated[id];\n }\n\n // Also update the row indexes? no need since the `refresh()`, further down, blows away the `rowsById[]` cache!\n\n id = newId;\n }\n this.items[this.idxById.get(id) as number] = item;\n\n // Also update the rows? no need since the `refresh()`, further down, blows away the `rows[]` cache and recalculates it via `recalc()`!\n\n if (!this.updated) {\n this.updated = {};\n }\n this.updated[id] = true;\n }\n\n /**\n * Updates a single item in the data view given the id and new value.\n * @param id The new id of the item.\n * @param item The item which should be the new value for the given id.\n */\n updateItem(id: DataIdType, item: T) {\n this.updateSingleItem(id, item);\n this.refresh();\n }\n\n /**\n * Updates multiple items in the data view given the new ids and new values.\n * @param id {Array} The array of new ids which is in the same order as the items.\n * @param newItems {Array} The new items that should be set in the data view for the given ids.\n */\n updateItems(ids: DataIdType[], newItems: T[]) {\n if (ids.length !== newItems.length) {\n throw new Error(\"[SlickGrid DataView] Mismatch on the length of ids and items provided to update\");\n }\n for (let i = 0, l = newItems.length; i < l; i++) {\n this.updateSingleItem(ids[i], newItems[i]);\n }\n this.refresh();\n }\n\n /**\n * Inserts a single item into the data view at the given position.\n * @param insertBefore {Number} The 0-based index before which the item should be inserted.\n * @param item The item to insert.\n */\n insertItem(insertBefore: number, item: TData) {\n this.items.splice(insertBefore, 0, item);\n this.updateIdxById(insertBefore);\n this.refresh();\n }\n\n /**\n * Inserts multiple items into the data view at the given position.\n * @param insertBefore {Number} The 0-based index before which the items should be inserted.\n * @param newItems {Array} The items to insert.\n */\n insertItems(insertBefore: number, newItems: TData[]) {\n // @ts-ignore\n Array.prototype.splice.apply(this.items, [insertBefore, 0].concat(newItems));\n this.updateIdxById(insertBefore);\n this.refresh();\n }\n\n /**\n * Adds a single item at the end of the data view.\n * @param item The item to add at the end.\n */\n addItem(item: TData) {\n this.items.push(item);\n this.updateIdxById(this.items.length - 1);\n this.refresh();\n }\n\n /**\n * Adds multiple items at the end of the data view.\n * @param {Array} newItems The items to add at the end.\n */\n addItems(newItems: TData[]) {\n this.items = this.items.concat(newItems);\n this.updateIdxById(this.items.length - newItems.length);\n this.refresh();\n }\n\n /**\n * Deletes a single item identified by the given id from the data view.\n * @param {String|Number} id The id identifying the object to delete.\n */\n deleteItem(id: DataIdType) {\n if (!this.idxById) { return; }\n if (this.isBulkSuspend) {\n this.bulkDeleteIds.set(id, true);\n } else {\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.idxById.delete(id);\n this.items.splice(idx, 1);\n this.updateIdxById(idx);\n this.refresh();\n }\n }\n\n /**\n * Deletes multiple item identified by the given ids from the data view.\n * @param {Array} ids The ids of the items to delete.\n */\n deleteItems(ids: DataIdType[]) {\n if (ids.length === 0 || !this.idxById) {\n return;\n }\n\n if (this.isBulkSuspend) {\n for (let i = 0, l = ids.length; i < l; i++) {\n const id = ids[i];\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.bulkDeleteIds.set(id, true);\n }\n } else {\n // collect all indexes\n const indexesToDelete: number[] = [];\n for (let i = 0, l = ids.length; i < l; i++) {\n const id = ids[i];\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.idxById.delete(id);\n indexesToDelete.push(idx);\n }\n\n // Remove from back to front\n indexesToDelete.sort();\n for (let i = indexesToDelete.length - 1; i >= 0; --i) {\n this.items.splice(indexesToDelete[i], 1);\n }\n\n // update lookup from front to back\n this.updateIdxById(indexesToDelete[0]);\n this.refresh();\n }\n }\n\n /** Add an item in a sorted dataset (a Sort function must be defined) */\n sortedAddItem(item: TData) {\n if (!this.sortComparer) {\n throw new Error('[SlickGrid DataView] sortedAddItem() requires a sort comparer, use sort()');\n }\n this.insertItem(this.sortedIndex(item), item);\n }\n\n /** Update an item in a sorted dataset (a Sort function must be defined) */\n sortedUpdateItem(id: string | number, item: TData) {\n if (!this.idxById) { return; }\n if (!this.idxById.has(id) || id !== item[this.idProperty as keyof TData]) {\n throw new Error('[SlickGrid DataView] Invalid or non-matching id ' + this.idxById.get(id));\n }\n if (!this.sortComparer) {\n throw new Error(\"[SlickGrid DataView] sortedUpdateItem() requires a sort comparer, use sort()\");\n }\n const oldItem = this.getItemById(id);\n if (this.sortComparer(oldItem, item) !== 0) {\n // item affects sorting -> must use sorted add\n this.deleteItem(id);\n this.sortedAddItem(item);\n } else { // update does not affect sorting -> regular update works fine\n this.updateItem(id, item);\n }\n }\n\n protected sortedIndex(searchItem: TData) {\n let low = 0;\n let high = this.items.length;\n\n while (low < high) {\n const mid = low + high >>> 1;\n if (this.sortComparer(this.items[mid], searchItem) === -1) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return low;\n }\n\n /** Get item count, that is the full dataset lenght of the DataView */\n getItemCount() {\n return this.items.length;\n }\n\n /** Get row count (rows displayed in current page) */\n getLength() {\n return this.rows.length;\n }\n\n /** Retrieve an item from the DataView at specific index */\n getItem(i: number) {\n const item = this.rows[i] as T;\n\n // if this is a group row, make sure totals are calculated and update the title\n if ((item as SlickGroup_)?.__group && (item as SlickGroup_).totals && !(item as SlickGroup_).totals?.initialized) {\n const gi = this.groupingInfos[(item as SlickGroup_).level];\n if (!gi.displayTotalsRow) {\n this.calculateTotals((item as SlickGroup_).totals);\n (item as SlickGroup_).title = gi.formatter ? gi.formatter((item as SlickGroup_)) : (item as SlickGroup_).value;\n }\n }\n // if this is a totals row, make sure it's calculated\n else if ((item as SlickGroupTotals_)?.__groupTotals && !(item as SlickGroupTotals_).initialized) {\n this.calculateTotals(item as SlickGroupTotals_);\n }\n\n return item;\n }\n\n getItemMetadata(i: number): ItemMetadata | null {\n const item = this.rows[i];\n if (item === undefined) {\n return null;\n }\n\n // overrides for grouping rows\n if ((item as SlickGroup_).__group) {\n return this._options.groupItemMetadataProvider!.getGroupRowMetadata(item as GroupingFormatterItem);\n }\n\n // overrides for totals rows\n if ((item as SlickGroupTotals_).__groupTotals) {\n return this._options.groupItemMetadataProvider!.getTotalsRowMetadata(item as { group: GroupingFormatterItem });\n }\n\n return null;\n }\n\n protected expandCollapseAllGroups(level?: number, collapse?: boolean) {\n if (!Utils.isDefined(level)) {\n for (let i = 0; i < this.groupingInfos.length; i++) {\n this.toggledGroupsByLevel[i] = {};\n this.groupingInfos[i].collapsed = collapse;\n\n if (collapse === true) {\n this.onGroupCollapsed.notify({ level: i, groupingKey: null });\n } else {\n this.onGroupExpanded.notify({ level: i, groupingKey: null });\n }\n }\n } else {\n this.toggledGroupsByLevel[level] = {};\n this.groupingInfos[level].collapsed = collapse;\n\n if (collapse === true) {\n this.onGroupCollapsed.notify({ level, groupingKey: null });\n } else {\n this.onGroupExpanded.notify({ level, groupingKey: null });\n }\n }\n this.refresh();\n }\n\n /**\n * @param {Number} [level] Optional level to collapse. If not specified, applies to all levels.\n */\n collapseAllGroups(level?: number) {\n this.expandCollapseAllGroups(level, true);\n }\n\n /**\n * @param {Number} [level] Optional level to expand. If not specified, applies to all levels.\n */\n expandAllGroups(level?: number) {\n this.expandCollapseAllGroups(level, false);\n }\n\n expandCollapseGroup(level: number, groupingKey: string, collapse?: boolean) {\n // @ts-ignore\n this.toggledGroupsByLevel[level][groupingKey] = this.groupingInfos[level].collapsed ^ collapse;\n this.refresh();\n }\n\n /**\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\n * variable argument list of grouping values denoting a unique path to the row. For\n * example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of\n * the 'high' group.\n */\n collapseGroup(...args: any) {\n const calledArgs = Array.prototype.slice.call(args);\n const arg0 = calledArgs[0];\n let groupingKey;\n let level;\n\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\n groupingKey = arg0;\n level = arg0.split(this.groupingDelimiter).length - 1;\n } else {\n groupingKey = args.join(this.groupingDelimiter);\n level = args.length - 1;\n }\n\n this.expandCollapseGroup(level, groupingKey, true);\n this.onGroupCollapsed.notify({ level, groupingKey });\n }\n\n /**\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\n * variable argument list of grouping values denoting a unique path to the row. For\n * example, calling expandGroup('high', '10%') will expand the '10%' subgroup of\n * the 'high' group.\n */\n expandGroup(...args: any) {\n const calledArgs = Array.prototype.slice.call(args);\n const arg0 = calledArgs[0];\n let groupingKey;\n let level;\n\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\n level = arg0.split(this.groupingDelimiter).length - 1;\n groupingKey = arg0;\n } else {\n level = args.length - 1;\n groupingKey = args.join(this.groupingDelimiter);\n }\n\n this.expandCollapseGroup(level, groupingKey, false);\n this.onGroupExpanded.notify({ level, groupingKey });\n }\n\n getGroups() {\n return this.groups;\n }\n\n protected extractGroups(rows: any[], parentGroup?: SlickGroup_) {\n let group;\n let val;\n const groups: SlickGroup_[] = [];\n const groupsByVal: any = {};\n let r;\n const level = parentGroup ? parentGroup.level + 1 : 0;\n const gi = this.groupingInfos[level];\n\n for (let i = 0, l = gi.predefinedValues?.length ?? 0; i < l; i++) {\n val = gi.predefinedValues?.[i];\n group = groupsByVal[val];\n if (!group) {\n group = new SlickGroup();\n group.value = val;\n group.level = level;\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\n groups[groups.length] = group;\n groupsByVal[val] = group;\n }\n }\n\n for (let i = 0, l = rows.length; i < l; i++) {\n r = rows[i];\n val = gi.getterIsAFn ? (gi.getter as Function)(r) : r[gi.getter as keyof TData];\n group = groupsByVal[val];\n if (!group) {\n group = new SlickGroup();\n group.value = val;\n group.level = level;\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\n groups[groups.length] = group;\n groupsByVal[val] = group;\n }\n\n group.rows[group.count++] = r;\n }\n\n if (level < this.groupingInfos.length - 1) {\n for (let i = 0; i < groups.length; i++) {\n group = groups[i];\n group.groups = this.extractGroups(group.rows, group);\n }\n }\n\n if (groups.length) {\n this.addTotals(groups, level);\n }\n\n groups.sort(this.groupingInfos[level].comparer);\n\n return groups;\n }\n\n protected calculateTotals(totals: SlickGroupTotals_) {\n const group = totals.group;\n const gi = this.groupingInfos[group.level ?? 0];\n const isLeafLevel = (group.level === this.groupingInfos.length);\n let agg: Aggregator, idx = gi.aggregators.length;\n\n if (!isLeafLevel && gi.aggregateChildGroups) {\n // make sure all the subgroups are calculated\n let i = group.groups?.length ?? 0;\n while (i--) {\n if (!group.groups[i].totals.initialized) {\n this.calculateTotals(group.groups[i].totals);\n }\n }\n }\n\n while (idx--) {\n agg = gi.aggregators[idx];\n agg.init();\n if (!isLeafLevel && gi.aggregateChildGroups) {\n gi.compiledAccumulators[idx].call(agg, group.groups);\n } else {\n gi.compiledAccumulators[idx].call(agg, group.rows);\n }\n agg.storeResult(totals);\n }\n totals.initialized = true;\n }\n\n protected addGroupTotals(group: SlickGroup_) {\n const gi = this.groupingInfos[group.level];\n const totals = new SlickGroupTotals();\n totals.group = group;\n group.totals = totals;\n if (!gi.lazyTotalsCalculation) {\n this.calculateTotals(totals);\n }\n }\n\n protected addTotals(groups: SlickGroup_[], level?: number) {\n level = level || 0;\n const gi = this.groupingInfos[level];\n const groupCollapsed = gi.collapsed;\n const toggledGroups = this.toggledGroupsByLevel[level];\n let idx = groups.length, g;\n while (idx--) {\n g = groups[idx];\n\n if (g.collapsed && !gi.aggregateCollapsed) {\n continue;\n }\n\n // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.\n if (g.groups) {\n this.addTotals(g.groups, level + 1);\n }\n\n if (gi.aggregators?.length && (\n gi.aggregateEmpty || g.rows.length || g.groups?.length)) {\n this.addGroupTotals(g);\n }\n\n g.collapsed = (groupCollapsed as any) ^ toggledGroups[g.groupingKey];\n g.title = gi.formatter ? gi.formatter(g) : g.value;\n }\n }\n\n protected flattenGroupedRows(groups: SlickGroup_[], level?: number) {\n level = level || 0;\n const gi = this.groupingInfos[level];\n const groupedRows: any[] = [];\n let rows: any[], gl = 0, g;\n for (let i = 0, l = groups.length; i < l; i++) {\n g = groups[i];\n groupedRows[gl++] = g;\n\n if (!g.collapsed) {\n rows = g.groups ? this.flattenGroupedRows(g.groups, level + 1) : g.rows;\n for (let j = 0, jj = rows.length; j < jj; j++) {\n groupedRows[gl++] = rows[j];\n }\n }\n\n if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)) {\n groupedRows[gl++] = g.totals;\n }\n }\n return groupedRows;\n }\n\n protected getFunctionInfo(fn: Function) {\n const fnStr = fn.toString();\n const usingEs5 = fnStr.indexOf('function') >= 0; // with ES6, the word function is not present\n const fnRegex = usingEs5 ? /^function[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/ : /^[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/;\n const matches = fn.toString().match(fnRegex) || [];\n return {\n params: matches[1].split(\",\"),\n body: matches[2]\n };\n }\n\n protected compileAccumulatorLoop(aggregator: Aggregator) {\n if (aggregator.accumulate) {\n const accumulatorInfo = this.getFunctionInfo(aggregator.accumulate);\n const fn: any = new Function(\n \"_items\",\n \"for (var \" + accumulatorInfo.params[0] + \", _i=0, _il=_items.length; _i<_il; _i++) {\" +\n accumulatorInfo.params[0] + \" = _items[_i]; \" +\n accumulatorInfo.body +\n \"}\"\n );\n const fnName = \"compiledAccumulatorLoop\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n } else {\n return function noAccumulator() { };\n }\n }\n\n protected compileFilter(): FilterFn {\n const filterInfo = this.getFunctionInfo(this.filter as Function);\n\n const filterPath1 = \"{ continue _coreloop; }$1\";\n const filterPath2 = \"{ _retval[_idx++] = $item$; continue _coreloop; }$1\";\n // make some allowances for minification - there's only so far we can go with RegEx\n const filterBody = filterInfo.body\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\n \"{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2\");\n\n // This preserves the function template code after JS compression,\n // so that replace() commands still work as expected.\n let tpl = [\n //\"function(_items, _args) { \",\n \"var _retval = [], _idx = 0; \",\n \"var $item$, $args$ = _args; \",\n \"_coreloop: \",\n \"for (var _i = 0, _il = _items.length; _i < _il; _i++) { \",\n \"$item$ = _items[_i]; \",\n \"$filter$; \",\n \"} \",\n \"return _retval; \"\n //\"}\"\n ].join(\"\");\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\n const fn: any = new Function(\"_items,_args\", tpl);\n const fnName = \"compiledFilter\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n }\n\n protected compileFilterWithCaching() {\n const filterInfo = this.getFunctionInfo(this.filter as Function);\n\n const filterPath1 = \"{ continue _coreloop; }$1\";\n const filterPath2 = \"{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1\";\n // make some allowances for minification - there's only so far we can go with RegEx\n const filterBody = filterInfo.body\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\n \"{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2\");\n\n // This preserves the function template code after JS compression,\n // so that replace() commands still work as expected.\n let tpl = [\n //\"function(_items, _args, _cache) { \",\n \"var _retval = [], _idx = 0; \",\n \"var $item$, $args$ = _args; \",\n \"_coreloop: \",\n \"for (var _i = 0, _il = _items.length; _i < _il; _i++) { \",\n \"$item$ = _items[_i]; \",\n \"if (_cache[_i]) { \",\n \"_retval[_idx++] = $item$; \",\n \"continue _coreloop; \",\n \"} \",\n \"$filter$; \",\n \"} \",\n \"return _retval; \"\n //\"}\"\n ].join(\"\");\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\n const fn: any = new Function(\"_items,_args,_cache\", tpl);\n const fnName = \"compiledFilterWithCaching\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n }\n\n /**\n * In ES5 we could set the function name on the fly but in ES6 this is forbidden and we need to set it through differently\n * We can use Object.defineProperty and set it the property to writable, see MDN for reference\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n * @param {*} fn\n * @param {string} fnName\n */\n protected setFunctionName(fn: any, fnName: string) {\n try {\n Object.defineProperty(fn, 'name', {\n writable: true,\n value: fnName\n });\n } catch (err) {\n fn.name = fnName;\n }\n }\n\n protected uncompiledFilter(items: TData[], args: any) {\n const retval: any[] = [];\n let idx = 0;\n\n for (let i = 0, ii = items.length; i < ii; i++) {\n if (this.filter?.(items[i], args)) {\n retval[idx++] = items[i];\n }\n }\n\n return retval;\n }\n\n protected uncompiledFilterWithCaching(items: TData[], args: any, cache: any) {\n const retval: any[] = [];\n let idx = 0,\n item: TData;\n\n for (let i = 0, ii = items.length; i < ii; i++) {\n item = items[i];\n if (cache[i]) {\n retval[idx++] = item;\n } else if (this.filter?.(item, args)) {\n retval[idx++] = item;\n cache[i] = true;\n }\n }\n\n return retval;\n }\n\n protected getFilteredAndPagedItems(items: TData[]) {\n if (this.filter) {\n const batchFilter = (this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter) as Function;\n const batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching) as Function;\n\n if (this.refreshHints.isFilterNarrowing) {\n this.filteredItems = batchFilter.call(this, this.filteredItems, this.filterArgs);\n } else if (this.refreshHints.isFilterExpanding) {\n this.filteredItems = batchFilterWithCaching.call(this, items, this.filterArgs, this.filterCache);\n } else if (!this.refreshHints.isFilterUnchanged) {\n this.filteredItems = batchFilter.call(this, items, this.filterArgs);\n }\n } else {\n // special case: if not filtering and not paging, the resulting\n // rows collection needs to be a copy so that changes due to sort\n // can be caught\n this.filteredItems = this.pagesize ? items : items.concat();\n }\n\n // get the current page\n let paged: TData[];\n if (this.pagesize) {\n if (this.filteredItems.length <= this.pagenum * this.pagesize) {\n if (this.filteredItems.length === 0) {\n this.pagenum = 0;\n } else {\n this.pagenum = Math.floor((this.filteredItems.length - 1) / this.pagesize);\n }\n }\n paged = this.filteredItems.slice(this.pagesize * this.pagenum, this.pagesize * this.pagenum + this.pagesize);\n } else {\n paged = this.filteredItems;\n }\n return { totalRows: this.filteredItems.length, rows: paged };\n }\n\n protected getRowDiffs(rows: TData[], newRows: TData[]) {\n let item: any, r, eitherIsNonData;\n const diff: number[] = [];\n let from = 0, to = Math.max(newRows.length, rows.length);\n\n if (this.refreshHints?.ignoreDiffsBefore) {\n from = Math.max(0,\n Math.min(newRows.length, this.refreshHints.ignoreDiffsBefore));\n }\n\n if (this.refreshHints?.ignoreDiffsAfter) {\n to = Math.min(newRows.length,\n Math.max(0, this.refreshHints.ignoreDiffsAfter));\n }\n\n for (let i = from, rl = rows.length; i < to; i++) {\n if (i >= rl) {\n diff[diff.length] = i;\n } else {\n item = newRows[i];\n r = rows[i];\n\n if (!item || (this.groupingInfos.length && (eitherIsNonData = ((item as SlickNonDataItem).__nonDataRow) || ((r as SlickNonDataItem).__nonDataRow)) &&\n (item as SlickGroup_).__group !== (r as SlickGroup_).__group ||\n (item as SlickGroup_).__group && !(item as SlickGroup_).equals(r as SlickGroup_))\n || (eitherIsNonData &&\n // no good way to compare totals since they are arbitrary DTOs\n // deep object comparison is pretty expensive\n // always considering them 'dirty' seems easier for the time being\n ((item as SlickGroupTotals_).__groupTotals || (r as SlickGroupTotals_).__groupTotals))\n || item[this.idProperty as keyof TData] !== r[this.idProperty as keyof TData]\n || (this.updated?.[item[this.idProperty as keyof TData]])\n ) {\n diff[diff.length] = i;\n }\n }\n }\n return diff;\n }\n\n protected recalc(_items: TData[]) {\n this.rowsById = undefined;\n\n if (this.refreshHints.isFilterNarrowing !== this.prevRefreshHints.isFilterNarrowing ||\n this.refreshHints.isFilterExpanding !== this.prevRefreshHints.isFilterExpanding) {\n this.filterCache = [];\n }\n\n const filteredItems = this.getFilteredAndPagedItems(_items);\n this.totalRows = filteredItems.totalRows;\n let newRows: TData[] = filteredItems.rows;\n\n this.groups = [];\n if (this.groupingInfos.length) {\n this.groups = this.extractGroups(newRows);\n if (this.groups.length) {\n newRows = this.flattenGroupedRows(this.groups);\n }\n }\n\n const diff = this.getRowDiffs(this.rows, newRows as TData[]);\n\n this.rows = newRows as TData[];\n\n return diff;\n }\n\n refresh() {\n if (this.suspend) {\n return;\n }\n\n const previousPagingInfo = Utils.extend(true, {}, this.getPagingInfo());\n\n const countBefore = this.rows.length;\n const totalRowsBefore = this.totalRows;\n\n let diff = this.recalc(this.items); // pass as direct refs to avoid closure perf hit\n\n // if the current page is no longer valid, go to last page and recalc\n // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized\n if (this.pagesize && this.totalRows < this.pagenum * this.pagesize) {\n this.pagenum = Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1);\n diff = this.recalc(this.items);\n }\n\n this.updated = null;\n this.prevRefreshHints = this.refreshHints;\n this.refreshHints = {};\n\n if (totalRowsBefore !== this.totalRows) {\n // use the previously saved paging info\n if (this.onBeforePagingInfoChanged.notify(previousPagingInfo, null, this).getReturnValue() !== false) {\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\n }\n }\n if (countBefore !== this.rows.length) {\n this.onRowCountChanged.notify({ previous: countBefore, current: this.rows.length, itemCount: this.items.length, dataView: this, callingOnRowsChanged: (diff.length > 0) }, null, this);\n }\n if (diff.length > 0) {\n this.onRowsChanged.notify({ rows: diff, itemCount: this.items.length, dataView: this, calledOnRowCountChanged: (countBefore !== this.rows.length) }, null, this);\n }\n if (countBefore !== this.rows.length || diff.length > 0) {\n this.onRowsOrCountChanged.notify({\n rowsDiff: diff, previousRowCount: countBefore, currentRowCount: this.rows.length, itemCount: this.items.length,\n rowCountChanged: countBefore !== this.rows.length, rowsChanged: diff.length > 0, dataView: this\n }, null, this);\n }\n }\n\n /**\n * Wires the grid and the DataView together to keep row selection tied to item ids.\n * This is useful since, without it, the grid only knows about rows, so if the items\n * move around, the same rows stay selected instead of the selection moving along\n * with the items.\n *\n * NOTE: This doesn't work with cell selection model.\n *\n * @param {SlickGrid} grid - The grid to sync selection with.\n * @param {Boolean} preserveHidden - Whether to keep selected items that go out of the\n * view due to them getting filtered out.\n * @param {Boolean} [preserveHiddenOnSelectionChange] - Whether to keep selected items\n * that are currently out of the view (see preserveHidden) as selected when selection\n * changes.\n * @return {Event} An event that notifies when an internal list of selected row ids\n * changes. This is useful since, in combination with the above two options, it allows\n * access to the full list selected row ids, and not just the ones visible to the grid.\n * @method syncGridSelection\n */\n syncGridSelection(grid: SlickGrid, preserveHidden: boolean, preserveHiddenOnSelectionChange?: boolean) {\n this._grid = grid;\n let inHandler: boolean;\n this.selectedRowIds = this.mapRowsToIds(grid.getSelectedRows());\n\n /** @param {Array} rowIds */\n const setSelectedRowIds = (rowIds: DataIdType[] | false) => {\n if (rowIds === false) {\n this.selectedRowIds = [];\n } else {\n if (this.selectedRowIds!.sort().join(',') !== rowIds.sort().join(',')) {\n this.selectedRowIds = rowIds;\n }\n }\n };\n\n const update = () => {\n if ((this.selectedRowIds || []).length > 0 && !inHandler) {\n inHandler = true;\n const selectedRows = this.mapIdsToRows(this.selectedRowIds || []);\n if (!preserveHidden) {\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: this.mapRowsToIds(selectedRows),\n rows: selectedRows,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n grid.setSelectedRows(selectedRows);\n inHandler = false;\n }\n };\n\n grid.onSelectedRowsChanged.subscribe((_e: Event, args: { rows: number[]; }) => {\n if (!inHandler) {\n const newSelectedRowIds = this.mapRowsToIds(args.rows);\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: newSelectedRowIds,\n rows: args.rows,\n added: true,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n });\n\n this.preSelectedRowIdsChangeFn = (args: { ids: DataIdType[]; added?: boolean; }) => {\n if (!inHandler) {\n inHandler = true;\n const overwrite = (typeof args.added === typeof undefined);\n\n if (overwrite) {\n setSelectedRowIds(args.ids);\n } else {\n let rowIds: DataIdType[];\n if (args.added) {\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\n // find the ones that are hidden\n const hiddenSelectedRowIds = this.selectedRowIds?.filter((id) => this.getRowById(id) === undefined);\n // add the newly selected ones\n rowIds = hiddenSelectedRowIds!.concat(args.ids);\n } else {\n rowIds = args.ids;\n }\n } else {\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\n // remove rows whose id is on the list\n rowIds = this.selectedRowIds!.filter((id) => args.ids.indexOf(id) === -1);\n } else {\n rowIds = [];\n }\n }\n setSelectedRowIds(rowIds);\n }\n inHandler = false;\n }\n };\n\n this.onRowsOrCountChanged.subscribe(update.bind(this));\n\n return this.onSelectedRowIdsChanged;\n }\n\n /**\n * Get all selected IDs\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedIds() {\n return this.selectedRowIds;\n }\n\n /**\n * Get all selected filtered IDs (similar to \"getAllSelectedIds\" but only return filtered data)\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedFilteredIds() {\n return this.getAllSelectedFilteredItems().map((item) => item[this.idProperty as keyof TData]);\n }\n\n /**\n * Set current row selected IDs array (regardless of Pagination)\n * NOTE: This will NOT change the selection in the grid, if you need to do that then you still need to call\n * \"grid.setSelectedRows(rows)\"\n * @param {Array} selectedIds - list of IDs which have been selected for this action\n * @param {Object} options\n * - `isRowBeingAdded`: defaults to true, are the new selected IDs being added (or removed) as new row selections\n * - `shouldTriggerEvent`: defaults to true, should we trigger `onSelectedRowIdsChanged` event\n * - `applyRowSelectionToGrid`: defaults to true, should we apply the row selections to the grid in the UI\n */\n setSelectedIds(selectedIds: Array, options?: Partial<{ isRowBeingAdded: boolean; shouldTriggerEvent: boolean; applyRowSelectionToGrid: boolean; }>) {\n let isRowBeingAdded = options?.isRowBeingAdded;\n const shouldTriggerEvent = options?.shouldTriggerEvent;\n const applyRowSelectionToGrid = options?.applyRowSelectionToGrid;\n\n if (isRowBeingAdded !== false) {\n isRowBeingAdded = true;\n }\n const selectedRows = this.mapIdsToRows(selectedIds);\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: selectedIds,\n rows: selectedRows,\n added: isRowBeingAdded,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn?.(selectedRowsChangedArgs);\n\n if (shouldTriggerEvent !== false) {\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n\n // should we also apply the row selection in to the grid (UI) as well?\n if (applyRowSelectionToGrid !== false && this._grid) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n /**\n * Get all selected dataContext items\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedItems() {\n const selectedData: TData[] = [];\n const selectedIds = this.getAllSelectedIds();\n selectedIds!.forEach((id) => {\n selectedData.push(this.getItemById(id));\n });\n return selectedData as T[];\n }\n\n /**\n * Get all selected filtered dataContext items (similar to \"getAllSelectedItems\" but only return filtered data)\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedFilteredItems() {\n if (!Array.isArray(this.selectedRowIds)) {\n return [];\n }\n\n const intersection = this.filteredItems.filter((a) => this.selectedRowIds!.some((b) => a[this.idProperty as keyof TData] === b));\n return (intersection || []) as T[];\n }\n\n syncGridCellCssStyles(grid: SlickGrid, key: string) {\n let hashById: any;\n let inHandler: boolean;\n\n const storeCellCssStyles = (hash: CssStyleHash) => {\n hashById = {};\n for (const row in hash) {\n const id = this.rows[row as any][this.idProperty as keyof TData];\n hashById[id] = hash[row];\n }\n };\n\n // since this method can be called after the cell styles have been set,\n // get the existing ones right away\n storeCellCssStyles(grid.getCellCssStyles(key));\n\n const update = () => {\n if (hashById) {\n inHandler = true;\n this.ensureRowsByIdCache();\n const newHash: CssStyleHash = {};\n for (const id in hashById) {\n const row = this.rowsById?.[id];\n if (Utils.isDefined(row)) {\n newHash[row] = hashById[id];\n }\n }\n grid.setCellCssStyles(key, newHash);\n inHandler = false;\n }\n };\n\n grid.onCellCssStylesChanged.subscribe((_e, args) => {\n if (inHandler) { return; }\n if (key !== args.key) { return; }\n if (args.hash) {\n storeCellCssStyles(args.hash);\n } else {\n grid.onCellCssStylesChanged.unsubscribe();\n this.onRowsOrCountChanged.unsubscribe(update);\n }\n });\n\n this.onRowsOrCountChanged.subscribe(update.bind(this));\n }\n}\n\nexport class AvgAggregator implements Aggregator {\n private _nonNullCount = 0;\n private _sum = 0;\n private _field: number | string;\n private _type = 'avg' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n this._nonNullCount = 0;\n this._sum = 0;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n this._nonNullCount++;\n this._sum += parseFloat(val);\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { avg: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n (groupTotals as any)[this._type] = {};\n }\n if (this._nonNullCount !== 0) {\n groupTotals[this._type][this._field] = this._sum / this._nonNullCount;\n }\n }\n}\n\nexport class MinAggregator implements Aggregator {\n private _min: number | null = null;\n private _field: number | string;\n private _type = 'min' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init() {\n this._min = null;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n if (this._min === null || val < this._min) {\n this._min = parseFloat(val);\n }\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { min: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._min;\n }\n}\n\nexport class MaxAggregator implements Aggregator {\n private _max: number | null = null;\n private _field: number | string;\n private _type = 'max' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n this._max = null;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n if (this._max === null || val > this._max) {\n this._max = parseFloat(val);\n }\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { max: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._max;\n }\n}\n\nexport class SumAggregator implements Aggregator {\n private _sum = 0;\n private _field: number | string;\n private _type = 'sum' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init() {\n this._sum = 0;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n this._sum += parseFloat(val);\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { sum: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._sum;\n }\n}\n\nexport class CountAggregator implements Aggregator {\n private _field: number | string;\n private _type = 'count' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { count: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = groupTotals.group.rows.length;\n }\n}\n\n// TODO: add more built-in aggregators\n// TODO: merge common aggregators in one to prevent needless iterating\n\nexport const Aggregators = {\n Avg: AvgAggregator,\n Min: MinAggregator,\n Max: MaxAggregator,\n Sum: SumAggregator,\n Count: CountAggregator\n};\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Data = window.Slick.Data || {};\n window.Slick.Data.DataView = SlickDataView;\n window.Slick.Data.Aggregators = Aggregators;\n}"], + "mappings": "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", "names": ["_a", "_b"] } diff --git a/dist/browser/slick.editors.js b/dist/browser/slick.editors.js index 379c671e1..66cbbaedb 100644 --- a/dist/browser/slick.editors.js +++ b/dist/browser/slick.editors.js @@ -52,7 +52,7 @@ item[this.args.column.field] = state; } isValueChanged() { - return !(this.input.value === "" && this.defaultValue == null) && this.input.value != this.defaultValue; + return !(this.input.value === "" && !Utils.isDefined(this.defaultValue)) && this.input.value !== this.defaultValue; } validate() { if (this.args.column.validator) { @@ -106,7 +106,7 @@ item[this.args.column.field] = state; } isValueChanged() { - return !(this.input.value === "" && this.defaultValue == null) && this.input.value != this.defaultValue; + return !(this.input.value === "" && !Utils.isDefined(this.defaultValue)) && this.input.value !== this.defaultValue; } validate() { if (isNaN(this.input.value)) @@ -156,7 +156,7 @@ } getDecimalPlaces() { let rtn = this.args.column.editorFixedDecimalPlaces; - return typeof rtn == "undefined" && (rtn = _FloatEditor.DefaultDecimalPlaces), !rtn && rtn !== 0 ? null : rtn; + return Utils.isDefined(rtn) || (rtn = _FloatEditor.DefaultDecimalPlaces), !rtn && rtn !== 0 ? null : rtn; } loadValue(item) { var _a, _b, _c; @@ -174,7 +174,7 @@ item[this.args.column.field] = state; } isValueChanged() { - return !(this.input.value === "" && this.defaultValue == null) && this.input.value != this.defaultValue; + return !(this.input.value === "" && !Utils.isDefined(this.defaultValue)) && this.input.value !== this.defaultValue; } validate() { if (isNaN(this.input.value)) @@ -254,7 +254,7 @@ item[this.args.column.field] = state; } isValueChanged() { - return !(this.input.value === "" && this.defaultValue == null) && this.input.value != this.defaultValue; + return !(this.input.value === "" && !Utils.isDefined(this.defaultValue)) && this.input.value !== this.defaultValue; } validate() { if (this.args.column.validator) { @@ -300,13 +300,13 @@ this.select.value = (this.defaultValue = item[this.args.column.field]) ? "yes" : "no"; } serializeValue() { - return this.select.value == "yes"; + return this.select.value === "yes"; } applyValue(item, state) { item[this.args.column.field] = state; } isValueChanged() { - return this.select.value != this.defaultValue; + return this.select.value !== this.defaultValue; } validate() { return { @@ -422,7 +422,7 @@ item[this.args.column.field] = state; } isValueChanged() { - return !(this.input.value === "" && this.defaultValue == null) && (parseInt(this.input.value, 10) || 0) != this.defaultValue; + return !(this.input.value === "" && !Utils.isDefined(this.defaultValue)) && (parseInt(this.input.value, 10) || 0) !== this.defaultValue; } validate() { return isNaN(parseInt(this.input.value, 10)) ? { @@ -468,15 +468,15 @@ }); } handleKeyDown(e) { - if (e.which == keyCode.ENTER && e.ctrlKey) + if (e.which === keyCode.ENTER && e.ctrlKey) this.save(); - else if (e.which == keyCode.ESCAPE) + else if (e.which === keyCode.ESCAPE) e.preventDefault(), this.cancel(); - else if (e.which == keyCode.TAB && e.shiftKey) + else if (e.which === keyCode.TAB && e.shiftKey) e.preventDefault(), this.args.grid.navigatePrev(); - else if (e.which == keyCode.TAB) + else if (e.which === keyCode.TAB) e.preventDefault(), this.args.grid.navigateNext(); - else if ((e.which == keyCode.LEFT || e.which == keyCode.RIGHT) && this.args.grid.getOptions().editorCellNavOnLRKeys) { + else if ((e.which === keyCode.LEFT || e.which === keyCode.RIGHT) && this.args.grid.getOptions().editorCellNavOnLRKeys) { let cursorPosition = this.selectionStart, textLength = e.target.value.length; e.keyCode === keyCode.LEFT && cursorPosition === 0 && this.args.grid.navigatePrev(), e.keyCode === keyCode.RIGHT && cursorPosition >= textLength - 1 && this.args.grid.navigateNext(); } @@ -513,7 +513,7 @@ item[this.args.column.field] = state; } isValueChanged() { - return !(this.input.value === "" && this.defaultValue == null) && this.input.value != this.defaultValue; + return !(this.input.value === "" && !Utils.isDefined(this.defaultValue)) && this.input.value !== this.defaultValue; } validate() { if (this.args.column.validator) { diff --git a/dist/browser/slick.editors.js.map b/dist/browser/slick.editors.js.map index daf4b2da7..67a258d8c 100644 --- a/dist/browser/slick.editors.js.map +++ b/dist/browser/slick.editors.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.editors.ts"], - "sourcesContent": ["import type { Editor, EditorArguments, EditorValidationResult, ElementPosition } from './models/index';\nimport { keyCode as keyCode_, Utils as Utils_ } from './slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * Contains basic SlickGrid editors.\n * @module Editors\n * @namespace Slick\n */\n\nexport class TextEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: number | string;\n protected navOnLR?: boolean;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.focus();\n this.input.select();\n\n // don't show Save/Cancel when it's a Composite Editor and also trigger a onCompositeEditorChange event when input changes\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n }\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n }\n\n destroy() {\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.removeEventListener('change', this.onChange.bind(this))\n this.input.remove();\n }\n\n focus() {\n this.input.focus();\n }\n\n getValue() {\n return this.input.value;\n }\n\n setValue(val: string) {\n this.input.value = val;\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field] || '';\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n }\n\n serializeValue() {\n return this.input.value;\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && this.defaultValue == null)) && (this.input.value != this.defaultValue);\n }\n\n validate() {\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class IntegerEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: string | number;\n protected navOnLR?: boolean;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.focus()\n this.input.select();\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n }\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n }\n\n destroy() {\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.removeEventListener('change', this.onChange.bind(this))\n this.input.remove();\n }\n\n focus() {\n this.input.focus();\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n }\n\n serializeValue() {\n return parseInt(this.input.value, 10) || 0;\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && this.defaultValue == null)) && (this.input.value != this.defaultValue);\n }\n\n validate() {\n if (isNaN(this.input.value as unknown as number)) {\n return {\n valid: false,\n msg: 'Please enter a valid integer'\n };\n }\n\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class FloatEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: string | number;\n protected navOnLR?: boolean;\n\n /** Default number of decimal places to use with FloatEditor */\n static DefaultDecimalPlaces?: number = undefined;\n\n /** Should we allow empty value when using FloatEditor */\n static AllowEmptyValue = false;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.focus()\n this.input.select();\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n };\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n };\n\n destroy() {\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.removeEventListener('change', this.onChange.bind(this))\n this.input.remove();\n };\n\n focus() {\n this.input.focus();\n }\n\n getDecimalPlaces() {\n // returns the number of fixed decimal places or null\n let rtn: number | undefined = this.args.column.editorFixedDecimalPlaces;\n if (typeof rtn == 'undefined') {\n rtn = FloatEditor.DefaultDecimalPlaces;\n }\n return (!rtn && rtn !== 0 ? null : rtn);\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n\n const decPlaces = this.getDecimalPlaces();\n if (decPlaces !== null\n && (this.defaultValue || this.defaultValue === 0)\n && (this.defaultValue as number)?.toFixed) {\n this.defaultValue = (this.defaultValue as number).toFixed(decPlaces);\n }\n\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n }\n\n serializeValue() {\n let rtn: number | undefined = parseFloat(this.input.value);\n if (FloatEditor.AllowEmptyValue) {\n if (!rtn && rtn !== 0) {\n rtn = undefined;\n }\n } else {\n rtn = rtn || 0;\n }\n\n const decPlaces = this.getDecimalPlaces();\n if (decPlaces !== null\n && (rtn || rtn === 0)\n && rtn.toFixed) {\n rtn = parseFloat(rtn.toFixed(decPlaces));\n }\n\n return rtn as number;\n }\n\n applyValue(item: any, state: number | string) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && this.defaultValue == null)) && (this.input.value != this.defaultValue);\n }\n\n validate() {\n if (isNaN(this.input.value as unknown as number)) {\n return {\n valid: false,\n msg: 'Please enter a valid number'\n };\n }\n\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class FlatpickrEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: string | number;\n protected flatpickrInstance: any;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n if (typeof flatpickr === 'undefined') {\n throw new Error('Flatpickr not loaded but required in SlickGrid.Editors, refer to Flatpickr documentation: https://flatpickr.js.org/getting-started/');\n }\n }\n\n init() {\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.focus();\n this.input.select();\n this.flatpickrInstance = flatpickr(this.input, {\n closeOnSelect: true,\n allowInput: true,\n altInput: true,\n altFormat: 'm/d/Y',\n dateFormat: 'm/d/Y',\n onChange: () => {\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n }\n },\n });\n\n if (!this.args.compositeEditorOptions) {\n setTimeout(() => {\n this.show();\n this.focus();\n }, 50);\n }\n\n Utils.width(this.input, (Utils.width(this.input) as number) - (!this.args.compositeEditorOptions ? 18 : 28));\n }\n\n destroy() {\n this.hide();\n if (this.flatpickrInstance) {\n this.flatpickrInstance.destroy();\n }\n this.input.remove();\n }\n\n show() {\n if (!this.args.compositeEditorOptions && this.flatpickrInstance) {\n this.flatpickrInstance.open();\n }\n }\n\n hide() {\n if (!this.args.compositeEditorOptions && this.flatpickrInstance) {\n this.flatpickrInstance.close();\n }\n }\n\n focus() {\n this.input.focus();\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n if (this.flatpickrInstance) {\n this.flatpickrInstance.setDate(this.defaultValue);\n }\n }\n\n serializeValue() {\n return this.input.value;\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && this.defaultValue == null)) && (this.input.value != this.defaultValue);\n }\n\n validate() {\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class YesNoSelectEditor implements Editor {\n protected select!: HTMLSelectElement;\n protected defaultValue?: string | number;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.select = Utils.createDomElement('select', { tabIndex: 0, className: 'editor-yesno' }, this.args.container);\n Utils.createDomElement('option', { value: 'yes', textContent: 'Yes' }, this.select);\n Utils.createDomElement('option', { value: 'no', textContent: 'No' }, this.select);\n\n this.select.focus();\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.select.addEventListener('change', this.onChange.bind(this));\n }\n }\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n }\n\n destroy() {\n this.select.removeEventListener('change', this.onChange.bind(this))\n this.select.remove();\n }\n\n focus() {\n this.select.focus();\n }\n\n loadValue(item: any) {\n this.select.value = ((this.defaultValue = item[this.args.column.field]) ? 'yes' : 'no');\n }\n\n serializeValue() {\n return this.select.value == 'yes';\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return this.select.value != this.defaultValue;\n }\n\n validate() {\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class CheckboxEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: boolean;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.input = Utils.createDomElement('input', { className: 'editor-checkbox', type: 'checkbox', value: 'true' }, this.args.container);\n this.input.focus();\n\n // trigger onCompositeEditorChange event when input checkbox changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n };\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n };\n\n destroy() {\n this.input.removeEventListener('change', this.onChange.bind(this));\n this.input.remove();\n };\n\n focus() {\n this.input.focus();\n };\n\n loadValue(item: any) {\n this.defaultValue = !!(item[this.args.column.field]);\n if (this.defaultValue) {\n this.input.checked = true;\n } else {\n this.input.checked = false;\n }\n };\n\n serializeValue() {\n return this.input.checked;\n };\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (this.serializeValue() !== this.defaultValue);\n }\n\n validate(): EditorValidationResult {\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class PercentCompleteEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: number;\n protected picker!: HTMLDivElement;\n protected slider!: HTMLInputElement | null;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n sliderInputHandler(e: MouseEvent & { target: HTMLButtonElement }) {\n this.input.value = e.target.value;\n }\n\n sliderChangeHandler() {\n // trigger onCompositeEditorChange event when slider stops and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n }\n }\n\n init() {\n this.input = Utils.createDomElement('input', { className: 'editor-percentcomplete', type: 'text' }, this.args.container);\n Utils.width(this.input, this.args.container.clientWidth - 25);\n\n this.picker = Utils.createDomElement('div', { className: 'editor-percentcomplete-picker' }, this.args.container);\n Utils.createDomElement('span', { className: 'editor-percentcomplete-picker-icon' }, this.picker);\n const containerHelper = Utils.createDomElement('div', { className: 'editor-percentcomplete-helper' }, this.picker);\n const containerWrapper = Utils.createDomElement('div', { className: 'editor-percentcomplete-wrapper' }, containerHelper);\n Utils.createDomElement('div', { className: 'editor-percentcomplete-slider' }, containerWrapper);\n this.slider = Utils.createDomElement('input', { className: 'editor-percentcomplete-slider', type: 'range', value: String(this.defaultValue ?? '') }, containerWrapper);\n const containerButtons = Utils.createDomElement('div', { className: 'editor-percentcomplete-buttons' }, containerWrapper);\n Utils.createDomElement('button', { value: '0', className: 'slick-btn slick-btn-default', textContent: 'Not started' }, containerButtons);\n containerButtons.appendChild(document.createElement('br'));\n Utils.createDomElement('button', { value: '50', className: 'slick-btn slick-btn-default', textContent: 'In Progress' }, containerButtons);\n containerButtons.appendChild(document.createElement('br'));\n Utils.createDomElement('button', { value: '100', className: 'slick-btn slick-btn-default', textContent: 'Complete' }, containerButtons);\n\n this.input.focus();\n this.input.select();\n\n this.slider.addEventListener('input', this.sliderInputHandler.bind(this) as EventListener);\n this.slider.addEventListener('change', this.sliderChangeHandler.bind(this));\n\n const buttons = this.picker.querySelectorAll('.editor-percentcomplete-buttons button');\n [].forEach.call(buttons, (button: HTMLButtonElement) => {\n button.addEventListener('click', this.onClick.bind(this) as EventListener);\n });\n };\n\n onClick(e: MouseEvent & { target: HTMLButtonElement }) {\n this.input.value = String(e.target.value ?? '');\n this.slider!.value = String(e.target.value ?? '');\n };\n\n destroy() {\n this.slider?.removeEventListener('input', this.sliderInputHandler.bind(this) as EventListener);\n this.slider?.removeEventListener('change', this.sliderChangeHandler.bind(this));\n this.picker.querySelectorAll('.editor-percentcomplete-buttons button')\n .forEach(button => button.removeEventListener('click', this.onClick.bind(this) as EventListener));\n this.input.remove();\n this.picker.remove();\n };\n\n focus() {\n this.input.focus();\n };\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n this.slider!.value = String(this.defaultValue ?? '');\n this.input.value = String(this.defaultValue);\n this.input.select();\n };\n\n serializeValue() {\n return parseInt(this.input.value, 10) || 0;\n };\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n };\n\n isValueChanged() {\n return (!(this.input.value === '' && this.defaultValue == null)) && ((parseInt(this.input.value as any, 10) || 0) != this.defaultValue);\n };\n\n validate(): EditorValidationResult {\n if (isNaN(parseInt(this.input.value, 10))) {\n return {\n valid: false,\n msg: 'Please enter a valid positive number'\n };\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n}\n\n/*\n * An example of a 'detached' editor.\n * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\n */\nexport class LongTextEditor implements Editor {\n protected input!: HTMLTextAreaElement;\n protected wrapper!: HTMLDivElement;\n protected defaultValue?: string;\n protected selectionStart = 0;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n const compositeEditorOptions = this.args.compositeEditorOptions;\n this.args.grid.getOptions().editorCellNavOnLRKeys;\n const container = compositeEditorOptions ? this.args.container : document.body;\n\n this.wrapper = Utils.createDomElement('div', { className: 'slick-large-editor-text' }, container);\n if (compositeEditorOptions) {\n this.wrapper.style.position = 'relative';\n Utils.setStyleSize(this.wrapper, 'padding', 0);\n Utils.setStyleSize(this.wrapper, 'border', 0);\n } else {\n this.wrapper.style.position = 'absolute';\n }\n\n this.input = Utils.createDomElement('textarea', { rows: 5, style: { background: 'white', width: '250px', height: '80px', border: '0', outline: '0' } }, this.wrapper);\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n } else {\n const btnContainer = Utils.createDomElement('div', { style: 'text-align:right' }, this.wrapper);\n Utils.createDomElement('button', { id: 'save', className: 'slick-btn slick-btn-primary', textContent: 'Save' }, btnContainer);\n Utils.createDomElement('button', { id: 'cancel', className: 'slick-btn slick-btn-default', textContent: 'Cancel' }, btnContainer);\n\n this.wrapper.querySelector('#save')!.addEventListener('click', this.save.bind(this));\n this.wrapper.querySelector('#cancel')!.addEventListener('click', this.cancel.bind(this));\n this.input.addEventListener('keydown', this.handleKeyDown.bind(this) as EventListener);\n this.position(this.args.position as ElementPosition);\n }\n\n this.input.focus();\n this.input.select();\n };\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n };\n\n handleKeyDown(e: KeyboardEvent & { target: HTMLInputElement }) {\n if (e.which == keyCode.ENTER && e.ctrlKey) {\n this.save();\n } else if (e.which == keyCode.ESCAPE) {\n e.preventDefault();\n this.cancel();\n } else if (e.which == keyCode.TAB && e.shiftKey) {\n e.preventDefault();\n this.args.grid.navigatePrev();\n } else if (e.which == keyCode.TAB) {\n e.preventDefault();\n this.args.grid.navigateNext();\n } else if (e.which == keyCode.LEFT || e.which == keyCode.RIGHT) {\n if (this.args.grid.getOptions().editorCellNavOnLRKeys) {\n const cursorPosition = this.selectionStart;\n const textLength = e.target.value.length;\n if (e.keyCode === keyCode.LEFT && cursorPosition === 0) {\n this.args.grid.navigatePrev();\n }\n if (e.keyCode === keyCode.RIGHT && cursorPosition >= textLength - 1) {\n this.args.grid.navigateNext();\n }\n }\n }\n };\n\n save() {\n const gridOptions = this.args.grid.getOptions() || {};\n if (gridOptions.autoCommitEdit) {\n this.args.grid.getEditorLock().commitCurrentEdit();\n } else {\n this.args.commitChanges();\n }\n };\n\n cancel() {\n this.input.value = String(this.defaultValue ?? '');\n this.args.cancelChanges();\n };\n\n hide() {\n Utils.hide(this.wrapper);\n };\n\n show() {\n Utils.show(this.wrapper);\n };\n\n position(position: ElementPosition) {\n Utils.setStyleSize(this.wrapper, 'top', (position.top || 0) - 5);\n Utils.setStyleSize(this.wrapper, 'left', (position.left || 0) - 2);\n };\n\n destroy() {\n if (this.args.compositeEditorOptions) {\n this.input.removeEventListener('change', this.onChange.bind(this));\n } else {\n this.wrapper.querySelector('#save')!.removeEventListener('click', this.save.bind(this));\n this.wrapper.querySelector('#cancel')!.removeEventListener('click', this.cancel.bind(this));\n this.input.removeEventListener('keydown', this.handleKeyDown.bind(this) as EventListener);\n }\n this.wrapper.remove();\n };\n\n focus() {\n this.input.focus();\n };\n\n loadValue(item: any) {\n this.input.value = this.defaultValue = item[this.args.column.field];\n this.input.select();\n };\n\n serializeValue() {\n return this.input.value;\n };\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n };\n\n isValueChanged() {\n return (!(this.input.value === '' && this.defaultValue == null)) && (this.input.value != this.defaultValue);\n };\n\n validate() {\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n}\n\n/*\n * Depending on the value of Grid option 'editorCellNavOnLRKeys', us\n * Navigate to the cell on the left if the cursor is at the beginning of the input string\n * and to the right cell if it's at the end. Otherwise, move the cursor within the text\n */\nfunction handleKeydownLRNav(e: KeyboardEvent & { target: HTMLInputElement; selectionStart: number; }) {\n const cursorPosition = e.selectionStart;\n const textLength = e.target.value.length;\n if ((e.keyCode === keyCode.LEFT && cursorPosition > 0) ||\n e.keyCode === keyCode.RIGHT && cursorPosition < textLength - 1) {\n e.stopImmediatePropagation();\n }\n}\n\nfunction handleKeydownLRNoNav(e: KeyboardEvent) {\n if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT) {\n e.stopImmediatePropagation();\n }\n}\n\nexport const Editors = {\n Text: TextEditor,\n Integer: IntegerEditor,\n Float: FloatEditor,\n Flatpickr: FlatpickrEditor,\n YesNoSelect: YesNoSelectEditor,\n Checkbox: CheckboxEditor,\n PercentComplete: PercentCompleteEditor,\n LongText: LongTextEditor\n};\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(Slick, {\n Editors\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import type { Editor, EditorArguments, EditorValidationResult, ElementPosition } from './models/index';\nimport { keyCode as keyCode_, Utils as Utils_ } from './slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * Contains basic SlickGrid editors.\n * @module Editors\n * @namespace Slick\n */\n\nexport class TextEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: number | string;\n protected navOnLR?: boolean;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.focus();\n this.input.select();\n\n // don't show Save/Cancel when it's a Composite Editor and also trigger a onCompositeEditorChange event when input changes\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n }\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n }\n\n destroy() {\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.removeEventListener('change', this.onChange.bind(this));\n this.input.remove();\n }\n\n focus() {\n this.input.focus();\n }\n\n getValue() {\n return this.input.value;\n }\n\n setValue(val: string) {\n this.input.value = val;\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field] || '';\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n }\n\n serializeValue() {\n return this.input.value;\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\n }\n\n validate() {\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class IntegerEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: string | number;\n protected navOnLR?: boolean;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.focus();\n this.input.select();\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n }\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n }\n\n destroy() {\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.removeEventListener('change', this.onChange.bind(this));\n this.input.remove();\n }\n\n focus() {\n this.input.focus();\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n }\n\n serializeValue() {\n return parseInt(this.input.value, 10) || 0;\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\n }\n\n validate() {\n if (isNaN(this.input.value as unknown as number)) {\n return {\n valid: false,\n msg: 'Please enter a valid integer'\n };\n }\n\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class FloatEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: string | number;\n protected navOnLR?: boolean;\n\n /** Default number of decimal places to use with FloatEditor */\n static DefaultDecimalPlaces?: number = undefined;\n\n /** Should we allow empty value when using FloatEditor */\n static AllowEmptyValue = false;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.focus();\n this.input.select();\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n };\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n };\n\n destroy() {\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.removeEventListener('change', this.onChange.bind(this));\n this.input.remove();\n };\n\n focus() {\n this.input.focus();\n }\n\n getDecimalPlaces() {\n // returns the number of fixed decimal places or null\n let rtn: number | undefined = this.args.column.editorFixedDecimalPlaces;\n if (!Utils.isDefined(rtn)) {\n rtn = FloatEditor.DefaultDecimalPlaces;\n }\n return (!rtn && rtn !== 0 ? null : rtn);\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n\n const decPlaces = this.getDecimalPlaces();\n if (decPlaces !== null\n && (this.defaultValue || this.defaultValue === 0)\n && (this.defaultValue as number)?.toFixed) {\n this.defaultValue = (this.defaultValue as number).toFixed(decPlaces);\n }\n\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n }\n\n serializeValue() {\n let rtn: number | undefined = parseFloat(this.input.value);\n if (FloatEditor.AllowEmptyValue) {\n if (!rtn && rtn !== 0) {\n rtn = undefined;\n }\n } else {\n rtn = rtn || 0;\n }\n\n const decPlaces = this.getDecimalPlaces();\n if (decPlaces !== null\n && (rtn || rtn === 0)\n && rtn.toFixed) {\n rtn = parseFloat(rtn.toFixed(decPlaces));\n }\n\n return rtn as number;\n }\n\n applyValue(item: any, state: number | string) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\n }\n\n validate() {\n if (isNaN(this.input.value as unknown as number)) {\n return {\n valid: false,\n msg: 'Please enter a valid number'\n };\n }\n\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class FlatpickrEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: string | number;\n protected flatpickrInstance: any;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n if (typeof flatpickr === 'undefined') {\n throw new Error('Flatpickr not loaded but required in SlickGrid.Editors, refer to Flatpickr documentation: https://flatpickr.js.org/getting-started/');\n }\n }\n\n init() {\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.focus();\n this.input.select();\n this.flatpickrInstance = flatpickr(this.input, {\n closeOnSelect: true,\n allowInput: true,\n altInput: true,\n altFormat: 'm/d/Y',\n dateFormat: 'm/d/Y',\n onChange: () => {\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n }\n },\n });\n\n if (!this.args.compositeEditorOptions) {\n setTimeout(() => {\n this.show();\n this.focus();\n }, 50);\n }\n\n Utils.width(this.input, (Utils.width(this.input) as number) - (!this.args.compositeEditorOptions ? 18 : 28));\n }\n\n destroy() {\n this.hide();\n if (this.flatpickrInstance) {\n this.flatpickrInstance.destroy();\n }\n this.input.remove();\n }\n\n show() {\n if (!this.args.compositeEditorOptions && this.flatpickrInstance) {\n this.flatpickrInstance.open();\n }\n }\n\n hide() {\n if (!this.args.compositeEditorOptions && this.flatpickrInstance) {\n this.flatpickrInstance.close();\n }\n }\n\n focus() {\n this.input.focus();\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n if (this.flatpickrInstance) {\n this.flatpickrInstance.setDate(this.defaultValue);\n }\n }\n\n serializeValue() {\n return this.input.value;\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\n }\n\n validate() {\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class YesNoSelectEditor implements Editor {\n protected select!: HTMLSelectElement;\n protected defaultValue?: string | number;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.select = Utils.createDomElement('select', { tabIndex: 0, className: 'editor-yesno' }, this.args.container);\n Utils.createDomElement('option', { value: 'yes', textContent: 'Yes' }, this.select);\n Utils.createDomElement('option', { value: 'no', textContent: 'No' }, this.select);\n\n this.select.focus();\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.select.addEventListener('change', this.onChange.bind(this));\n }\n }\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n }\n\n destroy() {\n this.select.removeEventListener('change', this.onChange.bind(this));\n this.select.remove();\n }\n\n focus() {\n this.select.focus();\n }\n\n loadValue(item: any) {\n this.select.value = ((this.defaultValue = item[this.args.column.field]) ? 'yes' : 'no');\n }\n\n serializeValue() {\n return this.select.value === 'yes';\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return this.select.value !== this.defaultValue;\n }\n\n validate() {\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class CheckboxEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: boolean;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.input = Utils.createDomElement('input', { className: 'editor-checkbox', type: 'checkbox', value: 'true' }, this.args.container);\n this.input.focus();\n\n // trigger onCompositeEditorChange event when input checkbox changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n };\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n };\n\n destroy() {\n this.input.removeEventListener('change', this.onChange.bind(this));\n this.input.remove();\n };\n\n focus() {\n this.input.focus();\n };\n\n loadValue(item: any) {\n this.defaultValue = !!(item[this.args.column.field]);\n if (this.defaultValue) {\n this.input.checked = true;\n } else {\n this.input.checked = false;\n }\n };\n\n serializeValue() {\n return this.input.checked;\n };\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (this.serializeValue() !== this.defaultValue);\n }\n\n validate(): EditorValidationResult {\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class PercentCompleteEditor implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: number;\n protected picker!: HTMLDivElement;\n protected slider!: HTMLInputElement | null;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n sliderInputHandler(e: MouseEvent & { target: HTMLButtonElement }) {\n this.input.value = e.target.value;\n }\n\n sliderChangeHandler() {\n // trigger onCompositeEditorChange event when slider stops and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n }\n }\n\n init() {\n this.input = Utils.createDomElement('input', { className: 'editor-percentcomplete', type: 'text' }, this.args.container);\n Utils.width(this.input, this.args.container.clientWidth - 25);\n\n this.picker = Utils.createDomElement('div', { className: 'editor-percentcomplete-picker' }, this.args.container);\n Utils.createDomElement('span', { className: 'editor-percentcomplete-picker-icon' }, this.picker);\n const containerHelper = Utils.createDomElement('div', { className: 'editor-percentcomplete-helper' }, this.picker);\n const containerWrapper = Utils.createDomElement('div', { className: 'editor-percentcomplete-wrapper' }, containerHelper);\n Utils.createDomElement('div', { className: 'editor-percentcomplete-slider' }, containerWrapper);\n this.slider = Utils.createDomElement('input', { className: 'editor-percentcomplete-slider', type: 'range', value: String(this.defaultValue ?? '') }, containerWrapper);\n const containerButtons = Utils.createDomElement('div', { className: 'editor-percentcomplete-buttons' }, containerWrapper);\n Utils.createDomElement('button', { value: '0', className: 'slick-btn slick-btn-default', textContent: 'Not started' }, containerButtons);\n containerButtons.appendChild(document.createElement('br'));\n Utils.createDomElement('button', { value: '50', className: 'slick-btn slick-btn-default', textContent: 'In Progress' }, containerButtons);\n containerButtons.appendChild(document.createElement('br'));\n Utils.createDomElement('button', { value: '100', className: 'slick-btn slick-btn-default', textContent: 'Complete' }, containerButtons);\n\n this.input.focus();\n this.input.select();\n\n this.slider.addEventListener('input', this.sliderInputHandler.bind(this) as EventListener);\n this.slider.addEventListener('change', this.sliderChangeHandler.bind(this));\n\n const buttons = this.picker.querySelectorAll('.editor-percentcomplete-buttons button');\n [].forEach.call(buttons, (button: HTMLButtonElement) => {\n button.addEventListener('click', this.onClick.bind(this) as EventListener);\n });\n };\n\n onClick(e: MouseEvent & { target: HTMLButtonElement }) {\n this.input.value = String(e.target.value ?? '');\n this.slider!.value = String(e.target.value ?? '');\n };\n\n destroy() {\n this.slider?.removeEventListener('input', this.sliderInputHandler.bind(this) as EventListener);\n this.slider?.removeEventListener('change', this.sliderChangeHandler.bind(this));\n this.picker.querySelectorAll('.editor-percentcomplete-buttons button')\n .forEach(button => button.removeEventListener('click', this.onClick.bind(this) as EventListener));\n this.input.remove();\n this.picker.remove();\n };\n\n focus() {\n this.input.focus();\n };\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n this.slider!.value = String(this.defaultValue ?? '');\n this.input.value = String(this.defaultValue);\n this.input.select();\n };\n\n serializeValue() {\n return parseInt(this.input.value, 10) || 0;\n };\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n };\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && ((parseInt(this.input.value as any, 10) || 0) !== this.defaultValue);\n };\n\n validate(): EditorValidationResult {\n if (isNaN(parseInt(this.input.value, 10))) {\n return {\n valid: false,\n msg: 'Please enter a valid positive number'\n };\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n}\n\n/*\n * An example of a 'detached' editor.\n * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\n */\nexport class LongTextEditor implements Editor {\n protected input!: HTMLTextAreaElement;\n protected wrapper!: HTMLDivElement;\n protected defaultValue?: string;\n protected selectionStart = 0;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n const compositeEditorOptions = this.args.compositeEditorOptions;\n this.args.grid.getOptions().editorCellNavOnLRKeys;\n const container = compositeEditorOptions ? this.args.container : document.body;\n\n this.wrapper = Utils.createDomElement('div', { className: 'slick-large-editor-text' }, container);\n if (compositeEditorOptions) {\n this.wrapper.style.position = 'relative';\n Utils.setStyleSize(this.wrapper, 'padding', 0);\n Utils.setStyleSize(this.wrapper, 'border', 0);\n } else {\n this.wrapper.style.position = 'absolute';\n }\n\n this.input = Utils.createDomElement('textarea', { rows: 5, style: { background: 'white', width: '250px', height: '80px', border: '0', outline: '0' } }, this.wrapper);\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n } else {\n const btnContainer = Utils.createDomElement('div', { style: 'text-align:right' }, this.wrapper);\n Utils.createDomElement('button', { id: 'save', className: 'slick-btn slick-btn-primary', textContent: 'Save' }, btnContainer);\n Utils.createDomElement('button', { id: 'cancel', className: 'slick-btn slick-btn-default', textContent: 'Cancel' }, btnContainer);\n\n this.wrapper.querySelector('#save')!.addEventListener('click', this.save.bind(this));\n this.wrapper.querySelector('#cancel')!.addEventListener('click', this.cancel.bind(this));\n this.input.addEventListener('keydown', this.handleKeyDown.bind(this) as EventListener);\n this.position(this.args.position as ElementPosition);\n }\n\n this.input.focus();\n this.input.select();\n };\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n });\n };\n\n handleKeyDown(e: KeyboardEvent & { target: HTMLInputElement }) {\n if (e.which === keyCode.ENTER && e.ctrlKey) {\n this.save();\n } else if (e.which === keyCode.ESCAPE) {\n e.preventDefault();\n this.cancel();\n } else if (e.which === keyCode.TAB && e.shiftKey) {\n e.preventDefault();\n this.args.grid.navigatePrev();\n } else if (e.which === keyCode.TAB) {\n e.preventDefault();\n this.args.grid.navigateNext();\n } else if (e.which === keyCode.LEFT || e.which === keyCode.RIGHT) {\n if (this.args.grid.getOptions().editorCellNavOnLRKeys) {\n const cursorPosition = this.selectionStart;\n const textLength = e.target.value.length;\n if (e.keyCode === keyCode.LEFT && cursorPosition === 0) {\n this.args.grid.navigatePrev();\n }\n if (e.keyCode === keyCode.RIGHT && cursorPosition >= textLength - 1) {\n this.args.grid.navigateNext();\n }\n }\n }\n };\n\n save() {\n const gridOptions = this.args.grid.getOptions() || {};\n if (gridOptions.autoCommitEdit) {\n this.args.grid.getEditorLock().commitCurrentEdit();\n } else {\n this.args.commitChanges();\n }\n };\n\n cancel() {\n this.input.value = String(this.defaultValue ?? '');\n this.args.cancelChanges();\n };\n\n hide() {\n Utils.hide(this.wrapper);\n };\n\n show() {\n Utils.show(this.wrapper);\n };\n\n position(position: ElementPosition) {\n Utils.setStyleSize(this.wrapper, 'top', (position.top || 0) - 5);\n Utils.setStyleSize(this.wrapper, 'left', (position.left || 0) - 2);\n };\n\n destroy() {\n if (this.args.compositeEditorOptions) {\n this.input.removeEventListener('change', this.onChange.bind(this));\n } else {\n this.wrapper.querySelector('#save')!.removeEventListener('click', this.save.bind(this));\n this.wrapper.querySelector('#cancel')!.removeEventListener('click', this.cancel.bind(this));\n this.input.removeEventListener('keydown', this.handleKeyDown.bind(this) as EventListener);\n }\n this.wrapper.remove();\n };\n\n focus() {\n this.input.focus();\n };\n\n loadValue(item: any) {\n this.input.value = this.defaultValue = item[this.args.column.field];\n this.input.select();\n };\n\n serializeValue() {\n return this.input.value;\n };\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n };\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\n };\n\n validate() {\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n}\n\n/*\n * Depending on the value of Grid option 'editorCellNavOnLRKeys', us\n * Navigate to the cell on the left if the cursor is at the beginning of the input string\n * and to the right cell if it's at the end. Otherwise, move the cursor within the text\n */\nfunction handleKeydownLRNav(e: KeyboardEvent & { target: HTMLInputElement; selectionStart: number; }) {\n const cursorPosition = e.selectionStart;\n const textLength = e.target.value.length;\n if ((e.keyCode === keyCode.LEFT && cursorPosition > 0) ||\n e.keyCode === keyCode.RIGHT && cursorPosition < textLength - 1) {\n e.stopImmediatePropagation();\n }\n}\n\nfunction handleKeydownLRNoNav(e: KeyboardEvent) {\n if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT) {\n e.stopImmediatePropagation();\n }\n}\n\nexport const Editors = {\n Text: TextEditor,\n Integer: IntegerEditor,\n Float: FloatEditor,\n Flatpickr: FlatpickrEditor,\n YesNoSelect: YesNoSelectEditor,\n Checkbox: CheckboxEditor,\n PercentComplete: PercentCompleteEditor,\n LongText: LongTextEditor\n};\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(Slick, {\n Editors\n });\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/slick.formatters.js b/dist/browser/slick.formatters.js index df650038a..3ebb837b1 100644 --- a/dist/browser/slick.formatters.js +++ b/dist/browser/slick.formatters.js @@ -1,8 +1,8 @@ "use strict"; (() => { // src/slick.formatters.ts - var Utils = Slick.Utils, PercentCompleteFormatter = (_row, _cell, value) => value == null || value === "" ? "-" : value < 50 ? `${value}%` : `${value}%`, PercentCompleteBarFormatter = (_row, _cell, value) => { - if (value == null || value === "") + var Utils = Slick.Utils, PercentCompleteFormatter = (_row, _cell, value) => !Utils.isDefined(value) || value === "" ? "-" : value < 50 ? `${value}%` : `${value}%`, PercentCompleteBarFormatter = (_row, _cell, value) => { + if (!Utils.isDefined(value) || value === "") return ""; let color; return value < 30 ? color = "red" : value < 70 ? color = "silver" : color = "green", ``; diff --git a/dist/browser/slick.formatters.js.map b/dist/browser/slick.formatters.js.map index ff5c49d45..69599d1ab 100644 --- a/dist/browser/slick.formatters.js.map +++ b/dist/browser/slick.formatters.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.formatters.ts"], - "sourcesContent": ["import type { Formatter } from './models/index';\nimport { Utils as Utils_ } from './slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * Contains basic SlickGrid formatters.\n *\n * NOTE: These are merely examples. You will most likely need to implement something more\n * robust/extensible/localizable/etc. for your use!\n *\n * @module Formatters\n * @namespace Slick\n */\n\nexport const PercentCompleteFormatter: Formatter = (_row, _cell, value) => {\n if (value == null || value === '') {\n return '-';\n } else if (value < 50) {\n return `${value}%`;\n } else {\n return `${value}%`;\n }\n}\n\nexport const PercentCompleteBarFormatter: Formatter = (_row, _cell, value) => {\n if (value == null || value === '') {\n return '';\n }\n\n let color;\n\n if (value < 30) {\n color = 'red';\n } else if (value < 70) {\n color = 'silver';\n } else {\n color = 'green';\n }\n\n return ``;\n}\n\nexport const YesNoFormatter: Formatter = (_row, _cell, value) => {\n return value ? 'Yes' : 'No';\n}\n\nexport const CheckboxFormatter: Formatter = (_row, _cell, value) => {\n return ``;\n}\n\nexport const CheckmarkFormatter: Formatter = (_row, _cell, value) => {\n return value ? `` : '';\n}\n\nexport const Formatters = {\n PercentComplete: PercentCompleteFormatter,\n PercentCompleteBar: PercentCompleteBarFormatter,\n YesNo: YesNoFormatter,\n Checkmark: CheckmarkFormatter,\n Checkbox: CheckboxFormatter\n};\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(Slick, {\n Formatters\n });\n}\n\n"], - "mappings": ";;;AAIA,MAAM,QAAoB,MAAM,OAYnB,2BAAsC,CAAC,MAAM,OAAO,UAC3D,SAAS,QAAQ,UAAU,KACtB,MACE,QAAQ,KACV,6CAA6C,KAAK,aAElD,6BAA6B,KAAK,YAIhC,8BAAyC,CAAC,MAAM,OAAO,UAAU;AAC5E,QAAI,SAAS,QAAQ,UAAU;AAC7B,aAAO;AAGT,QAAI;AAEJ,WAAI,QAAQ,KACV,QAAQ,QACC,QAAQ,KACjB,QAAQ,WAER,QAAQ,SAGH,wDAAwD,KAAK,UAAU,KAAK,aAAa,KAAK;AAAA,EACvG,GAEa,iBAA4B,CAAC,MAAM,OAAO,UAC9C,QAAQ,QAAQ,MAGZ,oBAA+B,CAAC,MAAM,OAAO,UACjD,iCAAiC,QAAQ,iBAAiB,eAAe,aAGrE,qBAAgC,CAAC,MAAM,OAAO,UAClD,QAAQ,wCAAwC,IAG5C,aAAa;AAAA,IACxB,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,OAAO;AAAA,IACP,WAAW;AAAA,IACX,UAAU;AAAA,EACZ;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;", + "sourcesContent": ["import type { Formatter } from './models/index';\nimport { Utils as Utils_ } from './slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * Contains basic SlickGrid formatters.\n *\n * NOTE: These are merely examples. You will most likely need to implement something more\n * robust/extensible/localizable/etc. for your use!\n *\n * @module Formatters\n * @namespace Slick\n */\n\nexport const PercentCompleteFormatter: Formatter = (_row, _cell, value) => {\n if (!Utils.isDefined(value) || value === '') {\n return '-';\n } else if (value < 50) {\n return `${value}%`;\n } else {\n return `${value}%`;\n }\n};\n\nexport const PercentCompleteBarFormatter: Formatter = (_row, _cell, value) => {\n if (!Utils.isDefined(value) || value === '') {\n return '';\n }\n\n let color;\n\n if (value < 30) {\n color = 'red';\n } else if (value < 70) {\n color = 'silver';\n } else {\n color = 'green';\n }\n\n return ``;\n};\n\nexport const YesNoFormatter: Formatter = (_row, _cell, value) => {\n return value ? 'Yes' : 'No';\n};\n\nexport const CheckboxFormatter: Formatter = (_row, _cell, value) => {\n return ``;\n};\n\nexport const CheckmarkFormatter: Formatter = (_row, _cell, value) => {\n return value ? `` : '';\n};\n\nexport const Formatters = {\n PercentComplete: PercentCompleteFormatter,\n PercentCompleteBar: PercentCompleteBarFormatter,\n YesNo: YesNoFormatter,\n Checkmark: CheckmarkFormatter,\n Checkbox: CheckboxFormatter\n};\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(Slick, {\n Formatters\n });\n}\n\n"], + "mappings": ";;;AAIA,MAAM,QAAoB,MAAM,OAYnB,2BAAsC,CAAC,MAAM,OAAO,UAC3D,CAAC,MAAM,UAAU,KAAK,KAAK,UAAU,KAChC,MACE,QAAQ,KACV,6CAA6C,KAAK,aAElD,6BAA6B,KAAK,YAIhC,8BAAyC,CAAC,MAAM,OAAO,UAAU;AAC5E,QAAI,CAAC,MAAM,UAAU,KAAK,KAAK,UAAU;AACvC,aAAO;AAGT,QAAI;AAEJ,WAAI,QAAQ,KACV,QAAQ,QACC,QAAQ,KACjB,QAAQ,WAER,QAAQ,SAGH,wDAAwD,KAAK,UAAU,KAAK,aAAa,KAAK;AAAA,EACvG,GAEa,iBAA4B,CAAC,MAAM,OAAO,UAC9C,QAAQ,QAAQ,MAGZ,oBAA+B,CAAC,MAAM,OAAO,UACjD,iCAAiC,QAAQ,iBAAiB,eAAe,aAGrE,qBAAgC,CAAC,MAAM,OAAO,UAClD,QAAQ,wCAAwC,IAG5C,aAAa;AAAA,IACxB,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,OAAO;AAAA,IACP,WAAW;AAAA,IACX,UAAU;AAAA,EACZ;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;", "names": [] } diff --git a/dist/browser/slick.grid.js b/dist/browser/slick.grid.js index 9777c14b5..df3ab8c64 100644 --- a/dist/browser/slick.grid.js +++ b/dist/browser/slick.grid.js @@ -23,7 +23,7 @@ this.options = options; ////////////////////////////////////////////////////////////////////////////////////////////// // Public API - __publicField(this, "slickGridVersion", "5.1.0"); + __publicField(this, "slickGridVersion", "5.2.0"); /** optional grid state clientId */ __publicField(this, "cid", ""); // Events @@ -433,7 +433,7 @@ for (let el of this._hiddenParents) { let old = {}; for (let name in this.cssShow) - old[name] = el.style[name], el.style[name] = this.cssShow[name]; + this.cssShow && (old[name] = el.style[name], el.style[name] = this.cssShow[name]); this.oldProps.push(old); } } @@ -442,7 +442,7 @@ for (let el of this._hiddenParents) { let old = this.oldProps[i++]; for (let name in this.cssShow) - el.style[name] = old[name]; + this.cssShow && (el.style[name] = old[name]); } } hasFrozenColumns() { @@ -619,8 +619,8 @@ // TODO: this is static. need to handle page mutation. bindAncestorScrollEvents() { let elem = this.hasFrozenRows && !this._options.frozenBottom ? this._canvasBottomL : this._canvasTopL; - for (; (elem = elem.parentNode) !== document.body && elem != null; ) - (elem == this._viewportTopL || elem.scrollWidth !== elem.clientWidth || elem.scrollHeight !== elem.clientHeight) && (this._boundAncestors.push(elem), this._bindingEventService.bind(elem, "scroll", this.handleActiveCellPositionChange.bind(this))); + for (; (elem = elem.parentNode) !== document.body && elem; ) + (elem === this._viewportTopL || elem.scrollWidth !== elem.clientWidth || elem.scrollHeight !== elem.clientHeight) && (this._boundAncestors.push(elem), this._bindingEventService.bind(elem, "scroll", this.handleActiveCellPositionChange.bind(this))); } unbindAncestorScrollEvents() { this._boundAncestors.forEach((ancestor) => { @@ -630,14 +630,14 @@ /** * Updates an existing column definition and a corresponding header DOM element with the new title and tooltip. * @param {Number|String} columnId Column id. - * @param {String} title New column name. + * @param {String} [title] New column name. * @param {String} [toolTip] New column tooltip. */ updateColumnHeader(columnId, title, toolTip) { if (!this.initialized) return; let idx = this.getColumnIndex(columnId); - if (idx == null) + if (!Utils.isDefined(idx)) return; let columnDef = this.columns[idx], header = this.getColumnByIndex(idx); header && (title !== void 0 && (this.columns[idx].name = title), toolTip !== void 0 && (this.columns[idx].toolTip = toolTip), this.trigger(this.onBeforeHeaderCellDestroy, { @@ -661,8 +661,8 @@ return this.hasFrozenColumns() ? idx <= this._options.frozenColumn ? this._headerL : this._headerR : this._headerL; } /** - * Get a specific Header Column DOM element - * @param {Number|String} [columnIdOrIdx] - column Id or index + * Get a specific Header Column DOM element by its column Id or index + * @param {Number|String} columnIdOrIdx - column Id or index */ getHeaderColumn(columnIdOrIdx) { let idx = typeof columnIdOrIdx == "number" ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx), targetHeader = this.hasFrozenColumns() ? idx <= this._options.frozenColumn ? this._headerL : this._headerR : this._headerL, targetIndex = this.hasFrozenColumns() ? idx <= this._options.frozenColumn ? idx : idx - this._options.frozenColumn - 1 : idx; @@ -689,14 +689,17 @@ return this._preHeaderPanelR; } /** - * Get Header Row Column DOM element by its column Id - * @param {Number|String} [columnIdOrIdx] - column Id or index + * Get Header Row Column DOM element by its column Id or index + * @param {Number|String} columnIdOrIdx - column Id or index */ getHeaderRowColumn(columnIdOrIdx) { let idx = typeof columnIdOrIdx == "number" ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx), headerRowTarget; return this.hasFrozenColumns() ? idx <= this._options.frozenColumn ? headerRowTarget = this._headerRowL : (headerRowTarget = this._headerRowR, idx -= this._options.frozenColumn + 1) : headerRowTarget = this._headerRowL, headerRowTarget.children[idx]; } - /** Get the Footer Row Column DOM element */ + /** + * Get the Footer Row Column DOM element by its column Id or index + * @param {Number|String} columnIdOrIdx - column Id or index + */ getFooterRowColumn(columnIdOrIdx) { let idx = typeof columnIdOrIdx == "number" ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx), footerRowTarget; return this.hasFrozenColumns() ? idx <= this._options.frozenColumn ? footerRowTarget = this._footerRowL : (footerRowTarget = this._footerRowR, idx -= this._options.frozenColumn + 1) : footerRowTarget = this._footerRowL, footerRowTarget.children[idx]; @@ -778,8 +781,8 @@ column: m, grid: this }), this._options.showHeaderRow) { - let headerRowCell = Utils.createDomElement("div", { className: `ui-state-default slick-state-default slick-headerrow-column l${i} r${i}` }, headerRowTarget), classname2 = this.hasFrozenColumns() && i <= this._options.frozenColumn ? "frozen" : null; - classname2 && headerRowCell.classList.add(classname2), this._bindingEventService.bind(headerRowCell, "mouseenter", this.handleHeaderRowMouseEnter.bind(this)), this._bindingEventService.bind(headerRowCell, "mouseleave", this.handleHeaderRowMouseLeave.bind(this)), Utils.storage.put(headerRowCell, "column", m), this.trigger(this.onHeaderRowCellRendered, { + let headerRowCell = Utils.createDomElement("div", { className: `ui-state-default slick-state-default slick-headerrow-column l${i} r${i}` }, headerRowTarget), frozenClasses = this.hasFrozenColumns() && i <= this._options.frozenColumn ? "frozen" : null; + frozenClasses && headerRowCell.classList.add(frozenClasses), this._bindingEventService.bind(headerRowCell, "mouseenter", this.handleHeaderRowMouseEnter.bind(this)), this._bindingEventService.bind(headerRowCell, "mouseleave", this.handleHeaderRowMouseLeave.bind(this)), Utils.storage.put(headerRowCell, "column", m), this.trigger(this.onHeaderRowCellRendered, { node: headerRowCell, column: m, grid: this @@ -811,7 +814,7 @@ return; let previousSortColumns = this.sortColumns.slice(), sortColumn = null, i = 0; for (; i < this.sortColumns.length; i++) - if (this.sortColumns[i].columnId == column.id) { + if (this.sortColumns[i].columnId === column.id) { sortColumn = this.sortColumns[i], sortColumn.sortAsc = !sortColumn.sortAsc; break; } @@ -837,7 +840,7 @@ let currentPosition = 0; return this._headers.forEach((header) => { header.querySelectorAll(".slick-header-column").forEach((column, i) => { - column.id == id && (currentPosition = i); + column.id === id && (currentPosition = i); }); }), currentPosition; } @@ -846,7 +849,8 @@ index > -1 && (arr.splice(index, 1), this.remove(arr, elem)); } setupColumnReorder() { - this.sortableSideLeftInstance && (this.sortableSideLeftInstance.destroy(), this.sortableSideRightInstance.destroy()); + var _a, _b; + (_a = this.sortableSideLeftInstance) == null || _a.destroy(), (_b = this.sortableSideRightInstance) == null || _b.destroy(); let columnScrollTimer = null, scrollColumnsRight = () => this._viewportScrollContainerX.scrollLeft = this._viewportScrollContainerX.scrollLeft + 10, scrollColumnsLeft = () => this._viewportScrollContainerX.scrollLeft = this._viewportScrollContainerX.scrollLeft - 10, canDragScroll, sortableOptions = { animation: 50, direction: "horizontal", @@ -861,13 +865,13 @@ canDragScroll = !this.hasFrozenColumns() || Utils.offset(e.item).left > Utils.offset(this._viewportScrollContainerX).left, canDragScroll && e.originalEvent.pageX > this._container.clientWidth ? columnScrollTimer || (columnScrollTimer = setInterval(scrollColumnsRight, 100)) : canDragScroll && e.originalEvent.pageX < Utils.offset(this._viewportScrollContainerX).left ? columnScrollTimer || (columnScrollTimer = setInterval(scrollColumnsLeft, 100)) : (clearInterval(columnScrollTimer), columnScrollTimer = null); }, onEnd: (e) => { - var _a, _b, _c; + var _a2, _b2, _c, _d, _e; clearInterval(columnScrollTimer), columnScrollTimer = null; let limit; - if (!((_a = this.getEditorLock()) != null && _a.commitCurrentEdit())) + if (!((_a2 = this.getEditorLock()) != null && _a2.commitCurrentEdit())) return; - let reorderedIds = (_b = this.sortableSideLeftInstance) == null ? void 0 : _b.toArray(); - reorderedIds = reorderedIds.concat((_c = this.sortableSideRightInstance) == null ? void 0 : _c.toArray()); + let reorderedIds = (_c = (_b2 = this.sortableSideLeftInstance) == null ? void 0 : _b2.toArray()) != null ? _c : []; + reorderedIds = reorderedIds.concat((_e = (_d = this.sortableSideRightInstance) == null ? void 0 : _d.toArray()) != null ? _e : []); let reorderedColumns = []; for (let i = 0; i < reorderedIds.length; i++) reorderedColumns.push(this.columns[this.getColumnIndex(reorderedIds[i])]); @@ -988,7 +992,7 @@ return p.forEach((val) => delta += Utils.toFloat(styles[val])), delta; } setFrozenOptions() { - if (this._options.frozenColumn = this._options.frozenColumn >= 0 && this._options.frozenColumn < this.columns.length ? parseInt(this._options.frozenColumn) : -1, this._options.frozenRow > -1) { + if (this._options.frozenColumn = this._options.frozenColumn >= 0 && this._options.frozenColumn < this.columns.length ? parseInt(this._options.frozenColumn, 10) : -1, this._options.frozenRow > -1) { this.hasFrozenRows = !0, this.frozenRowsHeight = this._options.frozenRow * this._options.rowHeight; let dataLength = this.getDataLength(); this.actualFrozenRow = this._options.frozenBottom ? dataLength - this._options.frozenRow : this._options.frozenRow; @@ -1034,7 +1038,7 @@ if (!this.stylesheet) { let sheets = document.styleSheets; for (i = 0; i < sheets.length; i++) - if ((sheets[i].ownerNode || sheets[i].owningElement) == this._style) { + if ((sheets[i].ownerNode || sheets[i].owningElement) === this._style) { this.stylesheet = sheets[i]; break; } @@ -1060,12 +1064,12 @@ * @param {boolean} shouldDestroyAllElements - do we want to destroy (nullify) all DOM elements as well? This help in avoiding mem leaks */ destroy(shouldDestroyAllElements) { - var _a, _b; + var _a, _b, _c, _d; this._bindingEventService.unbindAll(), this.slickDraggableInstance = this.destroyAllInstances(this.slickDraggableInstance), this.slickMouseWheelInstances = this.destroyAllInstances(this.slickMouseWheelInstances), this.slickResizableInstances = this.destroyAllInstances(this.slickResizableInstances), (_a = this.getEditorLock()) == null || _a.cancelCurrentEdit(), this.trigger(this.onBeforeDestroy, {}); let i = this.plugins.length; for (; i--; ) this.unregisterPlugin(this.plugins[i]); - this._options.enableColumnReorder && typeof ((_b = this.sortableSideLeftInstance) == null ? void 0 : _b.destroy) == "function" && (this.sortableSideLeftInstance.destroy(), this.sortableSideRightInstance.destroy()), this.unbindAncestorScrollEvents(), this._bindingEventService.unbindByEventName(this._container, "resize"), this.removeCssRules(), this._canvas.forEach((element) => { + this._options.enableColumnReorder && typeof ((_b = this.sortableSideLeftInstance) == null ? void 0 : _b.destroy) == "function" && ((_c = this.sortableSideLeftInstance) == null || _c.destroy(), (_d = this.sortableSideRightInstance) == null || _d.destroy()), this.unbindAncestorScrollEvents(), this._bindingEventService.unbindByEventName(this._container, "resize"), this.removeCssRules(), this._canvas.forEach((element) => { this._bindingEventService.unbindByEventName(element, "keydown"), this._bindingEventService.unbindByEventName(element, "click"), this._bindingEventService.unbindByEventName(element, "dblclick"), this._bindingEventService.unbindByEventName(element, "contextmenu"), this._bindingEventService.unbindByEventName(element, "mouseover"), this._bindingEventService.unbindByEventName(element, "mouseout"); }), this._viewport.forEach((view) => { this._bindingEventService.unbindByEventName(view, "scroll"); @@ -1094,7 +1098,7 @@ destroyAllInstances(inputInstances) { if (inputInstances) { let instances = Array.isArray(inputInstances) ? inputInstances : [inputInstances], instance; - for (; (instance = instances.pop()) != null; ) + for (; Utils.isDefined(instance = instances.pop()); ) instance && typeof instance.destroy == "function" && instance.destroy(); } return inputInstances = Array.isArray(inputInstances) ? [] : null, inputInstances; @@ -1193,7 +1197,7 @@ if (autoSize.headerWidthPx = 0, autoSize.ignoreHeaderText || (autoSize.headerWidthPx = this.getColHeaderWidth(columnDef)), autoSize.headerWidthPx === 0 && (autoSize.headerWidthPx = columnDef.width ? columnDef.width : columnDef.maxWidth ? columnDef.maxWidth : columnDef.minWidth ? columnDef.minWidth : 20), autoSize.colValueArray) return maxColWidth = this.getColWidth(columnDef, gridCanvas, autoSize.colValueArray), Math.max(autoSize.headerWidthPx, maxColWidth); let rowInfo = {}; - rowInfo.colIndex = colIndex, rowInfo.rowCount = this.getDataLength(), rowInfo.startIndex = 0, rowInfo.endIndex = rowInfo.rowCount - 1, rowInfo.valueArr = null, rowInfo.getRowVal = (i2) => this.getDataItem(i2)[columnDef.field]; + rowInfo.colIndex = colIndex, rowInfo.rowCount = this.getDataLength(), rowInfo.startIndex = 0, rowInfo.endIndex = rowInfo.rowCount - 1, rowInfo.valueArr = null, rowInfo.getRowVal = (j) => this.getDataItem(j)[columnDef.field]; let rowSelectionMode = (isInit ? autoSize.rowSelectionModeOnInit : void 0) || autoSize.rowSelectionMode; if (rowSelectionMode === RowSelectionMode.FirstRow && (rowInfo.endIndex = 0), rowSelectionMode === RowSelectionMode.LastRow && (rowInfo.endIndex = rowInfo.startIndex = rowInfo.rowCount - 1), rowSelectionMode === RowSelectionMode.FirstNRows && (rowInfo.endIndex = Math.min(autoSize.rowSelectionCount || 0, rowInfo.rowCount) - 1), autoSize.valueFilterMode === ValueFilterMode.DeDuplicate) { let rowsDict = {}; @@ -1204,7 +1208,7 @@ else { rowInfo.valueArr = []; for (let v in rowsDict) - rowInfo.valueArr.push(v); + rowsDict && rowInfo.valueArr.push(v); } rowInfo.startIndex = 0, rowInfo.endIndex = rowInfo.length - 1; } @@ -1321,7 +1325,7 @@ } /** * Returns the index of a column with a given id. Since columns can be reordered by the user, this can be used to get the column definition independent of the order: - * @param id A column id. + * @param {String | Number} id A column id. */ getColumnIndex(id) { return this.columnsById[id]; @@ -1341,12 +1345,12 @@ var _a; let x = 0, w = 0, rule; for (let i = 0; i < this.columns.length; i++) - (_a = this.columns[i]) != null && _a.hidden || (w = this.columns[i].width || 0, rule = this.getColumnCssRules(i), rule.left.style.left = `${x}px`, rule.right.style.right = (this._options.frozenColumn !== -1 && i > this._options.frozenColumn ? this.canvasWidthR : this.canvasWidthL) - x - w + "px", this._options.frozenColumn !== i && (x += this.columns[i].width)), this._options.frozenColumn == i && (x = 0); + (_a = this.columns[i]) != null && _a.hidden || (w = this.columns[i].width || 0, rule = this.getColumnCssRules(i), rule.left.style.left = `${x}px`, rule.right.style.right = (this._options.frozenColumn !== -1 && i > this._options.frozenColumn ? this.canvasWidthR : this.canvasWidthL) - x - w + "px", this._options.frozenColumn !== i && (x += this.columns[i].width)), this._options.frozenColumn === i && (x = 0); } /** * Accepts a columnId string and an ascending boolean. Applies a sort glyph in either ascending or descending form to the header of the column. Note that this does not actually sort the column. It only adds the sort glyph to the header. - * @param columnId - * @param ascending + * @param {String | Number} columnId + * @param {Boolean} ascending */ setSortColumn(columnId, ascending) { this.setSortColumns([{ columnId, sortAsc: ascending }]); @@ -1382,9 +1386,9 @@ }); let i = 1; this.sortColumns.forEach((col) => { - col.sortAsc == null && (col.sortAsc = !0); + Utils.isDefined(col.sortAsc) || (col.sortAsc = !0); let columnIndex = this.getColumnIndex(col.columnId); - if (columnIndex != null) { + if (Utils.isDefined(columnIndex)) { let column = this.getColumnByIndex(columnIndex); if (column) { column.classList.add("slick-header-column-sorted"); @@ -1444,7 +1448,7 @@ } /** * Sets grid columns. Column headers will be recreated and all rendered rows will be removed. To rerender the grid (if necessary), call render(). - * @param columnDefinitions An array of column definitions. + * @param {Column[]} columnDefinitions An array of column definitions. */ setColumns(columnDefinitions) { this.trigger(this.onBeforeSetColumns, { previousColumns: this.columns, newColumns: columnDefinitions, grid: this }), this.columns = columnDefinitions, this.updateColumnsInternal(); @@ -1473,13 +1477,13 @@ this._options = Utils.extend(this._options, args), this.trigger(this.onSetOptions, { optionsBefore: originalOptions, optionsAfter: this._options }), this.internal_setOptions(suppressRender, suppressColumnSet, suppressSetOverflow); } /** - * If option.mixinDefaults is true then external code maintains a reference to the options object. In this case there is no need - * to call setOptions() - changes can be made directly to the object. However setOptions() also performs some recalibration of the - * grid in reaction to changed options. activateChangedOptions call the same recalibration routines as setOptions() would have. - * @param {Boolean} [suppressRender] - do we want to supress the grid re-rendering? (defaults to false) - * @param {Boolean} [suppressColumnSet] - do we want to supress the columns set, via "setColumns()" method? (defaults to false) - * @param {Boolean} [suppressSetOverflow] - do we want to suppress the call to `setOverflow` - */ + * If option.mixinDefaults is true then external code maintains a reference to the options object. In this case there is no need + * to call setOptions() - changes can be made directly to the object. However setOptions() also performs some recalibration of the + * grid in reaction to changed options. activateChangedOptions call the same recalibration routines as setOptions() would have. + * @param {Boolean} [suppressRender] - do we want to supress the grid re-rendering? (defaults to false) + * @param {Boolean} [suppressColumnSet] - do we want to supress the columns set, via "setColumns()" method? (defaults to false) + * @param {Boolean} [suppressSetOverflow] - do we want to suppress the call to `setOverflow` + */ activateChangedOptions(suppressRender, suppressColumnSet, suppressSetOverflow) { this.prepareForOptionsChange(), this.invalidateRow(this.getDataLength()), this.trigger(this.onActivateChangedOptions, { options: this._options }), this.internal_setOptions(suppressRender, suppressColumnSet, suppressSetOverflow); } @@ -1521,7 +1525,7 @@ } /** * Returns the databinding item at a given position. - * @param index Item row index. + * @param {Number} index Item row index. */ getDataItem(i) { return this.data.getItem ? this.data.getItem(i) : this.data[i]; @@ -1607,7 +1611,10 @@ getRowFromPosition(y) { return Math.floor((y + this.offset) / this._options.rowHeight); } - /** Scroll to an Y position in the grid */ + /** + * Scroll to an Y position in the grid + * @param {Number} y + */ scrollTo(y) { var _a, _b; y = Math.max(y, 0), y = Math.min(y, (this.th || 0) - Utils.height(this._viewportScrollContainerY) + ((this.viewportHasHScroll || this.hasFrozenColumns()) && (_b = (_a = this.scrollbarDimensions) == null ? void 0 : _a.height) != null ? _b : 0)); @@ -1621,7 +1628,7 @@ this.prevScrollTop !== newScrollTop && (this.vScrollDir = this.prevScrollTop + oldOffset < newScrollTop + this.offset ? 1 : -1, this.lastRenderedScrollTop = this.scrollTop = this.prevScrollTop = newScrollTop, this.hasFrozenColumns() && (this._viewportTopL.scrollTop = newScrollTop), this.hasFrozenRows && (this._viewportBottomL.scrollTop = this._viewportBottomR.scrollTop = newScrollTop), this._viewportScrollContainerY && (this._viewportScrollContainerY.scrollTop = newScrollTop), this.trigger(this.onViewportChanged, {})); } defaultFormatter(_row, _cell, value) { - return value == null ? "" : (value + "").replace(/&/g, "&").replace(//g, ">"); + return Utils.isDefined(value) ? (value + "").replace(/&/g, "&").replace(//g, ">") : ""; } getFormatter(row, column) { var _a, _b, _c; @@ -1638,7 +1645,7 @@ } appendRowHtml(stringArrayL, stringArrayR, row, range, dataLength) { var _a, _b; - let d = this.getDataItem(row), dataLoading = row < dataLength && !d, rowCss = "slick-row" + (this.hasFrozenRows && row <= this._options.frozenRow ? " frozen" : "") + (dataLoading ? " loading" : "") + (row === this.activeRow && this._options.showCellSelection ? " active" : "") + (row % 2 == 1 ? " odd" : " even"); + let d = this.getDataItem(row), dataLoading = row < dataLength && !d, rowCss = "slick-row" + (this.hasFrozenRows && row <= this._options.frozenRow ? " frozen" : "") + (dataLoading ? " loading" : "") + (row === this.activeRow && this._options.showCellSelection ? " active" : "") + (row % 2 === 1 ? " odd" : " even"); d || (rowCss += " " + this._options.addNewRowCssClass); let metadata = (_b = (_a = this.data) == null ? void 0 : _a.getItemMetadata) == null ? void 0 : _b.call(_a, row); metadata != null && metadata.cssClasses && (rowCss += " " + metadata.cssClasses); @@ -1671,17 +1678,18 @@ item && (value = this.getDataItemValueForColumn(item, m), formatterResult = this.getFormatter(row, m)(row, cell, value, m, item, this), formatterResult == null && (formatterResult = "")); let appendCellResult = this.trigger(this.onBeforeAppendCell, { row, cell, value, dataContext: item }).getReturnValue(), addlCssClasses = typeof appendCellResult == "string" ? appendCellResult : ""; formatterResult != null && formatterResult.addClasses && (addlCssClasses += (addlCssClasses ? " " : "") + formatterResult.addClasses); - let toolTip = formatterResult != null && formatterResult.toolTip ? "title='" + formatterResult.toolTip + "'" : "", customAttrStr = ""; + let toolTip = formatterResult != null && formatterResult.toolTip ? `title="${formatterResult.toolTip}"` : "", customAttrStr = ""; if (m.hasOwnProperty("cellAttrs") && m.cellAttrs instanceof Object) for (let key in m.cellAttrs) m.cellAttrs.hasOwnProperty(key) && (customAttrStr += ` ${key}="${m.cellAttrs[key]}" `); stringArray.push(`

`), item && stringArray.push(Object.prototype.toString.call(formatterResult) !== "[object Object]" ? formatterResult : formatterResult.text), stringArray.push("
"), this.rowsCache[row].cellRenderQueue.push(cell), this.rowsCache[row].cellColSpans[cell] = colspan; } cleanupRows(rangeToKeep) { - for (let rowId in this.rowsCache) { - let i = +rowId, removeFrozenRow = !0; - this.hasFrozenRows && (this._options.frozenBottom && i >= this.actualFrozenRow || !this._options.frozenBottom && i <= this.actualFrozenRow) && (removeFrozenRow = !1), (i = parseInt(rowId, 10)) !== this.activeRow && (i < rangeToKeep.top || i > rangeToKeep.bottom) && removeFrozenRow && this.removeRowFromCache(i); - } + for (let rowId in this.rowsCache) + if (this.rowsCache) { + let i = +rowId, removeFrozenRow = !0; + this.hasFrozenRows && (this._options.frozenBottom && i >= this.actualFrozenRow || !this._options.frozenBottom && i <= this.actualFrozenRow) && (removeFrozenRow = !1), (i = parseInt(rowId, 10)) !== this.activeRow && (i < rangeToKeep.top || i > rangeToKeep.bottom) && removeFrozenRow && this.removeRowFromCache(i); + } this._options.enableAsyncPostRenderCleanup && this.startPostProcessingCleanup(); } /** Invalidate all grid rows and re-render the grid rows */ @@ -1692,10 +1700,13 @@ invalidateAllRows() { this.currentEditor && this.makeActiveCellNormal(); for (let row in this.rowsCache) - this.removeRowFromCache(+row); + this.rowsCache && this.removeRowFromCache(+row); this._options.enableAsyncPostRenderCleanup && this.startPostProcessingCleanup(); } - /** Invalidate a specific set of row numbers */ + /** + * Invalidate a specific set of row numbers + * @param {Number[]} rows + */ invalidateRows(rows) { if (!rows || !rows.length) return; @@ -1705,7 +1716,10 @@ this.currentEditor && this.activeRow === rows[i] && this.makeActiveCellNormal(), this.rowsCache[rows[i]] && this.removeRowFromCache(rows[i]); this._options.enableAsyncPostRenderCleanup && this.startPostProcessingCleanup(); } - /** Invalidate a specific row number */ + /** + * Invalidate a specific row number + * @param {Number} row + */ invalidateRow(row) { !row && row !== 0 || this.invalidateRows([row]); } @@ -1801,7 +1815,7 @@ var _a, _b; if ((!this._options.autoHeight || this._options.frozenColumn !== -1) && (this.topPanelH = this._options.showTopPanel ? this._options.topPanelHeight + this.getVBoxDelta(this._topPanelScrollers[0]) : 0, this.headerRowH = this._options.showHeaderRow ? this._options.headerRowHeight + this.getVBoxDelta(this._headerRowScroller[0]) : 0, this.footerRowH = this._options.showFooterRow ? this._options.footerRowHeight + this.getVBoxDelta(this._footerRowScroller[0]) : 0), this._options.autoHeight) { let fullHeight = this._paneHeaderL.offsetHeight; - fullHeight += this._options.showHeaderRow ? this._options.headerRowHeight + this.getVBoxDelta(this._headerRowScroller[0]) : 0, fullHeight += this._options.showFooterRow ? this._options.footerRowHeight + this.getVBoxDelta(this._footerRowScroller[0]) : 0, fullHeight += this.getCanvasWidth() > this.viewportW && (_b = (_a = this.scrollbarDimensions) == null ? void 0 : _a.height) != null ? _b : 0, this.viewportH = this._options.rowHeight * this.getDataLengthIncludingAddNew() + (this._options.frozenColumn == -1 ? fullHeight : 0); + fullHeight += this._options.showHeaderRow ? this._options.headerRowHeight + this.getVBoxDelta(this._headerRowScroller[0]) : 0, fullHeight += this._options.showFooterRow ? this._options.footerRowHeight + this.getVBoxDelta(this._footerRowScroller[0]) : 0, fullHeight += this.getCanvasWidth() > this.viewportW && (_b = (_a = this.scrollbarDimensions) == null ? void 0 : _a.height) != null ? _b : 0, this.viewportH = this._options.rowHeight * this.getDataLengthIncludingAddNew() + (this._options.frozenColumn === -1 ? fullHeight : 0); } else { let columnNamesH = this._options.showColumnHeader ? Utils.toFloat(Utils.height(this._headerScroller[0])) + this.getVBoxDelta(this._headerScroller[0]) : 0, preHeaderH = this._options.createPreHeaderPanel && this._options.showPreHeaderPanel ? this._options.preHeaderPanelHeight + this.getVBoxDelta(this._preHeaderPanelScroller) : 0, style = getComputedStyle(this._container); this.viewportH = Utils.toFloat(style.height) - Utils.toFloat(style.paddingTop) - Utils.toFloat(style.paddingBottom) - columnNamesH - this.topPanelH - this.headerRowH - this.footerRowH - preHeaderH; @@ -1811,7 +1825,7 @@ getViewportWidth() { return this.viewportW = parseFloat(Utils.innerSize(this._container, "width")), this.viewportW; } - /** Execute a Resize of the Canvas */ + /** Execute a Resize of the Grid Canvas */ resizeCanvas() { var _a, _b, _c, _d, _e, _f; if (!this.initialized) @@ -1827,9 +1841,12 @@ let paneBottomTop = this._paneTopL.offsetTop + this.paneTopH; this._options.autoHeight || Utils.height(this._viewportTopL, this.viewportTopH), this.hasFrozenColumns() ? (Utils.setStyleSize(this._paneTopR, "top", Utils.height(this._paneHeaderL)), Utils.height(this._paneTopR, this.paneTopH), Utils.height(this._viewportTopR, this.viewportTopH), this.hasFrozenRows && (Utils.setStyleSize(this._paneBottomL, "top", paneBottomTop), Utils.height(this._paneBottomL, this.paneBottomH), Utils.setStyleSize(this._paneBottomR, "top", paneBottomTop), Utils.height(this._paneBottomR, this.paneBottomH), Utils.height(this._viewportBottomR, this.paneBottomH))) : this.hasFrozenRows && (Utils.width(this._paneBottomL, "100%"), Utils.height(this._paneBottomL, this.paneBottomH), Utils.setStyleSize(this._paneBottomL, "top", paneBottomTop)), this.hasFrozenRows ? (Utils.height(this._viewportBottomL, this.paneBottomH), this._options.frozenBottom ? (Utils.height(this._canvasBottomL, this.frozenRowsHeight), this.hasFrozenColumns() && Utils.height(this._canvasBottomR, this.frozenRowsHeight)) : (Utils.height(this._canvasTopL, this.frozenRowsHeight), this.hasFrozenColumns() && Utils.height(this._canvasTopR, this.frozenRowsHeight))) : Utils.height(this._viewportTopR, this.viewportTopH), (!this.scrollbarDimensions || !this.scrollbarDimensions.width) && (this.scrollbarDimensions = this.measureScrollbar()), this._options.autosizeColsMode === GridAutosizeColsMode.LegacyForceFit && this.autosizeColumns(), this.updateRowCount(), this.handleScroll(), this.lastRenderedScrollLeft = -1, this.render(); } - /** Update paging information status from the View */ + /** + * Update paging information status from the View + * @param {PagingInfo} pagingInfo + */ updatePagingStatusFromView(pagingInfo) { - this.pagingActive = pagingInfo.pageSize !== 0, this.pagingIsLastPage = pagingInfo.pageNum == pagingInfo.totalPages - 1; + this.pagingActive = pagingInfo.pageSize !== 0, this.pagingIsLastPage = pagingInfo.pageNum === pagingInfo.totalPages - 1; } /** Update the dataset row count */ updateRowCount() { @@ -1845,14 +1862,14 @@ Number(i) > r1 && this.removeRowFromCache(+i); this._options.enableAsyncPostRenderCleanup && this.startPostProcessingCleanup(), this.activeCellNode && this.activeRow > r1 && this.resetActiveCell(), oldH = this.h, this._options.autoHeight ? this.h = this._options.rowHeight * numberOfRows : (this.th = Math.max(this._options.rowHeight * numberOfRows, tempViewportH - ((_b = (_a = this.scrollbarDimensions) == null ? void 0 : _a.height) != null ? _b : 0)), this.th < this.maxSupportedCssHeight ? (this.h = this.ph = this.th, this.n = 1, this.cj = 0) : (this.h = this.maxSupportedCssHeight, this.ph = this.h / 100, this.n = Math.floor(this.th / this.ph), this.cj = (this.th - this.h) / (this.n - 1))), (this.h !== oldH || this.enforceFrozenRowHeightRecalc) && (this.hasFrozenRows && !this._options.frozenBottom ? (Utils.height(this._canvasBottomL, this.h), this.hasFrozenColumns() && Utils.height(this._canvasBottomR, this.h)) : (Utils.height(this._canvasTopL, this.h), Utils.height(this._canvasTopR, this.h)), this.scrollTop = this._viewportScrollContainerY.scrollTop, this.enforceFrozenRowHeightRecalc = !1); let oldScrollTopInRange = this.scrollTop + this.offset <= this.th - tempViewportH; - this.th == 0 || this.scrollTop == 0 ? this.page = this.offset = 0 : oldScrollTopInRange ? this.scrollTo(this.scrollTop + this.offset) : this.scrollTo(this.th - tempViewportH + ((_d = (_c = this.scrollbarDimensions) == null ? void 0 : _c.height) != null ? _d : 0)), this.h !== oldH && this._options.autoHeight && this.resizeCanvas(), this._options.autosizeColsMode === GridAutosizeColsMode.LegacyForceFit && oldViewportHasVScroll !== this.viewportHasVScroll && this.autosizeColumns(), this.updateCanvasWidth(!1); + this.th === 0 || this.scrollTop === 0 ? this.page = this.offset = 0 : oldScrollTopInRange ? this.scrollTo(this.scrollTop + this.offset) : this.scrollTo(this.th - tempViewportH + ((_d = (_c = this.scrollbarDimensions) == null ? void 0 : _c.height) != null ? _d : 0)), this.h !== oldH && this._options.autoHeight && this.resizeCanvas(), this._options.autosizeColsMode === GridAutosizeColsMode.LegacyForceFit && oldViewportHasVScroll !== this.viewportHasVScroll && this.autosizeColumns(), this.updateCanvasWidth(!1); } /** @alias `getVisibleRange` */ getViewport(viewportTop, viewportLeft) { return this.getVisibleRange(viewportTop, viewportLeft); } getVisibleRange(viewportTop, viewportLeft) { - return viewportTop == null && (viewportTop = this.scrollTop), viewportLeft == null && (viewportLeft = this.scrollLeft), { + return viewportTop != null || (viewportTop = this.scrollTop), viewportLeft != null || (viewportLeft = this.scrollLeft), { top: this.getRowFromPosition(viewportTop), bottom: this.getRowFromPosition(viewportTop + this.viewportH) + 1, leftPx: viewportLeft, @@ -1862,7 +1879,7 @@ /** Get rendered range */ getRenderedRange(viewportTop, viewportLeft) { let range = this.getVisibleRange(viewportTop, viewportLeft), buffer = Math.round(this.viewportH / this._options.rowHeight), minBuffer = this._options.minRowBuffer; - return this.vScrollDir == -1 ? (range.top -= buffer, range.bottom += minBuffer) : this.vScrollDir == 1 ? (range.top -= minBuffer, range.bottom += buffer) : (range.top -= minBuffer, range.bottom += minBuffer), range.top = Math.max(0, range.top), range.bottom = Math.min(this.getDataLengthIncludingAddNew() - 1, range.bottom), range.leftPx -= this.viewportW, range.rightPx += this.viewportW, range.leftPx = Math.max(0, range.leftPx), range.rightPx = Math.min(this.canvasWidth, range.rightPx), range; + return this.vScrollDir === -1 ? (range.top -= buffer, range.bottom += minBuffer) : this.vScrollDir === 1 ? (range.top -= minBuffer, range.bottom += buffer) : (range.top -= minBuffer, range.bottom += minBuffer), range.top = Math.max(0, range.top), range.bottom = Math.min(this.getDataLengthIncludingAddNew() - 1, range.bottom), range.leftPx -= this.viewportW, range.rightPx += this.viewportW, range.leftPx = Math.max(0, range.leftPx), range.rightPx = Math.min(this.canvasWidth, range.rightPx), range; } ensureCellNodesInRowsCache(row) { let cacheEntry = this.rowsCache[row]; @@ -1888,10 +1905,10 @@ if (i <= this._options.frozenColumn || Array.isArray(this.columns) && this.columns[i] && this.columns[i].alwaysRenderColumn) continue; let colspan = cacheEntry.cellColSpans[i]; - (this.columnPosLeft[i] > range.rightPx || this.columnPosRight[Math.min(this.columns.length - 1, (i || 0) + colspan - 1)] < range.leftPx) && (row == this.activeRow && Number(i) == this.activeCell || cellsToRemove.push(i)); + (this.columnPosLeft[i] > range.rightPx || this.columnPosRight[Math.min(this.columns.length - 1, (i || 0) + colspan - 1)] < range.leftPx) && (row === this.activeRow && Number(i) === this.activeCell || cellsToRemove.push(i)); } let cellToRemove, cellNode; - for (; (cellToRemove = cellsToRemove.pop()) != null; ) + for (; Utils.isDefined(cellToRemove = cellsToRemove.pop()); ) cellNode = cacheEntry.cellNodesByColumnIdx[cellToRemove], this._options.enableAsyncPostRenderCleanup && ((_a = this.postProcessedRows[row]) != null && _a[cellToRemove]) ? this.queuePostProcessedCellForCleanup(cellNode, cellToRemove, row) : (_b = cellNode.parentElement) == null || _b.removeChild(cellNode), delete cacheEntry.cellColSpans[cellToRemove], delete cacheEntry.cellNodesByColumnIdx[cellToRemove], this.postProcessedRows[row] && delete this.postProcessedRows[row][cellToRemove], totalCellsRemoved++; } cleanUpAndRenderCells(range) { @@ -1908,7 +1925,7 @@ if (!(!this.columns[i] || this.columns[i].hidden)) { if (this.columnPosLeft[i] > range.rightPx) break; - if ((colspan = cacheEntry.cellColSpans[i]) != null) { + if (Utils.isDefined(colspan = cacheEntry.cellColSpans[i])) { i += colspan > 1 ? colspan - 1 : 0; continue; } @@ -1923,17 +1940,17 @@ if (!stringArray.length) return; let x = Utils.createDomElement("div", { innerHTML: this.sanitizeHtmlString(stringArray.join("")) }), processedRow, node; - for (; (processedRow = processedRows.pop()) != null; ) { + for (; Utils.isDefined(processedRow = processedRows.pop()); ) { cacheEntry = this.rowsCache[processedRow]; let columnIdx; - for (; (columnIdx = cacheEntry.cellRenderQueue.pop()) != null; ) + for (; Utils.isDefined(columnIdx = cacheEntry.cellRenderQueue.pop()); ) node = x.lastChild, this.hasFrozenColumns() && columnIdx > this._options.frozenColumn ? cacheEntry.rowNode[1].appendChild(node) : cacheEntry.rowNode[0].appendChild(node), cacheEntry.cellNodesByColumnIdx[columnIdx] = node; } } renderRows(range) { let stringArrayL = [], stringArrayR = [], rows = [], needToReselectCell = !1, dataLength = this.getDataLength(); for (let i = range.top, ii = range.bottom; i <= ii; i++) - this.rowsCache[i] || this.hasFrozenRows && this._options.frozenBottom && i == this.getDataLength() || (this.renderedRows++, rows.push(i), this.rowsCache[i] = { + this.rowsCache[i] || this.hasFrozenRows && this._options.frozenBottom && i === this.getDataLength() || (this.renderedRows++, rows.push(i), this.rowsCache[i] = { rowNode: null, // ColSpans of rendered cells (by column idx). // Can also be used for checking whether a cell has been rendered. @@ -1964,10 +1981,11 @@ this.postProcessFromRow = Math.min(this.postProcessFromRow, row), this.postProcessToRow = Math.max(this.postProcessToRow, row), this.startPostProcessing(); } updateRowPositions() { - for (let row in this.rowsCache) { - let rowNumber = row ? parseInt(row) : 0; - Utils.setStyleSize(this.rowsCache[rowNumber].rowNode[0], "top", this.getRowTop(rowNumber)); - } + for (let row in this.rowsCache) + if (this.rowsCache) { + let rowNumber = row ? parseInt(row, 10) : 0; + Utils.setStyleSize(this.rowsCache[rowNumber].rowNode[0], "top", this.getRowTop(rowNumber)); + } } /** (re)Render the grid */ render() { @@ -2021,7 +2039,7 @@ this.scrollTo(this.scrollTop + this.offset); else { let oldOffset = this.offset; - this.h == this.viewportH ? this.page = 0 : this.page = Math.min(this.n - 1, Math.floor(this.scrollTop * ((this.th - this.viewportH) / (this.h - this.viewportH)) * (1 / this.ph))), this.offset = Math.round(this.page * this.cj), oldOffset !== this.offset && this.invalidateAllRows(); + this.h === this.viewportH ? this.page = 0 : this.page = Math.min(this.n - 1, Math.floor(this.scrollTop * ((this.th - this.viewportH) / (this.h - this.viewportH)) * (1 / this.ph))), this.offset = Math.round(this.page * this.cj), oldOffset !== this.offset && this.invalidateAllRows(); } if (hScrollDist || vScrollDist) { let dx = Math.abs(this.lastRenderedScrollLeft - this.scrollLeft), dy = Math.abs(this.lastRenderedScrollTop - this.scrollTop); @@ -2072,7 +2090,7 @@ asyncPostProcessCleanupRows() { if (this.postProcessedCleanupQueue.length > 0) { let groupId = this.postProcessedCleanupQueue[0].groupId; - for (; this.postProcessedCleanupQueue.length > 0 && this.postProcessedCleanupQueue[0].groupId == groupId; ) { + for (; this.postProcessedCleanupQueue.length > 0 && this.postProcessedCleanupQueue[0].groupId === groupId; ) { let entry = this.postProcessedCleanupQueue.shift(); if ((entry == null ? void 0 : entry.actionType) === "R" && entry.node.forEach((node) => { node.remove(); @@ -2086,19 +2104,20 @@ } updateCellCssStylesOnRenderedRows(addedHash, removedHash) { let node, columnId, addedRowHash, removedRowHash; - for (let row in this.rowsCache) { - if (removedRowHash = removedHash == null ? void 0 : removedHash[row], addedRowHash = addedHash == null ? void 0 : addedHash[row], removedRowHash) - for (columnId in removedRowHash) - (!addedRowHash || removedRowHash[columnId] !== addedRowHash[columnId]) && (node = this.getCellNode(+row, this.getColumnIndex(columnId)), node && node.classList.remove(removedRowHash[columnId])); - if (addedRowHash) - for (columnId in addedRowHash) - (!removedRowHash || removedRowHash[columnId] !== addedRowHash[columnId]) && (node = this.getCellNode(+row, this.getColumnIndex(columnId)), node && node.classList.add(addedRowHash[columnId])); - } + for (let row in this.rowsCache) + if (this.rowsCache) { + if (removedRowHash = removedHash == null ? void 0 : removedHash[row], addedRowHash = addedHash == null ? void 0 : addedHash[row], removedRowHash) + for (columnId in removedRowHash) + (!addedRowHash || removedRowHash[columnId] !== addedRowHash[columnId]) && (node = this.getCellNode(+row, this.getColumnIndex(columnId)), node && node.classList.remove(removedRowHash[columnId])); + if (addedRowHash) + for (columnId in addedRowHash) + (!removedRowHash || removedRowHash[columnId] !== addedRowHash[columnId]) && (node = this.getCellNode(+row, this.getColumnIndex(columnId)), node && node.classList.add(addedRowHash[columnId])); + } } /** * Adds an "overlay" of CSS classes to cell DOM elements. SlickGrid can have many such overlays associated with different keys and they are frequently used by plugins. For example, SlickGrid uses this method internally to decorate selected cells with selectedCellCssClass (see options). - * @param key A unique key you can use in calls to setCellCssStyles and removeCellCssStyles. If a hash with that key has already been set, an exception will be thrown. - * @param hash A hash of additional cell CSS classes keyed by row number and then by column id. Multiple CSS classes can be specified and separated by space. + * @param {String} key A unique key you can use in calls to setCellCssStyles and removeCellCssStyles. If a hash with that key has already been set, an exception will be thrown. + * @param {CssStyleHash} hash A hash of additional cell CSS classes keyed by row number and then by column id. Multiple CSS classes can be specified and separated by space. * @example * `{ * 0: { number_column: SlickEvent; title_column: SlickEvent; }, @@ -2112,7 +2131,7 @@ } /** * Removes an "overlay" of CSS classes from cell DOM elements. See setCellCssStyles for more. - * @param key A string key. + * @param {String} key A string key. */ removeCellCssStyles(key) { this.cellCssClasses[key] && (this.updateCellCssStylesOnRenderedRows(null, this.cellCssClasses[key]), delete this.cellCssClasses[key], this.trigger(this.onCellCssStylesChanged, { key, hash: null, grid: this })); @@ -2138,15 +2157,15 @@ } /** * Flashes the cell twice by toggling the CSS class 4 times. - * @param {number} row A row index. - * @param {number} cell A column index. - * @param {number} [speed] (optional) - The milliseconds delay between the toggling calls. Defaults to 100 ms. + * @param {Number} row A row index. + * @param {Number} cell A column index. + * @param {Number} [speed] (optional) - The milliseconds delay between the toggling calls. Defaults to 100 ms. */ flashCell(row, cell, speed) { speed = speed || 250; let toggleCellClass = (cellNode, times) => { times < 1 || setTimeout(() => { - times % 2 == 0 ? cellNode.classList.add(this._options.cellFlashingCssClass || "") : cellNode.classList.remove(this._options.cellFlashingCssClass || ""), toggleCellClass(cellNode, times - 1); + times % 2 === 0 ? cellNode.classList.add(this._options.cellFlashingCssClass || "") : cellNode.classList.remove(this._options.cellFlashingCssClass || ""), toggleCellClass(cellNode, times - 1); }, speed); }; if (this.rowsCache[row]) { @@ -2185,20 +2204,20 @@ if (!handled && !e.shiftKey && !e.altKey) { if (this._options.editable && ((_a = this.currentEditor) != null && _a.keyCaptureList) && this.currentEditor.keyCaptureList.indexOf(String(e.which)) > -1) return; - e.which == keyCode.HOME ? handled = e.ctrlKey ? this.navigateTop() : this.navigateRowStart() : e.which == keyCode.END && (handled = e.ctrlKey ? this.navigateBottom() : this.navigateRowEnd()); + e.which === keyCode.HOME ? handled = e.ctrlKey ? this.navigateTop() : this.navigateRowStart() : e.which === keyCode.END && (handled = e.ctrlKey ? this.navigateBottom() : this.navigateRowEnd()); } if (!handled) if (!e.shiftKey && !e.altKey && !e.ctrlKey) { if (this._options.editable && ((_b = this.currentEditor) != null && _b.keyCaptureList) && this.currentEditor.keyCaptureList.indexOf(String(e.which)) > -1) return; - if (e.which == keyCode.ESCAPE) { + if (e.which === keyCode.ESCAPE) { if (!((_c = this.getEditorLock()) != null && _c.isActive())) return; this.cancelEditAndSetFocus(); } else - e.which == keyCode.PAGE_DOWN ? (this.navigatePageDown(), handled = !0) : e.which == keyCode.PAGE_UP ? (this.navigatePageUp(), handled = !0) : e.which == keyCode.LEFT ? handled = this.navigateLeft() : e.which == keyCode.RIGHT ? handled = this.navigateRight() : e.which == keyCode.UP ? handled = this.navigateUp() : e.which == keyCode.DOWN ? handled = this.navigateDown() : e.which == keyCode.TAB ? handled = this.navigateNext() : e.which == keyCode.ENTER && (this._options.editable && (this.currentEditor ? this.activeRow === this.getDataLength() ? this.navigateDown() : this.commitEditAndSetFocus() : (_d = this.getEditorLock()) != null && _d.commitCurrentEdit() && this.makeActiveCellEditable(void 0, void 0, e)), handled = !0); + e.which === keyCode.PAGE_DOWN ? (this.navigatePageDown(), handled = !0) : e.which === keyCode.PAGE_UP ? (this.navigatePageUp(), handled = !0) : e.which === keyCode.LEFT ? handled = this.navigateLeft() : e.which === keyCode.RIGHT ? handled = this.navigateRight() : e.which === keyCode.UP ? handled = this.navigateUp() : e.which === keyCode.DOWN ? handled = this.navigateDown() : e.which === keyCode.TAB ? handled = this.navigateNext() : e.which === keyCode.ENTER && (this._options.editable && (this.currentEditor ? this.activeRow === this.getDataLength() ? this.navigateDown() : this.commitEditAndSetFocus() : (_d = this.getEditorLock()) != null && _d.commitCurrentEdit() && this.makeActiveCellEditable(void 0, void 0, e)), handled = !0); } else - e.which == keyCode.TAB && e.shiftKey && !e.ctrlKey && !e.altKey && (handled = this.navigatePrev()); + e.which === keyCode.TAB && e.shiftKey && !e.ctrlKey && !e.altKey && (handled = this.navigatePrev()); if (handled) { e.stopPropagation(), e.preventDefault(); try { @@ -2215,7 +2234,7 @@ this.setFocus(), this.setTextSelection(selection); } let cell = this.getCellFromEvent(e); - if (!(!cell || this.currentEditor !== null && this.activeRow == cell.row && this.activeCell == cell.cell) && (evt = this.trigger(this.onClick, { row: cell.row, cell: cell.cell }, evt || e), !evt.isImmediatePropagationStopped() && this.canCellBeActive(cell.row, cell.cell) && (!((_a = this.getEditorLock()) != null && _a.isActive()) || (_b = this.getEditorLock()) != null && _b.commitCurrentEdit()))) { + if (!(!cell || this.currentEditor !== null && this.activeRow === cell.row && this.activeCell === cell.cell) && (evt = this.trigger(this.onClick, { row: cell.row, cell: cell.cell }, evt || e), !evt.isImmediatePropagationStopped() && this.canCellBeActive(cell.row, cell.cell) && (!((_a = this.getEditorLock()) != null && _a.isActive()) || (_b = this.getEditorLock()) != null && _b.commitCurrentEdit()))) { this.scrollRowIntoView(cell.row, !1); let preClickModeOn = ((_c = e.target) == null ? void 0 : _c.className) === preClickClassName, column = this.columns[cell.cell], suppressActiveCellChangedEvent = !!(this._options.editable && (column != null && column.editor) && this._options.suppressActiveCellChangeOnEdit); this.setActiveCellInternal(this.getCellNode(cell.row, cell.cell), null, preClickModeOn, suppressActiveCellChangedEvent, e); @@ -2227,7 +2246,7 @@ } handleDblClick(e) { let cell = this.getCellFromEvent(e); - !cell || this.currentEditor !== null && this.activeRow == cell.row && this.activeCell == cell.cell || (this.trigger(this.onDblClick, { row: cell.row, cell: cell.cell }, e), !e.defaultPrevented && this._options.editable && this.gotoCell(cell.row, cell.cell, !0, e)); + !cell || this.currentEditor !== null && this.activeRow === cell.row && this.activeCell === cell.cell || (this.trigger(this.onDblClick, { row: cell.row, cell: cell.cell }, e), !e.defaultPrevented && this._options.editable && this.gotoCell(cell.row, cell.cell, !0, e)); } handleHeaderMouseEnter(e) { let c = Utils.storage.get(e.target.closest(".slick-header-column"), "column"); @@ -2304,9 +2323,11 @@ getRowFromNode(rowNode) { var _a; for (let row in this.rowsCache) - for (let i in this.rowsCache[row].rowNode) - if (((_a = this.rowsCache[row].rowNode) == null ? void 0 : _a[+i]) === rowNode) - return row ? parseInt(row) : 0; + if (this.rowsCache) { + for (let i in this.rowsCache[row].rowNode) + if (((_a = this.rowsCache[row].rowNode) == null ? void 0 : _a[+i]) === rowNode) + return row ? parseInt(row, 10) : 0; + } return null; } /** @@ -2331,12 +2352,12 @@ Utils.parents(cellNode, ".grid-canvas-bottom").length && (rowOffset = this._options.frozenBottom ? Utils.height(this._canvasTopL) : this.frozenRowsHeight), row = this.getCellFromPoint(targetEvent.clientX - c.left, targetEvent.clientY - c.top + rowOffset + document.documentElement.scrollTop).row; } let cell = this.getCellFromNode(cellNode); - return row == null || cell == null ? null : { row, cell }; + return !Utils.isDefined(row) || !Utils.isDefined(cell) ? null : { row, cell }; } /** * Returns an object representing information about a cell's position. All coordinates are absolute and take into consideration the visibility and scrolling position of all ancestors. - * @param row A row number. - * @param cell A column number. + * @param {Number} row - A row number. + * @param {Number} cell - A column number. */ getCellNodeBox(row, cell) { var _a; @@ -2344,7 +2365,7 @@ return null; let frozenRowOffset = this.getFrozenRowOffset(row), y1 = this.getRowTop(row) - frozenRowOffset, y2 = y1 + this._options.rowHeight - 1, x1 = 0; for (let i = 0; i < cell; i++) - !this.columns[i] || this.columns[i].hidden || (x1 += this.columns[i].width || 0, this._options.frozenColumn == i && (x1 = 0)); + !this.columns[i] || this.columns[i].hidden || (x1 += this.columns[i].width || 0, this._options.frozenColumn === i && (x1 = 0)); let x2 = x1 + (((_a = this.columns[cell]) == null ? void 0 : _a.width) || 0); return { top: y1, @@ -2364,7 +2385,7 @@ this.setFocus(); } setFocus() { - this.tabbingDirection == -1 ? this._focusSink.focus() : this._focusSink2.focus(); + this.tabbingDirection === -1 ? this._focusSink.focus() : this._focusSink2.focus(); } /** Scroll to a specific cell and make it into the view */ scrollCellIntoView(row, cell, doPaging) { @@ -2387,11 +2408,11 @@ } setActiveCellInternal(newCell, opt_editMode, preClickModeOn, suppressActiveCellChangedEvent, e) { var _a, _b, _c, _d; - if (this.activeCellNode !== null && (this.makeActiveCellNormal(), this.activeCellNode.classList.remove("active"), (_b = (_a = this.rowsCache[this.activeRow]) == null ? void 0 : _a.rowNode) == null || _b.forEach((node) => node.classList.remove("active"))), this.activeCellNode = newCell, this.activeCellNode != null) { + if (this.activeCellNode !== null && (this.makeActiveCellNormal(), this.activeCellNode.classList.remove("active"), (_b = (_a = this.rowsCache[this.activeRow]) == null ? void 0 : _a.rowNode) == null || _b.forEach((node) => node.classList.remove("active"))), this.activeCellNode = newCell, Utils.isDefined(this.activeCellNode)) { let activeCellOffset = Utils.offset(this.activeCellNode), rowOffset = Math.floor(Utils.offset(Utils.parents(this.activeCellNode, ".grid-canvas")[0]).top), isBottom = Utils.parents(this.activeCellNode, ".grid-canvas-bottom").length; this.hasFrozenRows && isBottom && (rowOffset -= this._options.frozenBottom ? Utils.height(this._canvasTopL) : this.frozenRowsHeight); let cell = this.getCellFromPoint(activeCellOffset.left, Math.ceil(activeCellOffset.top) - rowOffset); - this.activeRow = cell.row, this.activeCell = this.activePosX = this.activeCell = this.activePosX = this.getCellFromNode(this.activeCellNode), opt_editMode == null && this._options.autoEditNewRow && (opt_editMode = this.activeRow == this.getDataLength() || this._options.autoEdit), this._options.showCellSelection && (this.activeCellNode.classList.add("active"), (_d = (_c = this.rowsCache[this.activeRow]) == null ? void 0 : _c.rowNode) == null || _d.forEach((node) => node.classList.add("active"))), this._options.editable && opt_editMode && this.isCellPotentiallyEditable(this.activeRow, this.activeCell) && (clearTimeout(this.h_editorLoader), this._options.asyncEditorLoading ? this.h_editorLoader = setTimeout(() => { + this.activeRow = cell.row, this.activeCell = this.activePosX = this.activeCell = this.activePosX = this.getCellFromNode(this.activeCellNode), !Utils.isDefined(opt_editMode) && this._options.autoEditNewRow && (opt_editMode = this.activeRow === this.getDataLength() || this._options.autoEdit), this._options.showCellSelection && (this.activeCellNode.classList.add("active"), (_d = (_c = this.rowsCache[this.activeRow]) == null ? void 0 : _c.rowNode) == null || _d.forEach((node) => node.classList.add("active"))), this._options.editable && opt_editMode && this.isCellPotentiallyEditable(this.activeRow, this.activeCell) && (clearTimeout(this.h_editorLoader), this._options.asyncEditorLoading ? this.h_editorLoader = setTimeout(() => { this.makeActiveCellEditable(void 0, preClickModeOn, e); }, this._options.asyncEditorLoadDelay) : this.makeActiveCellEditable(void 0, preClickModeOn, e)); } else @@ -2523,8 +2544,8 @@ getActiveCellNode() { return this.activeCellNode; } - //This get/set methods are used for keeping text-selection. These don't consider IE because they don't loose text-selection. - //Fix for firefox selection. See https://github.com/mleibman/SlickGrid/pull/746/files + // This get/set methods are used for keeping text-selection. These don't consider IE because they don't loose text-selection. + // Fix for firefox selection. See https://github.com/mleibman/SlickGrid/pull/746/files getTextSelection() { var _a; let textSelection = null; @@ -2561,7 +2582,7 @@ } scrollPage(dir) { let deltaRows = dir * this.numVisibleRows, bottomOfTopmostFullyVisibleRow = this.scrollTop + this._options.rowHeight - 1; - if (this.scrollTo((this.getRowFromPosition(bottomOfTopmostFullyVisibleRow) + deltaRows) * this._options.rowHeight), this.render(), this._options.enableCellNavigation && this.activeRow != null) { + if (this.scrollTo((this.getRowFromPosition(bottomOfTopmostFullyVisibleRow) + deltaRows) * this._options.rowHeight), this.render(), this._options.enableCellNavigation && Utils.isDefined(this.activeRow)) { let row = this.activeRow + deltaRows, dataLengthIncludingAddNew = this.getDataLengthIncludingAddNew(); row >= dataLengthIncludingAddNew && (row = dataLengthIncludingAddNew - 1), row < 0 && (row = 0); let cell = 0, prevCell = null, prevActivePosX = this.activePosX; @@ -2590,7 +2611,7 @@ let num_rows = this.getDataLength(); if (!num_rows) return !0; - if (row < 0 ? row = 0 : row >= num_rows && (row = num_rows - 1), this.scrollCellIntoView(row, 0, !0), this._options.enableCellNavigation && this.activeRow != null) { + if (row < 0 ? row = 0 : row >= num_rows && (row = num_rows - 1), this.scrollCellIntoView(row, 0, !0), this._options.enableCellNavigation && Utils.isDefined(this.activeRow)) { let cell = 0, prevCell = null, prevActivePosX = this.activePosX; for (; cell <= this.activePosX; ) this.canCellBeActive(row, cell) && (prevCell = cell), cell += this.getColspan(row, cell); @@ -2621,6 +2642,7 @@ this.canCellBeActive(row, cell) && (lastFocusableCell = cell), cell += this.getColspan(row, cell); return lastFocusableCell; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars gotoRight(row, cell, _posX) { if (cell >= this.columns.length) return null; @@ -2633,6 +2655,7 @@ posX: cell } : null; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars gotoLeft(row, cell, _posX) { if (cell <= 0) return null; @@ -2683,7 +2706,7 @@ } } gotoNext(row, cell, posX) { - if (row == null && cell == null && (row = cell = posX = 0, this.canCellBeActive(row, cell))) + if (!Utils.isDefined(row) && !Utils.isDefined(cell) && (row = cell = posX = 0, this.canCellBeActive(row, cell))) return { row, cell, @@ -2703,7 +2726,7 @@ return null; } gotoPrev(row, cell, posX) { - if (row == null && cell == null && (row = this.getDataLengthIncludingAddNew() - 1, cell = posX = this.columns.length - 1, this.canCellBeActive(row, cell))) + if (!Utils.isDefined(row) && !Utils.isDefined(cell) && (row = this.getDataLengthIncludingAddNew() - 1, cell = posX = this.columns.length - 1, this.canCellBeActive(row, cell))) return { row, cell, @@ -2721,6 +2744,7 @@ } return pos; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars gotoRowStart(row, _cell, _posX) { let newCell = this.findFirstFocusableCell(row); return newCell === null ? null : { @@ -2729,6 +2753,7 @@ posX: newCell }; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars gotoRowEnd(row, _cell, _posX) { let newCell = this.findLastFocusableCell(row); return newCell === null ? null : { @@ -2802,9 +2827,9 @@ end: this.gotoRowEnd }[dir].call(this, this.activeRow, this.activeCell, this.activePosX); if (pos) { - if (this.hasFrozenRows && this._options.frozenBottom && pos.row == this.getDataLength()) + if (this.hasFrozenRows && this._options.frozenBottom && pos.row === this.getDataLength()) return; - let isAddNewRow = pos.row == this.getDataLength(); + let isAddNewRow = pos.row === this.getDataLength(); return (!this._options.frozenBottom && pos.row >= this.actualFrozenRow || this._options.frozenBottom && pos.row < this.actualFrozenRow) && this.scrollCellIntoView(pos.row, pos.cell, !isAddNewRow && this._options.emulatePagingWhenScrolling), this.setActiveCellInternal(this.getCellNode(pos.row, pos.cell)), this.activePosX = pos.posX, !0; } else return this.setActiveCellInternal(this.getCellNode(this.activeRow, this.activeCell)), !1; @@ -2981,7 +3006,7 @@ * Distributed under MIT license. * All rights reserved. * - * SlickGrid v5.1.0 + * SlickGrid v5.2.0 * * NOTES: * Cell/row DOM manipulations are done directly bypassing JS DOM manipulation methods. diff --git a/dist/browser/slick.grid.js.map b/dist/browser/slick.grid.js.map index b29496589..187a9fd8d 100644 --- a/dist/browser/slick.grid.js.map +++ b/dist/browser/slick.grid.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.grid.ts"], - "sourcesContent": ["// @ts-ignore\nimport type SortableInstance from 'sortablejs';\n\nimport type {\n AutoSize,\n CellViewportRange,\n Column,\n ColumnSort,\n CssStyleHash,\n CSSStyleDeclarationWritable,\n CustomDataView,\n DOMEvent,\n DOMMouseOrTouchEvent,\n DragPosition,\n DragRowMove,\n Editor,\n EditController,\n Formatter,\n FormatterOverrideCallback,\n FormatterResultObject,\n GridOption as BaseGridOption,\n InteractionBase,\n ItemMetadata,\n MultiColumnSort,\n OnActiveCellChangedEventArgs,\n OnAddNewRowEventArgs,\n OnAutosizeColumnsEventArgs,\n OnBeforeUpdateColumnsEventArgs,\n OnBeforeAppendCellEventArgs,\n OnBeforeCellEditorDestroyEventArgs,\n OnBeforeColumnsResizeEventArgs,\n OnBeforeEditCellEventArgs,\n OnBeforeHeaderCellDestroyEventArgs,\n OnBeforeHeaderRowCellDestroyEventArgs,\n OnBeforeFooterRowCellDestroyEventArgs,\n OnBeforeSetColumnsEventArgs,\n OnCellChangeEventArgs,\n OnCellCssStylesChangedEventArgs,\n OnColumnsDragEventArgs,\n OnColumnsReorderedEventArgs,\n OnColumnsResizedEventArgs,\n OnColumnsResizeDblClickEventArgs,\n OnCompositeEditorChangeEventArgs,\n OnClickEventArgs,\n OnDblClickEventArgs,\n OnFooterContextMenuEventArgs,\n OnFooterRowCellRenderedEventArgs,\n OnHeaderCellRenderedEventArgs,\n OnFooterClickEventArgs,\n OnHeaderClickEventArgs,\n OnHeaderContextMenuEventArgs,\n OnHeaderMouseEventArgs,\n OnHeaderRowCellRenderedEventArgs,\n OnKeyDownEventArgs,\n OnValidationErrorEventArgs,\n OnRenderedEventArgs,\n OnSelectedRowsChangedEventArgs,\n OnSetOptionsEventArgs,\n OnActivateChangedOptionsEventArgs,\n OnScrollEventArgs,\n PagingInfo,\n Plugin,\n RowInfo,\n SelectionModel,\n SingleColumnSort,\n SlickGridEventData,\n SlickGridModel,\n} from './models/index';\nimport {\n BindingEventService as BindingEventService_,\n ColAutosizeMode as ColAutosizeMode_,\n GlobalEditorLock as GlobalEditorLock_,\n GridAutosizeColsMode as GridAutosizeColsMode_,\n keyCode as keyCode_,\n preClickClassName as preClickClassName_,\n RowSelectionMode as RowSelectionMode_,\n type SlickEditorLock,\n SlickEvent as SlickEvent_,\n SlickEventData as SlickEventData_,\n SlickRange as SlickRange_,\n Utils as Utils_,\n ValueFilterMode as ValueFilterMode_,\n WidthEvalMode as WidthEvalMode_,\n} from './slick.core';\nimport { Draggable as Draggable_, MouseWheel as MouseWheel_, Resizable as Resizable_ } from './slick.interactions';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst ColAutosizeMode = IIFE_ONLY ? Slick.ColAutosizeMode : ColAutosizeMode_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst GlobalEditorLock = IIFE_ONLY ? Slick.GlobalEditorLock : GlobalEditorLock_;\nconst GridAutosizeColsMode = IIFE_ONLY ? Slick.GridAutosizeColsMode : GridAutosizeColsMode_;\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\nconst preClickClassName = IIFE_ONLY ? Slick.preClickClassName : preClickClassName_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst RowSelectionMode = IIFE_ONLY ? Slick.RowSelectionMode : RowSelectionMode_;\nconst ValueFilterMode = IIFE_ONLY ? Slick.ValueFilterMode : ValueFilterMode_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\nconst WidthEvalMode = IIFE_ONLY ? Slick.WidthEvalMode : WidthEvalMode_;\nconst Draggable = IIFE_ONLY ? Slick.Draggable : Draggable_;\nconst MouseWheel = IIFE_ONLY ? Slick.MouseWheel : MouseWheel_;\nconst Resizable = IIFE_ONLY ? Slick.Resizable : Resizable_;\n\n/**\n * @license\n * (c) 2009-present Michael Leibman\n * michael{dot}leibman{at}gmail{dot}com\n * http://github.com/mleibman/slickgrid\n *\n * Distributed under MIT license.\n * All rights reserved.\n *\n * SlickGrid v5.1.0\n *\n * NOTES:\n * Cell/row DOM manipulations are done directly bypassing JS DOM manipulation methods.\n * This increases the speed dramatically, but can only be done safely because there are no event handlers\n * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\n * and do proper cleanup.\n */\n\n//////////////////////////////////////////////////////////////////////////////////////////////\n// SlickGrid class implementation (available as SlickGrid)\n\ninterface RowCaching {\n rowNode: HTMLElement[] | null,\n cellColSpans: Array;\n cellNodesByColumnIdx: HTMLElement[];\n cellRenderQueue: any[];\n}\n\nexport class SlickGrid = Column, O extends BaseGridOption = BaseGridOption> {\n //////////////////////////////////////////////////////////////////////////////////////////////\n // Public API\n slickGridVersion = '5.1.0';\n\n /** optional grid state clientId */\n cid = '';\n\n // Events\n onActiveCellChanged = new SlickEvent();\n onActiveCellPositionChanged = new SlickEvent();\n onAddNewRow = new SlickEvent();\n onAutosizeColumns = new SlickEvent();\n onBeforeAppendCell = new SlickEvent();\n onBeforeCellEditorDestroy = new SlickEvent();\n onBeforeColumnsResize = new SlickEvent();\n onBeforeDestroy = new SlickEvent();\n onBeforeEditCell = new SlickEvent();\n onBeforeFooterRowCellDestroy = new SlickEvent();\n onBeforeHeaderCellDestroy = new SlickEvent();\n onBeforeHeaderRowCellDestroy = new SlickEvent();\n onBeforeSetColumns = new SlickEvent();\n onBeforeSort = new SlickEvent();\n onBeforeUpdateColumns = new SlickEvent();\n onCellChange = new SlickEvent();\n onCellCssStylesChanged = new SlickEvent();\n onClick = new SlickEvent();\n onColumnsReordered = new SlickEvent();\n onColumnsDrag = new SlickEvent();\n onColumnsResized = new SlickEvent();\n onColumnsResizeDblClick = new SlickEvent();\n onCompositeEditorChange = new SlickEvent();\n onContextMenu = new SlickEvent();\n onDrag = new SlickEvent();\n onDblClick = new SlickEvent();\n onDragInit = new SlickEvent();\n onDragStart = new SlickEvent();\n onDragEnd = new SlickEvent();\n onFooterClick = new SlickEvent();\n onFooterContextMenu = new SlickEvent();\n onFooterRowCellRendered = new SlickEvent();\n onHeaderCellRendered = new SlickEvent();\n onHeaderClick = new SlickEvent();\n onHeaderContextMenu = new SlickEvent();\n onHeaderMouseEnter = new SlickEvent();\n onHeaderMouseLeave = new SlickEvent();\n onHeaderRowCellRendered = new SlickEvent();\n onHeaderRowMouseEnter = new SlickEvent();\n onHeaderRowMouseLeave = new SlickEvent();\n onKeyDown = new SlickEvent();\n onMouseEnter = new SlickEvent();\n onMouseLeave = new SlickEvent();\n onRendered = new SlickEvent();\n onScroll = new SlickEvent();\n onSelectedRowsChanged = new SlickEvent();\n onSetOptions = new SlickEvent();\n onActivateChangedOptions = new SlickEvent();\n onSort = new SlickEvent();\n onValidationError = new SlickEvent();\n onViewportChanged = new SlickEvent();\n\n // ---\n // protected variables\n\n // shared across all grids on the page\n protected scrollbarDimensions?: { height: number; width: number; };\n protected maxSupportedCssHeight!: number; // browser's breaking point\n\n protected canvas: HTMLCanvasElement | null = null;\n protected canvas_context: CanvasRenderingContext2D | null = null;\n\n // settings\n protected _options!: O;\n protected _defaults: BaseGridOption = {\n alwaysShowVerticalScroll: false,\n alwaysAllowHorizontalScroll: false,\n explicitInitialization: false,\n rowHeight: 25,\n defaultColumnWidth: 80,\n enableAddRow: false,\n leaveSpaceForNewRows: false,\n editable: false,\n autoEdit: true,\n autoEditNewRow: true,\n autoCommitEdit: false,\n suppressActiveCellChangeOnEdit: false,\n enableCellNavigation: true,\n enableColumnReorder: true,\n asyncEditorLoading: false,\n asyncEditorLoadDelay: 100,\n forceFitColumns: false,\n enableAsyncPostRender: false,\n asyncPostRenderDelay: 50,\n enableAsyncPostRenderCleanup: false,\n asyncPostRenderCleanupDelay: 40,\n auto: false,\n editorLock: GlobalEditorLock,\n showColumnHeader: true,\n showHeaderRow: false,\n headerRowHeight: 25,\n createFooterRow: false,\n showFooterRow: false,\n footerRowHeight: 25,\n createPreHeaderPanel: false,\n showPreHeaderPanel: false,\n preHeaderPanelHeight: 25,\n showTopPanel: false,\n topPanelHeight: 25,\n formatterFactory: null,\n editorFactory: null,\n cellFlashingCssClass: 'flashing',\n selectedCellCssClass: 'selected',\n multiSelect: true,\n enableTextSelectionOnCells: false,\n dataItemColumnValueExtractor: null,\n frozenBottom: false,\n frozenColumn: -1,\n frozenRow: -1,\n frozenRightViewportMinWidth: 100,\n fullWidthRows: false,\n multiColumnSort: false,\n numberedMultiColumnSort: false,\n tristateMultiColumnSort: false,\n sortColNumberInSeparateSpan: false,\n defaultFormatter: this.defaultFormatter,\n forceSyncScrolling: false,\n addNewRowCssClass: 'new-row',\n preserveCopiedSelectionOnPaste: false,\n showCellSelection: true,\n viewportClass: undefined,\n minRowBuffer: 3,\n emulatePagingWhenScrolling: true, // when scrolling off bottom of viewport, place new row at top of viewport\n editorCellNavOnLRKeys: false,\n enableMouseWheelScrollHandler: true,\n doPaging: true,\n autosizeColsMode: GridAutosizeColsMode.LegacyOff,\n autosizeColPaddingPx: 4,\n scrollRenderThrottling: 50,\n autosizeTextAvgToMWidthRatio: 0.75,\n viewportSwitchToScrollModeWidthPercent: undefined,\n viewportMinWidthPx: undefined,\n viewportMaxWidthPx: undefined,\n suppressCssChangesOnHiddenInit: false,\n ffMaxSupportedCssHeight: 6000000,\n maxSupportedCssHeight: 1000000000,\n sanitizer: undefined, // sanitize function, built in basic sanitizer is: Slick.RegexSanitizer(dirtyHtml)\n logSanitizedHtml: false, // log to console when sanitised - recommend true for testing of dev and production\n mixinDefaults: true\n };\n\n protected _columnDefaults = {\n name: '',\n resizable: true,\n sortable: false,\n minWidth: 30,\n maxWidth: undefined,\n rerenderOnResize: false,\n headerCssClass: null,\n defaultSortAsc: true,\n focusable: true,\n selectable: true,\n hidden: false\n } as Partial;\n\n protected _columnAutosizeDefaults: AutoSize = {\n ignoreHeaderText: false,\n colValueArray: undefined,\n allowAddlPercent: undefined,\n formatterOverride: undefined,\n autosizeMode: ColAutosizeMode.ContentIntelligent,\n rowSelectionModeOnInit: undefined,\n rowSelectionMode: RowSelectionMode.FirstNRows,\n rowSelectionCount: 100,\n valueFilterMode: ValueFilterMode.None,\n widthEvalMode: WidthEvalMode.Auto,\n sizeToRemaining: undefined,\n widthPx: undefined,\n contentSizePx: 0,\n headerWidthPx: 0,\n colDataTypeOf: undefined\n };\n\n // scroller\n protected th!: number; // virtual height\n protected h!: number; // real scrollable height\n protected ph!: number; // page height\n protected n!: number; // number of pages\n protected cj!: number; // \"jumpiness\" coefficient\n\n protected page = 0; // current page\n protected offset = 0; // current page offset\n protected vScrollDir = 1;\n protected _bindingEventService = new BindingEventService();\n protected initialized = false;\n protected _container!: HTMLElement;\n protected uid = `slickgrid_${Math.round(1000000 * Math.random())}`;\n protected _focusSink!: HTMLDivElement;\n protected _focusSink2!: HTMLDivElement;\n protected _groupHeaders: HTMLDivElement[] = [];\n protected _headerScroller: HTMLDivElement[] = [];\n protected _headers: HTMLDivElement[] = [];\n protected _headerRows!: HTMLDivElement[];\n protected _headerRowScroller!: HTMLDivElement[];\n protected _headerRowSpacerL!: HTMLDivElement;\n protected _headerRowSpacerR!: HTMLDivElement;\n protected _footerRow!: HTMLDivElement[];\n protected _footerRowScroller!: HTMLDivElement[];\n protected _footerRowSpacerL!: HTMLDivElement;\n protected _footerRowSpacerR!: HTMLDivElement;\n protected _preHeaderPanel!: HTMLDivElement;\n protected _preHeaderPanelScroller!: HTMLDivElement;\n protected _preHeaderPanelSpacer!: HTMLDivElement;\n protected _preHeaderPanelR!: HTMLDivElement;\n protected _preHeaderPanelScrollerR!: HTMLDivElement;\n protected _preHeaderPanelSpacerR!: HTMLDivElement;\n protected _topPanelScrollers!: HTMLDivElement[];\n protected _topPanels!: HTMLDivElement[];\n protected _viewport!: HTMLDivElement[];\n protected _canvas!: HTMLDivElement[];\n protected _style: any;\n protected _boundAncestors: HTMLElement[] = [];\n protected stylesheet?: { cssRules: Array<{ selectorText: string; }>; rules: Array<{ selectorText: string; }>; } | null;\n protected columnCssRulesL?: Array<{ selectorText: string; }>;\n protected columnCssRulesR?: Array<{ selectorText: string; }>;\n protected viewportH = 0;\n protected viewportW = 0;\n protected canvasWidth = 0;\n protected canvasWidthL = 0;\n protected canvasWidthR = 0;\n protected headersWidth = 0;\n protected headersWidthL = 0;\n protected headersWidthR = 0;\n protected viewportHasHScroll = false;\n protected viewportHasVScroll = false;\n protected headerColumnWidthDiff = 0;\n protected headerColumnHeightDiff = 0; // border+padding\n protected cellWidthDiff = 0;\n protected cellHeightDiff = 0;\n protected absoluteColumnMinWidth!: number;\n protected hasFrozenRows = false;\n protected frozenRowsHeight = 0;\n protected actualFrozenRow = -1;\n protected paneTopH = 0;\n protected paneBottomH = 0;\n protected viewportTopH = 0;\n protected viewportBottomH = 0;\n protected topPanelH = 0;\n protected headerRowH = 0;\n protected footerRowH = 0;\n\n protected tabbingDirection = 1;\n protected _activeCanvasNode!: HTMLDivElement;\n protected _activeViewportNode!: HTMLDivElement;\n protected activePosX!: number;\n protected activeRow!: number;\n protected activeCell!: number;\n protected activeCellNode: HTMLDivElement | null = null;\n protected currentEditor: Editor | null = null;\n protected serializedEditorValue: any;\n protected editController?: EditController;\n\n protected rowsCache: Array = {} as any;\n protected renderedRows = 0;\n protected numVisibleRows = 0;\n protected prevScrollTop = 0;\n protected scrollTop = 0;\n protected lastRenderedScrollTop = 0;\n protected lastRenderedScrollLeft = 0;\n protected prevScrollLeft = 0;\n protected scrollLeft = 0;\n\n protected selectionModel?: SelectionModel;\n protected selectedRows: number[] = [];\n\n protected plugins: Plugin[] = [];\n protected cellCssClasses: CssStyleHash = {};\n\n protected columnsById: Record = {};\n protected sortColumns: ColumnSort[] = [];\n protected columnPosLeft: number[] = [];\n protected columnPosRight: number[] = [];\n\n protected pagingActive = false;\n protected pagingIsLastPage = false;\n\n protected scrollThrottle!: { enqueue: () => void; dequeue: () => void; };\n\n // async call handles\n protected h_editorLoader: any = null;\n protected h_render = null;\n protected h_postrender: any = null;\n protected h_postrenderCleanup: any = null;\n protected postProcessedRows: any = {};\n protected postProcessToRow: number = null as any;\n protected postProcessFromRow: number = null as any;\n protected postProcessedCleanupQueue: Array<{\n actionType: string;\n groupId: number;\n node: HTMLElement | HTMLElement[];\n columnIdx?: number;\n rowIdx?: number;\n }> = [];\n protected postProcessgroupId = 0;\n\n // perf counters\n protected counter_rows_rendered = 0;\n protected counter_rows_removed = 0;\n\n protected _paneHeaderL!: HTMLDivElement;\n protected _paneHeaderR!: HTMLDivElement;\n protected _paneTopL!: HTMLDivElement;\n protected _paneTopR!: HTMLDivElement;\n protected _paneBottomL!: HTMLDivElement;\n protected _paneBottomR!: HTMLDivElement;\n protected _headerScrollerL!: HTMLDivElement;\n protected _headerScrollerR!: HTMLDivElement;\n protected _headerL!: HTMLDivElement;\n protected _headerR!: HTMLDivElement;\n protected _groupHeadersL!: HTMLDivElement;\n protected _groupHeadersR!: HTMLDivElement;\n protected _headerRowScrollerL!: HTMLDivElement;\n protected _headerRowScrollerR!: HTMLDivElement;\n protected _footerRowScrollerL!: HTMLDivElement;\n protected _footerRowScrollerR!: HTMLDivElement;\n protected _headerRowL!: HTMLDivElement;\n protected _headerRowR!: HTMLDivElement;\n protected _footerRowL!: HTMLDivElement;\n protected _footerRowR!: HTMLDivElement;\n protected _topPanelScrollerL!: HTMLDivElement;\n protected _topPanelScrollerR!: HTMLDivElement;\n protected _topPanelL!: HTMLDivElement;\n protected _topPanelR!: HTMLDivElement;\n protected _viewportTopL!: HTMLDivElement;\n protected _viewportTopR!: HTMLDivElement;\n protected _viewportBottomL!: HTMLDivElement;\n protected _viewportBottomR!: HTMLDivElement;\n protected _canvasTopL!: HTMLDivElement;\n protected _canvasTopR!: HTMLDivElement;\n protected _canvasBottomL!: HTMLDivElement;\n protected _canvasBottomR!: HTMLDivElement;\n protected _viewportScrollContainerX!: HTMLDivElement;\n protected _viewportScrollContainerY!: HTMLDivElement;\n protected _headerScrollContainer!: HTMLDivElement;\n protected _headerRowScrollContainer!: HTMLDivElement;\n protected _footerRowScrollContainer!: HTMLDivElement;\n\n // store css attributes if display:none is active in container or parent\n protected cssShow = { position: 'absolute', visibility: 'hidden', display: 'block' };\n protected _hiddenParents: HTMLElement[] = [];\n protected oldProps: Array> = [];\n protected enforceFrozenRowHeightRecalc = false;\n protected columnResizeDragging = false;\n protected slickDraggableInstance: InteractionBase | null = null;\n protected slickMouseWheelInstances: Array = [];\n protected slickResizableInstances: Array = [];\n protected sortableSideLeftInstance: SortableInstance;\n protected sortableSideRightInstance: SortableInstance;\n protected logMessageCount = 0;\n protected logMessageMaxCount = 30;\n\n /**\n * Creates a new instance of the grid.\n * @class SlickGrid\n * @constructor\n * @param {Node} container - Container node to create the grid in.\n * @param {Array|Object} data - An array of objects for databinding.\n * @param {Array} columns - An array of column definitions.\n * @param {Object} [options] - Grid this._options.\n **/\n constructor(protected container: HTMLElement | string, protected data: CustomDataView | TData[], protected columns: C[], protected options: Partial) {\n this.initialize();\n }\n\n //////////////////////////////////////////////////////////////////////////////////////////////\n // Initialization\n\n /** Initializes the grid. */\n init() {\n this.finishInitialization();\n }\n\n protected initialize() {\n if (typeof this.container === 'string') {\n this._container = document.querySelector(this.container) as HTMLDivElement;\n } else {\n this._container = this.container;\n }\n\n if (!this._container) {\n throw new Error(`SlickGrid requires a valid container, ${this.container} does not exist in the DOM.`);\n }\n\n // calculate these only once and share between grid instances\n if (this.options.mixinDefaults) {\n if (!this.options) { this.options = {}; }\n Utils.applyDefaults(this.options, this._defaults);\n } else {\n this._options = Utils.extend(true, {}, this._defaults, this.options);\n }\n this.scrollThrottle = this.actionThrottle(this.render.bind(this), this._options.scrollRenderThrottling as number);\n this.maxSupportedCssHeight = this.maxSupportedCssHeight || this.getMaxSupportedCssHeight();\n this.validateAndEnforceOptions();\n this._columnDefaults.width = this._options.defaultColumnWidth;\n\n if (!this._options.suppressCssChangesOnHiddenInit) {\n this.cacheCssForHiddenInit();\n }\n\n this.updateColumnProps();\n\n // validate loaded JavaScript modules against requested options\n if (this._options.enableColumnReorder && (!Sortable || !Sortable.create)) {\n throw new Error('SlickGrid requires Sortable.js module to be loaded');\n }\n\n this.editController = {\n commitCurrentEdit: this.commitCurrentEdit.bind(this),\n cancelCurrentEdit: this.cancelCurrentEdit.bind(this),\n };\n\n Utils.emptyElement(this._container);\n this._container.style.overflow = 'hidden';\n this._container.style.outline = String(0);\n this._container.classList.add(this.uid);\n this._container.classList.add('ui-widget');\n\n const containerStyles = window.getComputedStyle(this._container);\n if (!(/relative|absolute|fixed/).test(containerStyles.position)) {\n this._container.style.position = 'relative';\n }\n\n this._focusSink = Utils.createDomElement('div', { tabIndex: 0, style: { position: 'fixed', width: '0px', height: '0px', top: '0px', left: '0px', outline: '0px' } }, this._container);\n\n // Containers used for scrolling frozen columns and rows\n this._paneHeaderL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-header slick-pane-left', tabIndex: 0 }, this._container);\n this._paneHeaderR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-header slick-pane-right', tabIndex: 0 }, this._container);\n this._paneTopL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-top slick-pane-left', tabIndex: 0 }, this._container);\n this._paneTopR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-top slick-pane-right', tabIndex: 0 }, this._container);\n this._paneBottomL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-bottom slick-pane-left', tabIndex: 0 }, this._container);\n this._paneBottomR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-bottom slick-pane-right', tabIndex: 0 }, this._container);\n\n if (this._options.createPreHeaderPanel) {\n this._preHeaderPanelScroller = Utils.createDomElement('div', { className: 'slick-preheader-panel ui-state-default slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderL);\n this._preHeaderPanelScroller.appendChild(document.createElement('div'));\n this._preHeaderPanel = Utils.createDomElement('div', null, this._preHeaderPanelScroller);\n this._preHeaderPanelSpacer = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._preHeaderPanelScroller);\n\n this._preHeaderPanelScrollerR = Utils.createDomElement('div', { className: 'slick-preheader-panel ui-state-default slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderR);\n this._preHeaderPanelR = Utils.createDomElement('div', null, this._preHeaderPanelScrollerR);\n this._preHeaderPanelSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._preHeaderPanelScrollerR);\n\n if (!this._options.showPreHeaderPanel) {\n Utils.hide(this._preHeaderPanelScroller);\n Utils.hide(this._preHeaderPanelScrollerR);\n }\n }\n\n // Append the header scroller containers\n this._headerScrollerL = Utils.createDomElement('div', { className: 'slick-header ui-state-default slick-state-default slick-header-left' }, this._paneHeaderL);\n this._headerScrollerR = Utils.createDomElement('div', { className: 'slick-header ui-state-default slick-state-default slick-header-right' }, this._paneHeaderR);\n\n // Cache the header scroller containers\n this._headerScroller.push(this._headerScrollerL);\n this._headerScroller.push(this._headerScrollerR);\n\n // Append the columnn containers to the headers\n this._headerL = Utils.createDomElement('div', { className: 'slick-header-columns slick-header-columns-left', style: { left: '-1000px' } }, this._headerScrollerL);\n this._headerR = Utils.createDomElement('div', { className: 'slick-header-columns slick-header-columns-right', style: { left: '-1000px' } }, this._headerScrollerR);\n\n // Cache the header columns\n this._headers = [this._headerL, this._headerR];\n\n this._headerRowScrollerL = Utils.createDomElement('div', { className: 'slick-headerrow ui-state-default slick-state-default' }, this._paneTopL);\n this._headerRowScrollerR = Utils.createDomElement('div', { className: 'slick-headerrow ui-state-default slick-state-default' }, this._paneTopR);\n\n this._headerRowScroller = [this._headerRowScrollerL, this._headerRowScrollerR];\n\n this._headerRowSpacerL = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._headerRowScrollerL);\n this._headerRowSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._headerRowScrollerR);\n\n this._headerRowL = Utils.createDomElement('div', { className: 'slick-headerrow-columns slick-headerrow-columns-left' }, this._headerRowScrollerL);\n this._headerRowR = Utils.createDomElement('div', { className: 'slick-headerrow-columns slick-headerrow-columns-right' }, this._headerRowScrollerR);\n\n this._headerRows = [this._headerRowL, this._headerRowR];\n\n // Append the top panel scroller\n this._topPanelScrollerL = Utils.createDomElement('div', { className: 'slick-top-panel-scroller ui-state-default slick-state-default' }, this._paneTopL);\n this._topPanelScrollerR = Utils.createDomElement('div', { className: 'slick-top-panel-scroller ui-state-default slick-state-default' }, this._paneTopR);\n\n this._topPanelScrollers = [this._topPanelScrollerL, this._topPanelScrollerR];\n\n // Append the top panel\n this._topPanelL = Utils.createDomElement('div', { className: 'slick-top-panel', style: { width: '10000px' } }, this._topPanelScrollerL);\n this._topPanelR = Utils.createDomElement('div', { className: 'slick-top-panel', style: { width: '10000px' } }, this._topPanelScrollerR);\n\n this._topPanels = [this._topPanelL, this._topPanelR];\n\n if (!this._options.showColumnHeader) {\n this._headerScroller.forEach((el) => {\n Utils.hide(el);\n });\n }\n\n if (!this._options.showTopPanel) {\n this._topPanelScrollers.forEach((scroller) => {\n Utils.hide(scroller);\n })\n }\n\n if (!this._options.showHeaderRow) {\n this._headerRowScroller.forEach((scroller) => {\n Utils.hide(scroller);\n })\n }\n\n // Append the viewport containers\n this._viewportTopL = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-top slick-viewport-left', tabIndex: 0 }, this._paneTopL);\n this._viewportTopR = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-top slick-viewport-right', tabIndex: 0 }, this._paneTopR);\n this._viewportBottomL = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-bottom slick-viewport-left', tabIndex: 0 }, this._paneBottomL);\n this._viewportBottomR = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-bottom slick-viewport-right', tabIndex: 0 }, this._paneBottomR);\n\n // Cache the viewports\n this._viewport = [this._viewportTopL, this._viewportTopR, this._viewportBottomL, this._viewportBottomR];\n if (this._options.viewportClass) {\n this._viewport.forEach((view) => {\n view.classList.add(...(this._options.viewportClass || '').split(' '));\n });\n }\n\n // Default the active viewport to the top left\n this._activeViewportNode = this._viewportTopL;\n\n // Append the canvas containers\n this._canvasTopL = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-top grid-canvas-left', tabIndex: 0 }, this._viewportTopL);\n this._canvasTopR = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-top grid-canvas-right', tabIndex: 0 }, this._viewportTopR);\n this._canvasBottomL = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-bottom grid-canvas-left', tabIndex: 0 }, this._viewportBottomL);\n this._canvasBottomR = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-bottom grid-canvas-right', tabIndex: 0 }, this._viewportBottomR);\n\n // Cache the canvases\n this._canvas = [this._canvasTopL, this._canvasTopR, this._canvasBottomL, this._canvasBottomR];\n\n this.scrollbarDimensions = this.scrollbarDimensions || this.measureScrollbar();\n\n // Default the active canvas to the top left\n this._activeCanvasNode = this._canvasTopL;\n\n // pre-header\n if (this._preHeaderPanelSpacer) {\n Utils.width(this._preHeaderPanelSpacer, this.getCanvasWidth() + this.scrollbarDimensions.width);\n }\n\n this._headers.forEach((el) => {\n Utils.width(el, this.getHeadersWidth());\n })\n\n Utils.width(this._headerRowSpacerL, this.getCanvasWidth() + this.scrollbarDimensions.width);\n Utils.width(this._headerRowSpacerR, this.getCanvasWidth() + this.scrollbarDimensions.width);\n\n // footer Row\n if (this._options.createFooterRow) {\n this._footerRowScrollerR = Utils.createDomElement('div', { className: 'slick-footerrow ui-state-default slick-state-default' }, this._paneTopR);\n this._footerRowScrollerL = Utils.createDomElement('div', { className: 'slick-footerrow ui-state-default slick-state-default' }, this._paneTopL);\n\n this._footerRowScroller = [this._footerRowScrollerL, this._footerRowScrollerR];\n\n this._footerRowSpacerL = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._footerRowScrollerL);\n Utils.width(this._footerRowSpacerL, this.getCanvasWidth() + this.scrollbarDimensions.width);\n this._footerRowSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._footerRowScrollerR);\n Utils.width(this._footerRowSpacerR, this.getCanvasWidth() + this.scrollbarDimensions.width);\n\n\n this._footerRowL = Utils.createDomElement('div', { className: 'slick-footerrow-columns slick-footerrow-columns-left' }, this._footerRowScrollerL);\n this._footerRowR = Utils.createDomElement('div', { className: 'slick-footerrow-columns slick-footerrow-columns-right' }, this._footerRowScrollerR);\n\n this._footerRow = [this._footerRowL, this._footerRowR];\n\n if (!this._options.showFooterRow) {\n this._footerRowScroller.forEach((scroller) => {\n Utils.hide(scroller);\n });\n }\n }\n\n this._focusSink2 = this._focusSink.cloneNode(true) as HTMLDivElement;\n this._container.appendChild(this._focusSink2);\n\n if (!this._options.explicitInitialization) {\n this.finishInitialization();\n }\n }\n\n protected finishInitialization() {\n if (!this.initialized) {\n this.initialized = true;\n\n this.getViewportWidth();\n this.getViewportHeight();\n\n // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\n // calculate the diff so we can set consistent sizes\n this.measureCellPaddingAndBorder();\n\n // for usability reasons, all text selection in SlickGrid is disabled\n // with the exception of input and textarea elements (selection must\n // be enabled there so that editors work as expected); note that\n // selection in grid cells (grid body) is already unavailable in\n // all browsers except IE\n this.disableSelection(this._headers); // disable all text selection in header (including input and textarea)\n\n if (!this._options.enableTextSelectionOnCells) {\n // disable text selection in grid cells except in input and textarea elements\n // (this is IE-specific, because selectstart event will only fire in IE)\n this._viewport.forEach((view) => {\n this._bindingEventService.bind(view, 'selectstart', (event) => {\n if (event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement) {\n return;\n }\n });\n })\n }\n\n this.setFrozenOptions();\n this.setPaneVisibility();\n this.setScroller();\n this.setOverflow();\n\n this.updateColumnCaches();\n this.createColumnHeaders();\n this.createColumnFooter();\n this.setupColumnSort();\n this.createCssRules();\n this.resizeCanvas();\n this.bindAncestorScrollEvents();\n\n this._bindingEventService.bind(this._container, 'resize', this.resizeCanvas.bind(this));\n this._viewport.forEach((view) => {\n this._bindingEventService.bind(view, 'scroll', this.handleScroll.bind(this));\n });\n\n if (this._options.enableMouseWheelScrollHandler) {\n this._viewport.forEach((view) => {\n this.slickMouseWheelInstances.push(MouseWheel({\n element: view,\n onMouseWheel: this.handleMouseWheel.bind(this)\n }));\n });\n }\n\n this._headerScroller.forEach((el) => {\n this._bindingEventService.bind(el, 'contextmenu', this.handleHeaderContextMenu.bind(this) as EventListener);\n this._bindingEventService.bind(el, 'click', this.handleHeaderClick.bind(this) as EventListener);\n });\n\n this._headerRowScroller.forEach((scroller) => {\n this._bindingEventService.bind(scroller, 'scroll', this.handleHeaderRowScroll.bind(this) as EventListener);\n });\n\n if (this._options.createFooterRow) {\n this._footerRow.forEach((footer) => {\n this._bindingEventService.bind(footer, 'contextmenu', this.handleFooterContextMenu.bind(this) as EventListener);\n this._bindingEventService.bind(footer, 'click', this.handleFooterClick.bind(this) as EventListener);\n });\n\n this._footerRowScroller.forEach((scroller) => {\n this._bindingEventService.bind(scroller, 'scroll', this.handleFooterRowScroll.bind(this) as EventListener);\n });\n }\n\n if (this._options.createPreHeaderPanel) {\n this._bindingEventService.bind(this._preHeaderPanelScroller, 'scroll', this.handlePreHeaderPanelScroll.bind(this) as EventListener);\n }\n\n this._bindingEventService.bind(this._focusSink, 'keydown', this.handleKeyDown.bind(this) as EventListener);\n this._bindingEventService.bind(this._focusSink2, 'keydown', this.handleKeyDown.bind(this) as EventListener);\n\n this._canvas.forEach((element) => {\n this._bindingEventService.bind(element, 'keydown', this.handleKeyDown.bind(this) as EventListener);\n this._bindingEventService.bind(element, 'click', this.handleClick.bind(this) as EventListener);\n this._bindingEventService.bind(element, 'dblclick', this.handleDblClick.bind(this) as EventListener);\n this._bindingEventService.bind(element, 'contextmenu', this.handleContextMenu.bind(this) as EventListener);\n this._bindingEventService.bind(element, 'mouseover', this.handleCellMouseOver.bind(this) as EventListener);\n this._bindingEventService.bind(element, 'mouseout', this.handleCellMouseOut.bind(this) as EventListener);\n });\n\n if (Draggable) {\n this.slickDraggableInstance = Draggable({\n containerElement: this._container,\n allowDragFrom: 'div.slick-cell',\n onDragInit: this.handleDragInit.bind(this),\n onDragStart: this.handleDragStart.bind(this),\n onDrag: this.handleDrag.bind(this),\n onDragEnd: this.handleDragEnd.bind(this)\n });\n }\n\n if (!this._options.suppressCssChangesOnHiddenInit) {\n this.restoreCssFromHiddenInit();\n }\n }\n }\n\n /** handles \"display:none\" on container or container parents, related to issue: https://github.com/6pac/SlickGrid/issues/568 */\n cacheCssForHiddenInit() {\n this._hiddenParents = Utils.parents(this._container, ':hidden') as HTMLElement[];\n for (const el of this._hiddenParents) {\n const old: Partial = {};\n for (const name in this.cssShow) {\n old[name as any] = el.style[name as 'position' | 'visibility' | 'display'];\n el.style[name as any] = this.cssShow[name as 'position' | 'visibility' | 'display'];\n }\n this.oldProps.push(old);\n }\n }\n\n restoreCssFromHiddenInit() {\n // finish handle display:none on container or container parents\n // - put values back the way they were\n let i = 0;\n for (const el of this._hiddenParents) {\n const old = this.oldProps[i++];\n for (const name in this.cssShow) {\n el.style[name as CSSStyleDeclarationWritable] = (old as any)[name];\n }\n }\n }\n\n protected hasFrozenColumns() {\n return this._options.frozenColumn! > -1;\n }\n\n /** Register an external Plugin */\n registerPlugin(plugin: T) {\n this.plugins.unshift(plugin);\n plugin.init(this as unknown as SlickGridModel);\n }\n\n /** Unregister (destroy) an external Plugin */\n unregisterPlugin(plugin: Plugin) {\n for (let i = this.plugins.length; i >= 0; i--) {\n if (this.plugins[i] === plugin) {\n this.plugins[i]?.destroy();\n this.plugins.splice(i, 1);\n break;\n }\n }\n }\n\n /** Get a Plugin (addon) by its name */\n getPluginByName

(name: string) {\n for (let i = this.plugins.length - 1; i >= 0; i--) {\n if (this.plugins[i]?.pluginName === name) {\n return this.plugins[i] as P;\n }\n }\n return undefined;\n }\n\n /**\n * Unregisters a current selection model and registers a new one. See the definition of SelectionModel for more information.\n * @param {Object} selectionModel A SelectionModel.\n */\n setSelectionModel(model: SelectionModel) {\n if (this.selectionModel) {\n this.selectionModel.onSelectedRangesChanged.unsubscribe(this.handleSelectedRangesChanged.bind(this));\n if (this.selectionModel.destroy) {\n this.selectionModel.destroy();\n }\n }\n\n this.selectionModel = model;\n if (this.selectionModel) {\n this.selectionModel.init(this as unknown as SlickGridModel);\n this.selectionModel.onSelectedRangesChanged.subscribe(this.handleSelectedRangesChanged.bind(this));\n }\n }\n\n /** Returns the current SelectionModel. See here for more information about SelectionModels. */\n getSelectionModel() {\n return this.selectionModel;\n }\n\n /** Get Grid Canvas Node DOM Element */\n getCanvasNode(columnIdOrIdx?: number | string, rowIndex?: number) {\n return this._getContainerElement(this.getCanvases(), columnIdOrIdx, rowIndex) as HTMLDivElement;\n }\n\n /** Get the canvas DOM element */\n getActiveCanvasNode(e?: Event | SlickEventData_) {\n if (e === undefined) {\n return this._activeCanvasNode;\n }\n\n if (e instanceof SlickEventData) {\n e = e.getNativeEvent();\n }\n\n this._activeCanvasNode = (e as any)?.target.closest('.grid-canvas');\n return this._activeCanvasNode;\n }\n\n /** Get the canvas DOM element */\n getCanvases() {\n return this._canvas;\n }\n\n /** Get the Viewport DOM node element */\n getViewportNode(columnIdOrIdx: number | string, rowIndex: number) {\n return this._getContainerElement(this.getViewports(), columnIdOrIdx, rowIndex);\n }\n\n /** Get all the Viewport node elements */\n getViewports() {\n return this._viewport;\n }\n\n getActiveViewportNode(e: Event | SlickEventData_) {\n this.setActiveViewportNode(e);\n\n return this._activeViewportNode;\n }\n\n /** Sets an active viewport node */\n setActiveViewportNode(e: Event | SlickEventData_) {\n if (e instanceof SlickEventData) {\n e = e.getNativeEvent();\n }\n this._activeViewportNode = (e as any)?.target.closest('.slick-viewport');\n return this._activeViewportNode;\n }\n\n protected _getContainerElement(targetContainers: HTMLElement[], columnIdOrIdx?: number | string, rowIndex?: number) {\n if (!targetContainers) { return; }\n if (!columnIdOrIdx) { columnIdOrIdx = 0; }\n if (!rowIndex) { rowIndex = 0; }\n\n const idx = (typeof columnIdOrIdx === 'number' ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx));\n\n const isBottomSide = this.hasFrozenRows && rowIndex >= this.actualFrozenRow + (this._options.frozenBottom ? 0 : 1);\n const isRightSide = this.hasFrozenColumns() && idx > this._options.frozenColumn!;\n\n return targetContainers[(isBottomSide ? 2 : 0) + (isRightSide ? 1 : 0)];\n }\n\n protected measureScrollbar() {\n let className = '';\n this._viewport.forEach(v => className += v.className);\n const outerdiv = Utils.createDomElement('div', { className, style: { position: 'absolute', top: '-10000px', left: '-10000px', overflow: 'auto', width: '100px', height: '100px' } }, document.body);\n const innerdiv = Utils.createDomElement('div', { style: { width: '200px', height: '200px', overflow: 'auto' } }, outerdiv);\n const dim = {\n width: outerdiv.offsetWidth - outerdiv.clientWidth,\n height: outerdiv.offsetHeight - outerdiv.clientHeight\n };\n innerdiv.remove();\n outerdiv.remove();\n return dim;\n }\n\n /** Get the headers width in pixel */\n getHeadersWidth() {\n this.headersWidth = this.headersWidthL = this.headersWidthR = 0;\n const includeScrollbar = !this._options.autoHeight;\n\n let i = 0;\n const ii = this.columns.length;\n for (i = 0; i < ii; i++) {\n if (!this.columns[i] || this.columns[i].hidden) continue;\n\n const width = this.columns[i].width;\n\n if ((this._options.frozenColumn!) > -1 && (i > this._options.frozenColumn!)) {\n this.headersWidthR += width || 0;\n } else {\n this.headersWidthL += width || 0;\n }\n }\n\n if (includeScrollbar) {\n if ((this._options.frozenColumn!) > -1 && (i > this._options.frozenColumn!)) {\n this.headersWidthR += this.scrollbarDimensions?.width ?? 0;\n } else {\n this.headersWidthL += this.scrollbarDimensions?.width ?? 0;\n }\n }\n\n if (this.hasFrozenColumns()) {\n this.headersWidthL = this.headersWidthL + 1000;\n\n this.headersWidthR = Math.max(this.headersWidthR, this.viewportW) + this.headersWidthL;\n this.headersWidthR += this.scrollbarDimensions?.width ?? 0;\n } else {\n this.headersWidthL += this.scrollbarDimensions?.width ?? 0;\n this.headersWidthL = Math.max(this.headersWidthL, this.viewportW) + 1000;\n }\n\n this.headersWidth = this.headersWidthL + this.headersWidthR;\n return Math.max(this.headersWidth, this.viewportW) + 1000;\n }\n\n protected getHeadersWidthL() {\n this.headersWidthL = 0;\n\n this.columns.forEach((column, i) => {\n if (column.hidden) return;\n\n if (!((this._options.frozenColumn!) > -1 && (i > this._options.frozenColumn!))) {\n this.headersWidthL += column.width || 0;\n }\n });\n\n if (this.hasFrozenColumns()) {\n this.headersWidthL += 1000;\n } else {\n this.headersWidthL += this.scrollbarDimensions?.width ?? 0;\n this.headersWidthL = Math.max(this.headersWidthL, this.viewportW) + 1000;\n }\n\n return this.headersWidthL;\n }\n\n protected getHeadersWidthR() {\n this.headersWidthR = 0;\n\n this.columns.forEach((column, i) => {\n if (column.hidden) return;\n if ((this._options.frozenColumn!) > -1 && (i > this._options.frozenColumn!)) {\n this.headersWidthR += column.width || 0;\n }\n });\n\n if (this.hasFrozenColumns()) {\n this.headersWidthR = Math.max(this.headersWidthR, this.viewportW) + this.getHeadersWidthL();\n this.headersWidthR += this.scrollbarDimensions?.width ?? 0;\n }\n\n return this.headersWidthR;\n }\n\n /** Get the grid canvas width */\n getCanvasWidth(): number {\n const availableWidth = this.viewportHasVScroll ? this.viewportW - (this.scrollbarDimensions?.width ?? 0) : this.viewportW;\n let i = this.columns.length;\n\n this.canvasWidthL = this.canvasWidthR = 0;\n\n while (i--) {\n if (!this.columns[i] || this.columns[i].hidden) continue;\n\n if (this.hasFrozenColumns() && (i > this._options.frozenColumn!)) {\n this.canvasWidthR += this.columns[i].width || 0;\n } else {\n this.canvasWidthL += this.columns[i].width || 0;\n }\n }\n let totalRowWidth = this.canvasWidthL + this.canvasWidthR;\n if (this._options.fullWidthRows) {\n const extraWidth = Math.max(totalRowWidth, availableWidth) - totalRowWidth;\n if (extraWidth > 0) {\n totalRowWidth += extraWidth;\n if (this.hasFrozenColumns()) {\n this.canvasWidthR += extraWidth;\n } else {\n this.canvasWidthL += extraWidth;\n }\n }\n }\n return totalRowWidth;\n }\n\n protected updateCanvasWidth(forceColumnWidthsUpdate?: boolean) {\n const oldCanvasWidth = this.canvasWidth;\n const oldCanvasWidthL = this.canvasWidthL;\n const oldCanvasWidthR = this.canvasWidthR;\n this.canvasWidth = this.getCanvasWidth();\n\n const widthChanged = this.canvasWidth !== oldCanvasWidth || this.canvasWidthL !== oldCanvasWidthL || this.canvasWidthR !== oldCanvasWidthR;\n\n if (widthChanged || this.hasFrozenColumns() || this.hasFrozenRows) {\n Utils.width(this._canvasTopL, this.canvasWidthL);\n\n this.getHeadersWidth();\n\n Utils.width(this._headerL, this.headersWidthL);\n Utils.width(this._headerR, this.headersWidthR);\n\n if (this.hasFrozenColumns()) {\n const cWidth = Utils.width(this._container) || 0;\n if (cWidth > 0 && this.canvasWidthL > cWidth) {\n throw new Error('[SlickGrid] Frozen columns cannot be wider than the actual grid container width. '\n + 'Make sure to have less columns freezed or make your grid container wider');\n }\n Utils.width(this._canvasTopR, this.canvasWidthR);\n\n Utils.width(this._paneHeaderL, this.canvasWidthL);\n Utils.setStyleSize(this._paneHeaderR, 'left', this.canvasWidthL);\n Utils.setStyleSize(this._paneHeaderR, 'width', this.viewportW - this.canvasWidthL);\n\n Utils.width(this._paneTopL, this.canvasWidthL);\n Utils.setStyleSize(this._paneTopR, 'left', this.canvasWidthL);\n Utils.width(this._paneTopR, this.viewportW - this.canvasWidthL);\n\n Utils.width(this._headerRowScrollerL, this.canvasWidthL);\n Utils.width(this._headerRowScrollerR, this.viewportW - this.canvasWidthL);\n\n Utils.width(this._headerRowL, this.canvasWidthL);\n Utils.width(this._headerRowR, this.canvasWidthR);\n\n if (this._options.createFooterRow) {\n Utils.width(this._footerRowScrollerL, this.canvasWidthL);\n Utils.width(this._footerRowScrollerR, this.viewportW - this.canvasWidthL);\n\n Utils.width(this._footerRowL, this.canvasWidthL);\n Utils.width(this._footerRowR, this.canvasWidthR);\n }\n if (this._options.createPreHeaderPanel) {\n Utils.width(this._preHeaderPanel, this.canvasWidth);\n }\n Utils.width(this._viewportTopL, this.canvasWidthL);\n Utils.width(this._viewportTopR, this.viewportW - this.canvasWidthL);\n\n if (this.hasFrozenRows) {\n Utils.width(this._paneBottomL, this.canvasWidthL);\n Utils.setStyleSize(this._paneBottomR, 'left', this.canvasWidthL);\n\n Utils.width(this._viewportBottomL, this.canvasWidthL);\n Utils.width(this._viewportBottomR, this.viewportW - this.canvasWidthL);\n\n Utils.width(this._canvasBottomL, this.canvasWidthL);\n Utils.width(this._canvasBottomR, this.canvasWidthR);\n }\n } else {\n Utils.width(this._paneHeaderL, '100%');\n Utils.width(this._paneTopL, '100%');\n Utils.width(this._headerRowScrollerL, '100%');\n Utils.width(this._headerRowL, this.canvasWidth);\n\n if (this._options.createFooterRow) {\n Utils.width(this._footerRowScrollerL, '100%');\n Utils.width(this._footerRowL, this.canvasWidth);\n }\n\n if (this._options.createPreHeaderPanel) {\n Utils.width(this._preHeaderPanel, this.canvasWidth);\n }\n Utils.width(this._viewportTopL, '100%');\n\n if (this.hasFrozenRows) {\n Utils.width(this._viewportBottomL, '100%');\n Utils.width(this._canvasBottomL, this.canvasWidthL);\n }\n }\n }\n\n this.viewportHasHScroll = (this.canvasWidth >= this.viewportW - (this.scrollbarDimensions?.width ?? 0));\n\n Utils.width(this._headerRowSpacerL, this.canvasWidth + (this.viewportHasVScroll ? (this.scrollbarDimensions?.width ?? 0) : 0));\n Utils.width(this._headerRowSpacerR, this.canvasWidth + (this.viewportHasVScroll ? (this.scrollbarDimensions?.width ?? 0) : 0));\n\n if (this._options.createFooterRow) {\n Utils.width(this._footerRowSpacerL, this.canvasWidth + (this.viewportHasVScroll ? (this.scrollbarDimensions?.width ?? 0) : 0));\n Utils.width(this._footerRowSpacerR, this.canvasWidth + (this.viewportHasVScroll ? (this.scrollbarDimensions?.width ?? 0) : 0));\n }\n\n if (widthChanged || forceColumnWidthsUpdate) {\n this.applyColumnWidths();\n }\n }\n\n protected disableSelection(target: HTMLElement[]) {\n target.forEach((el) => {\n el.setAttribute('unselectable', 'on');\n (el.style as any).mozUserSelect = 'none';\n this._bindingEventService.bind(el, 'selectstart', () => false);\n });\n }\n\n protected getMaxSupportedCssHeight() {\n let supportedHeight = 1000000;\n // FF reports the height back but still renders blank after ~6M px\n //let testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;\n const testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? this._options.ffMaxSupportedCssHeight : this._options.maxSupportedCssHeight;\n const div = Utils.createDomElement('div', { style: { display: 'hidden' } }, document.body);\n\n while (true) {\n const test = supportedHeight * 2;\n Utils.height(div, test);\n const height = Utils.height(div);\n\n if (test > testUpTo! || height !== test) {\n break;\n } else {\n supportedHeight = test;\n }\n }\n\n div.remove();\n return supportedHeight;\n }\n\n /** Get grid unique identifier */\n getUID() {\n return this.uid;\n }\n\n /** Get Header Column Width Difference in pixel */\n getHeaderColumnWidthDiff() {\n return this.headerColumnWidthDiff;\n }\n\n /** Get scrollbar dimensions */\n getScrollbarDimensions() {\n return this.scrollbarDimensions;\n }\n\n /** Get the displayed scrollbar dimensions */\n getDisplayedScrollbarDimensions() {\n return {\n width: this.viewportHasVScroll ? (this.scrollbarDimensions?.width ?? 0) : 0,\n height: this.viewportHasHScroll ? (this.scrollbarDimensions?.height ?? 0) : 0\n };\n }\n\n /** Get the absolute column minimum width */\n getAbsoluteColumnMinWidth(): number {\n return this.absoluteColumnMinWidth;\n }\n\n // TODO: this is static. need to handle page mutation.\n protected bindAncestorScrollEvents() {\n let elem: HTMLElement | null = (this.hasFrozenRows && !this._options.frozenBottom) ? this._canvasBottomL : this._canvasTopL;\n while ((elem = elem!.parentNode as HTMLElement) !== document.body && elem != null) {\n // bind to scroll containers only\n if (elem == this._viewportTopL || elem.scrollWidth !== elem.clientWidth || elem.scrollHeight !== elem.clientHeight) {\n this._boundAncestors.push(elem);\n this._bindingEventService.bind(elem, 'scroll', this.handleActiveCellPositionChange.bind(this));\n }\n }\n }\n\n protected unbindAncestorScrollEvents() {\n this._boundAncestors.forEach((ancestor) => {\n this._bindingEventService.unbindByEventName(ancestor, 'scroll');\n });\n this._boundAncestors = [];\n }\n\n /**\n * Updates an existing column definition and a corresponding header DOM element with the new title and tooltip.\n * @param {Number|String} columnId Column id.\n * @param {String} title New column name.\n * @param {String} [toolTip] New column tooltip.\n */\n updateColumnHeader(columnId: number | string, title?: string, toolTip?: string) {\n if (!this.initialized) { return; }\n const idx = this.getColumnIndex(columnId);\n if (idx == null) {\n return;\n }\n\n const columnDef = this.columns[idx];\n const header: any = this.getColumnByIndex(idx);\n if (header) {\n if (title !== undefined) {\n this.columns[idx].name = title;\n }\n if (toolTip !== undefined) {\n this.columns[idx].toolTip = toolTip;\n }\n\n this.trigger(this.onBeforeHeaderCellDestroy, {\n node: header,\n column: columnDef,\n grid: this\n });\n\n header.setAttribute('title', toolTip || '');\n if (title !== undefined) {\n header.children[0].innerHTML = this.sanitizeHtmlString(title);\n }\n\n this.trigger(this.onHeaderCellRendered, {\n node: header,\n column: columnDef,\n grid: this\n });\n }\n }\n\n /**\n * Get the Header DOM element\n * @param {C} columnDef - column definition\n */\n getHeader(columnDef: C) {\n if (!columnDef) {\n return this.hasFrozenColumns() ? this._headers : this._headerL;\n }\n const idx = this.getColumnIndex(columnDef.id);\n return this.hasFrozenColumns() ? ((idx <= this._options.frozenColumn!) ? this._headerL : this._headerR) : this._headerL;\n }\n\n /**\n * Get a specific Header Column DOM element\n * @param {Number|String} [columnIdOrIdx] - column Id or index\n */\n getHeaderColumn(columnIdOrIdx: number | string) {\n const idx = (typeof columnIdOrIdx === 'number' ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx));\n const targetHeader = this.hasFrozenColumns() ? ((idx <= this._options.frozenColumn!) ? this._headerL : this._headerR) : this._headerL;\n const targetIndex = this.hasFrozenColumns() ? ((idx <= this._options.frozenColumn!) ? idx : idx - this._options.frozenColumn! - 1) : idx;\n\n return targetHeader.children[targetIndex] as HTMLDivElement;\n }\n\n /** Get the Header Row DOM element */\n getHeaderRow() {\n return this.hasFrozenColumns() ? this._headerRows : this._headerRows[0];\n }\n\n /** Get the Footer DOM element */\n getFooterRow() {\n return this.hasFrozenColumns() ? this._footerRow : this._footerRow[0];\n }\n\n /** @alias `getPreHeaderPanelLeft` */\n getPreHeaderPanel() {\n return this._preHeaderPanel;\n }\n\n /** Get the Pre-Header Panel Left DOM node element */\n getPreHeaderPanelLeft() {\n return this._preHeaderPanel;\n }\n\n /** Get the Pre-Header Panel Right DOM node element */\n getPreHeaderPanelRight() {\n return this._preHeaderPanelR;\n }\n\n /**\n * Get Header Row Column DOM element by its column Id\n * @param {Number|String} [columnIdOrIdx] - column Id or index\n */\n getHeaderRowColumn(columnIdOrIdx: number | string) {\n let idx = (typeof columnIdOrIdx === 'number' ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx));\n let headerRowTarget: HTMLDivElement;\n\n if (this.hasFrozenColumns()) {\n if (idx <= this._options.frozenColumn!) {\n headerRowTarget = this._headerRowL;\n } else {\n headerRowTarget = this._headerRowR;\n idx -= this._options.frozenColumn! + 1;\n }\n } else {\n headerRowTarget = this._headerRowL;\n }\n\n return headerRowTarget.children[idx] as HTMLDivElement;\n }\n\n /** Get the Footer Row Column DOM element */\n getFooterRowColumn(columnIdOrIdx: number | string) {\n let idx = (typeof columnIdOrIdx === 'number' ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx));\n let footerRowTarget: HTMLDivElement;\n\n if (this.hasFrozenColumns()) {\n if (idx <= this._options.frozenColumn!) {\n footerRowTarget = this._footerRowL;\n } else {\n footerRowTarget = this._footerRowR;\n\n idx -= this._options.frozenColumn! + 1;\n }\n } else {\n footerRowTarget = this._footerRowL;\n }\n\n return footerRowTarget.children[idx] as HTMLDivElement;\n }\n\n protected createColumnFooter() {\n if (this._options.createFooterRow) {\n this._footerRow.forEach((footer) => {\n const columnElements = footer.querySelectorAll('.slick-footerrow-column');\n columnElements.forEach((column) => {\n const columnDef = Utils.storage.get(column, 'column');\n this.trigger(this.onBeforeFooterRowCellDestroy, {\n node: column,\n column: columnDef,\n grid: this\n });\n });\n });\n\n Utils.emptyElement(this._footerRowL);\n Utils.emptyElement(this._footerRowR);\n\n for (let i = 0; i < this.columns.length; i++) {\n const m = this.columns[i];\n if (!m || m.hidden) continue;\n\n const footerRowCell = Utils.createDomElement('div', { className: `ui-state-default slick-state-default slick-footerrow-column l${i} r${i}` }, this.hasFrozenColumns() && (i > this._options.frozenColumn!) ? this._footerRowR : this._footerRowL);\n const className = this.hasFrozenColumns() && i <= this._options.frozenColumn! ? 'frozen' : null;\n if (className) {\n footerRowCell.classList.add(className);\n }\n\n Utils.storage.put(footerRowCell, 'column', m);\n\n this.trigger(this.onFooterRowCellRendered, {\n node: footerRowCell,\n column: m,\n grid: this\n });\n }\n }\n }\n\n protected handleHeaderMouseHoverOn(e: Event | SlickEventData_) {\n (e as any)?.target.classList.add('ui-state-hover', 'slick-state-hover');\n }\n\n protected handleHeaderMouseHoverOff(e: Event | SlickEventData_) {\n (e as any)?.target.classList.remove('ui-state-hover', 'slick-state-hover');\n }\n\n protected createColumnHeaders() {\n this._headers.forEach((header) => {\n const columnElements = header.querySelectorAll('.slick-header-column')\n columnElements.forEach((column) => {\n const columnDef = Utils.storage.get(column, 'column');\n if (columnDef) {\n this.trigger(this.onBeforeHeaderCellDestroy, {\n node: column,\n column: columnDef,\n grid: this\n });\n }\n });\n })\n\n Utils.emptyElement(this._headerL);\n Utils.emptyElement(this._headerR);\n\n this.getHeadersWidth();\n\n Utils.width(this._headerL, this.headersWidthL);\n Utils.width(this._headerR, this.headersWidthR);\n\n this._headerRows.forEach((row) => {\n const columnElements = row.querySelectorAll('.slick-headerrow-column');\n columnElements.forEach((column) => {\n const columnDef = Utils.storage.get(column, 'column');\n if (columnDef) {\n this.trigger(this.onBeforeHeaderRowCellDestroy, {\n node: this,\n column: columnDef,\n grid: this\n });\n }\n });\n });\n\n Utils.emptyElement(this._headerRowL);\n Utils.emptyElement(this._headerRowR);\n\n if (this._options.createFooterRow) {\n const footerRowColumnElements = this._footerRowL.querySelectorAll('.slick-footerrow-column');\n footerRowColumnElements.forEach((column) => {\n const columnDef = Utils.storage.get(column, 'column');\n if (columnDef) {\n this.trigger(this.onBeforeFooterRowCellDestroy, {\n node: this,\n column: columnDef,\n grid: this\n });\n }\n });\n Utils.emptyElement(this._footerRowL);\n\n if (this.hasFrozenColumns()) {\n const footerRowColumnElements = this._footerRowR.querySelectorAll('.slick-footerrow-column');\n footerRowColumnElements.forEach((column) => {\n const columnDef = Utils.storage.get(column, 'column');\n if (columnDef) {\n this.trigger(this.onBeforeFooterRowCellDestroy, {\n node: this,\n column: columnDef,\n grid: this\n });\n }\n });\n Utils.emptyElement(this._footerRowR);\n }\n }\n\n for (let i = 0; i < this.columns.length; i++) {\n const m: C = this.columns[i];\n const headerTarget = this.hasFrozenColumns() ? ((i <= this._options.frozenColumn!) ? this._headerL : this._headerR) : this._headerL;\n const headerRowTarget = this.hasFrozenColumns() ? ((i <= this._options.frozenColumn!) ? this._headerRowL : this._headerRowR) : this._headerRowL;\n\n const header = Utils.createDomElement('div', { id: `${this.uid + m.id}`, dataset: { id: String(m.id) }, className: 'ui-state-default slick-state-default slick-header-column', title: m.toolTip || '' }, headerTarget);\n Utils.createDomElement('span', { className: 'slick-column-name', innerHTML: this.sanitizeHtmlString(m.name as string) }, header);\n Utils.width(header, m.width! - this.headerColumnWidthDiff);\n\n let classname = m.headerCssClass || null;\n if (classname) {\n header.classList.add(...classname.split(' '));\n }\n classname = this.hasFrozenColumns() && i <= this._options.frozenColumn! ? 'frozen' : null;\n if (classname) {\n header.classList.add(classname);\n }\n\n this._bindingEventService.bind(header, 'mouseenter', this.handleHeaderMouseEnter.bind(this) as EventListener);\n this._bindingEventService.bind(header, 'mouseleave', this.handleHeaderMouseLeave.bind(this) as EventListener);\n\n Utils.storage.put(header, 'column', m);\n\n if (this._options.enableColumnReorder || m.sortable) {\n this._bindingEventService.bind(header, 'mouseenter', this.handleHeaderMouseHoverOn.bind(this) as EventListener);\n this._bindingEventService.bind(header, 'mouseleave', this.handleHeaderMouseHoverOff.bind(this) as EventListener);\n }\n\n if (m.hasOwnProperty('headerCellAttrs') && m.headerCellAttrs instanceof Object) {\n for (const key in m.headerCellAttrs) {\n if (m.headerCellAttrs.hasOwnProperty(key)) {\n header.setAttribute(key, m.headerCellAttrs[key]);\n }\n }\n }\n\n if (m.sortable) {\n header.classList.add('slick-header-sortable');\n Utils.createDomElement('div', { className: `slick-sort-indicator ${this._options.numberedMultiColumnSort && !this._options.sortColNumberInSeparateSpan ? ' slick-sort-indicator-numbered' : ''}` }, header);\n if (this._options.numberedMultiColumnSort && this._options.sortColNumberInSeparateSpan) {\n Utils.createDomElement('div', { className: 'slick-sort-indicator-numbered' }, header);\n }\n }\n\n this.trigger(this.onHeaderCellRendered, {\n node: header,\n column: m,\n grid: this\n });\n\n if (this._options.showHeaderRow) {\n const headerRowCell = Utils.createDomElement('div', { className: `ui-state-default slick-state-default slick-headerrow-column l${i} r${i}` }, headerRowTarget);\n const classname = this.hasFrozenColumns() && i <= this._options.frozenColumn! ? 'frozen' : null;\n if (classname) {\n headerRowCell.classList.add(classname);\n }\n\n this._bindingEventService.bind(headerRowCell, 'mouseenter', this.handleHeaderRowMouseEnter.bind(this) as EventListener);\n this._bindingEventService.bind(headerRowCell, 'mouseleave', this.handleHeaderRowMouseLeave.bind(this) as EventListener);\n\n Utils.storage.put(headerRowCell, 'column', m);\n\n this.trigger(this.onHeaderRowCellRendered, {\n node: headerRowCell,\n column: m,\n grid: this\n });\n }\n if (this._options.createFooterRow && this._options.showFooterRow) {\n const footerRowTarget = this.hasFrozenColumns() ? ((i <= this._options.frozenColumn!) ? this._footerRow[0] : this._footerRow[1]) : this._footerRow[0];\n const footerRowCell = Utils.createDomElement('div', { className: `ui-state-default slick-state-default slick-footerrow-column l${i} r${i}` }, footerRowTarget);\n Utils.storage.put(footerRowCell, 'column', m)\n\n this.trigger(this.onFooterRowCellRendered, {\n node: footerRowCell,\n column: m,\n grid: this\n });\n }\n }\n\n this.setSortColumns(this.sortColumns);\n this.setupColumnResize();\n if (this._options.enableColumnReorder) {\n if (typeof this._options.enableColumnReorder === 'function') {\n this._options.enableColumnReorder(this as unknown as SlickGridModel, this._headers, this.headerColumnWidthDiff, this.setColumns as any, this.setupColumnResize, this.columns, this.getColumnIndex, this.uid, this.trigger);\n } else {\n this.setupColumnReorder();\n }\n }\n }\n\n protected setupColumnSort() {\n this._headers.forEach((header) => {\n this._bindingEventService.bind(header, 'click', (e: any) => {\n if (this.columnResizeDragging) {\n return;\n }\n\n if (e.target.classList.contains('slick-resizable-handle')) {\n return;\n }\n\n const coll = e.target.closest('.slick-header-column');\n if (!coll) {\n return;\n }\n\n const column = Utils.storage.get(coll, 'column');\n if (column.sortable) {\n if (!this.getEditorLock()?.commitCurrentEdit()) {\n return;\n }\n\n const previousSortColumns = this.sortColumns.slice();\n let sortColumn: ColumnSort | null = null;\n let i = 0;\n for (; i < this.sortColumns.length; i++) {\n if (this.sortColumns[i].columnId == column.id) {\n sortColumn = this.sortColumns[i];\n sortColumn.sortAsc = !sortColumn.sortAsc;\n break;\n }\n }\n const hadSortCol = !!sortColumn;\n\n if (this._options.tristateMultiColumnSort) {\n if (!sortColumn) {\n sortColumn = { columnId: column.id, sortAsc: column.defaultSortAsc, sortCol: column };\n }\n if (hadSortCol && sortColumn.sortAsc) {\n // three state: remove sort rather than go back to ASC\n this.sortColumns.splice(i, 1);\n sortColumn = null;\n }\n if (!this._options.multiColumnSort) {\n this.sortColumns = [];\n }\n if (sortColumn && (!hadSortCol || !this._options.multiColumnSort)) {\n this.sortColumns.push(sortColumn);\n }\n } else {\n // legacy behaviour\n if (e.metaKey && this._options.multiColumnSort) {\n if (sortColumn) {\n this.sortColumns.splice(i, 1);\n }\n } else {\n if ((!e.shiftKey && !e.metaKey) || !this._options.multiColumnSort) {\n this.sortColumns = [];\n }\n\n if (!sortColumn) {\n sortColumn = { columnId: column.id, sortAsc: column.defaultSortAsc, sortCol: column };\n this.sortColumns.push(sortColumn);\n } else if (this.sortColumns.length === 0) {\n this.sortColumns.push(sortColumn);\n }\n }\n }\n\n let onSortArgs;\n if (!this._options.multiColumnSort) {\n onSortArgs = {\n multiColumnSort: false,\n previousSortColumns: previousSortColumns,\n columnId: (this.sortColumns.length > 0 ? column.id : null),\n sortCol: (this.sortColumns.length > 0 ? column : null),\n sortAsc: (this.sortColumns.length > 0 ? this.sortColumns[0].sortAsc : true)\n };\n } else {\n onSortArgs = {\n multiColumnSort: true,\n previousSortColumns: previousSortColumns,\n sortCols: this.sortColumns.map((col) => {\n return { columnId: this.columns[this.getColumnIndex(col.columnId)].id, sortCol: this.columns[this.getColumnIndex(col.columnId)], sortAsc: col.sortAsc };\n })\n };\n }\n\n if (this.trigger(this.onBeforeSort, onSortArgs, e).getReturnValue() !== false) {\n this.setSortColumns(this.sortColumns);\n this.trigger(this.onSort, onSortArgs, e);\n }\n }\n });\n });\n }\n\n protected currentPositionInHeader(id: number | string) {\n let currentPosition = 0;\n this._headers.forEach((header) => {\n const columnElements = header.querySelectorAll('.slick-header-column')\n columnElements.forEach((column, i) => {\n if (column.id == id) {\n currentPosition = i;\n }\n });\n });\n\n return currentPosition;\n }\n\n protected remove(arr: any[], elem: HTMLElement) {\n const index = arr.lastIndexOf(elem);\n if (index > -1) {\n arr.splice(index, 1);\n this.remove(arr, elem);\n }\n }\n\n protected setupColumnReorder() {\n if (this.sortableSideLeftInstance) {\n this.sortableSideLeftInstance.destroy();\n this.sortableSideRightInstance.destroy();\n }\n\n let columnScrollTimer: any = null;\n\n const scrollColumnsRight = () => this._viewportScrollContainerX.scrollLeft = this._viewportScrollContainerX.scrollLeft + 10;\n const scrollColumnsLeft = () => this._viewportScrollContainerX.scrollLeft = this._viewportScrollContainerX.scrollLeft - 10;\n\n let canDragScroll;\n const sortableOptions = {\n animation: 50,\n direction: 'horizontal',\n chosenClass: 'slick-header-column-active',\n ghostClass: 'slick-sortable-placeholder',\n draggable: '.slick-header-column',\n dragoverBubble: false,\n revertClone: true,\n scroll: !this.hasFrozenColumns(), // enable auto-scroll\n onStart: (e: { item: any; originalEvent: MouseEvent; }) => {\n canDragScroll = !this.hasFrozenColumns() ||\n Utils.offset(e.item)!.left > Utils.offset(this._viewportScrollContainerX)!.left;\n\n if (canDragScroll && e.originalEvent.pageX > this._container.clientWidth) {\n if (!(columnScrollTimer)) {\n columnScrollTimer = setInterval(scrollColumnsRight, 100);\n }\n } else if (canDragScroll && e.originalEvent.pageX < Utils.offset(this._viewportScrollContainerX)!.left) {\n if (!(columnScrollTimer)) {\n columnScrollTimer = setInterval(scrollColumnsLeft, 100);\n }\n } else {\n clearInterval(columnScrollTimer);\n columnScrollTimer = null;\n }\n },\n onEnd: (e: MouseEvent & { item: any; originalEvent: MouseEvent; }) => {\n const cancel = false;\n clearInterval(columnScrollTimer);\n columnScrollTimer = null;\n let limit;\n\n if (cancel || !this.getEditorLock()?.commitCurrentEdit()) {\n return;\n }\n\n let reorderedIds = this.sortableSideLeftInstance?.toArray();\n reorderedIds = reorderedIds.concat(this.sortableSideRightInstance?.toArray());\n\n const reorderedColumns: C[] = [];\n for (let i = 0; i < reorderedIds.length; i++) {\n reorderedColumns.push(this.columns[this.getColumnIndex(reorderedIds[i])]);\n }\n this.setColumns(reorderedColumns);\n\n this.trigger(this.onColumnsReordered, { impactedColumns: this.getImpactedColumns(limit) });\n e.stopPropagation();\n this.setupColumnResize();\n if (this.activeCellNode) {\n this.setFocus(); // refocus on active cell\n }\n }\n };\n\n this.sortableSideLeftInstance = Sortable.create(this._headerL, sortableOptions);\n this.sortableSideRightInstance = Sortable.create(this._headerR, sortableOptions);\n }\n\n protected getHeaderChildren() {\n const a = Array.from(this._headers[0].children);\n const b = Array.from(this._headers[1].children);\n return a.concat(b) as HTMLElement[];\n }\n\n protected getImpactedColumns(limit?: { start: number; end: number; }) {\n let impactedColumns: C[] = [];\n\n if (limit) {\n for (let i = limit.start; i <= limit.end; i++) {\n impactedColumns.push(this.columns[i]);\n }\n } else {\n impactedColumns = this.columns;\n }\n\n return impactedColumns;\n }\n\n protected handleResizeableHandleDoubleClick(evt: MouseEvent & { target: HTMLDivElement; }) {\n const triggeredByColumn = evt.target.parentElement!.id.replace(this.uid, '');\n this.trigger(this.onColumnsResizeDblClick, { triggeredByColumn: triggeredByColumn });\n }\n\n protected setupColumnResize() {\n if (typeof Resizable === 'undefined') {\n throw new Error(`Slick.Resizable is undefined, make sure to import \"slick.interactions.js\"`);\n }\n\n let j: number, k: number, c: C, pageX: number, minPageX: number, maxPageX: number, firstResizable: number | undefined, lastResizable = -1;\n let frozenLeftColMaxWidth = 0;\n\n const children: HTMLElement[] = this.getHeaderChildren();\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const handles = child.querySelectorAll('.slick-resizable-handle');\n handles.forEach((handle) => handle.remove());\n\n if (i >= this.columns.length || !this.columns[i] || this.columns[i].hidden) {\n continue;\n }\n\n if (this.columns[i].resizable) {\n if (firstResizable === undefined) {\n firstResizable = i;\n }\n lastResizable = i;\n }\n }\n\n if (firstResizable === undefined) {\n return;\n }\n\n for (let i = 0; i < children.length; i++) {\n const colElm = children[i];\n\n if (i >= this.columns.length || !this.columns[i] || this.columns[i].hidden) {\n continue;\n }\n if (i < firstResizable || (this._options.forceFitColumns && i >= lastResizable)) {\n continue;\n }\n\n const resizeableHandle = Utils.createDomElement('div', { className: 'slick-resizable-handle', role: 'separator', ariaOrientation: 'horizontal' }, colElm);\n this._bindingEventService.bind(resizeableHandle, 'dblclick', this.handleResizeableHandleDoubleClick.bind(this) as EventListener);\n\n this.slickResizableInstances.push(\n Resizable({\n resizeableElement: colElm as HTMLElement,\n resizeableHandleElement: resizeableHandle,\n onResizeStart: (e: DOMMouseOrTouchEvent, resizeElms: { resizeableElement: HTMLElement; }): boolean | void => {\n const targetEvent = e.touches ? e.touches[0] : e;\n if (!this.getEditorLock()?.commitCurrentEdit()) {\n return false;\n }\n pageX = targetEvent.pageX;\n frozenLeftColMaxWidth = 0;\n resizeElms.resizeableElement.classList.add('slick-header-column-active');\n let shrinkLeewayOnRight: number | null = null;\n let stretchLeewayOnRight: number | null = null;\n // lock each column's width option to current width\n for (let pw = 0; pw < children.length; pw++) {\n if (pw >= this.columns.length || !this.columns[pw] || this.columns[pw].hidden) {\n continue;\n }\n this.columns[pw].previousWidth = children[pw].offsetWidth;\n }\n if (this._options.forceFitColumns) {\n shrinkLeewayOnRight = 0;\n stretchLeewayOnRight = 0;\n // colums on right affect maxPageX/minPageX\n for (j = i + 1; j < this.columns.length; j++) {\n c = this.columns[j];\n if (c && c.resizable && !c.hidden) {\n if (stretchLeewayOnRight !== null) {\n if (c.maxWidth) {\n stretchLeewayOnRight += c.maxWidth - (c.previousWidth || 0);\n } else {\n stretchLeewayOnRight = null;\n }\n }\n shrinkLeewayOnRight += (c.previousWidth || 0) - Math.max(c.minWidth || 0, this.absoluteColumnMinWidth);\n }\n }\n }\n let shrinkLeewayOnLeft = 0;\n let stretchLeewayOnLeft: number | null = 0;\n for (j = 0; j <= i; j++) {\n // columns on left only affect minPageX\n c = this.columns[j];\n if (c && c.resizable && !c.hidden) {\n if (stretchLeewayOnLeft !== null) {\n if (c.maxWidth) {\n stretchLeewayOnLeft += c.maxWidth - (c.previousWidth || 0);\n } else {\n stretchLeewayOnLeft = null;\n }\n }\n shrinkLeewayOnLeft += (c.previousWidth || 0) - Math.max(c.minWidth || 0, this.absoluteColumnMinWidth);\n }\n }\n if (shrinkLeewayOnRight === null) {\n shrinkLeewayOnRight = 100000;\n }\n if (shrinkLeewayOnLeft === null) {\n shrinkLeewayOnLeft = 100000;\n }\n if (stretchLeewayOnRight === null) {\n stretchLeewayOnRight = 100000;\n }\n if (stretchLeewayOnLeft === null) {\n stretchLeewayOnLeft = 100000;\n }\n maxPageX = pageX + Math.min(shrinkLeewayOnRight, stretchLeewayOnLeft);\n minPageX = pageX - Math.min(shrinkLeewayOnLeft, stretchLeewayOnRight);\n },\n onResize: (e: DOMMouseOrTouchEvent, resizeElms: { resizeableElement: HTMLElement; resizeableHandleElement: HTMLElement; }) => {\n const targetEvent = e.touches ? e.touches[0] : e;\n this.columnResizeDragging = true;\n let actualMinWidth;\n const d = Math.min(maxPageX, Math.max(minPageX, targetEvent.pageX)) - pageX\n let x;\n let newCanvasWidthL = 0, newCanvasWidthR = 0;\n const viewportWidth = this.viewportHasVScroll ? this.viewportW - (this.scrollbarDimensions?.width ?? 0) : this.viewportW;\n\n if (d < 0) { // shrink column\n x = d;\n\n for (j = i; j >= 0; j--) {\n c = this.columns[j];\n if (c && c.resizable && !c.hidden) {\n actualMinWidth = Math.max(c.minWidth || 0, this.absoluteColumnMinWidth);\n if (x && (c.previousWidth || 0) + x < actualMinWidth) {\n x += (c.previousWidth || 0) - actualMinWidth;\n c.width = actualMinWidth;\n } else {\n c.width = (c.previousWidth || 0) + x;\n x = 0;\n }\n }\n }\n\n for (k = 0; k <= i; k++) {\n c = this.columns[k];\n if (!c || c.hidden) { continue; }\n\n if (this.hasFrozenColumns() && (k > this._options.frozenColumn!)) {\n newCanvasWidthR += c.width || 0;\n } else {\n newCanvasWidthL += c.width || 0;\n }\n }\n\n if (this._options.forceFitColumns) {\n x = -d;\n for (j = i + 1; j < this.columns.length; j++) {\n c = this.columns[j];\n if (!c || c.hidden) { continue; }\n if (c.resizable) {\n if (x && c.maxWidth && (c.maxWidth - (c.previousWidth || 0) < x)) {\n x -= c.maxWidth - (c.previousWidth || 0);\n c.width = c.maxWidth;\n } else {\n c.width = (c.previousWidth || 0) + x;\n x = 0;\n }\n\n if (this.hasFrozenColumns() && (j > this._options.frozenColumn!)) {\n newCanvasWidthR += c.width || 0;\n } else {\n newCanvasWidthL += c.width || 0;\n }\n }\n }\n } else {\n for (j = i + 1; j < this.columns.length; j++) {\n c = this.columns[j];\n if (!c || c.hidden) { continue; }\n\n if (this.hasFrozenColumns() && (j > this._options.frozenColumn!)) {\n newCanvasWidthR += c.width || 0;\n } else {\n newCanvasWidthL += c.width || 0;\n }\n }\n }\n\n if (this._options.forceFitColumns) {\n x = -d;\n for (j = i + 1; j < this.columns.length; j++) {\n c = this.columns[j];\n if (!c || c.hidden) { continue; }\n if (c.resizable) {\n if (x && c.maxWidth && (c.maxWidth - (c.previousWidth || 0) < x)) {\n x -= c.maxWidth - (c.previousWidth || 0);\n c.width = c.maxWidth;\n } else {\n c.width = (c.previousWidth || 0) + x;\n x = 0;\n }\n }\n }\n }\n } else { // stretch column\n x = d;\n\n newCanvasWidthL = 0;\n newCanvasWidthR = 0;\n\n for (j = i; j >= 0; j--) {\n c = this.columns[j];\n if (!c || c.hidden) { continue; }\n if (c.resizable) {\n if (x && c.maxWidth && (c.maxWidth - (c.previousWidth || 0) < x)) {\n x -= c.maxWidth - (c.previousWidth || 0);\n c.width = c.maxWidth;\n } else {\n const newWidth = (c.previousWidth || 0) + x;\n const resizedCanvasWidthL = this.canvasWidthL + x;\n\n if (this.hasFrozenColumns() && (j <= this._options.frozenColumn!)) {\n // if we're on the left frozen side, we need to make sure that our left section width never goes over the total viewport width\n if (newWidth > frozenLeftColMaxWidth && resizedCanvasWidthL < (viewportWidth - this._options.frozenRightViewportMinWidth!)) {\n frozenLeftColMaxWidth = newWidth; // keep max column width ref, if we go over the limit this number will stop increasing\n }\n c.width = ((resizedCanvasWidthL + this._options.frozenRightViewportMinWidth!) > viewportWidth) ? frozenLeftColMaxWidth : newWidth;\n } else {\n c.width = newWidth;\n }\n x = 0;\n }\n }\n }\n\n for (k = 0; k <= i; k++) {\n c = this.columns[k];\n if (!c || c.hidden) { continue; }\n\n if (this.hasFrozenColumns() && (k > this._options.frozenColumn!)) {\n newCanvasWidthR += c.width || 0;\n } else {\n newCanvasWidthL += c.width || 0;\n }\n }\n\n if (this._options.forceFitColumns) {\n x = -d;\n for (j = i + 1; j < this.columns.length; j++) {\n c = this.columns[j];\n if (!c || c.hidden) { continue; }\n if (c.resizable) {\n actualMinWidth = Math.max(c.minWidth || 0, this.absoluteColumnMinWidth);\n if (x && (c.previousWidth || 0) + x < actualMinWidth) {\n x += (c.previousWidth || 0) - actualMinWidth;\n c.width = actualMinWidth;\n } else {\n c.width = (c.previousWidth || 0) + x;\n x = 0;\n }\n\n if (this.hasFrozenColumns() && (j > this._options.frozenColumn!)) {\n newCanvasWidthR += c.width || 0;\n } else {\n newCanvasWidthL += c.width || 0;\n }\n }\n }\n } else {\n for (j = i + 1; j < this.columns.length; j++) {\n c = this.columns[j];\n if (!c || c.hidden) { continue; }\n\n if (this.hasFrozenColumns() && (j > this._options.frozenColumn!)) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n newCanvasWidthR += c.width || 0;\n } else {\n newCanvasWidthL += c.width || 0;\n }\n }\n }\n }\n\n if (this.hasFrozenColumns() && newCanvasWidthL !== this.canvasWidthL) {\n Utils.width(this._headerL, newCanvasWidthL + 1000);\n Utils.setStyleSize(this._paneHeaderR, 'left', newCanvasWidthL);\n }\n\n this.applyColumnHeaderWidths();\n if (this._options.syncColumnCellResize) {\n this.applyColumnWidths();\n }\n this.trigger(this.onColumnsDrag, {\n triggeredByColumn: resizeElms.resizeableElement,\n resizeHandle: resizeElms.resizeableHandleElement\n });\n },\n onResizeEnd: (_e: Event, resizeElms: { resizeableElement: HTMLElement; }) => {\n resizeElms.resizeableElement.classList.remove('slick-header-column-active');\n\n const triggeredByColumn = resizeElms.resizeableElement.id.replace(this.uid, '');\n if (this.trigger(this.onBeforeColumnsResize, { triggeredByColumn: triggeredByColumn }).getReturnValue() === true) {\n this.applyColumnHeaderWidths();\n }\n let newWidth;\n for (j = 0; j < this.columns.length; j++) {\n c = this.columns[j];\n if (!c || c.hidden) { continue; }\n newWidth = children[j].offsetWidth;\n\n if (c.previousWidth !== newWidth && c.rerenderOnResize) {\n this.invalidateAllRows();\n }\n }\n this.updateCanvasWidth(true);\n this.render();\n this.trigger(this.onColumnsResized, { triggeredByColumn: triggeredByColumn });\n setTimeout(() => { this.columnResizeDragging = false; }, 300);\n }\n })\n );\n }\n }\n\n protected getVBoxDelta(el: HTMLElement) {\n const p = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\n const styles = getComputedStyle(el);\n let delta = 0;\n p.forEach((val) => delta += Utils.toFloat(styles[val as any]));\n return delta;\n }\n\n protected setFrozenOptions() {\n this._options.frozenColumn = (this._options.frozenColumn! >= 0 && this._options.frozenColumn! < this.columns.length)\n ? parseInt(this._options.frozenColumn as unknown as string)\n : -1;\n\n if (this._options.frozenRow! > -1) {\n this.hasFrozenRows = true;\n this.frozenRowsHeight = (this._options.frozenRow!) * this._options.rowHeight!;\n const dataLength = this.getDataLength();\n\n this.actualFrozenRow = (this._options.frozenBottom)\n ? (dataLength - this._options.frozenRow!)\n : this._options.frozenRow!;\n } else {\n this.hasFrozenRows = false;\n }\n }\n\n protected setPaneVisibility() {\n if (this.hasFrozenColumns()) {\n Utils.show(this._paneHeaderR);\n Utils.show(this._paneTopR);\n\n if (this.hasFrozenRows) {\n Utils.show(this._paneBottomL);\n Utils.show(this._paneBottomR);\n } else {\n Utils.hide(this._paneBottomR);\n Utils.hide(this._paneBottomL);\n }\n } else {\n Utils.hide(this._paneHeaderR);\n Utils.hide(this._paneTopR);\n Utils.hide(this._paneBottomR);\n\n if (this.hasFrozenRows) {\n Utils.show(this._paneBottomL);\n } else {\n Utils.hide(this._paneBottomR);\n Utils.hide(this._paneBottomL);\n }\n }\n }\n\n protected setOverflow() {\n this._viewportTopL.style.overflowX = (this.hasFrozenColumns()) ? (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'hidden' : 'scroll') : (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'hidden' : 'auto');\n this._viewportTopL.style.overflowY = (!this.hasFrozenColumns() && this._options.alwaysShowVerticalScroll) ? 'scroll' : ((this.hasFrozenColumns()) ? (this.hasFrozenRows ? 'hidden' : 'hidden') : (this.hasFrozenRows ? 'scroll' : 'auto'));\n\n this._viewportTopR.style.overflowX = (this.hasFrozenColumns()) ? (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'hidden' : 'scroll') : (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'hidden' : 'auto');\n this._viewportTopR.style.overflowY = this._options.alwaysShowVerticalScroll ? 'scroll' : ((this.hasFrozenColumns()) ? (this.hasFrozenRows ? 'scroll' : 'auto') : (this.hasFrozenRows ? 'scroll' : 'auto'));\n\n this._viewportBottomL.style.overflowX = (this.hasFrozenColumns()) ? (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'scroll' : 'auto') : (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'auto' : 'auto');\n this._viewportBottomL.style.overflowY = (!this.hasFrozenColumns() && this._options.alwaysShowVerticalScroll) ? 'scroll' : ((this.hasFrozenColumns()) ? (this.hasFrozenRows ? 'hidden' : 'hidden') : (this.hasFrozenRows ? 'scroll' : 'auto'));\n\n this._viewportBottomR.style.overflowX = (this.hasFrozenColumns()) ? (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'scroll' : 'auto') : (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'auto' : 'auto');\n this._viewportBottomR.style.overflowY = this._options.alwaysShowVerticalScroll ? 'scroll' : ((this.hasFrozenColumns()) ? (this.hasFrozenRows ? 'auto' : 'auto') : (this.hasFrozenRows ? 'auto' : 'auto'));\n\n if (this._options.viewportClass) {\n this._viewportTopL.classList.add(...this._options.viewportClass.split(' '));\n this._viewportTopR.classList.add(...this._options.viewportClass.split(' '));\n this._viewportBottomL.classList.add(...this._options.viewportClass.split(' '));\n this._viewportBottomR.classList.add(...this._options.viewportClass.split(' '));\n }\n }\n\n protected setScroller() {\n if (this.hasFrozenColumns()) {\n this._headerScrollContainer = this._headerScrollerR;\n this._headerRowScrollContainer = this._headerRowScrollerR;\n this._footerRowScrollContainer = this._footerRowScrollerR;\n\n if (this.hasFrozenRows) {\n if (this._options.frozenBottom) {\n this._viewportScrollContainerX = this._viewportBottomR;\n this._viewportScrollContainerY = this._viewportTopR;\n } else {\n this._viewportScrollContainerX = this._viewportScrollContainerY = this._viewportBottomR;\n }\n } else {\n this._viewportScrollContainerX = this._viewportScrollContainerY = this._viewportTopR;\n }\n } else {\n this._headerScrollContainer = this._headerScrollerL;\n this._headerRowScrollContainer = this._headerRowScrollerL;\n this._footerRowScrollContainer = this._footerRowScrollerL;\n\n if (this.hasFrozenRows) {\n if (this._options.frozenBottom) {\n this._viewportScrollContainerX = this._viewportBottomL;\n this._viewportScrollContainerY = this._viewportTopL;\n } else {\n this._viewportScrollContainerX = this._viewportScrollContainerY = this._viewportBottomL;\n }\n } else {\n this._viewportScrollContainerX = this._viewportScrollContainerY = this._viewportTopL;\n }\n }\n }\n\n protected measureCellPaddingAndBorder() {\n const h = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];\n const v = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\n const header = this._headers[0];\n\n this.headerColumnWidthDiff = this.headerColumnHeightDiff = 0;\n this.cellWidthDiff = this.cellHeightDiff = 0;\n\n let el = Utils.createDomElement('div', { className: 'ui-state-default slick-state-default slick-header-column', style: { visibility: 'hidden' }, textContent: '-' }, header);\n let style = getComputedStyle(el);\n if (style.boxSizing !== 'border-box') {\n h.forEach((val) => this.headerColumnWidthDiff += Utils.toFloat(style[val as any]));\n v.forEach((val) => this.headerColumnHeightDiff += Utils.toFloat(style[val as any]));\n }\n el.remove();\n\n const r = Utils.createDomElement('div', { className: 'slick-row' }, this._canvas[0]);\n el = Utils.createDomElement('div', { className: 'slick-cell', id: '', style: { visibility: 'hidden' }, textContent: '-' }, r);\n style = getComputedStyle(el);\n if (style.boxSizing !== 'border-box') {\n h.forEach((val) => this.cellWidthDiff += Utils.toFloat(style[val as any]));\n v.forEach((val) => this.cellHeightDiff += Utils.toFloat(style[val as any]));\n }\n r.remove();\n\n this.absoluteColumnMinWidth = Math.max(this.headerColumnWidthDiff, this.cellWidthDiff);\n }\n\n protected createCssRules() {\n const template = Utils.createDomElement('template', { innerHTML: '