@progress/kendo-angular-dropdowns 21.4.1 → 22.0.0-develop.1

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.
Files changed (84) hide show
  1. package/common/localization/messages.d.ts +1 -1
  2. package/dropdowntrees/checked-state/base-check.directive.d.ts +1 -1
  3. package/fesm2022/progress-kendo-angular-dropdowns.mjs +173 -173
  4. package/package.json +14 -22
  5. package/schematics/ngAdd/index.js +2 -2
  6. package/esm2022/autocomplete/autocomplete.component.mjs +0 -1687
  7. package/esm2022/autocomplete/autocomplete.module.mjs +0 -70
  8. package/esm2022/comboboxes/combobox-column/column-cell-template.directive.mjs +0 -42
  9. package/esm2022/comboboxes/combobox-column/column-header-template.directive.mjs +0 -40
  10. package/esm2022/comboboxes/combobox-column/combobox-column.component.mjs +0 -116
  11. package/esm2022/comboboxes/combobox-column/util.mjs +0 -60
  12. package/esm2022/comboboxes/combobox.component.mjs +0 -2149
  13. package/esm2022/comboboxes/combobox.module.mjs +0 -77
  14. package/esm2022/comboboxes/multicolumncombobox.component.mjs +0 -883
  15. package/esm2022/common/adaptive-renderer.component.mjs +0 -253
  16. package/esm2022/common/constants/error-messages.mjs +0 -61
  17. package/esm2022/common/data.service.mjs +0 -250
  18. package/esm2022/common/disabled-items/disabled-items.service.mjs +0 -47
  19. package/esm2022/common/disabled-items/item-disabled.mjs +0 -5
  20. package/esm2022/common/filter-input.directive.mjs +0 -39
  21. package/esm2022/common/filtering/filter-settings.mjs +0 -5
  22. package/esm2022/common/filtering/filter.directive.mjs +0 -136
  23. package/esm2022/common/filtering/filterable-component.mjs +0 -34
  24. package/esm2022/common/list-item.directive.mjs +0 -25
  25. package/esm2022/common/list.component.mjs +0 -968
  26. package/esm2022/common/localization/custom-messages.component.mjs +0 -96
  27. package/esm2022/common/localization/localized-messages.directive.mjs +0 -47
  28. package/esm2022/common/localization/messages.mjs +0 -77
  29. package/esm2022/common/models/checkboxes-settings.mjs +0 -15
  30. package/esm2022/common/models/direction.mjs +0 -5
  31. package/esm2022/common/models/fillmode.mjs +0 -5
  32. package/esm2022/common/models/list-type.mjs +0 -5
  33. package/esm2022/common/models/page-change-event.mjs +0 -5
  34. package/esm2022/common/models/popup-settings.mjs +0 -5
  35. package/esm2022/common/models/preventable-event.mjs +0 -25
  36. package/esm2022/common/models/remove-tag-event.mjs +0 -23
  37. package/esm2022/common/models/rounded.mjs +0 -5
  38. package/esm2022/common/models/size.mjs +0 -5
  39. package/esm2022/common/models/virtualization-settings.mjs +0 -24
  40. package/esm2022/common/navigation/navigation-action.mjs +0 -32
  41. package/esm2022/common/navigation/navigation.service.mjs +0 -188
  42. package/esm2022/common/searchbar.component.mjs +0 -386
  43. package/esm2022/common/selection/selectable.directive.mjs +0 -83
  44. package/esm2022/common/selection/selection.service.mjs +0 -166
  45. package/esm2022/common/shared-events.directive.mjs +0 -99
  46. package/esm2022/common/taglist.component.mjs +0 -295
  47. package/esm2022/common/templates/custom-item-template.directive.mjs +0 -48
  48. package/esm2022/common/templates/fixed-group-template.directive.mjs +0 -55
  49. package/esm2022/common/templates/footer-template.directive.mjs +0 -49
  50. package/esm2022/common/templates/group-tag-template.directive.mjs +0 -47
  51. package/esm2022/common/templates/group-template.directive.mjs +0 -55
  52. package/esm2022/common/templates/header-template.directive.mjs +0 -49
  53. package/esm2022/common/templates/item-template.directive.mjs +0 -48
  54. package/esm2022/common/templates/no-data-template.directive.mjs +0 -49
  55. package/esm2022/common/templates/tag-template.directive.mjs +0 -46
  56. package/esm2022/common/templates/value-template.directive.mjs +0 -50
  57. package/esm2022/common/util.mjs +0 -376
  58. package/esm2022/directives.mjs +0 -172
  59. package/esm2022/dropdownlist/dropdownlist.component.mjs +0 -1999
  60. package/esm2022/dropdownlist/dropdownlist.module.mjs +0 -79
  61. package/esm2022/dropdowns.module.mjs +0 -76
  62. package/esm2022/dropdowntrees/checked-state/base-check.directive.mjs +0 -76
  63. package/esm2022/dropdowntrees/checked-state/check-all.directive.mjs +0 -170
  64. package/esm2022/dropdowntrees/checked-state/check.directive.mjs +0 -168
  65. package/esm2022/dropdowntrees/checked-state/checkable-settings.mjs +0 -5
  66. package/esm2022/dropdowntrees/checked-state/checked-item.mjs +0 -5
  67. package/esm2022/dropdowntrees/data-binding/dropdowntree/flat-binding.directive.mjs +0 -69
  68. package/esm2022/dropdowntrees/data-binding/dropdowntree/hierarchy-binding.directive.mjs +0 -62
  69. package/esm2022/dropdowntrees/data-binding/multiselecttree/flat-binding.directive.mjs +0 -69
  70. package/esm2022/dropdowntrees/data-binding/multiselecttree/hierarchy-binding.directive.mjs +0 -62
  71. package/esm2022/dropdowntrees/dropdowntree.component.mjs +0 -1967
  72. package/esm2022/dropdowntrees/dropdowntrees.module.mjs +0 -79
  73. package/esm2022/dropdowntrees/expanded-state/expand.directive.mjs +0 -49
  74. package/esm2022/dropdowntrees/lookup/lookup.mjs +0 -5
  75. package/esm2022/dropdowntrees/lookup/lookup.service.mjs +0 -82
  76. package/esm2022/dropdowntrees/multiselecttree.component.mjs +0 -2359
  77. package/esm2022/dropdowntrees/summary-tag/summary-tag.directive.mjs +0 -70
  78. package/esm2022/dropdowntrees/templates/node-template.directive.mjs +0 -31
  79. package/esm2022/index.mjs +0 -55
  80. package/esm2022/multiselect/multiselect.component.mjs +0 -2380
  81. package/esm2022/multiselect/multiselect.module.mjs +0 -79
  82. package/esm2022/multiselect/summary-tag.directive.mjs +0 -68
  83. package/esm2022/package-metadata.mjs +0 -16
  84. package/esm2022/progress-kendo-angular-dropdowns.mjs +0 -8
@@ -1,2380 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { isPresent, isArray, isObjectArray, resolveAllValues, selectedIndices, getter, isNumber, isUntouched, inDropDown, getSizeClass, getRoundedClass, getFillModeClass, animationDuration, isTruthy, setListBoxAriaLabelledBy, setActionSheetTitle } from '../common/util';
6
- import { SearchBarComponent } from '../common/searchbar.component';
7
- import { ViewChild, Renderer2, ViewContainerRef, Component, HostBinding, Input, ElementRef, TemplateRef, Output, EventEmitter, isDevMode, forwardRef, ContentChild, ChangeDetectorRef, KeyValueDiffers, NgZone, Injector } from '@angular/core';
8
- import { Subscription, Subject, of, merge } from 'rxjs';
9
- import { isChanged, isDocumentAvailable, KendoInput, hasObservers, anyChanged, SuffixTemplateDirective, PrefixTemplateDirective, isControlRequired, SeparatorComponent, ResizeSensorComponent, Keys, TemplateContextDirective, guid, normalizeKeys, parseCSSClassNames } from '@progress/kendo-angular-common';
10
- import { AdaptiveService } from '@progress/kendo-angular-utils';
11
- import { catchError, filter, map, take, tap } from 'rxjs/operators';
12
- import { NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
13
- import { validatePackage } from '@progress/kendo-licensing';
14
- import { packageMetadata } from '../package-metadata';
15
- import { SelectionService } from '../common/selection/selection.service';
16
- import { NavigationService } from '../common/navigation/navigation.service';
17
- import { NavigationAction } from '../common/navigation/navigation-action';
18
- import { DisabledItemsService } from '../common/disabled-items/disabled-items.service';
19
- import { ItemTemplateDirective } from '../common/templates/item-template.directive';
20
- import { CustomItemTemplateDirective } from '../common/templates/custom-item-template.directive';
21
- import { GroupTemplateDirective } from '../common/templates/group-template.directive';
22
- import { FixedGroupTemplateDirective } from '../common/templates/fixed-group-template.directive';
23
- import { HeaderTemplateDirective } from '../common/templates/header-template.directive';
24
- import { FooterTemplateDirective } from '../common/templates/footer-template.directive';
25
- import { TagTemplateDirective } from '../common/templates/tag-template.directive';
26
- import { GroupTagTemplateDirective } from '../common/templates/group-tag-template.directive';
27
- import { NoDataTemplateDirective } from '../common/templates/no-data-template.directive';
28
- import { MultiselectMessages } from '../common/constants/error-messages';
29
- import { PreventableEvent } from '../common/models/preventable-event';
30
- import { RemoveTagEvent } from '../common/models/remove-tag-event';
31
- import { LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
32
- import { PopupService } from '@progress/kendo-angular-popup';
33
- import { FilterableComponent } from '../common/filtering/filterable-component';
34
- import { DataService } from '../common/data.service';
35
- import { ListComponent } from '../common/list.component';
36
- import { normalizeCheckboxesSettings } from '../common/models/checkboxes-settings';
37
- import { normalizeVirtualizationSettings } from '../common/models/virtualization-settings';
38
- import { xIcon } from '@progress/kendo-svg-icons';
39
- import { AdaptiveRendererComponent } from '../common/adaptive-renderer.component';
40
- import { TagListComponent } from '../common/taglist.component';
41
- import { NgTemplateOutlet } from '@angular/common';
42
- import { SharedDropDownEventsDirective } from '../common/shared-events.directive';
43
- import { LocalizedMessagesDirective } from '../common/localization/localized-messages.directive';
44
- import { IconWrapperComponent } from '@progress/kendo-angular-icons';
45
- import { touchEnabled } from '@progress/kendo-common';
46
- import * as i0 from "@angular/core";
47
- import * as i1 from "@progress/kendo-angular-l10n";
48
- import * as i2 from "@progress/kendo-angular-popup";
49
- import * as i3 from "../common/data.service";
50
- import * as i4 from "../common/selection/selection.service";
51
- import * as i5 from "../common/navigation/navigation.service";
52
- import * as i6 from "../common/disabled-items/disabled-items.service";
53
- import * as i7 from "@progress/kendo-angular-utils";
54
- const MULTISELECT_VALUE_ACCESSOR = {
55
- multi: true,
56
- provide: NG_VALUE_ACCESSOR,
57
- useExisting: forwardRef(() => MultiSelectComponent)
58
- };
59
- const DEFAULT_SIZE = 'medium';
60
- const DEFAULT_ROUNDED = 'medium';
61
- const DEFAULT_FILL_MODE = 'solid';
62
- /**
63
- * Represents the [Kendo UI MultiSelect component for Angular]({% slug overview_multiselect %}).
64
- *
65
- * Use the `MultiSelectComponent` to show a dropdown list where users can select multiple items.
66
- * [See example]({% slug overview_multiselect %}).
67
- *
68
- * @example
69
- * ```typescript
70
- * @Component({
71
- * selector: 'my-app',
72
- * template: `
73
- * <kendo-multiselect
74
- * [data]="listItems"
75
- * textField="name"
76
- * valueField="id"
77
- * placeholder="Select items...">
78
- * </kendo-multiselect>
79
- * `
80
- * })
81
- * export class AppComponent {
82
- * public listItems = [
83
- * { id: 1, name: "Item 1" },
84
- * { id: 2, name: "Item 2" },
85
- * { id: 3, name: "Item 3" }
86
- * ];
87
- * }
88
- * ```
89
- * @remarks
90
- * Supported children components are: {@link CustomMessagesComponent}.
91
- */
92
- export class MultiSelectComponent {
93
- wrapper;
94
- localization;
95
- popupService;
96
- dataService;
97
- selectionService;
98
- navigationService;
99
- disabledItemsService;
100
- cdr;
101
- differs;
102
- renderer;
103
- _zone;
104
- injector;
105
- hostElement;
106
- adaptiveService;
107
- /**
108
- * @hidden
109
- */
110
- animationDuration = animationDuration;
111
- /**
112
- * @hidden
113
- */
114
- xIcon = xIcon;
115
- listBoxId = `k-${guid()}`;
116
- tagListId = `k-${guid()}`;
117
- tagPrefix = "tag-" + guid();
118
- optionPrefix = "option-" + guid();
119
- popupRef;
120
- text;
121
- tags;
122
- focusedTagIndex = undefined;
123
- /**
124
- * @hidden
125
- */
126
- adaptiveRendererComponent;
127
- /**
128
- * @hidden
129
- */
130
- get actionSheet() {
131
- return this.adaptiveRendererComponent?.actionSheet;
132
- }
133
- /**
134
- * @hidden
135
- */
136
- get actionSheetSearchBar() {
137
- return this.adaptiveRendererComponent?.actionSheetSearchBar;
138
- }
139
- /**
140
- * @hidden
141
- */
142
- get ariaControls() {
143
- return this.isOpen ? this.listBoxId : undefined;
144
- }
145
- /**
146
- * @hidden
147
- */
148
- get isControlRequired() {
149
- return isControlRequired(this.formControl);
150
- }
151
- /**
152
- * @hidden
153
- */
154
- get formControl() {
155
- const ngControl = this.injector.get(NgControl, null);
156
- return ngControl?.control || null;
157
- }
158
- /**
159
- * Focuses a specific item in the MultiSelect based on the provided index.
160
- * Sets the index to `-1` to focus the custom item if available.
161
- * Pass `null` or an invalid index to remove focus.
162
- */
163
- focusItemAt(index) {
164
- const minIndex = this.allowCustom ? -1 : 0;
165
- const isInRange = minIndex <= 0 && index < this.data.length;
166
- if (isPresent(index) && isInRange && !this.disabledItemsService.isIndexDisabled(index)) {
167
- this.selectionService.focus(index);
168
- }
169
- else {
170
- this.selectionService.focus(null);
171
- }
172
- }
173
- /**
174
- * Focuses the MultiSelect input element.
175
- */
176
- focus() {
177
- if (!this.disabled) {
178
- this.searchbar.focus();
179
- }
180
- }
181
- /**
182
- * @hidden
183
- */
184
- handleInputFocus() {
185
- this.handleFocus();
186
- if (hasObservers(this.inputFocus)) {
187
- this._zone.run(() => {
188
- this.inputFocus.emit();
189
- });
190
- }
191
- }
192
- /**
193
- * Removes focus from the MultiSelect input element.
194
- */
195
- blur() {
196
- if (!this.disabled) {
197
- this.searchbar.blur();
198
- }
199
- }
200
- /**
201
- * @hidden
202
- */
203
- handleFocus() {
204
- this._zone.run(() => {
205
- if (!this.isFocused && hasObservers(this.onFocus)) {
206
- this.onFocus.emit();
207
- }
208
- this.isFocused = true;
209
- });
210
- }
211
- /**
212
- * @hidden
213
- */
214
- handleBlur() {
215
- if (!this.isActionSheetExpanded) {
216
- this.blurComponent();
217
- }
218
- }
219
- /**
220
- * @hidden
221
- */
222
- handleInputBlur() {
223
- if (!this.isActionSheetExpanded) {
224
- if (!this.isFocused) {
225
- return;
226
- }
227
- if (hasObservers(this.inputBlur) ||
228
- hasObservers(this.filterChange) ||
229
- hasObservers(this.close) ||
230
- isUntouched(this.wrapper.nativeElement) ||
231
- this.formControl?.updateOn === 'blur') {
232
- this._zone.run(() => {
233
- this.closePopup();
234
- if (!(this.isOpen && this.allowCustom)) {
235
- this.clearFilter();
236
- }
237
- this.inputBlur.emit();
238
- this.onTouchedCallback();
239
- });
240
- }
241
- else {
242
- if (!this.allowCustom) {
243
- this.clearFilter();
244
- }
245
- this.closePopup();
246
- }
247
- }
248
- }
249
- /**
250
- * @hidden
251
- */
252
- onPointerDown(event) {
253
- event.preventDefault();
254
- }
255
- /**
256
- * @hidden
257
- */
258
- onResize() {
259
- const currentWindowSize = this.adaptiveService.size;
260
- if (this.isAdaptiveModeEnabled && this.windowSize !== currentWindowSize) {
261
- if (this.isOpen) {
262
- this.togglePopup(false);
263
- }
264
- this.windowSize = currentWindowSize;
265
- this.cdr.detectChanges();
266
- }
267
- if (this.isOpen && !this.isActionSheetExpanded) {
268
- const popupWrapper = this.popupRef.popupElement;
269
- const { min, max } = this.width;
270
- popupWrapper.style.minWidth = min;
271
- popupWrapper.style.width = max;
272
- }
273
- }
274
- get appendTo() {
275
- const { appendTo } = this.popupSettings;
276
- if (!appendTo || appendTo === 'root') {
277
- return undefined;
278
- }
279
- return appendTo === 'component' ? this.container : appendTo;
280
- }
281
- /**
282
- * Shows or hides the current group sticky header when using grouped data.
283
- * By default the sticky header is displayed ([see example]({% slug grouping_autocomplete %}#toc-sticky-header)).
284
- */
285
- showStickyHeader = true;
286
- /**
287
- * @hidden
288
- */
289
- focusableId = `k-${guid()}`;
290
- /**
291
- * Controls whether the options list closes after item selection finishes ([see example]({% slug openstate_multiselect %}#toc-keeping-the-options-list-open-while-on-focus)).
292
- * Set to `false` to keep the list open while the component has focus.
293
- *
294
- * @default true
295
- */
296
- autoClose = true;
297
- /**
298
- * Controls the loading state of the MultiSelect.
299
- * Set to `true` to display the loading indicator.
300
- */
301
- loading;
302
- /**
303
- * Sets the data source for the MultiSelect.
304
- * Provide the data as an array of items.
305
- */
306
- set data(data) {
307
- this.dataService.data = data || [];
308
- if (this.virtual) {
309
- this.virtual.skip = 0;
310
- }
311
- if (this.initialized) {
312
- this.setState(this.value);
313
- }
314
- }
315
- get data() {
316
- const virtual = this.virtual;
317
- if (virtual) {
318
- const start = virtual.skip || 0;
319
- const end = start + virtual.pageSize;
320
- //Use length instead of itemsCount because of grouping
321
- virtual.total = this.dataService.data.length;
322
- return this.dataService.data.slice(start, end);
323
- }
324
- return this.dataService.data;
325
- }
326
- /**
327
- * Sets the selected values of the MultiSelect.
328
- * Accepts primitive values (strings, numbers) or complex objects.
329
- * Use the `valuePrimitive` property to define the value type.
330
- * > The component ignores selected values that don't exist in the data source.
331
- */
332
- set value(values) {
333
- this._value = values ? values : [];
334
- if (!this.differ && this.value) {
335
- this.differ = this.differs.find(this.value).create();
336
- }
337
- this.valueChangeDetected = true;
338
- if (this.initialized) {
339
- this.setState(this.value);
340
- }
341
- }
342
- get value() {
343
- return this._value;
344
- }
345
- /**
346
- * Sets the field name that contains the item value in the data objects.
347
- * Skip this property when your data contains only primitive values.
348
- * Supports nested property paths like `category.id`.
349
- */
350
- valueField;
351
- /**
352
- * Sets the field name that contains the item text in the data objects.
353
- * Skip this property when your data contains only primitive values.
354
- * Supports nested property paths like `category.name`.
355
- */
356
- textField;
357
- /**
358
- * Sets the [`tabindex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) attribute of the component.
359
- *
360
- * @default 0
361
- */
362
- tabindex = 0;
363
- /**
364
- * @hidden
365
- */
366
- set tabIndex(tabIndex) {
367
- this.tabindex = tabIndex;
368
- }
369
- get tabIndex() {
370
- return this.tabindex;
371
- }
372
- /**
373
- * Sets the size of the component.
374
- *
375
- * @default "medium"
376
- */
377
- set size(size) {
378
- const newSize = size ? size : DEFAULT_SIZE;
379
- this.renderer.removeClass(this.wrapper.nativeElement, getSizeClass('input', this.size));
380
- if (size !== 'none') {
381
- this.renderer.addClass(this.wrapper.nativeElement, getSizeClass('input', newSize));
382
- }
383
- this._size = newSize;
384
- }
385
- get size() {
386
- return this._size;
387
- }
388
- /**
389
- * Sets the border radius of the component.
390
- *
391
- * @default "medium"
392
- */
393
- set rounded(rounded) {
394
- const newRounded = rounded ? rounded : DEFAULT_ROUNDED;
395
- this.renderer.removeClass(this.wrapper.nativeElement, getRoundedClass(this.rounded));
396
- if (rounded !== 'none') {
397
- this.renderer.addClass(this.wrapper.nativeElement, getRoundedClass(newRounded));
398
- }
399
- this._rounded = newRounded;
400
- }
401
- get rounded() {
402
- return this._rounded;
403
- }
404
- /**
405
- * Sets the fill mode of the component.
406
- *
407
- * @default "solid"
408
- */
409
- set fillMode(fillMode) {
410
- const newFillMode = fillMode ? fillMode : DEFAULT_FILL_MODE;
411
- this.renderer.removeClass(this.wrapper.nativeElement, getFillModeClass('input', this.fillMode));
412
- if (fillMode !== 'none') {
413
- this.renderer.addClass(this.wrapper.nativeElement, getFillModeClass('input', newFillMode));
414
- }
415
- this._fillMode = newFillMode;
416
- }
417
- get fillMode() {
418
- return this._fillMode;
419
- }
420
- /**
421
- * Sets the placeholder text for the MultiSelect input.
422
- * When the values are selected, it disappears.
423
- */
424
- set placeholder(text) {
425
- this._placeholder = text || '';
426
- }
427
- get placeholder() {
428
- return this.selectedDataItems.length ? '' : this._placeholder;
429
- }
430
- /**
431
- * Controls the adaptive mode behavior of the component.
432
- * Set to `auto` to enable adaptive rendering on small screens.
433
- *
434
- * @default "none"
435
- */
436
- adaptiveMode = 'none';
437
- /**
438
- * Sets the title text for the ActionSheet in adaptive mode.
439
- * Uses the component's label text by default.
440
- */
441
- adaptiveTitle = '';
442
- /**
443
- * Sets the subtitle text for the ActionSheet in adaptive mode.
444
- * No subtitle appears by default.
445
- */
446
- adaptiveSubtitle;
447
- /**
448
- * @hidden
449
- */
450
- get isAdaptiveModeEnabled() {
451
- return this.adaptiveMode === 'auto';
452
- }
453
- /**
454
- * Controls the disabled state of the component.
455
- * When true, sets the component to disabled.
456
- * To learn how to disable the component in reactive forms, refer to the article on [Forms Support](slug:formssupport_multiselect#toc-managing-the-multiselect-disabled-state-in-reactive-forms).
457
- *
458
- * @default false
459
- */
460
- disabled = false;
461
- /**
462
- * Determines wether the item will be disabled. The function is executed for each data item.
463
- * The function receives the item as an argument and should return `true` if the item is disabled.
464
- */
465
- set itemDisabled(fn) {
466
- if (typeof fn !== 'function') {
467
- throw new Error(`itemDisabled must be a function, but received ${JSON.stringify(fn)}.`);
468
- }
469
- this.disabledItemsService.itemDisabled = fn;
470
- }
471
- /**
472
- * Controls whether checkboxes appear before each item in the popup list.
473
- * Pass `true` to enable checkboxes or an object to configure checkbox settings.
474
- *
475
- * @default false
476
- */
477
- set checkboxes(settings) {
478
- this._checkboxes = normalizeCheckboxesSettings(settings);
479
- }
480
- get checkboxes() {
481
- return this._checkboxes;
482
- }
483
- /**
484
- * Controls the read-only state of the component.
485
- * When true, the component does not allow user input or selection changes.
486
- *
487
- * @default false
488
- */
489
- readonly = false;
490
- /**
491
- * Enables the filtering functionality of the MultiSelect.
492
- * Set to `true` to allow users to filter the data by typing.
493
- *
494
- * @default false
495
- */
496
- filterable = false;
497
- /**
498
- * Enables virtualization to improve performance with large datasets.
499
- * Pass `true` for default settings or an object to configure virtualization.
500
- */
501
- set virtual(settings) {
502
- this._virtualSettings = normalizeVirtualizationSettings(settings);
503
- }
504
- get virtual() {
505
- return this._virtualSettings;
506
- }
507
- /**
508
- * Configures the popup appearance and behavior.
509
- * Set properties like `animate`, `width`, `height`, `popupClass`, and `appendTo`.
510
- */
511
- set popupSettings(settings) {
512
- this._popupSettings = Object.assign({ animate: true }, settings);
513
- }
514
- get popupSettings() {
515
- return this._popupSettings;
516
- }
517
- /**
518
- * Sets the height of the options list in the popup.
519
- * This affects only the list height, not the entire popup container.
520
- *
521
- * @default 200
522
- */
523
- set listHeight(_listHeight) {
524
- this._listHeight = _listHeight;
525
- }
526
- get listHeight() {
527
- if (this.isAdaptive) {
528
- return;
529
- }
530
- return this._listHeight;
531
- }
532
- _listHeight = 200;
533
- /**
534
- * Controls the type of selected values.
535
- * Set to `true` for primitive values or `false` for object references.
536
- * When undefined, the component determines the type based on `valueField`.
537
- */
538
- set valuePrimitive(isPrimitive) {
539
- this._valuePrimitive = isPrimitive;
540
- }
541
- get valuePrimitive() {
542
- if (!isPresent(this._valuePrimitive)) {
543
- return !isPresent(this.valueField);
544
- }
545
- return this._valuePrimitive;
546
- }
547
- /**
548
- * Controls whether a clear button appears when items are selected.
549
- * Set to `true` to show the button that clears all selections.
550
- *
551
- * @default true
552
- */
553
- clearButton = true;
554
- /**
555
- * Sets a function that transforms selected data items into display tags.
556
- * Use this to customize how selected items appear as tags.
557
- *
558
- * @default (tags) => tags || []
559
- */
560
- tagMapper = (tags) => tags || [];
561
- /**
562
- * Allows users to add custom values not present in the data source.
563
- * Set to `true` to enable custom value input.
564
- * This feature is not available in adaptive mode.
565
- *
566
- * @default false
567
- */
568
- allowCustom = false;
569
- /**
570
- * Sets a function that normalizes custom user input into data items.
571
- * Use this when your data items differ from simple strings.
572
- */
573
- valueNormalizer = (text) => text.pipe(map((userInput) => {
574
- const comparer = (item) => typeof item === 'string' && userInput.toLowerCase() === item.toLowerCase();
575
- const matchingValue = this.value.find(comparer);
576
- if (matchingValue) {
577
- return matchingValue;
578
- }
579
- const matchingItem = this.dataService.find(comparer);
580
- return matchingItem ? matchingItem : userInput;
581
- }));
582
- /**
583
- * Sets HTML attributes for the inner input element.
584
- * You cannot change attributes essential for component functionality.
585
- */
586
- inputAttributes;
587
- /**
588
- * Fires when the user types in the input field.
589
- * Use this event to filter the data source based on user input.
590
- */
591
- filterChange = new EventEmitter();
592
- /**
593
- * Fires when the value changes through user interaction or the Clear button.
594
- * This event does not fire when you change the value programmatically.
595
- */
596
- valueChange = new EventEmitter();
597
- /**
598
- * Fires before the popup opens.
599
- * You can prevent the popup from opening by calling `preventDefault()` on the event.
600
- */
601
- open = new EventEmitter();
602
- /**
603
- * Fires after the popup opens completely.
604
- */
605
- opened = new EventEmitter();
606
- /**
607
- * Fires before the popup closes.
608
- * You can prevent the popup from closing by calling `preventDefault()` on the event.
609
- */
610
- close = new EventEmitter();
611
- /**
612
- * Fires after the popup closes completely.
613
- */
614
- closed = new EventEmitter();
615
- /**
616
- * Fires when the user focuses the MultiSelect component.
617
- */
618
- onFocus = new EventEmitter();
619
- /**
620
- * Fires when the MultiSelect component loses focus.
621
- */
622
- onBlur = new EventEmitter();
623
- /**
624
- * Fires when the user focuses the input element inside the MultiSelect.
625
- */
626
- inputFocus = new EventEmitter();
627
- /**
628
- * Fires when the input element inside the MultiSelect loses focus.
629
- */
630
- inputBlur = new EventEmitter();
631
- /**
632
- * Fires before a tag gets removed from the selection.
633
- * You can prevent tag removal by calling `preventDefault()` on the event.
634
- */
635
- removeTag = new EventEmitter();
636
- container;
637
- searchbar;
638
- tagList;
639
- popupTemplate;
640
- optionsList;
641
- template;
642
- customItemTemplate;
643
- groupTemplate;
644
- fixedGroupTemplate;
645
- headerTemplate;
646
- footerTemplate;
647
- tagTemplate;
648
- groupTagTemplate;
649
- noDataTemplate;
650
- /**
651
- * @hidden
652
- */
653
- suffixTemplate;
654
- /**
655
- * @hidden
656
- */
657
- prefixTemplate;
658
- hostClasses = true;
659
- get dir() {
660
- return this.direction;
661
- }
662
- get disabledClass() {
663
- return this.disabled;
664
- }
665
- get isLoading() {
666
- return this.loading;
667
- }
668
- /**
669
- * @hidden
670
- */
671
- windowSize = 'large';
672
- /**
673
- * @hidden
674
- */
675
- get isActionSheetExpanded() {
676
- return this.actionSheet?.expanded;
677
- }
678
- /**
679
- * @hidden
680
- */
681
- get isAdaptive() {
682
- return this.isAdaptiveModeEnabled && this.windowSize !== 'large';
683
- }
684
- /**
685
- * @hidden
686
- */
687
- applyValue() {
688
- if (!this.isActionSheetExpanded) {
689
- return;
690
- }
691
- const isValueChanged = !(this.value.every(i => this._valueHolder.find(item => i === item)) && this._valueHolder.length === this.value.length);
692
- if (isValueChanged) {
693
- this.value = this._valueHolder;
694
- this._valueHolder = [];
695
- this.emitValueChange();
696
- }
697
- this.clearFilter();
698
- this.togglePopup(false);
699
- if (this.allowCustom && this.isCustomValueSelected) {
700
- this.isCustomValueSelected = false;
701
- }
702
- }
703
- disabledIndices;
704
- initialized = false;
705
- _size = 'medium';
706
- _rounded = 'medium';
707
- _fillMode = 'solid';
708
- _valueHolder = [];
709
- isCustomValueSelected = false;
710
- constructor(wrapper, localization, popupService, dataService, selectionService, navigationService, disabledItemsService, cdr, differs, renderer, _zone, injector, hostElement, adaptiveService) {
711
- this.wrapper = wrapper;
712
- this.localization = localization;
713
- this.popupService = popupService;
714
- this.dataService = dataService;
715
- this.selectionService = selectionService;
716
- this.navigationService = navigationService;
717
- this.disabledItemsService = disabledItemsService;
718
- this.cdr = cdr;
719
- this.differs = differs;
720
- this.renderer = renderer;
721
- this._zone = _zone;
722
- this.injector = injector;
723
- this.hostElement = hostElement;
724
- this.adaptiveService = adaptiveService;
725
- validatePackage(packageMetadata);
726
- this.popupPointerDownHandler = this.onPointerDown.bind(this);
727
- this.data = [];
728
- this.direction = this.localization.rtl ? 'rtl' : 'ltr';
729
- this.subscribeEvents();
730
- this.subscribeTouchEvents();
731
- }
732
- get listContainerClasses() {
733
- const containerClasses = ['k-list-container', 'k-multiselect-popup'];
734
- if (!this.popupSettings.popupClass) {
735
- return containerClasses;
736
- }
737
- const parsedPopupClasses = parseCSSClassNames(this.popupSettings.popupClass);
738
- if (parsedPopupClasses?.length) {
739
- containerClasses.push(...parsedPopupClasses);
740
- }
741
- return containerClasses;
742
- }
743
- /**
744
- * @hidden
745
- */
746
- get customItemSizeClass() {
747
- const currentSize = this.isAdaptive ? 'large' : this.size;
748
- return `${currentSize ? getSizeClass('list', currentSize) : ''}`;
749
- }
750
- get width() {
751
- let wrapperOffsetWidth = 0;
752
- if (isDocumentAvailable()) {
753
- wrapperOffsetWidth = this.wrapper.nativeElement.offsetWidth;
754
- }
755
- const width = this.popupSettings.width || wrapperOffsetWidth;
756
- const minWidth = isNaN(wrapperOffsetWidth) ? wrapperOffsetWidth : `${wrapperOffsetWidth}px`;
757
- const maxWidth = isNaN(width) ? width : `${width}px`;
758
- return { min: minWidth, max: maxWidth };
759
- }
760
- get height() {
761
- const popupHeight = this.popupSettings.height;
762
- return isPresent(popupHeight) ? `${popupHeight}px` : 'auto';
763
- }
764
- get activeDescendant() {
765
- const focusedTagIndex = this.focusedTagIndex;
766
- const focusedListIndex = this.selectionService.focused;
767
- let prefix;
768
- let focusedIndex;
769
- if (isPresent(focusedTagIndex) && !this.isOpen) {
770
- focusedIndex = focusedTagIndex;
771
- prefix = this.tagPrefix;
772
- }
773
- else if (isPresent(focusedListIndex) && focusedListIndex !== -1 && this.isOpen) {
774
- focusedIndex = focusedListIndex;
775
- prefix = this.optionPrefix;
776
- }
777
- else {
778
- return null;
779
- }
780
- return prefix + "-" + focusedIndex;
781
- }
782
- get clearButtonVisibility() {
783
- if (touchEnabled) {
784
- return 'visible';
785
- }
786
- }
787
- /**
788
- * @hidden
789
- */
790
- verifySettings() {
791
- if (!isDevMode() || this.value.length === 0) {
792
- return;
793
- }
794
- if (!isArray(this.value)) {
795
- throw new Error(MultiselectMessages.array);
796
- }
797
- if (this.valuePrimitive === true && isObjectArray(this.value)) {
798
- throw new Error(MultiselectMessages.primitive);
799
- }
800
- if (this.valuePrimitive === false && !isObjectArray(this.value)) {
801
- throw new Error(MultiselectMessages.object);
802
- }
803
- const valueOrText = !isPresent(this.valueField) !== !isPresent(this.textField);
804
- if (valueOrText) {
805
- throw new Error(MultiselectMessages.textAndValue);
806
- }
807
- }
808
- /**
809
- * @hidden
810
- */
811
- change(event) {
812
- if (event.isMultipleSelection) {
813
- // Existing items.
814
- if (isPresent(event.added) && event.added.length > 0) {
815
- event.added.forEach((itemIndex) => {
816
- const dataItem = this.dataService.itemAt(itemIndex);
817
- const newItem = (this.valuePrimitive && isPresent(dataItem) && isPresent(getter(dataItem, this.valueField))) ? getter(dataItem, this.valueField) : dataItem;
818
- if (newItem) {
819
- if (!this.isAdaptive || !this.isActionSheetExpanded) {
820
- this.value = [...this.value, newItem];
821
- }
822
- else {
823
- this._valueHolder = [...this._valueHolder, newItem];
824
- }
825
- }
826
- });
827
- }
828
- if (isPresent(event.removed) && event.removed.length > 0) {
829
- event.removed.forEach((itemIndex) => {
830
- const dataItem = this.dataService.itemAt(itemIndex);
831
- const filter = (item) => getter(item, this.valueField) !== getter(dataItem, this.valueField);
832
- if (!this.isAdaptive || !this.isActionSheetExpanded) {
833
- this.value = this.value.filter(filter);
834
- }
835
- else {
836
- this._valueHolder = this._valueHolder.filter(filter);
837
- }
838
- });
839
- this.cdr.detectChanges();
840
- }
841
- }
842
- else {
843
- const isCustomItem = (isPresent(event.added) || isPresent(event.removed)) && (event.added === -1 || event.removed === -1);
844
- if (isCustomItem) {
845
- this.addCustomValue(this.text);
846
- return; // The change is emited asynchronosly.
847
- }
848
- // Existing items.
849
- if (isPresent(event.added)) {
850
- const dataItem = this.dataService.itemAt(event.added);
851
- const newItem = (this.valuePrimitive && isPresent(dataItem) && isPresent(getter(dataItem, this.valueField))) ? getter(dataItem, this.valueField) : dataItem;
852
- if (!this.isAdaptive || !this.isActionSheetExpanded) {
853
- this.value = [...this.value, newItem];
854
- }
855
- else {
856
- this._valueHolder = [...this._valueHolder, newItem];
857
- }
858
- }
859
- if (isPresent(event.removed)) {
860
- const dataItem = this.dataService.itemAt(event.removed);
861
- const filter = (item) => getter(item, this.valueField) !== getter(dataItem, this.valueField);
862
- if (!this.isAdaptive || !this.isActionSheetExpanded) {
863
- this.value = this.value.filter(filter);
864
- }
865
- else {
866
- this._valueHolder = this._valueHolder.filter(filter);
867
- }
868
- this.selectionService.focused = event.removed;
869
- this.cdr.detectChanges();
870
- }
871
- }
872
- if (!this.isAdaptive || !this.isActionSheetExpanded) {
873
- this.emitValueChange();
874
- }
875
- }
876
- /**
877
- * @hidden
878
- */
879
- setState(value) {
880
- let data = this.dataService.data;
881
- if (this.dataService.grouped) {
882
- data = data.filter(item => !item.header).map(item => item.value);
883
- }
884
- const selection = selectedIndices(this.value, data, this.valueField);
885
- this.selectionService.resetSelection(selection);
886
- if (this.disabledItemsService.isIndexDisabled(this.selectionService.focused)) {
887
- this.selectionService.focused = this.firstFocusableIndex(0);
888
- }
889
- if (this.isOpen && this.selectionService.focused === undefined) {
890
- if (this.dataService.itemsCount > 0) {
891
- this.selectionService.focused = this.firstFocusableIndex(0);
892
- if (this.allowCustom) {
893
- this.selectionService.focused = 0;
894
- }
895
- }
896
- else if (this.allowCustom) {
897
- this.selectionService.focused = -1;
898
- }
899
- }
900
- if (this.valuePrimitive && !this.valueField) {
901
- this.selectedDataItems = value.slice();
902
- }
903
- if (isObjectArray(value) || this.valuePrimitive && this.valueField) {
904
- this.selectedDataItems = resolveAllValues(value, data, this.valueField);
905
- }
906
- if (this.selectedDataItems.length < value.length) {
907
- this.selectedDataItems = value
908
- .map(current => {
909
- const dataItem = this.selectedDataItems.find(item => getter(item, this.valueField) === getter(current, this.valueField));
910
- return isPresent(dataItem) ? dataItem : this.resolveDataItemFromTags(current);
911
- })
912
- .filter(dataItem => isPresent(dataItem));
913
- }
914
- this.tags = this.tagMapper(this.selectedDataItems.slice(0));
915
- this.disabledIndices = this.disabledItemsMapper();
916
- this.cdr.markForCheck();
917
- }
918
- /**
919
- * @hidden
920
- */
921
- handleFilter(text) {
922
- if (this.isActionSheetExpanded && this.allowCustom && this.isCustomValueSelected) {
923
- this.addCustomValue(this.text);
924
- this.addCustomValue(text);
925
- }
926
- this.text = text;
927
- if (text && !this.isOpen) {
928
- this.openPopup();
929
- }
930
- if (this.filterable) {
931
- this.filterChange.emit(text);
932
- }
933
- else {
934
- this.searchTextAndFocus(text);
935
- }
936
- this.searchbar.setInputSize();
937
- }
938
- /**
939
- * @hidden
940
- */
941
- pageChange(event) {
942
- const virtual = this.virtual;
943
- virtual.skip = event.skip;
944
- }
945
- /**
946
- * @hidden
947
- */
948
- clearFilter() {
949
- if (this.filterable && this.text) {
950
- this.filterChange.emit("");
951
- }
952
- this.text = "";
953
- /* Clearing the value from the input as the setInputSize calculation will be incorrect otherwise.
954
- Calling cdr.detectChanges to clear the input value as a result of property binding
955
- causes JAWS to read outdated tag values in IE upon tag selection for some reason. */
956
- this.searchbar.input.nativeElement.value = "";
957
- this.searchbar.setInputSize();
958
- }
959
- /**
960
- * @hidden
961
- */
962
- handleNavigate(event) {
963
- const code = normalizeKeys(event);
964
- const navigateInput = this.text && code !== Keys.ArrowDown && code !== Keys.ArrowUp;
965
- const selectValue = this.text && code === Keys.Enter || code === Keys.Escape;
966
- const deleteTag = !this.text && code === Keys.Backspace && this.tags.length > 0;
967
- if (code === Keys.Backspace && this.isActionSheetExpanded) {
968
- return;
969
- }
970
- if (deleteTag) {
971
- this.handleBackspace();
972
- return;
973
- }
974
- if (this.disabled || navigateInput && !selectValue) {
975
- return;
976
- }
977
- const eventData = event;
978
- const focused = isNaN(this.selectionService.focused) ? -1 : this.selectionService.focused;
979
- const action = this.navigationService.process({
980
- current: focused,
981
- max: this.dataService.itemsCount - 1,
982
- min: this.allowCustom && this.text ? -1 : 0,
983
- open: this.isOpen,
984
- originalEvent: eventData
985
- });
986
- if (action !== NavigationAction.Undefined &&
987
- ((action === NavigationAction.Enter && this.isOpen) || action !== NavigationAction.Enter) &&
988
- (!this.isActionSheetExpanded && action === NavigationAction.Tab)) {
989
- event.preventDefault();
990
- }
991
- }
992
- /**
993
- * @hidden
994
- */
995
- handleRemoveTag({ tag }) {
996
- const eventArgs = new RemoveTagEvent(tag);
997
- if (this.disabled || this.readonly) {
998
- return;
999
- }
1000
- this.focus();
1001
- this.removeTag.emit(eventArgs);
1002
- if (eventArgs.isDefaultPrevented()) {
1003
- return;
1004
- }
1005
- if (tag instanceof Array) {
1006
- this.removeGroupTag(tag);
1007
- }
1008
- else {
1009
- this.removeSingleTag(tag);
1010
- }
1011
- this.cdr.detectChanges();
1012
- }
1013
- /**
1014
- * @hidden
1015
- */
1016
- clearAll(event) {
1017
- event?.stopImmediatePropagation();
1018
- event?.preventDefault();
1019
- this.focus();
1020
- this.clearFilter();
1021
- this.selectionService.lastClickedIndex = null;
1022
- const selected = this.selectionService.selected;
1023
- this.value = this.value.filter((_item, index) => this.disabledItemsService.isIndexDisabled(selected[index]));
1024
- this.emitValueChange();
1025
- }
1026
- /**
1027
- * @hidden
1028
- */
1029
- addCustomValue(text) {
1030
- this.customValueSubject.next(text);
1031
- }
1032
- ngAfterContentChecked() {
1033
- this.verifySettings();
1034
- }
1035
- ngDoCheck() {
1036
- const valueChanges = this.differ && this.differ.diff(this.value);
1037
- if (valueChanges && !this.valueChangeDetected) {
1038
- this.setState(this.value);
1039
- }
1040
- this.valueChangeDetected = false;
1041
- }
1042
- ngOnInit() {
1043
- this.renderer.removeAttribute(this.wrapper.nativeElement, "tabindex");
1044
- this.createCustomValueStream();
1045
- this.subs.add(this.localization
1046
- .changes.subscribe(({ rtl }) => {
1047
- this.direction = rtl ? 'rtl' : 'ltr';
1048
- this.cdr.markForCheck();
1049
- }));
1050
- this.setState(this.value);
1051
- this.setComponentClasses();
1052
- this.initialized = true;
1053
- }
1054
- ngOnChanges(changes) {
1055
- const virtual = this.virtual;
1056
- const requestInitialData = virtual && changes.data && changes.data.isFirstChange();
1057
- if (requestInitialData) {
1058
- this.pageChange({ skip: 0, take: virtual.pageSize });
1059
- }
1060
- if (isChanged('valueNormalizer', changes)) {
1061
- this.createCustomValueStream();
1062
- }
1063
- if (anyChanged(['textField', 'valueField', 'valuePrimitive'], changes)) {
1064
- this.setState(this.value);
1065
- }
1066
- }
1067
- ngAfterViewInit() {
1068
- this.windowSize = this.adaptiveService.size;
1069
- this.cdr.detectChanges();
1070
- this.searchbar.setInputSize();
1071
- this.subs.add(this.renderer.listen(this.wrapper.nativeElement, 'mousedown', this.handleMousedown.bind(this)));
1072
- this.subs.add(this.renderer.listen(this.wrapper.nativeElement, 'keydown', this.handleKeydown.bind(this)));
1073
- this._zone.onStable.pipe(take(1)).subscribe(() => {
1074
- const ariaLabel = this.searchbar.input.nativeElement.getAttribute('aria-labelledby') ||
1075
- this.searchbar.input.nativeElement.getAttribute('data-kendo-label-id');
1076
- if (ariaLabel) {
1077
- this.renderer.setAttribute(this.tagList.hostElement.nativeElement, 'aria-labelledby', ariaLabel);
1078
- }
1079
- });
1080
- }
1081
- ngOnDestroy() {
1082
- this._toggle(false);
1083
- this.unsubscribeEvents();
1084
- }
1085
- /**
1086
- * Toggles the visibility of the popup or actionSheet
1087
- * ([see example]({% slug openstate_multiselect %}#toc-setting-the-initially-opened-component)).
1088
- * If you use the `toggle` method to open or close the popup or actionSheet, the respective `open` and `close` events will not be fired.
1089
- *
1090
- * @param open - The state of the popup.
1091
- */
1092
- toggle(open) {
1093
- // The Promise is required for opening the popup on load.
1094
- // Otherwise, the "Expression has changed..." type error will be thrown.
1095
- Promise.resolve(null).then(() => {
1096
- const shouldOpen = isPresent(open) ? open : !this._open;
1097
- this._toggle(shouldOpen);
1098
- this.cdr.markForCheck();
1099
- });
1100
- }
1101
- /**
1102
- * Returns the current open state. Returns `true` if the popup or actionSheet is open.
1103
- */
1104
- get isOpen() {
1105
- return isTruthy(this._open || this.isActionSheetExpanded);
1106
- }
1107
- /**
1108
- * Resets the MultiSelect by clearing the text and value.
1109
- * This method does not trigger the `selectionChange` and `valueChange` events.
1110
- */
1111
- reset() {
1112
- this.text = "";
1113
- this.value = [];
1114
- }
1115
- /**
1116
- * @hidden
1117
- */
1118
- messageFor(key) {
1119
- return this.localization.get(key);
1120
- }
1121
- // NG MODEL BINDINGS
1122
- /**
1123
- * @hidden
1124
- */
1125
- writeValue(value) {
1126
- this.value = value || [];
1127
- }
1128
- /**
1129
- * @hidden
1130
- */
1131
- registerOnChange(fn) {
1132
- this.onChangeCallback = fn;
1133
- }
1134
- /**
1135
- * @hidden
1136
- */
1137
- registerOnTouched(fn) {
1138
- this.onTouchedCallback = fn;
1139
- }
1140
- /**
1141
- * @hidden
1142
- */
1143
- setDisabledState(isDisabled) {
1144
- this.cdr.markForCheck();
1145
- this.disabled = isDisabled;
1146
- }
1147
- /**
1148
- * @hidden
1149
- */
1150
- onTagMapperChange() {
1151
- this.tags = this.tagMapper(this.selectedDataItems.slice(0));
1152
- this.cdr.markForCheck();
1153
- }
1154
- /**
1155
- * @hidden
1156
- */
1157
- handleClick() {
1158
- this.windowSize = this.adaptiveService.size;
1159
- if (this.isAdaptive) {
1160
- this.togglePopup(true);
1161
- }
1162
- }
1163
- onChangeCallback = (_) => { };
1164
- onTouchedCallback = (_) => { };
1165
- _placeholder = '';
1166
- _open = false;
1167
- _value = [];
1168
- _popupSettings = { animate: true };
1169
- _virtualSettings;
1170
- _valuePrimitive;
1171
- _checkboxes = { enabled: false };
1172
- _isFocused = false;
1173
- set isFocused(isFocused) {
1174
- this.renderer[isFocused ? 'addClass' : 'removeClass'](this.wrapper.nativeElement, 'k-focus');
1175
- this._isFocused = isFocused;
1176
- }
1177
- get isFocused() {
1178
- return this._isFocused;
1179
- }
1180
- selectedDataItems = [];
1181
- popupPointerDownHandler;
1182
- isOpenPrevented = false;
1183
- customValueSubject = new Subject();
1184
- customValueSubscription;
1185
- subs = new Subscription();
1186
- touchstartDisposeHandler;
1187
- direction;
1188
- differ;
1189
- valueChangeDetected;
1190
- subscribeEvents() {
1191
- if (!isDocumentAvailable()) {
1192
- return;
1193
- }
1194
- const isOpen = () => this.isOpen;
1195
- const isClosed = () => !this.isOpen;
1196
- const isTagFocused = () => !this.isOpen && this.focusedTagIndex !== undefined;
1197
- [
1198
- this.selectionService.onChange.subscribe(this.handleItemChange.bind(this)),
1199
- this.navigationService.esc.subscribe(() => {
1200
- if (this.isOpen) {
1201
- this.closePopup();
1202
- }
1203
- else if (this.isFocused && this.selectedDataItems.length > 0) {
1204
- this.clearAll();
1205
- }
1206
- }),
1207
- this.navigationService.enter.pipe(filter(isOpen)).subscribe(this.handleEnter.bind(this)),
1208
- this.navigationService.open.subscribe(this.openPopup.bind(this)),
1209
- this.navigationService.close.subscribe(this.handleClose.bind(this)),
1210
- this.navigationService.up.pipe(filter(isOpen)).subscribe((event) => this.handleUp(event.index)),
1211
- this.navigationService.home.pipe(filter(() => isClosed)).subscribe(this.handleHome.bind(this)),
1212
- this.navigationService.end.pipe(filter(() => isClosed)).subscribe(this.handleEnd.bind(this)),
1213
- this.navigationService.backspace.pipe(filter(isTagFocused)).subscribe(this.handleBackspace.bind(this)),
1214
- this.navigationService.delete.pipe(filter(isTagFocused)).subscribe(this.handleDelete.bind(this)),
1215
- this.navigationService.left.subscribe(this.direction === 'rtl' ? this.handleRightKey.bind(this) : this.handleLeftKey.bind(this)),
1216
- this.navigationService.right.subscribe(this.direction === 'rtl' ? this.handleLeftKey.bind(this) : this.handleRightKey.bind(this)),
1217
- this.navigationService.down.subscribe((event) => this.handleDownKey(event.index)),
1218
- this.navigationService.selectprevious.pipe(filter(isOpen)).subscribe((event) => this.handleSelectUpDown(event)),
1219
- this.navigationService.selectnext.pipe(filter(isOpen)).subscribe((event) => this.handleSelectUpDown(event)),
1220
- this.navigationService.selectalltobeginning.pipe(filter(isOpen)).subscribe(() => this.handleSelectAllToBeginning()),
1221
- this.navigationService.selectalltoend.pipe(filter(isOpen)).subscribe(() => this.handleSelectAllToEnd()),
1222
- merge(this.navigationService.pagedown, this.navigationService.pageup).subscribe((event) => {
1223
- if (this.isOpen) {
1224
- event.originalEvent.preventDefault();
1225
- const code = normalizeKeys(event.originalEvent);
1226
- this.optionsList.scrollWithOnePage(NavigationAction[code]);
1227
- }
1228
- })
1229
- ].forEach(s => this.subs.add(s));
1230
- }
1231
- subscribeTouchEvents() {
1232
- if (!isDocumentAvailable() || !touchEnabled) {
1233
- return;
1234
- }
1235
- this._zone.runOutsideAngular(() =>
1236
- // Roll up MultiSelect on iOS when tapped outside
1237
- this.touchstartDisposeHandler = this.renderer.listen(document, 'touchstart', (e) => {
1238
- const target = e.target;
1239
- if ((this.isFocused || this.isOpen) && !inDropDown(this.wrapper, target, this.popupRef)) {
1240
- this._zone.run(() => {
1241
- this.blur();
1242
- if (this.isOpen) {
1243
- this.togglePopup(false);
1244
- }
1245
- });
1246
- }
1247
- }));
1248
- }
1249
- unsubscribeEvents() {
1250
- if (!isDocumentAvailable()) {
1251
- return;
1252
- }
1253
- this.subs.unsubscribe();
1254
- if (this.customValueSubscription) {
1255
- this.customValueSubscription.unsubscribe();
1256
- }
1257
- if (this.touchstartDisposeHandler) {
1258
- this.touchstartDisposeHandler();
1259
- }
1260
- }
1261
- removeGroupTag(dataItems) {
1262
- let data = this.dataService.data;
1263
- if (this.dataService.grouped) {
1264
- data = data.filter(item => !item.header).map(item => item.value);
1265
- }
1266
- const dataItemValues = new Set(dataItems.map(item => getter(item, this.valueField)));
1267
- this.value = this.value.filter(value => {
1268
- const index = selectedIndices([value], data, this.valueField)[0];
1269
- const isDataItemDisabled = this.disabledItemsService.isIndexDisabled(index);
1270
- return !dataItemValues.has(getter(value, this.valueField)) || isDataItemDisabled;
1271
- });
1272
- this.emitValueChange();
1273
- }
1274
- removeSingleTag(dataItem) {
1275
- let data = this.dataService.data;
1276
- if (this.dataService.grouped) {
1277
- data = data.filter(item => !item.header).map(item => item.value);
1278
- }
1279
- const index = selectedIndices([dataItem], data, this.valueField)[0];
1280
- if (this.disabledItemsService.isIndexDisabled(index)) {
1281
- return;
1282
- }
1283
- if (isNumber(index)) {
1284
- this.selectionService.deselect(index);
1285
- this.selectionService.focused = index;
1286
- this.togglePopup(false);
1287
- }
1288
- else { // the deleted item is not present in the source
1289
- const filter = item => getter(item, this.valueField) !== getter(dataItem, this.valueField);
1290
- this.value = this.value.filter(filter);
1291
- this.emitValueChange();
1292
- }
1293
- }
1294
- /**
1295
- * @hidden
1296
- *
1297
- * Determines which of the provided tags should be disabled and stores their position indices
1298
- */
1299
- disabledItemsMapper() {
1300
- const { selected } = this.selectionService;
1301
- return new Set(this.selectedDataItems.reduce((indices, _item, index) => {
1302
- if (this.disabledItemsService.isIndexDisabled(selected[index])) {
1303
- indices.push(index);
1304
- }
1305
- return indices;
1306
- }, []));
1307
- }
1308
- createCustomValueStream() {
1309
- if (this.customValueSubscription) {
1310
- this.customValueSubscription.unsubscribe();
1311
- }
1312
- this.customValueSubscription = this.customValueSubject.pipe(tap(() => {
1313
- this.loading = true;
1314
- this.disabled = true;
1315
- this.cdr.detectChanges();
1316
- }), this.valueNormalizer, catchError(() => {
1317
- this.loading = false;
1318
- this.disabled = false;
1319
- if (this.autoClose) {
1320
- this.togglePopup(false);
1321
- }
1322
- if (this.autoClose || !this.filterable) {
1323
- this.clearFilter();
1324
- }
1325
- this.nextTick(() => {
1326
- this.searchbar.focus();
1327
- });
1328
- this.createCustomValueStream();
1329
- return of(null);
1330
- }))
1331
- .subscribe((normalizedValue) => {
1332
- this.loading = false;
1333
- this.disabled = false;
1334
- if (isPresent(normalizedValue)) { // if valueNormalizer returns `null` or `undefined` custom value is discarded
1335
- const newValue = this.valuePrimitive ? getter(normalizedValue, this.valueField) : normalizedValue;
1336
- const itemIndex = this.dataService.indexOf(newValue);
1337
- const customItem = itemIndex === -1;
1338
- if (this.value.indexOf(newValue) === -1) {
1339
- !this.isActionSheetExpanded && (this.tags = this.tagMapper([...this.selectedDataItems, normalizedValue]));
1340
- if (!customItem) {
1341
- this.selectionService.add(itemIndex);
1342
- }
1343
- else if (this.isActionSheetExpanded) {
1344
- const isValueInHolder = this._valueHolder.some(item => getter(item, this.valueField) === newValue);
1345
- if (isValueInHolder) {
1346
- this._valueHolder = this._valueHolder.filter(item => getter(item, this.valueField) !== newValue);
1347
- this.isCustomValueSelected = false;
1348
- }
1349
- else {
1350
- this._valueHolder = [...this._valueHolder, newValue];
1351
- this.isCustomValueSelected = true;
1352
- }
1353
- }
1354
- else {
1355
- this.value = [...this.value, newValue];
1356
- }
1357
- }
1358
- else if (!customItem && this.selectionService.isSelected(itemIndex)) {
1359
- this.selectionService.deselect(itemIndex);
1360
- this.selectionService.focused = itemIndex;
1361
- }
1362
- else if (this.isActionSheetExpanded) {
1363
- this._valueHolder = this._valueHolder.filter(item => getter(item, this.valueField) !== newValue);
1364
- this.isCustomValueSelected = false;
1365
- }
1366
- else {
1367
- this.value = this.value.filter(item => getter(item, this.valueField) !== newValue);
1368
- }
1369
- !this.isActionSheetExpanded && this.emitValueChange();
1370
- }
1371
- if (this.autoClose) {
1372
- this.togglePopup(false);
1373
- }
1374
- if ((this.autoClose || !this.filterable) && !this.isActionSheetExpanded) {
1375
- this.clearFilter();
1376
- }
1377
- if (!this.isActionSheetExpanded) {
1378
- this.nextTick(() => {
1379
- this.searchbar.focus();
1380
- });
1381
- }
1382
- });
1383
- }
1384
- handleItemChange(event) {
1385
- this.change(event);
1386
- if (this.autoClose && !event.preventClosingPopup && !this.isActionSheetExpanded) {
1387
- this.togglePopup(false);
1388
- }
1389
- if ((this.autoClose || !this.filterable) && !this.isActionSheetExpanded) {
1390
- this.clearFilter();
1391
- }
1392
- }
1393
- handleMousedown(event) {
1394
- if (event.target.closest('.k-input-prefix') || event.target.closest('.k-input-suffix')) {
1395
- return;
1396
- }
1397
- if (!this.isActionSheetExpanded) {
1398
- const inputElement = this.searchbar.input.nativeElement;
1399
- if (event.button === 0) {
1400
- if (this.isFocused && (this.isOpen || this.isOpenPrevented) && event.target === inputElement) {
1401
- return;
1402
- }
1403
- if (!touchEnabled || (touchEnabled && event.target.tagName !== 'SPAN')) {
1404
- this.searchbar.focus();
1405
- }
1406
- // The check is needed otherwise when appended to the component, the popup reopens on click
1407
- // https://github.com/telerik/kendo-angular/issues/3738
1408
- if ((this.popupRef && this.popupRef.popupElement.contains(event.target))) {
1409
- return;
1410
- }
1411
- event.preventDefault();
1412
- this.togglePopup(!this.isOpen);
1413
- }
1414
- }
1415
- }
1416
- handleKeydown(event) {
1417
- const code = normalizeKeys(event);
1418
- if (this.isFocused && this.isOpen && (event.ctrlKey || event.metaKey) && code === Keys.KeyA) {
1419
- event.preventDefault();
1420
- this.handleSelectAll();
1421
- }
1422
- }
1423
- handleEnter(event) {
1424
- const service = this.selectionService;
1425
- const focusedIndex = this.selectionService.focused;
1426
- this.selectionService.lastClickedIndex = focusedIndex;
1427
- if (this.isOpen) {
1428
- event.originalEvent.preventDefault();
1429
- }
1430
- if (focusedIndex === -1) {
1431
- if (this.allowCustom && this.text) {
1432
- this.addCustomValue(this.text);
1433
- }
1434
- return; // Clear filter & close are done at customValueSubscription due to race conditions.
1435
- }
1436
- if (service.isSelected(focusedIndex)) {
1437
- service.deselect(focusedIndex);
1438
- service.focused = focusedIndex;
1439
- }
1440
- else {
1441
- service.add(focusedIndex);
1442
- }
1443
- if (this.autoClose && !this.isActionSheetExpanded) {
1444
- this.togglePopup(false);
1445
- }
1446
- if (this.autoClose || !this.filterable) {
1447
- this.clearFilter();
1448
- }
1449
- }
1450
- handleClose() {
1451
- this.closePopup();
1452
- this.searchbar.focus();
1453
- }
1454
- handleEnd() {
1455
- this.focusedTagIndex = this.tags.length - 1;
1456
- }
1457
- handleHome() {
1458
- this.focusedTagIndex = 0;
1459
- }
1460
- sortSelectionAscending() {
1461
- return this.selectionService.selected.sort((a, b) => a - b);
1462
- }
1463
- handleSelectAll() {
1464
- const selectedItemsCount = this.selectionService.selected.length;
1465
- const dataItemsCount = this.dataService.data.length;
1466
- const dataItemsWithoutHeadersCount = this.dataService.data.filter(i => !i.header).length;
1467
- if ((!this.dataService.grouped && selectedItemsCount === dataItemsCount) ||
1468
- (this.dataService.grouped && selectedItemsCount === dataItemsWithoutHeadersCount)) {
1469
- this.clearAll();
1470
- }
1471
- else {
1472
- this.selectionService.selectFromTo(0, dataItemsCount - 1);
1473
- this.selectionService.emitMultipleAddedRemoved();
1474
- }
1475
- }
1476
- handleSelectAllToBeginning() {
1477
- const selectedItemsCount = this.selectionService.selected.length;
1478
- const dataItemsCount = this.dataService.data.length;
1479
- const focusedItem = this.selectionService.focused;
1480
- const largestIndex = this.sortSelectionAscending()[selectedItemsCount - 1];
1481
- if (selectedItemsCount !== dataItemsCount) {
1482
- this.selectionService.unselectFromTo(largestIndex, focusedItem + 1);
1483
- this.selectionService.selectFromTo(0, focusedItem);
1484
- }
1485
- this.nextTick(() => this.selectionService.focus(0));
1486
- this.selectionService.emitMultipleAddedRemoved();
1487
- }
1488
- handleSelectAllToEnd() {
1489
- const selectedItemsCount = this.selectionService.selected.length;
1490
- const dataItemsCount = this.dataService.data.length;
1491
- const focusedItem = this.selectionService.focused;
1492
- if (selectedItemsCount !== dataItemsCount) {
1493
- this.selectionService.unselectFromTo(focusedItem - 1, 0);
1494
- this.selectionService.selectFromTo(focusedItem, dataItemsCount - 1);
1495
- }
1496
- if (this.dataService.grouped) {
1497
- const lastItemIndex = this.dataService.groupIndices[this.dataService.groupIndices.length - 1] - 1;
1498
- this.nextTick(() => this.selectionService.focus(lastItemIndex));
1499
- }
1500
- else {
1501
- this.nextTick(() => this.selectionService.focus(dataItemsCount - 1));
1502
- }
1503
- this.selectionService.emitMultipleAddedRemoved();
1504
- }
1505
- handleSelectUpDown(event) {
1506
- const focusedIndex = this.selectionService.focused;
1507
- if (!isPresent(focusedIndex)) {
1508
- return;
1509
- }
1510
- let indexToSelect;
1511
- if (event.originalEvent.key === 'ArrowUp') {
1512
- indexToSelect = focusedIndex > 0 ? focusedIndex - 1 : focusedIndex;
1513
- }
1514
- else {
1515
- indexToSelect = focusedIndex < this.dataService.data.length - 1 ? focusedIndex + 1 : focusedIndex;
1516
- }
1517
- if (!isPresent(this.selectionService.lastClickedIndex)) {
1518
- this.selectionService.lastClickedIndex = focusedIndex;
1519
- }
1520
- this.selectRangeFromTo(indexToSelect);
1521
- }
1522
- /**
1523
- * Selects all items between the focused item and the last clicked item (index). Also removes all other selected items.
1524
- */
1525
- selectRangeFromTo(indexToSelect) {
1526
- const lastClickedIndex = this.selectionService.lastClickedIndex;
1527
- if (lastClickedIndex > indexToSelect) {
1528
- this.selectionService.unselectNotNeededIndices(indexToSelect, lastClickedIndex, this.dataService.data.length);
1529
- this.selectionService.selectFromTo(indexToSelect, this.selectionService.lastClickedIndex);
1530
- this.selectionService.emitMultipleAddedRemoved();
1531
- }
1532
- else {
1533
- this.selectionService.unselectNotNeededIndices(lastClickedIndex, indexToSelect, this.dataService.data.length);
1534
- this.selectionService.selectFromTo(lastClickedIndex, indexToSelect);
1535
- this.selectionService.emitMultipleAddedRemoved();
1536
- }
1537
- this.nextTick(() => this.selectionService.focus(indexToSelect));
1538
- }
1539
- handleUp(index) {
1540
- this.selectionService.focused = index;
1541
- }
1542
- handleBackspace() {
1543
- if (this.focusedTagIndex !== undefined) {
1544
- this.handleDelete();
1545
- }
1546
- else {
1547
- this.handleRemoveTag({ tag: this.tags[this.tags.length - 1] });
1548
- this.searchbar.focus();
1549
- }
1550
- }
1551
- handleDelete() {
1552
- this.handleRemoveTag({ tag: this.tags[this.focusedTagIndex] });
1553
- if (this.focusedTagIndex === this.tags.length) {
1554
- this.focusedTagIndex = undefined;
1555
- }
1556
- }
1557
- handleLeftKey() {
1558
- if (this.focusedTagIndex === undefined || this.focusedTagIndex < 0) {
1559
- this.focusedTagIndex = this.tags.length - 1;
1560
- }
1561
- else if (this.focusedTagIndex !== 0) {
1562
- this.focusedTagIndex--;
1563
- }
1564
- }
1565
- handleDownKey(index) {
1566
- if (this.isOpen) {
1567
- this.selectionService.focused = index || this.firstFocusableIndex(0);
1568
- }
1569
- else {
1570
- this.openPopup();
1571
- }
1572
- }
1573
- handleRightKey() {
1574
- const last = this.tags.length - 1;
1575
- if (this.focusedTagIndex === last) {
1576
- this.focusedTagIndex = undefined;
1577
- }
1578
- else if (this.focusedTagIndex < last) {
1579
- this.focusedTagIndex++;
1580
- }
1581
- }
1582
- findIndex(text, startsFrom = 0) {
1583
- let itemText;
1584
- text = text.toLowerCase();
1585
- const index = this.dataService.findIndex(item => {
1586
- if (this.dataService.grouped) {
1587
- itemText = getter(item.value, this.textField);
1588
- }
1589
- else {
1590
- itemText = getter(item, this.textField);
1591
- }
1592
- itemText = !isPresent(itemText) ? "" : itemText.toString().toLowerCase();
1593
- return text && itemText.startsWith(text);
1594
- }, startsFrom);
1595
- if (this.disabledItemsService.isIndexDisabled(index)) {
1596
- return (index + 1 > this.dataService.itemsCount) ? -1 : this.findIndex(text, index + 1);
1597
- }
1598
- else {
1599
- return index;
1600
- }
1601
- }
1602
- searchTextAndFocus(text) {
1603
- const index = this.findIndex(text);
1604
- this.selectionService.focused = index;
1605
- }
1606
- closePopup() {
1607
- this.togglePopup(false);
1608
- this.focusedTagIndex = undefined;
1609
- }
1610
- openPopup() {
1611
- this.togglePopup(true);
1612
- this.focusedTagIndex = undefined;
1613
- }
1614
- /**
1615
- * @hidden
1616
- */
1617
- togglePopup(open) {
1618
- const isDisabled = this.disabled || this.readonly;
1619
- const sameState = this.isOpen === open;
1620
- if (isDisabled || sameState) {
1621
- return;
1622
- }
1623
- const isDefaultPrevented = this.triggerPopupEvents(open);
1624
- if (open) {
1625
- this.isOpenPrevented = isDefaultPrevented;
1626
- }
1627
- if (!isDefaultPrevented) {
1628
- this._toggle(open);
1629
- }
1630
- }
1631
- triggerPopupEvents(open) {
1632
- const eventArgs = new PreventableEvent();
1633
- if (open) {
1634
- this.open.emit(eventArgs);
1635
- }
1636
- else {
1637
- this.close.emit(eventArgs);
1638
- }
1639
- return eventArgs.isDefaultPrevented();
1640
- }
1641
- _toggle(open) {
1642
- this._open = open;
1643
- this.destroyPopup();
1644
- if (this.isActionSheetExpanded) {
1645
- this.actionSheet.toggle(false);
1646
- this.closed.emit();
1647
- this.isFocused = false;
1648
- }
1649
- if (this._open) {
1650
- this.createPopup();
1651
- }
1652
- }
1653
- destroyPopup() {
1654
- if (this.popupRef) {
1655
- this.popupRef.popupElement
1656
- .removeEventListener('pointerdown', this.popupPointerDownHandler);
1657
- this.popupRef.close();
1658
- this.popupRef = null;
1659
- }
1660
- }
1661
- createPopup() {
1662
- if (this.virtual) {
1663
- this.virtual.skip = 0;
1664
- }
1665
- this.windowSize = this.adaptiveService.size;
1666
- if (this.isAdaptive) {
1667
- this.openActionSheet();
1668
- return;
1669
- }
1670
- const horizontalAlign = this.direction === "rtl" ? "right" : "left";
1671
- const anchorPosition = { horizontal: horizontalAlign, vertical: "bottom" };
1672
- const popupPosition = { horizontal: horizontalAlign, vertical: "top" };
1673
- const appendToComponent = typeof this.popupSettings.appendTo === 'string' && this.popupSettings.appendTo === 'component';
1674
- this.popupRef = this.popupService.open({
1675
- anchor: this.wrapper,
1676
- anchorAlign: anchorPosition,
1677
- animate: this.popupSettings.animate,
1678
- appendTo: this.appendTo,
1679
- content: this.popupTemplate,
1680
- popupAlign: popupPosition,
1681
- popupClass: this.listContainerClasses,
1682
- positionMode: appendToComponent ? 'fixed' : 'absolute'
1683
- });
1684
- const popupWrapper = this.popupRef.popupElement;
1685
- const { min, max } = this.width;
1686
- if (!this.appendTo) {
1687
- this.renderer.setAttribute(popupWrapper, 'role', 'region');
1688
- this.renderer.setAttribute(popupWrapper, 'aria-label', this.messageFor('popupLabel'));
1689
- }
1690
- popupWrapper.addEventListener('pointerdown', this.popupPointerDownHandler);
1691
- popupWrapper.style.minWidth = min;
1692
- popupWrapper.style.width = max;
1693
- popupWrapper.style.height = this.height;
1694
- popupWrapper.setAttribute("dir", this.direction);
1695
- this.popupRef.popupOpen.subscribe(() => {
1696
- this.cdr.detectChanges();
1697
- if (!this.dataService.grouped) {
1698
- setListBoxAriaLabelledBy(this.optionsList, this.searchbar.input, this.renderer);
1699
- }
1700
- this.optionsList.scrollToItem(this.selectionService.focused);
1701
- this.selectionService.focus(this.selectionService.focused);
1702
- this.opened.emit();
1703
- });
1704
- this.popupRef.popupClose.subscribe(() => {
1705
- this.closed.emit();
1706
- });
1707
- this.popupRef.popupAnchorViewportLeave.subscribe(() => {
1708
- this.togglePopup(false);
1709
- });
1710
- }
1711
- emitValueChange() {
1712
- this.onChangeCallback(this.value);
1713
- this.valueChange.emit(this.value);
1714
- }
1715
- resolveDataItemFromTags(value) {
1716
- if (!(this.tags && this.tags.length && isPresent(value))) {
1717
- return undefined;
1718
- }
1719
- // Flattening the tags array in case of a summary tag occurrence.
1720
- const tags = this.tags.reduce((acc, tag) => {
1721
- const items = isArray(tag) ? tag : [tag];
1722
- acc.push(...items);
1723
- return acc;
1724
- }, []);
1725
- return tags.find(tag => getter(tag, this.valueField) === getter(value, this.valueField));
1726
- }
1727
- firstFocusableIndex(index) {
1728
- const maxIndex = this.dataService.itemsCount;
1729
- if (this.disabledItemsService.isIndexDisabled(index)) {
1730
- const nextIndex = index + 1;
1731
- return (nextIndex < maxIndex) ? this.firstFocusableIndex(nextIndex) : undefined;
1732
- }
1733
- else {
1734
- return index;
1735
- }
1736
- }
1737
- nextTick(f) {
1738
- this._zone.runOutsideAngular(() => {
1739
- // Use `setTimeout` instead of a resolved promise
1740
- // because the latter does not wait long enough.
1741
- setTimeout(() => this._zone.run(f));
1742
- });
1743
- }
1744
- setComponentClasses() {
1745
- if (this.size !== 'none') {
1746
- this.renderer.addClass(this.wrapper.nativeElement, getSizeClass('input', this.size));
1747
- }
1748
- if (this.rounded !== 'none') {
1749
- this.renderer.addClass(this.wrapper.nativeElement, getRoundedClass(this.rounded));
1750
- }
1751
- if (this.fillMode !== 'none') {
1752
- this.renderer.addClass(this.wrapper.nativeElement, getFillModeClass('input', this.fillMode));
1753
- }
1754
- }
1755
- openActionSheet() {
1756
- this.actionSheet.toggle(true);
1757
- // Stores the current value state until the user either accepts or cancels it
1758
- this._valueHolder = [...this.value];
1759
- this.cdr.detectChanges();
1760
- if (!this.dataService.grouped) {
1761
- setListBoxAriaLabelledBy(this.optionsList, this.searchbar.input, this.renderer);
1762
- }
1763
- this.adaptiveTitle = setActionSheetTitle(this.searchbar.input, this.adaptiveTitle);
1764
- this.cdr.detectChanges();
1765
- this.opened.emit();
1766
- this.optionsList.scrollToItem(this.selectionService.focused);
1767
- this.selectionService.focus(this.selectionService.focused);
1768
- this.actionSheetSearchBar.focus();
1769
- }
1770
- blurComponent() {
1771
- if (!this.isFocused) {
1772
- return;
1773
- }
1774
- this.isFocused = false;
1775
- if (hasObservers(this.onBlur) ||
1776
- hasObservers(this.filterChange) ||
1777
- hasObservers(this.close) ||
1778
- isUntouched(this.wrapper.nativeElement)) {
1779
- this._zone.run(() => {
1780
- this.closePopup();
1781
- if (!(this.isOpen && this.allowCustom)) {
1782
- this.clearFilter();
1783
- }
1784
- this.onBlur.emit();
1785
- this.onTouchedCallback();
1786
- });
1787
- }
1788
- else {
1789
- if (!this.allowCustom) {
1790
- this.clearFilter();
1791
- }
1792
- this.closePopup();
1793
- }
1794
- }
1795
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MultiSelectComponent, deps: [{ token: i0.ElementRef }, { token: i1.LocalizationService }, { token: i2.PopupService }, { token: i3.DataService }, { token: i4.SelectionService }, { token: i5.NavigationService }, { token: i6.DisabledItemsService }, { token: i0.ChangeDetectorRef }, { token: i0.KeyValueDiffers }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i0.Injector }, { token: i0.ElementRef }, { token: i7.AdaptiveService }], target: i0.ɵɵFactoryTarget.Component });
1796
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MultiSelectComponent, isStandalone: true, selector: "kendo-multiselect", inputs: { showStickyHeader: "showStickyHeader", focusableId: "focusableId", autoClose: "autoClose", loading: "loading", data: "data", value: "value", valueField: "valueField", textField: "textField", tabindex: "tabindex", tabIndex: "tabIndex", size: "size", rounded: "rounded", fillMode: "fillMode", placeholder: "placeholder", adaptiveMode: "adaptiveMode", adaptiveTitle: "adaptiveTitle", adaptiveSubtitle: "adaptiveSubtitle", disabled: "disabled", itemDisabled: "itemDisabled", checkboxes: "checkboxes", readonly: "readonly", filterable: "filterable", virtual: "virtual", popupSettings: "popupSettings", listHeight: "listHeight", valuePrimitive: "valuePrimitive", clearButton: "clearButton", tagMapper: "tagMapper", allowCustom: "allowCustom", valueNormalizer: "valueNormalizer", inputAttributes: "inputAttributes" }, outputs: { filterChange: "filterChange", valueChange: "valueChange", open: "open", opened: "opened", close: "close", closed: "closed", onFocus: "focus", onBlur: "blur", inputFocus: "inputFocus", inputBlur: "inputBlur", removeTag: "removeTag" }, host: { properties: { "class.k-readonly": "this.readonly", "class.k-multiselect": "this.hostClasses", "class.k-input": "this.hostClasses", "attr.dir": "this.dir", "class.k-disabled": "this.disabledClass", "class.k-loading": "this.isLoading" } }, providers: [
1797
- MULTISELECT_VALUE_ACCESSOR,
1798
- DataService,
1799
- SelectionService,
1800
- NavigationService,
1801
- DisabledItemsService,
1802
- LocalizationService,
1803
- {
1804
- provide: L10N_PREFIX,
1805
- useValue: 'kendo.multiselect'
1806
- },
1807
- {
1808
- provide: FilterableComponent, useExisting: forwardRef(() => MultiSelectComponent)
1809
- },
1810
- {
1811
- provide: KendoInput, useExisting: forwardRef(() => MultiSelectComponent)
1812
- }
1813
- ], queries: [{ propertyName: "template", first: true, predicate: ItemTemplateDirective, descendants: true }, { propertyName: "customItemTemplate", first: true, predicate: CustomItemTemplateDirective, descendants: true }, { propertyName: "groupTemplate", first: true, predicate: GroupTemplateDirective, descendants: true }, { propertyName: "fixedGroupTemplate", first: true, predicate: FixedGroupTemplateDirective, descendants: true }, { propertyName: "headerTemplate", first: true, predicate: HeaderTemplateDirective, descendants: true }, { propertyName: "footerTemplate", first: true, predicate: FooterTemplateDirective, descendants: true }, { propertyName: "tagTemplate", first: true, predicate: TagTemplateDirective, descendants: true }, { propertyName: "groupTagTemplate", first: true, predicate: GroupTagTemplateDirective, descendants: true }, { propertyName: "noDataTemplate", first: true, predicate: NoDataTemplateDirective, descendants: true }, { propertyName: "suffixTemplate", first: true, predicate: SuffixTemplateDirective, descendants: true }, { propertyName: "prefixTemplate", first: true, predicate: PrefixTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "adaptiveRendererComponent", first: true, predicate: AdaptiveRendererComponent, descendants: true }, { propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "searchbar", first: true, predicate: SearchBarComponent, descendants: true, static: true }, { propertyName: "tagList", first: true, predicate: TagListComponent, descendants: true, static: true }, { propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true, static: true }, { propertyName: "optionsList", first: true, predicate: ["optionsList"], descendants: true }], exportAs: ["kendoMultiSelect"], usesOnChanges: true, ngImport: i0, template: `
1814
- <ng-container kendoMultiSelectLocalizedMessages
1815
- i18n-noDataText="kendo.multiselect.noDataText|The text displayed in the popup when there are no items"
1816
- noDataText="NO DATA FOUND"
1817
-
1818
- i18n-clearTitle="kendo.multiselect.clearTitle|The title of the clear button"
1819
- clearTitle="clear"
1820
-
1821
- i18n-popupLabel="kendo.multiselect.popupLabel|The label of the popup element that contains the list of options when its role is 'region'"
1822
- popupLabel="Options list"
1823
-
1824
- i18n-adaptiveCloseButtonTitle="kendo.multiselect.adaptiveCloseButtonTitle|The title of the Close button of the ActionSheet that is rendered instead of the Popup when using small screen devices in adaptive mode."
1825
- adaptiveCloseButtonTitle="Close"
1826
-
1827
- i18n-useCustomValueText="kendo.multiselect.useCustomValueText|The text displayed when the user types a custom value that is not in the list of options."
1828
- useCustomValueText="{{ 'Use &quot;{customValue}&quot;' }}"
1829
- >
1830
- </ng-container>
1831
-
1832
- <ng-container
1833
- kendoDropDownSharedEvents
1834
- [hostElement]="hostElement"
1835
- [(isFocused)]="isFocused"
1836
- (handleBlur)="handleBlur()"
1837
- (onFocus)="handleFocus()"
1838
- >
1839
- @if (prefixTemplate) {
1840
- <span class="k-input-prefix k-input-prefix-horizontal">
1841
- <ng-template [ngTemplateOutlet]="prefixTemplate?.templateRef">
1842
- </ng-template>
1843
- </span>
1844
- }
1845
- @if (prefixTemplate && prefixTemplate.showSeparator) {
1846
- <kendo-separator></kendo-separator>
1847
- }
1848
- <div class="k-input-values">
1849
- <kendo-taglist
1850
- [size]="size"
1851
- [rounded]="rounded"
1852
- [fillMode]="fillMode"
1853
- [id]="tagListId"
1854
- [tags]="tags"
1855
- [textField]="textField"
1856
- [valueField]="valueField"
1857
- [focused]="focusedTagIndex"
1858
- [disabled]="disabled"
1859
- [template]="tagTemplate"
1860
- [groupTemplate]="groupTagTemplate"
1861
- [tagPrefix]="tagPrefix"
1862
- [disabledIndices]="disabledIndices"
1863
- (removeTag)="handleRemoveTag($event)"
1864
- >
1865
- </kendo-taglist>
1866
- <input
1867
- kendoSearchbar
1868
- [ariaControls]="ariaControls"
1869
- [ariaExpanded]="isOpen"
1870
- [id]="focusableId"
1871
- [tagListId]="tagListId"
1872
- [isLoading]="loading"
1873
- [isFilterable]="filterable"
1874
- [activeDescendant]="activeDescendant"
1875
- [userInput]="text"
1876
- [disabled]="disabled"
1877
- [readonly]="readonly || this.isAdaptive"
1878
- [tabIndex]="tabIndex"
1879
- [isRequired]="isControlRequired"
1880
- [placeholder]="placeholder"
1881
- [inputAttributes]="inputAttributes"
1882
- (onNavigate)="handleNavigate($event)"
1883
- (valueChange)="handleFilter($event)"
1884
- (onBlur)="handleInputBlur()"
1885
- (onFocus)="handleInputFocus()"
1886
- (click)="handleClick()"
1887
- />
1888
- </div>
1889
-
1890
- @if (!loading && !readonly && clearButton && (tags?.length || text?.length)) {
1891
- <span
1892
- class="k-clear-value"
1893
- [style.visibility]="clearButtonVisibility"
1894
- [attr.title]="messageFor('clearTitle')"
1895
- role="button"
1896
- tabindex="-1"
1897
- (mousedown)="clearAll($event)"
1898
- >
1899
- <kendo-icon-wrapper
1900
- class="k-icon"
1901
- name="x"
1902
- [svgIcon]="xIcon"
1903
- >
1904
- </kendo-icon-wrapper>
1905
- </span>
1906
- }
1907
- @if (loading) {
1908
- <span
1909
- class="k-icon k-i-loading k-input-loading-icon"
1910
- >
1911
- </span>
1912
- }
1913
- @if (suffixTemplate && suffixTemplate.showSeparator) {
1914
- <kendo-separator></kendo-separator>
1915
- }
1916
- @if (suffixTemplate) {
1917
- <span class="k-input-suffix k-input-suffix-horizontal">
1918
- <ng-template [ngTemplateOutlet]="suffixTemplate?.templateRef">
1919
- </ng-template>
1920
- </span>
1921
- }
1922
- </ng-container>
1923
-
1924
- <ng-template #popupTemplate>
1925
- <ng-container *ngTemplateOutlet="sharedPopupActionSheetTemplate"></ng-container>
1926
- </ng-template>
1927
- @if (isOpen || isAdaptiveModeEnabled) {
1928
- <kendo-resize-sensor (resize)="onResize()"></kendo-resize-sensor>
1929
- }
1930
- <ng-container #container></ng-container>
1931
-
1932
- <kendo-adaptive-renderer
1933
- [sharedPopupActionSheetTemplate]="sharedPopupActionSheetTemplate"
1934
- [title]="adaptiveTitle"
1935
- [showTextInput]="true"
1936
- [subtitle]="adaptiveSubtitle"
1937
- (closePopup)="applyValue()"
1938
- (textInputChange)="handleFilter($event)"
1939
- [placeholder]="placeholder"
1940
- (navigate)="handleNavigate($event)"
1941
- [searchBarValue]="text">
1942
- </kendo-adaptive-renderer>
1943
-
1944
- <ng-template #sharedPopupActionSheetTemplate>
1945
- <!--header template-->
1946
- @if (headerTemplate) {
1947
- <ng-template
1948
- [templateContext]="{
1949
- templateRef: headerTemplate.templateRef
1950
- }">
1951
- </ng-template>
1952
- }
1953
- <!--list-->
1954
- <kendo-list
1955
- #optionsList
1956
- [size]="isAdaptive ? 'large' : size"
1957
- [rounded]="rounded"
1958
- [id]="listBoxId"
1959
- [optionPrefix]="optionPrefix"
1960
- [data]="data"
1961
- [textField]="textField"
1962
- [valueField]="valueField"
1963
- [template]="template"
1964
- [groupTemplate]="groupTemplate"
1965
- [fixedGroupTemplate]="fixedGroupTemplate"
1966
- [height]="listHeight"
1967
- [show]="isOpen"
1968
- [multipleSelection]="true"
1969
- [virtual]="virtual"
1970
- (pageChange)="pageChange($event)"
1971
- [checkboxes]="checkboxes"
1972
- [isMultiselect]="true"
1973
- [isActionSheetExpanded]="isActionSheetExpanded"
1974
- [showStickyHeader]="showStickyHeader"
1975
- [customItemTemplate]="customItemTemplate"
1976
- [text]="text"
1977
- [allowCustom]="allowCustom"
1978
- >
1979
- </kendo-list>
1980
- <!--no data template-->
1981
- @if (data.length === 0) {
1982
- <div class="k-no-data">
1983
- @if (noDataTemplate) {
1984
- <ng-template
1985
- [templateContext]="{
1986
- templateRef: noDataTemplate ? noDataTemplate.templateRef : undefined
1987
- }">
1988
- </ng-template>
1989
- }
1990
- @if (!noDataTemplate) {
1991
- <div>{{ messageFor('noDataText') }}</div>
1992
- }
1993
- </div>
1994
- }
1995
- <!--footer template-->
1996
- @if (footerTemplate) {
1997
- <ng-template
1998
- [templateContext]="{
1999
- templateRef: footerTemplate.templateRef
2000
- }">
2001
- </ng-template>
2002
- }
2003
- </ng-template>
2004
- `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "\n [kendoDropDownListLocalizedMessages],\n [kendoDropDownTreeLocalizedMessages],\n [kendoComboBoxLocalizedMessages],\n [kendoMultiColumnComboBoxLocalizedMessages],\n [kendoAutoCompleteLocalizedMessages],\n [kendoMultiSelectLocalizedMessages],\n [kendoMultiSelectTreeLocalizedMessages]\n " }, { kind: "directive", type: SharedDropDownEventsDirective, selector: "[kendoDropDownSharedEvents]", inputs: ["hostElement", "clearButtonClicked", "isFocused"], outputs: ["isFocusedChange", "onFocus", "handleBlur"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SeparatorComponent, selector: "kendo-separator", inputs: ["orientation"] }, { kind: "component", type: TagListComponent, selector: "kendo-taglist", inputs: ["tags", "textField", "valueField", "valueDepth", "focused", "template", "groupTemplate", "disabled", "tagPrefix", "id", "size", "rounded", "fillMode", "disabledIndices"], outputs: ["removeTag"] }, { kind: "component", type: SearchBarComponent, selector: "input[kendoSearchbar]", inputs: ["tagListId", "readonly", "disabled", "isRequired", "isSuggestable", "isFilterable", "userInput", "suggestedText", "inputAttributes", "id", "activeDescendant", "tabIndex", "isLoading", "ariaControls", "ariaExpanded", "placeholder"], outputs: ["valueChange", "onBlur", "onFocus", "onClick", "onNavigate"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { kind: "component", type: AdaptiveRendererComponent, selector: "kendo-adaptive-renderer", inputs: ["title", "subtitle", "showTextInput", "sharedPopupActionSheetTemplate", "text", "placeholder", "searchBarValue", "filterable"], outputs: ["closePopup", "textInputChange", "navigate", "onExpand"] }, { kind: "directive", type: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }, { kind: "component", type: ListComponent, selector: "kendo-list", inputs: ["selected", "focused", "textField", "valueField", "height", "template", "groupTemplate", "fixedGroupTemplate", "show", "id", "optionPrefix", "multipleSelection", "virtual", "type", "checkboxes", "ariaLive", "isMultiselect", "isActionSheetExpanded", "showStickyHeader", "rowWidth", "customItemTemplate", "text", "allowCustom", "defaultItem", "data", "size", "rounded"], outputs: ["onClick", "pageChange", "listResize", "popupListScroll"] }] });
2005
- }
2006
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MultiSelectComponent, decorators: [{
2007
- type: Component,
2008
- args: [{
2009
- exportAs: 'kendoMultiSelect',
2010
- providers: [
2011
- MULTISELECT_VALUE_ACCESSOR,
2012
- DataService,
2013
- SelectionService,
2014
- NavigationService,
2015
- DisabledItemsService,
2016
- LocalizationService,
2017
- {
2018
- provide: L10N_PREFIX,
2019
- useValue: 'kendo.multiselect'
2020
- },
2021
- {
2022
- provide: FilterableComponent, useExisting: forwardRef(() => MultiSelectComponent)
2023
- },
2024
- {
2025
- provide: KendoInput, useExisting: forwardRef(() => MultiSelectComponent)
2026
- }
2027
- ],
2028
- selector: 'kendo-multiselect',
2029
- template: `
2030
- <ng-container kendoMultiSelectLocalizedMessages
2031
- i18n-noDataText="kendo.multiselect.noDataText|The text displayed in the popup when there are no items"
2032
- noDataText="NO DATA FOUND"
2033
-
2034
- i18n-clearTitle="kendo.multiselect.clearTitle|The title of the clear button"
2035
- clearTitle="clear"
2036
-
2037
- i18n-popupLabel="kendo.multiselect.popupLabel|The label of the popup element that contains the list of options when its role is 'region'"
2038
- popupLabel="Options list"
2039
-
2040
- i18n-adaptiveCloseButtonTitle="kendo.multiselect.adaptiveCloseButtonTitle|The title of the Close button of the ActionSheet that is rendered instead of the Popup when using small screen devices in adaptive mode."
2041
- adaptiveCloseButtonTitle="Close"
2042
-
2043
- i18n-useCustomValueText="kendo.multiselect.useCustomValueText|The text displayed when the user types a custom value that is not in the list of options."
2044
- useCustomValueText="{{ 'Use &quot;{customValue}&quot;' }}"
2045
- >
2046
- </ng-container>
2047
-
2048
- <ng-container
2049
- kendoDropDownSharedEvents
2050
- [hostElement]="hostElement"
2051
- [(isFocused)]="isFocused"
2052
- (handleBlur)="handleBlur()"
2053
- (onFocus)="handleFocus()"
2054
- >
2055
- @if (prefixTemplate) {
2056
- <span class="k-input-prefix k-input-prefix-horizontal">
2057
- <ng-template [ngTemplateOutlet]="prefixTemplate?.templateRef">
2058
- </ng-template>
2059
- </span>
2060
- }
2061
- @if (prefixTemplate && prefixTemplate.showSeparator) {
2062
- <kendo-separator></kendo-separator>
2063
- }
2064
- <div class="k-input-values">
2065
- <kendo-taglist
2066
- [size]="size"
2067
- [rounded]="rounded"
2068
- [fillMode]="fillMode"
2069
- [id]="tagListId"
2070
- [tags]="tags"
2071
- [textField]="textField"
2072
- [valueField]="valueField"
2073
- [focused]="focusedTagIndex"
2074
- [disabled]="disabled"
2075
- [template]="tagTemplate"
2076
- [groupTemplate]="groupTagTemplate"
2077
- [tagPrefix]="tagPrefix"
2078
- [disabledIndices]="disabledIndices"
2079
- (removeTag)="handleRemoveTag($event)"
2080
- >
2081
- </kendo-taglist>
2082
- <input
2083
- kendoSearchbar
2084
- [ariaControls]="ariaControls"
2085
- [ariaExpanded]="isOpen"
2086
- [id]="focusableId"
2087
- [tagListId]="tagListId"
2088
- [isLoading]="loading"
2089
- [isFilterable]="filterable"
2090
- [activeDescendant]="activeDescendant"
2091
- [userInput]="text"
2092
- [disabled]="disabled"
2093
- [readonly]="readonly || this.isAdaptive"
2094
- [tabIndex]="tabIndex"
2095
- [isRequired]="isControlRequired"
2096
- [placeholder]="placeholder"
2097
- [inputAttributes]="inputAttributes"
2098
- (onNavigate)="handleNavigate($event)"
2099
- (valueChange)="handleFilter($event)"
2100
- (onBlur)="handleInputBlur()"
2101
- (onFocus)="handleInputFocus()"
2102
- (click)="handleClick()"
2103
- />
2104
- </div>
2105
-
2106
- @if (!loading && !readonly && clearButton && (tags?.length || text?.length)) {
2107
- <span
2108
- class="k-clear-value"
2109
- [style.visibility]="clearButtonVisibility"
2110
- [attr.title]="messageFor('clearTitle')"
2111
- role="button"
2112
- tabindex="-1"
2113
- (mousedown)="clearAll($event)"
2114
- >
2115
- <kendo-icon-wrapper
2116
- class="k-icon"
2117
- name="x"
2118
- [svgIcon]="xIcon"
2119
- >
2120
- </kendo-icon-wrapper>
2121
- </span>
2122
- }
2123
- @if (loading) {
2124
- <span
2125
- class="k-icon k-i-loading k-input-loading-icon"
2126
- >
2127
- </span>
2128
- }
2129
- @if (suffixTemplate && suffixTemplate.showSeparator) {
2130
- <kendo-separator></kendo-separator>
2131
- }
2132
- @if (suffixTemplate) {
2133
- <span class="k-input-suffix k-input-suffix-horizontal">
2134
- <ng-template [ngTemplateOutlet]="suffixTemplate?.templateRef">
2135
- </ng-template>
2136
- </span>
2137
- }
2138
- </ng-container>
2139
-
2140
- <ng-template #popupTemplate>
2141
- <ng-container *ngTemplateOutlet="sharedPopupActionSheetTemplate"></ng-container>
2142
- </ng-template>
2143
- @if (isOpen || isAdaptiveModeEnabled) {
2144
- <kendo-resize-sensor (resize)="onResize()"></kendo-resize-sensor>
2145
- }
2146
- <ng-container #container></ng-container>
2147
-
2148
- <kendo-adaptive-renderer
2149
- [sharedPopupActionSheetTemplate]="sharedPopupActionSheetTemplate"
2150
- [title]="adaptiveTitle"
2151
- [showTextInput]="true"
2152
- [subtitle]="adaptiveSubtitle"
2153
- (closePopup)="applyValue()"
2154
- (textInputChange)="handleFilter($event)"
2155
- [placeholder]="placeholder"
2156
- (navigate)="handleNavigate($event)"
2157
- [searchBarValue]="text">
2158
- </kendo-adaptive-renderer>
2159
-
2160
- <ng-template #sharedPopupActionSheetTemplate>
2161
- <!--header template-->
2162
- @if (headerTemplate) {
2163
- <ng-template
2164
- [templateContext]="{
2165
- templateRef: headerTemplate.templateRef
2166
- }">
2167
- </ng-template>
2168
- }
2169
- <!--list-->
2170
- <kendo-list
2171
- #optionsList
2172
- [size]="isAdaptive ? 'large' : size"
2173
- [rounded]="rounded"
2174
- [id]="listBoxId"
2175
- [optionPrefix]="optionPrefix"
2176
- [data]="data"
2177
- [textField]="textField"
2178
- [valueField]="valueField"
2179
- [template]="template"
2180
- [groupTemplate]="groupTemplate"
2181
- [fixedGroupTemplate]="fixedGroupTemplate"
2182
- [height]="listHeight"
2183
- [show]="isOpen"
2184
- [multipleSelection]="true"
2185
- [virtual]="virtual"
2186
- (pageChange)="pageChange($event)"
2187
- [checkboxes]="checkboxes"
2188
- [isMultiselect]="true"
2189
- [isActionSheetExpanded]="isActionSheetExpanded"
2190
- [showStickyHeader]="showStickyHeader"
2191
- [customItemTemplate]="customItemTemplate"
2192
- [text]="text"
2193
- [allowCustom]="allowCustom"
2194
- >
2195
- </kendo-list>
2196
- <!--no data template-->
2197
- @if (data.length === 0) {
2198
- <div class="k-no-data">
2199
- @if (noDataTemplate) {
2200
- <ng-template
2201
- [templateContext]="{
2202
- templateRef: noDataTemplate ? noDataTemplate.templateRef : undefined
2203
- }">
2204
- </ng-template>
2205
- }
2206
- @if (!noDataTemplate) {
2207
- <div>{{ messageFor('noDataText') }}</div>
2208
- }
2209
- </div>
2210
- }
2211
- <!--footer template-->
2212
- @if (footerTemplate) {
2213
- <ng-template
2214
- [templateContext]="{
2215
- templateRef: footerTemplate.templateRef
2216
- }">
2217
- </ng-template>
2218
- }
2219
- </ng-template>
2220
- `,
2221
- standalone: true,
2222
- imports: [LocalizedMessagesDirective, SharedDropDownEventsDirective, NgTemplateOutlet, SeparatorComponent, TagListComponent, SearchBarComponent, IconWrapperComponent, ResizeSensorComponent, AdaptiveRendererComponent, TemplateContextDirective, ListComponent]
2223
- }]
2224
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.LocalizationService }, { type: i2.PopupService }, { type: i3.DataService }, { type: i4.SelectionService }, { type: i5.NavigationService }, { type: i6.DisabledItemsService }, { type: i0.ChangeDetectorRef }, { type: i0.KeyValueDiffers }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i0.Injector }, { type: i0.ElementRef }, { type: i7.AdaptiveService }], propDecorators: { adaptiveRendererComponent: [{
2225
- type: ViewChild,
2226
- args: [AdaptiveRendererComponent]
2227
- }], showStickyHeader: [{
2228
- type: Input
2229
- }], focusableId: [{
2230
- type: Input
2231
- }], autoClose: [{
2232
- type: Input
2233
- }], loading: [{
2234
- type: Input
2235
- }], data: [{
2236
- type: Input
2237
- }], value: [{
2238
- type: Input
2239
- }], valueField: [{
2240
- type: Input
2241
- }], textField: [{
2242
- type: Input
2243
- }], tabindex: [{
2244
- type: Input
2245
- }], tabIndex: [{
2246
- type: Input,
2247
- args: ["tabIndex"]
2248
- }], size: [{
2249
- type: Input
2250
- }], rounded: [{
2251
- type: Input
2252
- }], fillMode: [{
2253
- type: Input
2254
- }], placeholder: [{
2255
- type: Input
2256
- }], adaptiveMode: [{
2257
- type: Input
2258
- }], adaptiveTitle: [{
2259
- type: Input
2260
- }], adaptiveSubtitle: [{
2261
- type: Input
2262
- }], disabled: [{
2263
- type: Input
2264
- }], itemDisabled: [{
2265
- type: Input
2266
- }], checkboxes: [{
2267
- type: Input
2268
- }], readonly: [{
2269
- type: Input
2270
- }, {
2271
- type: HostBinding,
2272
- args: ['class.k-readonly']
2273
- }], filterable: [{
2274
- type: Input
2275
- }], virtual: [{
2276
- type: Input
2277
- }], popupSettings: [{
2278
- type: Input
2279
- }], listHeight: [{
2280
- type: Input
2281
- }], valuePrimitive: [{
2282
- type: Input
2283
- }], clearButton: [{
2284
- type: Input
2285
- }], tagMapper: [{
2286
- type: Input
2287
- }], allowCustom: [{
2288
- type: Input
2289
- }], valueNormalizer: [{
2290
- type: Input
2291
- }], inputAttributes: [{
2292
- type: Input
2293
- }], filterChange: [{
2294
- type: Output
2295
- }], valueChange: [{
2296
- type: Output
2297
- }], open: [{
2298
- type: Output
2299
- }], opened: [{
2300
- type: Output
2301
- }], close: [{
2302
- type: Output
2303
- }], closed: [{
2304
- type: Output
2305
- }], onFocus: [{
2306
- type: Output,
2307
- args: ['focus']
2308
- }], onBlur: [{
2309
- type: Output,
2310
- args: ['blur']
2311
- }], inputFocus: [{
2312
- type: Output
2313
- }], inputBlur: [{
2314
- type: Output
2315
- }], removeTag: [{
2316
- type: Output
2317
- }], container: [{
2318
- type: ViewChild,
2319
- args: ['container', { read: ViewContainerRef, static: true }]
2320
- }], searchbar: [{
2321
- type: ViewChild,
2322
- args: [SearchBarComponent, { static: true }]
2323
- }], tagList: [{
2324
- type: ViewChild,
2325
- args: [TagListComponent, { static: true }]
2326
- }], popupTemplate: [{
2327
- type: ViewChild,
2328
- args: ['popupTemplate', { static: true }]
2329
- }], optionsList: [{
2330
- type: ViewChild,
2331
- args: ['optionsList', { static: false }]
2332
- }], template: [{
2333
- type: ContentChild,
2334
- args: [ItemTemplateDirective, { static: false }]
2335
- }], customItemTemplate: [{
2336
- type: ContentChild,
2337
- args: [CustomItemTemplateDirective, { static: false }]
2338
- }], groupTemplate: [{
2339
- type: ContentChild,
2340
- args: [GroupTemplateDirective, { static: false }]
2341
- }], fixedGroupTemplate: [{
2342
- type: ContentChild,
2343
- args: [FixedGroupTemplateDirective, { static: false }]
2344
- }], headerTemplate: [{
2345
- type: ContentChild,
2346
- args: [HeaderTemplateDirective, { static: false }]
2347
- }], footerTemplate: [{
2348
- type: ContentChild,
2349
- args: [FooterTemplateDirective, { static: false }]
2350
- }], tagTemplate: [{
2351
- type: ContentChild,
2352
- args: [TagTemplateDirective, { static: false }]
2353
- }], groupTagTemplate: [{
2354
- type: ContentChild,
2355
- args: [GroupTagTemplateDirective, { static: false }]
2356
- }], noDataTemplate: [{
2357
- type: ContentChild,
2358
- args: [NoDataTemplateDirective, { static: false }]
2359
- }], suffixTemplate: [{
2360
- type: ContentChild,
2361
- args: [SuffixTemplateDirective]
2362
- }], prefixTemplate: [{
2363
- type: ContentChild,
2364
- args: [PrefixTemplateDirective]
2365
- }], hostClasses: [{
2366
- type: HostBinding,
2367
- args: ['class.k-multiselect']
2368
- }, {
2369
- type: HostBinding,
2370
- args: ['class.k-input']
2371
- }], dir: [{
2372
- type: HostBinding,
2373
- args: ['attr.dir']
2374
- }], disabledClass: [{
2375
- type: HostBinding,
2376
- args: ['class.k-disabled']
2377
- }], isLoading: [{
2378
- type: HostBinding,
2379
- args: ['class.k-loading']
2380
- }] } });