@danielgindi/dgtable.js 2.0.7 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +547 -282
- package/dist/SelectionHelper.d.ts +24 -0
- package/dist/SelectionHelper.d.ts.map +1 -0
- package/dist/by_column_filter.d.ts +14 -0
- package/dist/by_column_filter.d.ts.map +1 -0
- package/dist/cell_preview.d.ts +28 -0
- package/dist/cell_preview.d.ts.map +1 -0
- package/dist/column_collection.d.ts +41 -0
- package/dist/column_collection.d.ts.map +1 -0
- package/dist/column_resize.d.ts +25 -0
- package/dist/column_resize.d.ts.map +1 -0
- package/dist/constants.d.ts +19 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/header_events.d.ts +63 -0
- package/dist/header_events.d.ts.map +1 -0
- package/dist/helpers.d.ts +50 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/index.d.ts +166 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/internal.d.ts +56 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/lib.cjs.js +6909 -3929
- package/dist/lib.cjs.js.map +1 -1
- package/dist/lib.cjs.min.js +2 -2
- package/dist/lib.cjs.min.js.map +1 -1
- package/dist/lib.es6.js +6911 -3931
- package/dist/lib.es6.js.map +1 -1
- package/dist/lib.es6.min.js +2 -2
- package/dist/lib.es6.min.js.map +1 -1
- package/dist/lib.umd.js +9251 -4346
- package/dist/lib.umd.js.map +1 -1
- package/dist/lib.umd.min.js +2 -2
- package/dist/lib.umd.min.js.map +1 -1
- package/dist/private_types.d.ts +145 -0
- package/dist/private_types.d.ts.map +1 -0
- package/dist/rendering.d.ts +57 -0
- package/dist/rendering.d.ts.map +1 -0
- package/dist/row_collection.d.ts +38 -0
- package/dist/row_collection.d.ts.map +1 -0
- package/dist/types.d.ts +221 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/util.d.ts +9 -0
- package/dist/util.d.ts.map +1 -0
- package/eslint.config.mjs +1 -0
- package/package.json +17 -12
- package/src/SelectionHelper.ts +90 -0
- package/src/by_column_filter.ts +36 -0
- package/src/cell_preview.ts +325 -0
- package/src/column_collection.ts +131 -0
- package/src/column_resize.ts +363 -0
- package/src/constants.ts +22 -0
- package/src/header_events.ts +369 -0
- package/src/helpers.ts +291 -0
- package/src/index.ts +1628 -0
- package/src/internal.ts +263 -0
- package/src/private_types.ts +156 -0
- package/src/rendering.ts +771 -0
- package/src/row_collection.ts +197 -0
- package/src/types.ts +265 -0
- package/src/util.ts +27 -0
- package/tsconfig.json +38 -0
- package/src/SelectionHelper.js +0 -65
- package/src/by_column_filter.js +0 -25
- package/src/column_collection.js +0 -153
- package/src/index.js +0 -3991
- package/src/row_collection.js +0 -183
- package/src/util.js +0 -17
package/README.md
CHANGED
|
@@ -1,288 +1,553 @@
|
|
|
1
|
-
DGTable.js
|
|
2
|
-
==========
|
|
3
|
-
|
|
4
|
-
This is a table View for vanilla JS, which is meant to be high-performance, and allow simple user interactions with the UI, such as:
|
|
5
|
-
* Sorting
|
|
6
|
-
* Sorting by more than one column
|
|
7
|
-
* Moving columns
|
|
8
|
-
* Resizing columns
|
|
9
|
-
* Full cell preview when hovering
|
|
10
|
-
* Native RTL support
|
|
11
|
-
* Variable row height
|
|
12
|
-
|
|
13
|
-
Other features implemented are:
|
|
14
|
-
* Mix absolute column widths with relative column widths
|
|
15
|
-
* Virtual table mode (to supply high performance with hundreds of thousands of rows). This is the default.
|
|
16
|
-
* Non-virtual table mode is fully supported, but for giant amounts of data it is not recommended.
|
|
17
|
-
* Option to set a fixed width for the table so resizing (relative) columns will still make sure the table will not be less (and/or more) than the specified width.
|
|
18
|
-
* Option to have both scrollbars inside the table. (set `width: DGTable.Width.SCROLL`)
|
|
19
|
-
|
|
20
|
-
`jquery.dgtable` users:
|
|
21
|
-
* Older `jquery.dgtable` can either keep using `jquery.dgtable`, or migrate to this new version which is more lightweight.
|
|
22
|
-
* The new version's API is the same as the old one, except that:
|
|
23
|
-
* No `$el` property
|
|
24
|
-
* No auto-clear of jQuery data.
|
|
25
|
-
* There is now an `emit` method instead of `trigger`.
|
|
26
|
-
* Event arguments are now always a single value/object.
|
|
27
|
-
* Props on DOM elements are now: `'columnName'` on a cell, `'index'/'vIndex'` on a row, `'columnName'/rowIndex'/'rowVIndex'` on a cellPreview
|
|
28
|
-
|
|
29
|
-
My TODO list:
|
|
30
|
-
* TODO: Have a simple and accurate API documentation here in the readme
|
|
31
|
-
|
|
32
|
-
## Dev environment
|
|
33
|
-
|
|
34
|
-
* Using grunt over Node.js to automate validating and building.
|
|
35
|
-
* After installing Node.js, use `npm install`, and `npm install -g grunt-cli` to prepare building environment.
|
|
36
|
-
* Use `grunt style` to just test for correct styling.
|
|
37
|
-
* Use `grunt build` or just `grunt` to compile for release.
|
|
38
|
-
* I am using Google Closure Compiler, because UglifyJS does not work with the JSDoc, and there's a major difference in size & performance of the output code.
|
|
39
|
-
* Some features of jshint are disabled because it does not work well with JSDoc which is used for Google Closue Compiler.
|
|
40
|
-
* Indentations in my editor are set to 4 spaces, and jshint validates that.
|
|
41
|
-
|
|
42
|
-
## Me
|
|
43
|
-
* Hi! I am Daniel Cohen Gindi. Or in short- Daniel.
|
|
44
|
-
* danielgindi@gmail.com is my email address.
|
|
45
|
-
* That's all you need to know.
|
|
46
|
-
|
|
47
|
-
## Help
|
|
48
|
-
|
|
49
|
-
I have invested, and investing, a lot of time in this project.
|
|
50
|
-
If you want to help, you could:
|
|
51
|
-
* Actually code, and issue pull requests
|
|
52
|
-
* Test the library under different conditions and browsers
|
|
53
|
-
* Create more demo pages
|
|
54
|
-
* Spread the word
|
|
55
|
-
*
|
|
56
|
-
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=G22LPLJ79NBYQ)
|
|
57
|
-
|
|
58
|
-
## API
|
|
59
|
-
|
|
60
|
-
To create a new table, just use `var myTable = new DGTable(INIT_OPTIONS)`.
|
|
61
|
-
|
|
62
|
-
#### `INIT_OPTIONS`
|
|
63
|
-
|
|
64
|
-
* **columns**: `COLUMN_OPTIONS[]` (Array of COLUMN_OPTIONS objects)
|
|
65
|
-
* **name**: `string` Name of the column
|
|
66
|
-
* **label**: `string=name` Used for the header of this column
|
|
67
|
-
* **dataPath**: `string=name` Path to the data to show (Defaults to `name`)
|
|
68
|
-
* **comparePath**: `string=name` Path to the data to use for comparison (Defaults to `dataPath`)
|
|
69
|
-
* **width**: `number|string`
|
|
70
|
-
* A simple number (i.e `10`, `30`, `50`) will set an absolute width for the column.
|
|
71
|
-
* A percentage (i.e `'30%'`) or a 0-1 decimal value (i.e `0.2`, `0.7`) will set a relative width for the column, out of the full table's width.
|
|
72
|
-
* Any other value, like `0`, `null` etc. will set an automatic width mode, base of the header's content length.
|
|
73
|
-
* **resizable**: `boolean=true` Is this column resizable?
|
|
74
|
-
* **sortable**: `boolean=true` Is this column sortable?
|
|
75
|
-
* **movable**: `boolean=true` Is this column movable?
|
|
76
|
-
* **visible**: `boolean=true` Is this column visible?
|
|
77
|
-
* **cellClasses**: `string` Classes to add to the DOM element of this cell
|
|
78
|
-
* **ignoreMin**: `boolean=false` Should this column ignore the minimum width specified for the table columns?
|
|
79
|
-
* **height**: `number` Suggested height for the table
|
|
80
|
-
* **width**: `DGTable.Width=DGTable.Width.NONE` The way that the width of the table will be handled
|
|
81
|
-
* `DGTable.Width.NONE`: No special handling
|
|
82
|
-
* `DGTable.Width.AUTO`: Sets the width automatically
|
|
83
|
-
* `DGTable.Width.SCROLL`: Creates a horizontal scroll when required
|
|
84
|
-
* **virtualTable**: `boolean=true` When set, the table will work in virtual mode, which means only the visible rows are rendered. Rows must have fixed height in this mode.
|
|
85
|
-
* **estimatedRowHeight**: `number?` Sets the estimated row height for the table. This is used for virtual table mode, to calculate the estimated scroll size. Will be auto calculated by default.
|
|
86
|
-
* **resizableColumns**: `boolean=true` Turns on or off the resizable columns globally.
|
|
87
|
-
* **movableColumns**: `boolean=true` Turns on or off the movable columns globally.
|
|
88
|
-
* **sortableColumns**: `number=1` How many columns can you sort by, one after another?
|
|
89
|
-
* **adjustColumnWidthForSortArrow**: `boolean=true` When set, the columns will automatically grow to accommodate for the sort arrow.
|
|
90
|
-
* **relativeWidthGrowsToFillWidth**: `boolean=true` When set, relative width columns automatically grow to fill the table's width.
|
|
91
|
-
* **relativeWidthShrinksToFillWidth**: `boolean=false` When set, relative width columns automatically shrink to fill the table's width.
|
|
92
|
-
* **convertColumnWidthsToRelative**: `boolean=false` When set, auto-width columns are automatically converted to relatives.
|
|
93
|
-
* **autoFillTableWidth**: `boolean=false` When set, columns are stretched proportionally to fill the table width (only if there is space left). Will supersede `relativeWidthGrowsToFillWidth` in the future.
|
|
94
|
-
* **allowCancelSort**: `boolean=true` When set, the sorting arrows will have 3 modes - asc, desc, and cancelled.
|
|
95
|
-
* **cellClasses**: `string` Classes to add to the DOM element of all cells
|
|
96
|
-
* **sortColumn**: `string|string[]|COLUMN_SORT_OPTIONS|COLUMN_SORT_OPTIONS[]` Columns to sort by
|
|
97
|
-
* Can be a column or an array of columns.
|
|
98
|
-
* Each column is a `string` or a `COLUMN_SORT_OPTIONS`:
|
|
99
|
-
* **column**: `string` Column name
|
|
100
|
-
* **descending**: `boolean=false` Is this column sorted in descending order?
|
|
101
|
-
* **cellFormatter**: `Function(string value, string columnName, Object rowData)string` *(optional)* A formatter function which will return the HTML for the cell. By default the formatter is a plain HTML formatter.
|
|
102
|
-
* **headerCellFormatter**: `Function(string value, string columnName)string` *(optional)* A formatter function which will return the HTML for the cell's header. By default the formatter is a plain HTML formatter.
|
|
103
|
-
* **rowsBufferSize**: `number=10` The size of the rows buffer, for virtual table
|
|
104
|
-
* **minColumnWidth**: `number=35` In pixels, the minimum width for a column
|
|
105
|
-
* **resizeAreaWidth**: `number=8` The size of the area where you can drag to resize.
|
|
106
|
-
* **onComparatorRequired**: `function(columnName: string, descending: boolean, defaultComparator: function(a,b):number):{function(a,b):number}` A callback that can pass a comparator function for each column and mode as required.
|
|
107
|
-
* **resizerClassName**: `string='dgtable-resize'` Class name for the dragged resizing element (showing when resizing a column)
|
|
108
|
-
* **tableClassName**: `string='dgtable'` Class name for the table
|
|
109
|
-
* **allowCellPreview**: `boolean=true` When set, hovering on truncated cells will show a preview of the full content.
|
|
110
|
-
* **allowHeaderCellPreview**: `boolean=true` Allow for toggling off **allowCellPreview** for headers specifically.
|
|
111
|
-
* **cellPreviewAutoBackground**: `boolean=true` When set, the preview cell will receive its background automatically from the cell.
|
|
112
|
-
* **cellPreviewClassName**: `string='dgtable-cell-preview'` Class name for the cell preview element
|
|
113
|
-
* **className**: `string='dgtable-wrapper'` Element class name.
|
|
114
|
-
* **el**: `Element?` Optional element to take over
|
|
115
|
-
* **filter**: `Function(row: Object, args: Object): boolean` *(optional)* A filter function for using with the `filter` method
|
|
116
|
-
|
|
117
|
-
#### Events triggered by DGTable:
|
|
118
|
-
|
|
119
|
-
* `renderskeleton`: The table is re-drawing it's base elements, including headers. Will always be followed by a `render` event.
|
|
120
|
-
* `render`: The table has finished rendering (after adding rows etc.).
|
|
121
|
-
* `cellpreview`: We are about to show a cell preview - `{ el: Element, rowIndex: number|null, name: string, rowData: Object|null, cell: Element, cellEl: Element }`
|
|
122
|
-
* At this stage you can prevent showing the preview, by calling `table.hideCellPreview`
|
|
123
|
-
* `cellpreviewdestroy`: Cell preview element is about to be destroyed after hiding - `{ el: Element, name: string, filteredRowIndex: number|null, rowIndex: Object|null, cell: Element, cellEl: Element }`
|
|
124
|
-
* You can use this event to release any resources that you may have used in `cellPreview` event.
|
|
125
|
-
* `headerrowcreate`: The header row has just been created - `Element`
|
|
126
|
-
* `headerrowdestroy`: Called just before removing the header row DOM element from the table - `Element`
|
|
127
|
-
* `rowcreate`: A row has just been created - `{ filteredRowIndex: number, rowIndex: number, rowEl: Element, rowData: Object }`
|
|
128
|
-
* `rowclick`: A row has just been created - `{ event: MouseEvent, rowIndex: number, rowIndex: number, rowEl: Element, rowData: Object }`
|
|
129
|
-
* `rowdestroy`: Called just before removing a row DOM element from the table - `Element`
|
|
130
|
-
* `addrows`: Data rows have been added to the table - `({ count: number, clear: boolean })`
|
|
131
|
-
* `addcolumn`: A column was added - `string` (the column's name)
|
|
132
|
-
* `removecolumn`: A column was removed - `string` (the column's name)
|
|
133
|
-
* `movecolumn`: A column was moved - `({ name: string, src: number, dest: number })`
|
|
134
|
-
* `showcolumn`: A column was shown - `string` (the column's name)
|
|
135
|
-
* `hidecolumn`: A column was hidden - `string` (the column's name)
|
|
136
|
-
* `columnwidth`: A column was resized - `({ name: string, width: number|string, oldWidth: number|string })`
|
|
137
|
-
* `filter`: A filter was applied - `any` - the arguments passed to the filter method
|
|
138
|
-
* `filterclear`: A filter was cleared
|
|
139
|
-
* `sort`: The data was sorted - `{ sorts: { "column": "column's name", "descending": true|false }[], resort: true|undefined, comparator: Function }`
|
|
140
|
-
* `headercontextmenu`: A context menu should be shown for a header cell - `({ columnName: string, pageX: number, pageY: number, bounds: { left: number, top: number, width: number, height: number } })`
|
|
141
|
-
|
|
142
|
-
- Member functions:
|
|
143
|
-
* `on(eventName, {Function?} callback)`: Adds an event listener
|
|
144
|
-
* `once(eventName, {Function?} callback)`: Adds a one-shot event listener
|
|
145
|
-
* `off(eventName, {Function?} callback)`: Removes an event listener
|
|
146
|
-
* `render()`: Renders the view. Should be called after adding to the DOM, and when the viewport has changed and the table has no knowledge of it.
|
|
147
|
-
* `clearAndRender({boolean} render = true)`: Forces a full render of the table
|
|
148
|
-
* `setColumns({COLUMN_OPTIONS[]} columns, {boolean} render = true) {DGTable}`: Sets the table columns
|
|
149
|
-
* `addColumn({COLUMN_OPTIONS} columnData, {string|number} before = -1, {boolean} render = true) {DGTable}`: Add a column to the table
|
|
150
|
-
* **columnData**: Column properties. Same manner as in the **columns** options when initializing the DGTable
|
|
151
|
-
* **before**: Column name or order to be inserted before.
|
|
152
|
-
* *returns* Self, to allow for call chaining.
|
|
153
|
-
* `removeColumn({string} column, {boolean} render = true) {DGTable}`: Remove a column from the table
|
|
154
|
-
* **column**: Column name
|
|
155
|
-
* *returns* Self, to allow for call chaining.
|
|
156
|
-
* `setFilter({Function(row: Object, args: Object): boolean} filterFunc) {DGTable}`: Sets a new filtering function, set null for default.
|
|
157
|
-
* **filterFunc**: The filtering function receives a row and an options object, and returns true for any row that passes the filter.
|
|
158
|
-
* *returns* Self, to allow for call chaining.
|
|
159
|
-
* `setCellFormatter({Function(value: *, columnName: string, row: Object):string|null} formatter) {DGTable}`: Sets a new cell formatter.
|
|
160
|
-
* **formatter**: The cell formatter. Should return an HTML.
|
|
161
|
-
* *returns* Self, to allow for call chaining.
|
|
162
|
-
* `setHeaderCellFormatter({Function(label: string, columnName: string):string|null} formatter) {DGTable}`: Sets a new header cell formatter.
|
|
163
|
-
* **formatter**: The cell formatter. Should return an HTML.
|
|
164
|
-
* *returns* Self, to allow for call chaining.
|
|
165
|
-
* `filter({Object} args) {DGTable}`: Filter the visible rows in the table
|
|
166
|
-
* **args**: Options to pass to the filtering function
|
|
167
|
-
* *returns* Self, to allow for call chaining.
|
|
168
|
-
* `filter({{column: string, keyword: string, caseSensitive: boolean}} args) {DGTable}`: Syntax for default filtering function.
|
|
169
|
-
* **args.column**: Name of the column to filter on
|
|
170
|
-
* **args.keyword**: Tests the specified column if contains this keyword
|
|
171
|
-
* **args.caseSensitive**: Use caseSensitive filtering
|
|
172
|
-
* *returns* Self, to allow for call chaining.
|
|
173
|
-
* `clearFilter() {DGTable}`: Clears the current filter
|
|
174
|
-
* *returns* Self, to allow for call chaining.
|
|
175
|
-
* `setColumnLabel({string} column, {string} label) {DGTable}`: Set a new label to a column
|
|
176
|
-
* **column**: Name of the column
|
|
177
|
-
* **label**: New label for the column
|
|
178
|
-
* *returns* Self, to allow for call chaining.
|
|
179
|
-
* `moveColumn({string|number} src, {string|number} dest, visibleOnly = true) {DGTable}`: Move a column to a new position
|
|
180
|
-
* **src**: Name or position of the column to be moved
|
|
181
|
-
* **dest**: Name of the column currently in the desired position, or the position itself
|
|
182
|
-
* **visibleOnly**: Should consider only visible columns and visible-relative indexes
|
|
183
|
-
* *returns* Self, to allow for call chaining.
|
|
184
|
-
* `sort({string?} column, {boolean?} descending, {boolean=false} add) {DGTable}`: Sort the table. This does not render automatically, so you may need to call render() too.
|
|
185
|
-
* **src**: Name of the column to sort on
|
|
186
|
-
* **descending**: Sort in descending order (if not specified, defaults to false or reverses current descending mode if sorting by same column)
|
|
187
|
-
* **add**: Should this sort be on top of the existing sort? (For multiple column sort)
|
|
188
|
-
* *returns* Self, to allow for call chaining.
|
|
189
|
-
* `resort() {DGTable}`: Re-sort the table using current sort specifiers. This does not render automatically, so you may need to call render() too.
|
|
190
|
-
* *returns* Self, to allow for call chaining.
|
|
191
|
-
* `setColumnVisible({string} column, {boolean} visible) {DGTable}`: Show or hide a column
|
|
192
|
-
* **column**: Unique column name
|
|
193
|
-
* **visible**: New visibility mode for the column
|
|
194
|
-
* *returns* Self, to allow for call chaining.
|
|
195
|
-
* `isColumnVisible({string} column, {boolean} visible) {boolean}`: Get the visibility mode of a column
|
|
196
|
-
* *returns* True if visible
|
|
197
|
-
* `setMinColumnWidth({number} minColumnWidth) {DGTable}`: Globally set the minimum column width
|
|
198
|
-
* **minColumnWidth**: Minimum column width
|
|
199
|
-
* *returns* Self, to allow for call chaining.
|
|
200
|
-
* `getMinColumnWidth() {number}`: Get the current minimum column width
|
|
201
|
-
* *returns* Minimum column width
|
|
202
|
-
* `setSortableColumns({number} sortableColumns) {DGTable}`: Set the limit on concurrent columns sortedh
|
|
203
|
-
* **sortableColumns**: Minimum column width
|
|
204
|
-
* *returns* Self, to allow for call chaining.
|
|
205
|
-
* `getSortableColumns() {number}`: Get the limit on concurrent columns sorted
|
|
206
|
-
* *returns* How many sortable columns are allowed?
|
|
207
|
-
* `getHeaderRowElement() {Element}`: Get the DOM element of the header row
|
|
208
|
-
* *returns* a DOM element
|
|
209
|
-
* `setMovableColumns({boolean} movableColumns) {DGTable}`: *Undocumented yet*
|
|
210
|
-
* `getMovableColumns() {boolean}`: *Undocumented yet*
|
|
211
|
-
* `setResizableColumns({boolean} resizableColumns) {DGTable}`: *Undocumented yet*
|
|
212
|
-
* `getResizableColumns() {boolean}`: *Undocumented yet*
|
|
213
|
-
* `setOnComparatorRequired({function(columnName: string, descending: boolean, defaultComparator: function(a,b):number):{function(a,b):number}}|null comparatorCallback) {DGTable}`: Sets a functions that supplies comparators dynamically
|
|
214
|
-
* **comparatorCallback**: a function that returns the comparator for a specific column
|
|
215
|
-
* `setCustomSortingProvider({{function(data: any[], sort: function(any[]):any[]):any[]}|null} customSortingProvider) {DGTable}`: sets custom sorting function for a data set
|
|
216
|
-
* **customSortingProvider**: provides a custom sorting function (not the comparator, but a sort() alternative) for a data set
|
|
217
|
-
* `setColumnWidth({string} column, {number|string} width) {DGTable}`: *Undocumented yet*
|
|
218
|
-
* `getColumnWidth({string} column) {string|null}`: *Undocumented yet*
|
|
219
|
-
* `getColumnConfig({string} column name) {SERIALIZED_COLUMN}`: *Undocumented yet*
|
|
220
|
-
* `getColumnsConfig() {Object}`: *Undocumented yet*
|
|
221
|
-
* `getSortedColumns() {Array.<SERIALIZED_COLUMN_SORT>}`: *Undocumented yet*
|
|
222
|
-
* `getHtmlForRowCell(row: number, columnName: string) {string}`: Returns the HTML for specified cell in a row.
|
|
223
|
-
* **row**: Index of row
|
|
224
|
-
* **columnName**: Name of cell
|
|
225
|
-
* *returns* HTML for cell. By default cell content is *not* HTML encoded, you should encode appropriately in your `cellFormatter`.
|
|
226
|
-
* `getHtmlForRowDataCell(rowData: Object, columnName: string) {string|null}`: Returns the HTML string for a specific cell. Can be used externally for special cases (i.e. when setting a fresh HTML in the cell preview through the callback).
|
|
227
|
-
* **rowData**: Actual row data
|
|
228
|
-
* **columnName**: Name of column
|
|
229
|
-
* *returns* string for the specified cell
|
|
230
|
-
* `getDataForRow(rowIndex: number): Object`: Gets the row data for a specific row
|
|
231
|
-
* *returns* row data at the specified index, out of all rows (not filtered)
|
|
232
|
-
* `getRowCount(): number`: Gets the number of rows
|
|
233
|
-
* *returns* the number of rows
|
|
234
|
-
* `getIndexForRow(row: Object): number`: Finds the index of the specified row
|
|
235
|
-
* *returns* the index of the specified row
|
|
236
|
-
* `getFilteredRowCount(): number`: Gets the number of filtered rows
|
|
237
|
-
* *returns* the number of rows in the filtered set (defaults to full row count if no filtering is active)
|
|
238
|
-
* `getIndexForFilteredRow(row: Object): number`: Finds the index of the specified row within the filtered results
|
|
239
|
-
* *returns* the index of the specified row
|
|
240
|
-
* `getDataForFilteredRow(row: number): Object`: *Undocumented yet*
|
|
241
|
-
* `getRowElement(rowIndex: number): Element`: Returns the element of the specified row (unfiltered index)
|
|
242
|
-
* `getRowYPos(rowIndex: number): number?`: Returns the Y pos of the specified row (unfiltered index)
|
|
243
|
-
* `tableWidthChanged() {DGTable}`: *Undocumented yet*
|
|
244
|
-
* `tableHeightChanged() {DGTable}`: *Undocumented yet*
|
|
245
|
-
* `addRows({Object[]} data, {number} at = -1, {boolean} resort = false, {boolean} render = true) {DGTable}`: Adds the specified rows at the specified position, and optionally resorts the data
|
|
246
|
-
* `removeRow({number} rowIndex, {boolean} render = true) {DGTable}`: Removes one row at the specified position
|
|
247
|
-
* `removeRows({number} rowIndex, {number} count, {boolean} render = true) {DGTable}`: Removes rows at the specified position
|
|
248
|
-
* `refreshRow({number} rowIndex) {DGTable}`: Refreshes the row specified
|
|
249
|
-
* *returns* Self
|
|
250
|
-
* `refreshAllVirtualRows() {DGTable}`: Refreshes all virtual rows
|
|
251
|
-
* *returns* Self
|
|
252
|
-
* `setRows(data: Object[], resort: boolean=false) {DGTable}`: Rests the table rows to the provided array of rows.
|
|
253
|
-
* **data**: New rows for the table
|
|
254
|
-
* **resort**: Should re-sort the table?
|
|
255
|
-
* *returns* Self, to allow for call chaining.
|
|
256
|
-
* `getUrlForElementContent({string} id) {string?}`: *Undocumented yet*
|
|
257
|
-
* `isWorkerSupported() {boolean}`: *Undocumented yet*
|
|
258
|
-
* `createWebWorker({string} url) {Worker?}`: *Undocumented yet*
|
|
259
|
-
* `unbindWebWorker({Worker} worker) {DGTable}`: *Undocumented yet*
|
|
260
|
-
* `hideCellPreview() {DGTable}`: Hide any cell preview showing currently, or prevent showing a cell preview from within the `cellpreview` event.
|
|
261
|
-
* `destroy()`: Destroy the table and free all of its memory.
|
|
1
|
+
# DGTable.js
|
|
262
2
|
|
|
263
|
-
|
|
3
|
+
A high-performance virtual table component for vanilla JavaScript.
|
|
264
4
|
|
|
265
|
-
|
|
266
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@danielgindi/dgtable)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
267
7
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **High Performance** - Virtual scrolling renders only visible rows, handling hundreds of thousands of rows smoothly
|
|
11
|
+
- **Column Management** - Sort, resize, reorder, and hide/show columns
|
|
12
|
+
- **Multi-column Sorting** - Sort by multiple columns simultaneously
|
|
13
|
+
- **Flexible Column Widths** - Mix absolute, relative, and auto-calculated widths
|
|
14
|
+
- **Cell Preview** - Hover tooltips for truncated cell content
|
|
15
|
+
- **Sticky Columns** - Pin columns to the start or end of the table
|
|
16
|
+
- **RTL Support** - Native right-to-left language support
|
|
17
|
+
- **Variable Row Height** - Support for rows with different heights
|
|
18
|
+
- **Filtering** - Built-in filtering with custom filter function support
|
|
19
|
+
- **Web Worker Support** - Load data asynchronously via Web Workers
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @danielgindi/dgtable
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
import DGTable from '@danielgindi/dgtable';
|
|
31
|
+
|
|
32
|
+
const table = new DGTable({
|
|
33
|
+
columns: [
|
|
34
|
+
{ name: 'id', label: 'ID', width: 80 },
|
|
35
|
+
{ name: 'name', label: 'Name', width: '30%' },
|
|
36
|
+
{ name: 'email', label: 'Email' },
|
|
37
|
+
],
|
|
38
|
+
height: 400,
|
|
39
|
+
virtualTable: true,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
document.getElementById('container').appendChild(table.el);
|
|
43
|
+
|
|
44
|
+
table.setRows([
|
|
45
|
+
{ id: 1, name: 'John Doe', email: 'john@example.com' },
|
|
46
|
+
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' },
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
table.render();
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Migration from jquery.dgtable
|
|
53
|
+
|
|
54
|
+
If you're migrating from the older jQuery version:
|
|
55
|
+
|
|
56
|
+
- No `$el` property - use `table.el` instead
|
|
57
|
+
- No auto-clear of jQuery data
|
|
58
|
+
- Use `emit()` instead of `trigger()` for events
|
|
59
|
+
- Event arguments are now always a single value/object
|
|
60
|
+
- DOM element properties: `'columnName'` on cells, `'index'/'vIndex'` on rows
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## API Reference
|
|
65
|
+
|
|
66
|
+
### Constructor Options
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
new DGTable(options?: DGTableOptions)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### Table Options
|
|
73
|
+
|
|
74
|
+
| Option | Type | Default | Description |
|
|
75
|
+
|--------|------|---------|-------------|
|
|
76
|
+
| `el` | `Element` | - | Optional existing element to use as container |
|
|
77
|
+
| `className` | `string` | `'dgtable-wrapper'` | CSS class for the wrapper element |
|
|
78
|
+
| `height` | `number` | - | Table height in pixels |
|
|
79
|
+
| `width` | `DGTable.Width` | `NONE` | Width handling mode: `NONE`, `AUTO`, or `SCROLL` |
|
|
80
|
+
| `virtualTable` | `boolean` | `true` | Enable virtual scrolling (recommended for large datasets) |
|
|
81
|
+
| `estimatedRowHeight` | `number` | `40` | Estimated row height for virtual scrolling calculations |
|
|
82
|
+
| `rowsBufferSize` | `number` | `3` | Number of rows to render outside visible area |
|
|
83
|
+
|
|
84
|
+
#### Column Options
|
|
85
|
+
|
|
86
|
+
| Option | Type | Default | Description |
|
|
87
|
+
|--------|------|---------|-------------|
|
|
88
|
+
| `columns` | `ColumnOptions[]` | `[]` | Array of column definitions |
|
|
89
|
+
| `minColumnWidth` | `number` | `35` | Minimum column width in pixels |
|
|
90
|
+
| `resizableColumns` | `boolean` | `true` | Allow column resizing |
|
|
91
|
+
| `movableColumns` | `boolean` | `true` | Allow column reordering |
|
|
92
|
+
| `sortableColumns` | `number` | `1` | Maximum number of columns to sort by |
|
|
93
|
+
| `allowCancelSort` | `boolean` | `true` | Allow cycling through asc → desc → none |
|
|
94
|
+
| `adjustColumnWidthForSortArrow` | `boolean` | `true` | Auto-expand columns for sort indicator |
|
|
95
|
+
| `relativeWidthGrowsToFillWidth` | `boolean` | `true` | Expand relative columns to fill space |
|
|
96
|
+
| `relativeWidthShrinksToFillWidth` | `boolean` | `false` | Shrink relative columns to fit |
|
|
97
|
+
| `convertColumnWidthsToRelative` | `boolean` | `false` | Convert auto widths to relative |
|
|
98
|
+
| `autoFillTableWidth` | `boolean` | `false` | Stretch columns to fill table width |
|
|
99
|
+
| `resizeAreaWidth` | `number` | `8` | Width of resize drag area in pixels |
|
|
100
|
+
|
|
101
|
+
#### Column Definition
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
{
|
|
105
|
+
name: string; // Required: unique identifier
|
|
106
|
+
label?: string; // Header text (defaults to name)
|
|
107
|
+
width?: number | string; // number (px), '30%', or 0.3 (relative)
|
|
108
|
+
dataPath?: string | string[]; // Path to data (defaults to [name])
|
|
109
|
+
comparePath?: string | string[]; // Path for sorting (defaults to dataPath)
|
|
110
|
+
resizable?: boolean; // Allow resizing this column (default: true)
|
|
111
|
+
sortable?: boolean; // Allow sorting by this column (default: true)
|
|
112
|
+
movable?: boolean; // Allow moving this column (default: true)
|
|
113
|
+
visible?: boolean; // Column visibility (default: true)
|
|
114
|
+
sticky?: 'start' | 'end' | false | null; // Pin to start or end
|
|
115
|
+
cellClasses?: string; // Additional CSS classes for cells
|
|
116
|
+
ignoreMin?: boolean; // Ignore minColumnWidth for this column
|
|
117
|
+
order?: number; // Column order
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### Formatting & Filtering
|
|
122
|
+
|
|
123
|
+
| Option | Type | Description |
|
|
124
|
+
|--------|------|-------------|
|
|
125
|
+
| `cellFormatter` | `(value: unknown, columnName: string, rowData: RowData) => string` | Custom cell HTML renderer |
|
|
126
|
+
| `headerCellFormatter` | `(label: string, columnName: string) => string` | Custom header cell renderer |
|
|
127
|
+
| `filter` | `(row: RowData, args: unknown) => boolean` | Custom filter function |
|
|
128
|
+
| `sortColumn` | `string \| string[] \| ColumnSortOptions \| ColumnSortOptions[]` | Initial sort configuration |
|
|
129
|
+
| `onComparatorRequired` | `(columnName: string, descending: boolean, defaultComparator: ComparatorFunction) => ComparatorFunction` | Custom comparator provider |
|
|
130
|
+
| `customSortingProvider` | `(data: RowData[], sort: (data: RowData[]) => RowData[]) => RowData[]` | Custom sorting implementation |
|
|
131
|
+
|
|
132
|
+
#### Styling
|
|
133
|
+
|
|
134
|
+
| Option | Type | Default | Description |
|
|
135
|
+
|--------|------|---------|-------------|
|
|
136
|
+
| `tableClassName` | `string` | `'dgtable'` | Base CSS class for the table |
|
|
137
|
+
| `cellClasses` | `string` | `''` | Additional classes for all cells |
|
|
138
|
+
| `resizerClassName` | `string` | `'dgtable-resize'` | Class for resize handle |
|
|
139
|
+
| `cellPreviewClassName` | `string` | `'dgtable-cell-preview'` | Class for cell preview |
|
|
140
|
+
| `allowCellPreview` | `boolean` | `true` | Show preview on hover |
|
|
141
|
+
| `allowHeaderCellPreview` | `boolean` | `true` | Show preview for headers |
|
|
142
|
+
| `cellPreviewAutoBackground` | `boolean` | `true` | Match preview background to cell |
|
|
143
|
+
| `resizeAreaWidth` | `number` | `8` | Width of resize drag area |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
### Methods
|
|
148
|
+
|
|
149
|
+
#### Rendering
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
table.render() // Render the table
|
|
153
|
+
table.clearAndRender(render=true) // Force full re-render
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### Column Management
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
table.setColumns(columns, render=true) // Replace all columns
|
|
160
|
+
table.addColumn(columnData, before=-1, render) // Add a column
|
|
161
|
+
table.removeColumn(columnName, render=true) // Remove a column
|
|
162
|
+
table.setColumnLabel(column, label) // Update column label
|
|
163
|
+
table.moveColumn(src, dest, visibleOnly=true) // Reorder columns
|
|
164
|
+
table.setColumnVisible(column, visible) // Show/hide column
|
|
165
|
+
table.isColumnVisible(column) // Check visibility
|
|
166
|
+
table.setColumnWidth(column, width) // Set column width
|
|
167
|
+
table.getColumnWidth(column) // Get column width
|
|
168
|
+
table.getColumnConfig(column) // Get column config
|
|
169
|
+
table.getColumnsConfig() // Get all columns config
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Sorting
|
|
173
|
+
|
|
174
|
+
```javascript
|
|
175
|
+
table.sort(column, descending, add=false) // Sort by column
|
|
176
|
+
table.resort() // Re-apply current sort
|
|
177
|
+
table.getSortedColumns() // Get current sort state
|
|
178
|
+
table.setSortableColumns(count) // Set max sortable columns
|
|
179
|
+
table.getSortableColumns() // Get max sortable columns
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### Data Management
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
table.setRows(data, resort=false) // Replace all rows
|
|
186
|
+
table.addRows(data, at=-1, resort=false, render=true) // Add rows
|
|
187
|
+
table.removeRow(rowIndex, render=true) // Remove one row
|
|
188
|
+
table.removeRows(rowIndex, count, render=true) // Remove multiple rows
|
|
189
|
+
table.refreshRow(rowIndex, render=true) // Refresh a row
|
|
190
|
+
table.refreshAllVirtualRows() // Refresh all visible rows
|
|
191
|
+
|
|
192
|
+
table.getRowCount() // Total row count
|
|
193
|
+
table.getFilteredRowCount() // Filtered row count
|
|
194
|
+
table.getDataForRow(rowIndex) // Get row data by index
|
|
195
|
+
table.getDataForFilteredRow(filteredIndex) // Get filtered row data
|
|
196
|
+
table.getIndexForRow(rowData) // Find row index
|
|
197
|
+
table.getIndexForFilteredRow(rowData) // Find filtered row index
|
|
198
|
+
table.getRowElement(rowIndex) // Get row DOM element
|
|
199
|
+
table.getRowYPos(rowIndex) // Get row Y position
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### Filtering
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
table.setFilter(filterFn) // Set custom filter function
|
|
206
|
+
table.filter(args) // Apply filter with arguments
|
|
207
|
+
table.clearFilter() // Clear active filter
|
|
208
|
+
|
|
209
|
+
// Built-in filter example:
|
|
210
|
+
table.filter({ column: 'name', keyword: 'john', caseSensitive: false });
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### Formatters
|
|
214
|
+
|
|
215
|
+
```javascript
|
|
216
|
+
table.setCellFormatter(fn) // Set cell formatter
|
|
217
|
+
table.setHeaderCellFormatter(fn) // Set header formatter
|
|
218
|
+
table.getHtmlForRowCell(rowIndex, columnName) // Get cell HTML
|
|
219
|
+
table.getHtmlForRowDataCell(rowData, columnName) // Get cell HTML from data
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### Layout
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
table.tableWidthChanged(forceUpdate=false, renderColumns=true) // Notify width change
|
|
226
|
+
table.tableHeightChanged() // Notify height change
|
|
227
|
+
table.setMinColumnWidth(width) // Set global min width
|
|
228
|
+
table.getMinColumnWidth() // Get global min width
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### Cell Preview
|
|
232
|
+
|
|
233
|
+
```javascript
|
|
234
|
+
table.hideCellPreview() // Hide or prevent cell preview
|
|
235
|
+
table.abortCellPreview() // Alias for hideCellPreview()
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### Column Features
|
|
239
|
+
|
|
240
|
+
```javascript
|
|
241
|
+
table.setMovableColumns(movable) // Enable/disable column moving
|
|
242
|
+
table.getMovableColumns() // Get movable state
|
|
243
|
+
table.setResizableColumns(resizable) // Enable/disable column resizing
|
|
244
|
+
table.getResizableColumns() // Get resizable state
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### Sorting Customization
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
table.setOnComparatorRequired(callback) // Set comparator provider
|
|
251
|
+
table.setCustomSortingProvider(provider) // Set custom sort provider
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
#### Web Workers
|
|
255
|
+
|
|
256
|
+
```javascript
|
|
257
|
+
table.isWorkerSupported() // Check Web Worker support
|
|
258
|
+
table.createWebWorker(url, start=true, resort=false) // Create worker
|
|
259
|
+
table.unbindWebWorker(worker) // Unbind worker
|
|
260
|
+
table.getUrlForElementContent(elementId) // Create blob URL from element
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### DOM Access
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
table.el // The table wrapper element
|
|
267
|
+
table.getHeaderRowElement() // Get header row element
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
#### Events
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// TypeScript users get full autocompletion and type checking!
|
|
274
|
+
table.on('rowclick', (data) => {
|
|
275
|
+
// data is typed as RowClickEvent
|
|
276
|
+
console.log(data.rowIndex, data.rowData);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// Custom events are also supported (for using table as event bus)
|
|
280
|
+
table.on('my-custom-event', (data) => {
|
|
281
|
+
// data is typed as `unknown` by default
|
|
282
|
+
console.log(data);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// You can specify the type for custom events
|
|
286
|
+
table.on<{ customField: string }>('my-typed-event', (data) => {
|
|
287
|
+
console.log(data.customField); // TypeScript knows the type
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
table.on(event, handler) // Add event listener (typed for built-in events)
|
|
291
|
+
table.once(event, handler) // Add one-time listener (typed)
|
|
292
|
+
table.off(event, handler) // Remove listener
|
|
293
|
+
table.emit(event, data) // Emit event (typed for built-in events)
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### Lifecycle
|
|
297
|
+
|
|
298
|
+
```javascript
|
|
299
|
+
table.destroy() // Destroy table and free memory
|
|
300
|
+
table.close() // Alias for destroy()
|
|
301
|
+
table.remove() // Alias for destroy()
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
### Events
|
|
307
|
+
|
|
308
|
+
Subscribe to events using `table.on(eventName, handler)`.
|
|
309
|
+
|
|
310
|
+
Built-in events have fully typed handlers with autocompletion. You can also use the table's event system as an event bus for your own custom events.
|
|
311
|
+
|
|
312
|
+
#### Rendering Events
|
|
313
|
+
|
|
314
|
+
| Event | Data Type | Description |
|
|
315
|
+
|-------|-----------|-------------|
|
|
316
|
+
| `render` | `undefined` | Table finished rendering |
|
|
317
|
+
| `renderskeleton` | `undefined` | Table structure rebuilt |
|
|
318
|
+
|
|
319
|
+
#### Row Events
|
|
320
|
+
|
|
321
|
+
| Event | Data Type | Description |
|
|
322
|
+
|-------|-----------|-------------|
|
|
323
|
+
| `rowcreate` | `RowCreateEvent` | Row element created |
|
|
324
|
+
| `rowclick` | `RowClickEvent` | Row clicked |
|
|
325
|
+
| `rowdestroy` | `HTMLElement` | Row element about to be removed |
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
interface RowCreateEvent {
|
|
329
|
+
filteredRowIndex: number; // Index in filtered data
|
|
330
|
+
rowIndex: number; // Index in original data
|
|
331
|
+
rowEl: HTMLElement; // The row DOM element
|
|
332
|
+
rowData: RowData; // The row data object
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
interface RowClickEvent {
|
|
336
|
+
event: MouseEvent; // The original mouse event
|
|
337
|
+
filteredRowIndex: number; // Index in filtered data
|
|
338
|
+
rowIndex: number; // Index in original data
|
|
339
|
+
rowEl: HTMLElement; // The row DOM element
|
|
340
|
+
rowData: RowData; // The row data object
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
#### Cell Preview Events
|
|
345
|
+
|
|
346
|
+
| Event | Data Type | Description |
|
|
347
|
+
|-------|-----------|-------------|
|
|
348
|
+
| `cellpreview` | `CellPreviewEvent` | Cell preview showing |
|
|
349
|
+
| `cellpreviewdestroy` | `CellPreviewDestroyEvent` | Cell preview hiding |
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
interface CellPreviewEvent {
|
|
353
|
+
el: Element | null; // Preview element's first child
|
|
354
|
+
name: string; // Column name
|
|
355
|
+
rowIndex: number | null; // Row index (null for header)
|
|
356
|
+
rowData: RowData | null; // Row data (null for header)
|
|
357
|
+
cell: HTMLElement; // Original cell element
|
|
358
|
+
cellEl: HTMLElement; // Cell's inner element
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
interface CellPreviewDestroyEvent {
|
|
362
|
+
el: ChildNode | null; // Preview element's first child
|
|
363
|
+
name: string; // Column name
|
|
364
|
+
rowIndex: number | null; // Row index (null for header)
|
|
365
|
+
rowData: RowData | null; // Row data (null for header)
|
|
366
|
+
cell: HTMLElement | null; // Original cell element
|
|
367
|
+
cellEl: ChildNode | null; // Cell's inner element
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
#### Header Events
|
|
372
|
+
|
|
373
|
+
| Event | Data Type | Description |
|
|
374
|
+
|-------|-----------|-------------|
|
|
375
|
+
| `headerrowcreate` | `HTMLElement` | Header row created |
|
|
376
|
+
| `headercontextmenu` | `HeaderContextMenuEvent` | Header right-click |
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
interface HeaderContextMenuEvent {
|
|
380
|
+
columnName: string; // Column that was right-clicked
|
|
381
|
+
pageX: number; // Mouse X position
|
|
382
|
+
pageY: number; // Mouse Y position
|
|
383
|
+
bounds: { // Cell bounds
|
|
384
|
+
left: number;
|
|
385
|
+
top: number;
|
|
386
|
+
width: number;
|
|
387
|
+
height: number;
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
#### Column Events
|
|
393
|
+
|
|
394
|
+
| Event | Data Type | Description |
|
|
395
|
+
|-------|-----------|-------------|
|
|
396
|
+
| `addcolumn` | `string` | Column name added |
|
|
397
|
+
| `removecolumn` | `string` | Column name removed |
|
|
398
|
+
| `movecolumn` | `MoveColumnEvent` | Column moved |
|
|
399
|
+
| `showcolumn` | `string` | Column name shown |
|
|
400
|
+
| `hidecolumn` | `string` | Column name hidden |
|
|
401
|
+
| `columnwidth` | `ColumnWidthEvent` | Column resized |
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
interface MoveColumnEvent {
|
|
405
|
+
name: string; // Column name
|
|
406
|
+
src: number; // Original order position
|
|
407
|
+
dest: number; // New order position
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
interface ColumnWidthEvent {
|
|
411
|
+
name: string; // Column name
|
|
412
|
+
width: number; // New width
|
|
413
|
+
oldWidth: number; // Previous width
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
#### Data Events
|
|
418
|
+
|
|
419
|
+
| Event | Data Type | Description |
|
|
420
|
+
|-------|-----------|-------------|
|
|
421
|
+
| `addrows` | `AddRowsEvent` | Rows added |
|
|
422
|
+
| `sort` | `SortEvent` | Data sorted |
|
|
423
|
+
| `filter` | `unknown` | Filter applied (filter args) |
|
|
424
|
+
| `filterclear` | `{}` | Filter cleared |
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
interface AddRowsEvent {
|
|
428
|
+
count: number; // Number of rows added
|
|
429
|
+
clear: boolean; // Whether table was cleared first
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
interface SortEvent {
|
|
433
|
+
sorts: SerializedColumnSort[]; // Current sort state
|
|
434
|
+
resort?: boolean; // True if re-sorting existing data
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
#### Example Usage
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
// Row click handler
|
|
442
|
+
table.on('rowclick', (data) => {
|
|
443
|
+
console.log('Clicked row:', data.rowIndex, data.rowData);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
// Column resize handler
|
|
447
|
+
table.on('columnwidth', (data) => {
|
|
448
|
+
console.log(`Column ${data.name} resized from ${data.oldWidth} to ${data.width}`);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Sort handler
|
|
452
|
+
table.on('sort', (data) => {
|
|
453
|
+
console.log('Sorted by:', data.sorts);
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// Cell preview handler
|
|
457
|
+
table.on('cellpreview', (data) => {
|
|
458
|
+
// Customize preview content
|
|
459
|
+
if (data.el) {
|
|
460
|
+
data.el.innerHTML += '<span class="custom-badge">Preview</span>';
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## TypeScript Types
|
|
468
|
+
|
|
469
|
+
The library exports the following types for TypeScript users:
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
import type {
|
|
473
|
+
// Configuration types
|
|
474
|
+
DGTableOptions, // Constructor options
|
|
475
|
+
ColumnOptions, // Column definition
|
|
476
|
+
ColumnSortOptions, // Sort specification { column, descending? }
|
|
477
|
+
SerializedColumn, // Saved column config
|
|
478
|
+
SerializedColumnSort, // Saved sort config
|
|
479
|
+
RowData, // Row data (Record<string, unknown>)
|
|
271
480
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
481
|
+
// Function types
|
|
482
|
+
CellFormatter, // Cell formatter function
|
|
483
|
+
HeaderCellFormatter, // Header cell formatter function
|
|
484
|
+
FilterFunction, // Filter function
|
|
485
|
+
ComparatorFunction, // Row comparator function
|
|
486
|
+
OnComparatorRequired, // Comparator provider callback
|
|
487
|
+
CustomSortingProvider, // Custom sorting function
|
|
278
488
|
|
|
279
|
-
|
|
280
|
-
|
|
489
|
+
// Event types
|
|
490
|
+
RowCreateEvent, // 'rowcreate' event data
|
|
491
|
+
RowClickEvent, // 'rowclick' event data
|
|
492
|
+
CellPreviewEvent, // 'cellpreview' event data
|
|
493
|
+
CellPreviewDestroyEvent, // 'cellpreviewdestroy' event data
|
|
494
|
+
HeaderContextMenuEvent, // 'headercontextmenu' event data
|
|
495
|
+
MoveColumnEvent, // 'movecolumn' event data
|
|
496
|
+
ColumnWidthEvent, // 'columnwidth' event data
|
|
497
|
+
AddRowsEvent, // 'addrows' event data
|
|
498
|
+
SortEvent, // 'sort' event data
|
|
281
499
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
500
|
+
// Event map (for advanced typing)
|
|
501
|
+
DGTableEventMap, // Maps event names to their data types
|
|
502
|
+
} from '@danielgindi/dgtable';
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
The `DGTableEventMap` interface provides full autocompletion when using `.on()`, `.once()`, `.off()`, and `.emit()`:
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
// Event names autocomplete, and handler receives correctly typed data
|
|
509
|
+
table.on('rowclick', (data) => {
|
|
510
|
+
// TypeScript knows: data.event, data.rowIndex, data.rowData, etc.
|
|
511
|
+
console.log(`Clicked row ${data.rowIndex}`);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
table.on('columnwidth', (data) => {
|
|
515
|
+
// TypeScript knows: data.name, data.width, data.oldWidth
|
|
516
|
+
console.log(`Column ${data.name} resized to ${data.width}px`);
|
|
517
|
+
});
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## Development
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
# Install dependencies
|
|
526
|
+
npm install
|
|
527
|
+
|
|
528
|
+
# Build
|
|
529
|
+
npm run build
|
|
530
|
+
|
|
531
|
+
# Lint
|
|
532
|
+
npm run lint
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
## Author
|
|
536
|
+
|
|
537
|
+
**Daniel Cohen Gindi** - danielgindi@gmail.com
|
|
538
|
+
|
|
539
|
+
## Contributing
|
|
540
|
+
|
|
541
|
+
Contributions are welcome! Please feel free to:
|
|
542
|
+
|
|
543
|
+
- Report bugs and issues
|
|
544
|
+
- Submit pull requests
|
|
545
|
+
- Improve documentation
|
|
546
|
+
- Share your use cases
|
|
547
|
+
|
|
548
|
+
## License
|
|
549
|
+
|
|
550
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
551
|
+
|
|
552
|
+
Copyright (c) 2013-present Daniel Cohen Gindi
|
|
553
|
+
|