@dhtmlx/grid 9.3.7 → 9.3.9

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.
@@ -5,7 +5,20 @@ export declare class Loader {
5
5
  private _changes;
6
6
  constructor(parent: IDataCollection, changes: any);
7
7
  load(url: IDataProxy, driver?: IDataDriver | DataDriver): Promise<any>;
8
- parse(data: any | any[], driver?: IDataDriver | DataDriver): any;
8
+ /**
9
+ * Converts the raw input with a driver and hands it over to the collection.
10
+ * A partial response of a lazy-loading source is handled differently: into an empty collection
11
+ * it is expanded to the full length reported by the source, with the items outside the received
12
+ * range put in as `$empty` placeholders; into a collection that already holds those placeholders
13
+ * it is merged over them, and the collection is not refilled at all.
14
+ * @param data - Items or a serialized string.
15
+ * @param driver - Data driver used to parse the input. Defaults to the JSON driver.
16
+ * @param resetRules - Whether the collection should drop its sorting and non-permanent
17
+ * filtering rules before taking the data. Set when the whole dataset is replaced. Defaults to `false`.
18
+ * @returns The parsed items.
19
+ * @internal
20
+ */
21
+ parse(data: any | any[], driver?: IDataDriver | DataDriver, resetRules?: boolean): any;
9
22
  save(url: IDataProxy): void;
10
23
  updateChanges(changes: IDataChangeStack): void;
11
24
  private _setPromise;
@@ -44,24 +44,118 @@ export declare class DataCollection<T extends IDataItem = IDataItem> implements
44
44
  getId(index: number): Id;
45
45
  getLength(): number;
46
46
  isDataLoaded(from?: number, to?: number): boolean;
47
+ /**
48
+ * Filters the collection.
49
+ * Replaces the currently applied filters unless `config.add` is set; permanent filters always
50
+ * survive and are combined with the new rule - they are applied first and the new rule narrows
51
+ * the result further, so the two act as AND. Calling the method without a rule drops all
52
+ * non-permanent filters and restores the unfiltered order.
53
+ * @param rule - A single rule, a set of rules combined with AND, or a predicate. Omit to reset filtering.
54
+ * @param config - Options that control how the rule is applied and stored.
55
+ * @param silent - Whether to suppress the `filter` event. Defaults to `false`.
56
+ * @returns The id the filter is stored under, or `undefined` if no rule was passed or the call
57
+ * only reapplied the already stored filters.
58
+ * @example
59
+ * ```ts
60
+ * // keep items whose "age" is 30 or more
61
+ * collection.filter({ by: "age", match: "30", compare: (value, match) => Number(value) >= Number(match) });
62
+ *
63
+ * // narrow the current result further instead of replacing it
64
+ * collection.filter({ by: "country", match: "France" }, { add: true });
65
+ *
66
+ * // a filter that survives resetFilter() and data reloading
67
+ * collection.filter({ by: "archived", match: false }, { permanent: true });
68
+ *
69
+ * collection.filter();
70
+ * ```
71
+ */
47
72
  filter(rule?: IFilterMode | IFilterComplexMode | IFilterCallback, config?: IFilterConfig, silent?: boolean): string;
73
+ /**
74
+ * Removes the applied filters and restores the unfiltered order. Whatever is left after the
75
+ * removal is reapplied to the restored order.
76
+ * Permanent filters are kept and reapplied unless `config.permanent` is set.
77
+ * @param config - Restricts the reset to a single filter or extends it to permanent ones. Omit to
78
+ * drop all non-permanent filters. `permanent` wins over `id`: passing both removes every filter,
79
+ * not just the one with that id.
80
+ * @param silent - Whether to suppress the `filter` event. Defaults to `false`.
81
+ * @returns `true` if no user-facing filters are left applied. Filters applied internally by a
82
+ * widget are not counted, so the result can be `true` while such a filter is still in effect.
83
+ * @example
84
+ * ```ts
85
+ * collection.resetFilter(); // all non-permanent filters
86
+ * collection.resetFilter({ id: filterId }); // one filter
87
+ * collection.resetFilter({ permanent: true }); // everything, permanent included
88
+ * ```
89
+ */
48
90
  resetFilter(config?: IResetFilterConfig, silent?: boolean): boolean;
91
+ /**
92
+ * Returns the currently applied filters, keyed by filter id.
93
+ * Filters applied internally by a widget are omitted; use {@link DataCollection.getRawFilters} to get them as well.
94
+ * @param config - Set `permanent` to return only permanent filters.
95
+ * @returns The applied filters, or `null` if there are none.
96
+ */
49
97
  getFilters(config?: {
50
98
  permanent?: boolean;
51
99
  }): IFilter;
100
+ /**
101
+ * Returns the currently applied filters including the ones applied internally by a widget.
102
+ * @param config - Set `permanent` to return only permanent filters.
103
+ * @returns The applied filters, or `null` if there are none.
104
+ */
52
105
  getRawFilters(config?: {
53
106
  permanent?: boolean;
54
107
  }): IFilter;
55
108
  find(conf: IFilterMode | DataCallback<T>): any;
56
109
  findAll(conf: IFilterMode | DataCallback<T>): any[];
110
+ /**
111
+ * Sorts the collection.
112
+ * A rule applied on its own replaces whatever was applied before. Multi-level sorting is built
113
+ * by applying the base level with `smartSorting: true`: while that base is in place every next
114
+ * rule is appended as another level instead of replacing it, whether it comes with
115
+ * `smartSorting: false` or with no config at all. A rule for a field that is already a level
116
+ * only changes that level's direction. Calling the method without a rule resets the sorting
117
+ * and restores the original order.
118
+ * Does not work while data is being lazy-loaded.
119
+ * @param rule - The sorting rule. Omit to reset the sorting.
120
+ * @param config - Options that control how the rule is combined with the already applied ones.
121
+ * @param ignore - Internal. Reorders the data without recording the rule in the sorting state
122
+ * and without firing the `change` event. A call that resets the sorting still clears the state.
123
+ * Defaults to `false`.
124
+ * @example
125
+ * ```ts
126
+ * collection.sort({ by: "country", dir: "asc" });
127
+ *
128
+ * // two-level sorting: by country, then by population
129
+ * collection.sort({ by: "country", dir: "asc" }, { smartSorting: true });
130
+ * collection.sort({ by: "population", dir: "desc" }, { smartSorting: false });
131
+ *
132
+ * // sorting anew while a base is in place - reset first
133
+ * collection.sort();
134
+ * collection.sort({ by: "population", dir: "desc" });
135
+ * ```
136
+ */
57
137
  sort(rule?: ISortMode, config?: ISortConfig, ignore?: boolean): void;
58
- getSortingStates(): ISortMode[];
138
+ /**
139
+ * Returns the currently applied sorting rules, from the base level to the last one added.
140
+ * The array is the one the collection sorts by, not a copy: do not modify it.
141
+ * @returns The applied rules, or an empty array if the collection is not sorted.
142
+ */
143
+ getSortingStates(): ISortingState[];
59
144
  copy(id: Id | Id[], index: number, target?: IDataCollection | ITreeCollection, targetId?: Id): Id | Id[];
60
145
  move(id: Id | Id[], index: number, target?: IDataCollection | ITreeCollection, targetId?: Id, newId?: Id): Id | Id[];
61
146
  forEach(callback: DataCallback<T>): void;
62
147
  load(url: IDataProxy | string, driver?: IDataDriver | DataDriver): Promise<any>;
63
148
  parse(data: T[] | string, driver?: DataDriver | IDataDriver): any;
64
- $parse(data: any[]): void;
149
+ /**
150
+ * Puts already normalized data into the collection and notifies the subscribers.
151
+ * Called by the loader once a driver has converted the raw input into an array of items.
152
+ * @param data - Normalized items.
153
+ * @param resetRules - Whether to drop the sorting and non-permanent filtering rules before
154
+ * putting the data in. Set for `parse()` and `load()`, which replace the whole dataset, and
155
+ * not set for grouping, which only rebuilds the order. Defaults to `false`.
156
+ * @internal
157
+ */
158
+ $parse(data: any[], resetRules?: boolean): void;
65
159
  save(url: IDataProxy | string): void;
66
160
  changeId(id: Id, newId?: Id, silent?: boolean): void;
67
161
  isSaved(): boolean;
@@ -90,12 +184,81 @@ export declare class DataCollection<T extends IDataItem = IDataItem> implements
90
184
  protected _approximate(data: any[], values: string[], maxNum: number): any[];
91
185
  protected _onChange(status: Statuses, id: Id, obj: any): void;
92
186
  protected _addToOrder(array: any[], obj: any, index?: number): void;
187
+ /**
188
+ * Reorders the data by all currently stored sorting rules.
189
+ * @internal
190
+ */
93
191
  protected _applySorters(): void;
192
+ /**
193
+ * Narrows the data by a single rule, remembering the unfiltered order on first use.
194
+ * @param rule - The rule to apply. A missing rule is a no-op.
195
+ * @throws If the rule is neither a predicate nor a valid field/value pair.
196
+ * @internal
197
+ */
94
198
  protected _applyFilters(rule?: IFilterMode | IFilterCallback): void;
95
- protected _reapplyFilters(): void;
199
+ /**
200
+ * Drops the sorting rules and restores the order the data had before sorting.
201
+ * If filtering was applied on top of the sorting, it is reapplied to the restored order.
202
+ * @internal
203
+ */
204
+ protected _resetSorting(): void;
205
+ /**
206
+ * Forgets the filters that do not outlive a data change, keeping the permanent ones.
207
+ * @internal
208
+ */
209
+ protected _dropNonPermanentFilters(): void;
210
+ /**
211
+ * Drops the rules that must not outlive a full data replacement: the sorting and
212
+ * the non-permanent filters. The counterpart of {@link DataCollection._reapplyRules},
213
+ * which restores everything that does outlive it.
214
+ * Called before the new data is put in, so the surviving permanent filters are only forgotten
215
+ * here, not reapplied: applying them to an empty collection would memorize an empty
216
+ * pre-filter state and lose the data that comes next.
217
+ * @internal
218
+ */
219
+ protected _resetRules(): void;
220
+ /**
221
+ * Restores the rules that outlive a data change: the permanent filters and,
222
+ * while smart sorting is on, the sorting order. Called after items are added, updated or parsed,
223
+ * and after a tree is sorted.
224
+ * @internal
225
+ */
226
+ protected _reapplyRules(): void;
227
+ /**
228
+ * Turns a field/value rule into a predicate.
229
+ * @param rule - The rule to convert.
230
+ * @returns The predicate, or `undefined` if the rule has no field or no value to match.
231
+ * @internal
232
+ */
96
233
  protected _getRuleCallback(rule: IFilterMode): IFilterCallback;
234
+ /**
235
+ * Strips the filters applied by a widget, leaving only those the user set.
236
+ * @param filters - The filters to strip.
237
+ * @returns The user-facing filters.
238
+ * @internal
239
+ */
97
240
  protected _getPureFilters(filters: IFilter): IFilter;
241
+ /**
242
+ * Flattens stored filters into a set of predicates that can be reapplied at once.
243
+ * @param filters - The stored filters.
244
+ * @returns A set of predicates keyed by index.
245
+ * @internal
246
+ */
98
247
  protected _normalizeFilters(filters: any): any;
248
+ /**
249
+ * Checks that a rule can be applied: it is either a predicate or has both a field and a value.
250
+ * @param rule - The rule to check.
251
+ * @returns Whether the rule is valid.
252
+ * @internal
253
+ */
99
254
  protected _checkFilterRule(rule: IFilterMode | IFilterCallback): boolean;
255
+ /**
256
+ * Clears the collection and hands the data over to the loader.
257
+ * @param data - Items or a serialized string.
258
+ * @param driver - Data driver used to parse the input. Defaults to the JSON driver.
259
+ * @param grouping - Whether the call rebuilds the order for grouping rather than replaces the
260
+ * dataset. Grouping keeps the sorting and filtering rules, a replacement drops them. Defaults to `false`.
261
+ * @internal
262
+ */
100
263
  private _parse;
101
264
  }
@@ -21,8 +21,42 @@ export declare class TreeCollection<T extends IDataItem = IDataItem> extends Dat
21
21
  removeAll(id?: Id): void;
22
22
  update(id: Id, newItem: IUpdateObject, silent?: boolean): void;
23
23
  getIndex(id: Id): number;
24
+ /**
25
+ * Sorts the tree, reordering the items within each parent independently.
26
+ * The rules are combined the same way as in {@link DataCollection.sort}, but unlike it this
27
+ * method has no lazy-loading guard and reorders whatever is currently in the tree.
28
+ * @param rule - The sorting rule. Omit to reset the sorting.
29
+ * @param config - Options that control how the rule is combined with the already applied ones.
30
+ * @param ignore - Internal. Reorders the data without recording the rule in the sorting state
31
+ * and without firing the `change` event. A call that resets the sorting still clears the state.
32
+ * Defaults to `false`.
33
+ */
24
34
  sort(rule?: ISortMode, config?: ISortConfig, ignore?: boolean): void;
35
+ /**
36
+ * Filters the tree, keeping the matched items together with their parent chain.
37
+ * By default every item at every nesting level is matched; `config.type` narrows that
38
+ * to a single level or to leaf items only. Rules are stored and combined the same way as in
39
+ * {@link DataCollection.filter}, but a rule without `compare` is matched differently: the field
40
+ * value has to contain `match` ignoring case, rather than be loosely equal to it, and a rule
41
+ * with an empty `match` is skipped instead of filtering everything out.
42
+ * @param rule - A single rule, a set of rules combined with AND, or a predicate. Omit to reset filtering.
43
+ * @param config - Options that control which items the rule is matched against and how it is stored.
44
+ * @param silent - Whether to suppress the `filter` event. Defaults to `false`.
45
+ * @returns The id the filter is stored under, or `undefined` if no rule was passed.
46
+ * @example
47
+ * ```ts
48
+ * // match every item at any level
49
+ * collection.filter({ by: "status", match: "done" });
50
+ *
51
+ * // match leaf items only
52
+ * collection.filter({ by: "status", match: "done" }, { type: "leafs" });
53
+ * ```
54
+ */
25
55
  filter(rule?: IFilterMode | IFilterComplexMode | IFilterCallback, config?: ITreeFilterConfig, silent?: boolean): string;
56
+ /**
57
+ * Restores the original order of the tree, dropping the sorting and every filter,
58
+ * permanent ones included.
59
+ */
26
60
  restoreOrder(): void;
27
61
  copy(id: Id, index: number, target?: IDataCollection | ITreeCollection, targetId?: Id): Id;
28
62
  copy(id: Id[], index: number, target?: IDataCollection | ITreeCollection, targetId?: Id): Id[];
@@ -65,8 +99,35 @@ export declare class TreeCollection<T extends IDataItem = IDataItem> extends Dat
65
99
  protected _parseItem(item: any): void;
66
100
  private _recursiveFilter;
67
101
  private _serialize;
102
+ /**
103
+ * Narrows the tree by a single rule, keeping the parent chain of every matched item
104
+ * and remembering the unfiltered tree on first use.
105
+ * @param rule - The rule to apply. A missing or empty rule is a no-op.
106
+ * @param config - Options that control which items the rule is matched against.
107
+ * @throws If the rule is neither a predicate nor a valid field/value pair.
108
+ * @internal
109
+ */
68
110
  private _applyFilter;
111
+ /**
112
+ * Unwraps the stored filters into their bare rules, keeping them keyed by filter id.
113
+ * Unlike {@link DataCollection._normalizeFilters} it does not turn the rules into predicates:
114
+ * {@link TreeCollection._applyFilter} needs the original rule to walk the tree, and it needs the
115
+ * id to look the matching config up.
116
+ * @param filters - The stored filters.
117
+ * @returns The bare rules, keyed by filter id.
118
+ * @internal
119
+ */
69
120
  protected _normalizeFilters(filters: any): any;
70
121
  protected _checkFilterRule(rule: IFilterMode | IFilterComplexMode | IFilterCallback): boolean;
122
+ /**
123
+ * Drops the sorting rules and rebuilds the tree in the order it had before sorting.
124
+ * If filtering was applied on top of the sorting, it is reapplied to the restored tree.
125
+ * @internal
126
+ */
127
+ protected _resetSorting(): void;
128
+ /**
129
+ * Reorders the children of every parent by all currently stored sorting rules.
130
+ * @internal
131
+ */
71
132
  protected _applySorters(): void;
72
133
  }
@@ -18,48 +18,130 @@ export interface ILazyConfig {
18
18
  delay?: number;
19
19
  prepare?: number;
20
20
  }
21
+ /** Sorting direction: ascending or descending. */
21
22
  export type TSortDir = "asc" | "desc";
23
+ /**
24
+ * A single sorting rule. Set either `by` or `rule`; with neither of them the rule has no effect.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * // sort by a field
29
+ * collection.sort({ by: "country", dir: "asc" });
30
+ *
31
+ * // sort by a computed value
32
+ * collection.sort({ by: "date", dir: "desc", as: value => new Date(value).getTime() });
33
+ *
34
+ * // sort by a custom comparator
35
+ * collection.sort({ rule: (a, b) => a.price - b.price });
36
+ * ```
37
+ */
22
38
  export interface ISortMode {
39
+ /** Name of the field to sort by. */
23
40
  by?: string | number;
41
+ /** Sorting direction. Defaults to `"asc"`. */
24
42
  dir?: TSortDir;
43
+ /** Maps a field value to the value actually compared (e.g. a date string to a timestamp). Ignored if `rule` is set. */
25
44
  as?: (a: any) => any;
45
+ /** Custom comparator applied to whole items. Takes precedence over `by` and `as`. */
26
46
  rule?: (a: any, b: any) => number;
27
47
  }
48
+ /** An applied sorting rule together with the config it was applied with. */
28
49
  export type ISortingState = ISortMode & ISortConfig;
50
+ /** Predicate that decides whether an item passes the filter. */
29
51
  export type IFilterCallback = (obj: any) => boolean;
52
+ /**
53
+ * A single filtering rule.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * // keep items whose "country" equals "France"
58
+ * collection.filter({ by: "country", match: "France" });
59
+ *
60
+ * // keep items whose "age" is 30 or more
61
+ * collection.filter({ by: "age", match: "30", compare: (value, match) => Number(value) >= Number(match) });
62
+ * ```
63
+ */
30
64
  export interface IFilterMode {
65
+ /** Name of the field to filter by. */
31
66
  by?: Id;
32
- match?: string | number | boolean;
67
+ /**
68
+ * Value the field is matched against. A multiselect filter passes an array of values,
69
+ * which `compare` is expected to treat as "any of these" — see `multi`.
70
+ */
71
+ match?: string | number | boolean | Array<string | number | boolean>;
72
+ /**
73
+ * Custom comparison. Without it the field value is compared to `match` loosely by a flat
74
+ * collection, while a tree one checks that the value contains `match` ignoring case.
75
+ */
33
76
  compare?: (value: any, match: any, obj: any, multi?: boolean) => boolean;
34
- multi?: any;
35
- }
77
+ /**
78
+ * Marks the field as holding several values at once (a multiselect column stores them
79
+ * as a comma-separated string). Passed to `compare` as its last argument, both by a flat
80
+ * collection and by a tree one.
81
+ */
82
+ multi?: boolean;
83
+ }
84
+ /** A set of filtering rules combined with AND, keyed by an arbitrary name. */
36
85
  export interface IFilterComplexMode {
37
86
  [key: string]: IFilterMode;
38
87
  }
88
+ /** Applied filters, keyed by filter id. */
39
89
  export interface IFilter {
40
90
  [key: string]: IFilterParams;
41
91
  }
92
+ /** An applied filtering rule together with the config it was applied with. */
42
93
  export interface IFilterParams {
43
94
  rule: IFilterMode | IFilterComplexMode | IFilterCallback;
44
95
  config: IFilterConfig | ITreeFilterConfig;
45
96
  }
97
+ /** Options that control how a filtering rule is applied and stored. */
46
98
  export interface IFilterConfig {
99
+ /** Id to store the filter under. Reapplying with the same id replaces the previous rule. Generated automatically if omitted. */
47
100
  id?: string;
101
+ /** Applies the rule on top of the already filtered data instead of replacing the active filters. */
48
102
  add?: boolean;
49
- smartFilter?: boolean;
103
+ /**
104
+ * Marks the filter as permanent. Permanent filters are not dropped by `resetFilter()`
105
+ * and are reapplied to newly loaded data after `parse()` / `load()`.
106
+ */
50
107
  permanent?: boolean;
108
+ /**
109
+ * Reapplies the stored filters instead of registering a new one.
110
+ * @internal
111
+ */
51
112
  $restore?: boolean;
113
+ /**
114
+ * Hides the filter from `getFilters()` and from the `filter` event.
115
+ * @internal
116
+ */
52
117
  $local?: boolean;
118
+ /** @deprecated Not used. Kept for backward compatibility. */
119
+ smartFilter?: boolean;
53
120
  }
121
+ /** Options that control which filters `resetFilter()` removes. */
54
122
  export interface IResetFilterConfig {
123
+ /** Removes only the filter with this id. */
55
124
  id?: string;
125
+ /** Removes permanent filters as well. Without it they survive the reset. */
56
126
  permanent?: boolean;
57
127
  }
128
+ /** Options that control how a sorting rule is applied and stored. */
58
129
  export interface ISortConfig {
130
+ /**
131
+ * Makes the rule the base level of a multi-level sorting: the previously applied
132
+ * levels are discarded and the order is maintained when items are added or updated.
133
+ * While such a base is in place every next rule is appended as another level instead of
134
+ * replacing it - both with `smartSorting: false` and with no config at all. Without a base
135
+ * every rule replaces whatever is applied.
136
+ * To sort anew while a base is in place, reset the sorting first: `sort()`, then `sort(rule)`.
137
+ */
59
138
  smartSorting?: boolean;
60
139
  }
140
+ /** Options that control how a filtering rule is applied to a tree collection. */
61
141
  export interface ITreeFilterConfig extends IFilterConfig {
142
+ /** Which items the rule is matched against: all of them, a single level, or leaf items only. */
62
143
  type?: TreeFilterType;
144
+ /** Nesting level the rule is applied to when `type` is `"level"`. */
63
145
  level?: number;
64
146
  }
65
147
  export interface IUpdateObject {
@@ -91,7 +173,7 @@ export interface IDataCollection<T extends IDataItem = IDataItem> {
91
173
  isGrouped(): boolean;
92
174
  load(url: IDataProxy | string, driver?: IDataDriver | DataDriver): Promise<any>;
93
175
  parse(data: T[] | string, driver?: DataDriver | IDataDriver): void;
94
- $parse(data: any[]): void;
176
+ $parse(data: any[], resetRules?: boolean): void;
95
177
  add(newItem: IDataItem, index?: number): Id;
96
178
  add(newItem: IDataItem[], index?: number): Id[];
97
179
  add(newItem: IDataItem | IDataItem[], index?: number): Id | Id[];
@@ -105,7 +187,7 @@ export interface IDataCollection<T extends IDataItem = IDataItem> {
105
187
  getLength(): number;
106
188
  isDataLoaded(from?: number, to?: number): boolean;
107
189
  getId(index: number): Id;
108
- filter(rule?: IFilterMode | IFilterCallback, config?: IFilterConfig, silent?: boolean): string;
190
+ filter(rule?: IFilterMode | IFilterComplexMode | IFilterCallback, config?: IFilterConfig, silent?: boolean): string;
109
191
  resetFilter(config?: IResetFilterConfig, silent?: boolean): boolean;
110
192
  getFilters(config?: {
111
193
  permanent?: boolean;
@@ -118,7 +200,7 @@ export interface IDataCollection<T extends IDataItem = IDataItem> {
118
200
  findAll(rule: IFilterMode): T[];
119
201
  map(callback: DataCallback<T>): T[];
120
202
  mapRange(from: number, to: number, callback: DataCallback<T>): T[];
121
- sort(rule?: ISortMode, config?: ISortConfig): void;
203
+ sort(rule?: ISortMode, config?: ISortConfig, ignore?: boolean): void;
122
204
  getSortingStates(): ISortingState[];
123
205
  serialize(driver?: DataDriver): T[];
124
206
  copy(id: Id | Id[], index: number, target?: IDataCollection | ITreeCollection, targetId?: Id): Id | Id[];
@@ -163,9 +245,13 @@ export interface ICsvDriverConfig {
163
245
  rowDelimiter?: string;
164
246
  columnDelimiter?: string;
165
247
  }
248
+ /** Scope a tree filtering rule is matched against. */
166
249
  export declare enum TreeFilterType {
250
+ /** Every item at any nesting level. */
167
251
  all = "all",
252
+ /** Only items at the level given by {@link ITreeFilterConfig.level}. */
168
253
  level = "level",
254
+ /** Only items without children. */
169
255
  leafs = "leafs"
170
256
  }
171
257
  export type DataCallback<T> = (item: T, index?: number, array?: T[]) => any;
@@ -180,9 +266,9 @@ export interface ITreeCollection<T extends IDataItem = IDataItem> extends IDataC
180
266
  getLength(id?: Id): number;
181
267
  getIndex(id: Id): number;
182
268
  getItems(id: Id): T[];
183
- sort(rule?: ISortMode, config?: ISortConfig): void;
269
+ sort(rule?: ISortMode, config?: ISortConfig, ignore?: boolean): void;
184
270
  map(callback: DataCallback<T>, parent?: Id, direct?: boolean): any;
185
- filter(rule?: IFilterMode | IFilterCallback, config?: ITreeFilterConfig, silent?: boolean): string;
271
+ filter(rule?: IFilterMode | IFilterComplexMode | IFilterCallback, config?: ITreeFilterConfig, silent?: boolean): string;
186
272
  restoreOrder(): void;
187
273
  copy(id: Id, index: number, target?: IDataCollection | ITreeCollection, targetId?: Id): Id;
188
274
  copy(id: Id[], index: number, target?: IDataCollection | ITreeCollection, targetId?: Id): Id[];
@@ -31,8 +31,8 @@ export declare class ExtendedGrid extends Grid implements IExtendedGrid {
31
31
  protected _afterEditEndProcess(value: any, editableRow: any, editableColumn: any): void;
32
32
  protected _setSort(): void;
33
33
  protected getNormalizeContentHeight(row: IFooter | IHeader, col: ICol, config: IGridConfig): number;
34
- protected _prepareData(data: IDataItem[] | IDataCollection): IRow[] | IDataItem[];
35
- protected _prepareDataFromTo(data: IDataCollection, from: number, to: number): IDataItem[];
34
+ protected _prepareData(data: IDataItem[] | IDataCollection): IRow[];
35
+ protected _prepareDataFromTo(data: IDataCollection, from: number, to: number): IRow[];
36
36
  protected _dragStart(event: any): void;
37
37
  protected _group(order: IGroupOrderItem[]): void;
38
38
  protected _expand(row: IRow): boolean;
@@ -44,4 +44,7 @@ export declare class ExtendedGrid extends Grid implements IExtendedGrid {
44
44
  private _changeGroupItemAfterSort;
45
45
  private _isGroupableColumn;
46
46
  private _isGroupClosable;
47
+ private _buildRowIdToIndex;
48
+ private _buildSpanCalculationMap;
49
+ private _applyAutoRowHeights;
47
50
  }
@@ -91,6 +91,7 @@ export declare class Grid extends View implements IGrid {
91
91
  protected _checkFilters(reset?: boolean): void;
92
92
  protected _setUniqueData(sync?: boolean): void;
93
93
  protected _checkSelectFilterValue(): void;
94
+ protected _resetFilterUI(): void;
94
95
  protected _clearFilterValue(allCols?: boolean): void;
95
96
  protected _adjustColumns(): void;
96
97
  protected _prepareData(data: IDataItem[] | IDataCollection): any[] | IDataItem[];
@@ -14,6 +14,7 @@ export declare function isContentTooltip(config: IGridConfig, col: ICol, cell: a
14
14
  export declare function getTooltipConfig(config: IGridConfig, col?: ICol, cell?: IHeader | IFooter | ISpan, type?: "footer" | "header"): IGridTooltipConfig;
15
15
  export declare function isTooltip(config: IGridConfig, element: ICol | ISpan): boolean | IGridTooltipConfig;
16
16
  export declare function isHtmlEnable(config: IGridConfig, col: ICol, content?: IHeader | IFooter): boolean;
17
+ export declare function isInteractiveTarget(target: EventTarget): boolean;
17
18
  export declare function getTotalWidth(columns: ICol[]): number;
18
19
  export declare function getTotalHeight(rows: IRow[]): number;
19
20
  export declare function scrollFixedColsAndRows(e: WheelEvent): void;
@@ -56,6 +56,7 @@ export declare class Selection implements ISelection {
56
56
  private _removeCells;
57
57
  private _init;
58
58
  private _toHTML;
59
+ private _getSelectionLayout;
59
60
  private _isUnselected;
60
61
  private _findIndex;
61
62
  private _cellKey;
@@ -452,6 +452,14 @@ export interface ISpan {
452
452
  $colsVisibility?: number[];
453
453
  $renderFrom?: RenderFrom[];
454
454
  }
455
+ export interface ISpanCalculationInfo {
456
+ colIndex: number;
457
+ colspan: number;
458
+ rowspan: number;
459
+ spanWidth: number;
460
+ startRowIndex: number;
461
+ spanText?: string;
462
+ }
455
463
  export interface IContent {
456
464
  id?: string;
457
465
  text?: string | ((args: ISummaryList) => string);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhtmlx/grid",
3
- "version": "9.3.7",
3
+ "version": "9.3.9",
4
4
  "description": "DHTMLX Grid - JavaScript data grid library. GPL v2 edition for GPL-compatible open-source projects; commercial licenses are available for proprietary and production use.",
5
5
  "keywords": ["dhtmlx","grid","datagrid","table","treegrid","data-table","javascript","typescript"],
6
6
  "homepage":"https://docs.dhtmlx.com/suite/grid/",
package/whatsnew.txt CHANGED
@@ -1,3 +1,30 @@
1
+ # Version 9.3.9 (August 13, 2026)
2
+
3
+ ### Updates
4
+
5
+ - DataCollection/TreeCollection. The `parse()` and `load()` methods now reset existing sorting and filtering. Only filters with `permanent: true` are retained and reapplied to the new dataset
6
+ - Grid. Visual sorting indicators and header filter values are now automatically reset when data is reloaded via `parse()` or `load()`
7
+
8
+ ### Fixes
9
+
10
+ - DataCollection. Fixed inconsistent results in `forEach()` and `map()` when `update()` was called from within the callback while sorting was active
11
+ - Grid. Fixed the duplication of selection overlays on spanned cells when using `selection: "complex"`
12
+ - Grid. Fixed a checkbox click in a sortable column header triggering a sort action
13
+ - Grid. Fixed a bug where an `undefined` CSS class was added to cells when using the `mark` property
14
+ - Grid. Fixed removing a grouped column via its "close" icon starting a column drag action
15
+ - Grid. Resolved an issue where `removeAll()` cleared header filter inputs but failed to reset the underlying filtering rules
16
+ - Grid. Fixed multiselect filtering for columns with `editorType: "multiselect"`; cells are now correctly matched if any of their values satisfy the filter
17
+ - TreeCollection. Fixed an issue where the tree could appear empty after `parse()` if a permanent filter was active
18
+ - TreeCollection. Fixed a bug where items were added twice when inserted into a sorted tree
19
+ - TreeCollection. Fixed the `multi` property of a filtering rule not being passed to the `compare` callback
20
+
21
+ # Version 9.3.8 (August 3, 2026)
22
+
23
+ ### Fixes
24
+
25
+ - Fixed the height calculation for rows with `rowspan` when `autoHeight: true` is enabled, ensuring the container expands to fit the entire spanned content.
26
+ - Resolved an initialization error that occurred when using `autoWidth` with grouped data and an external `TreeCollection`.
27
+
1
28
  # Version 9.3.7 (July 29, 2026)
2
29
 
3
30
  ### Updates