ng-jvx-multiselect 1.1.28

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 (56) hide show
  1. package/README.md +330 -0
  2. package/_index.scss +1 -0
  3. package/esm2020/lib/directives/ng-jvx-disabled-option.directive.mjs +49 -0
  4. package/esm2020/lib/directives/ng-jvx-focus.directive.mjs +29 -0
  5. package/esm2020/lib/directives/ng-jvx-group-header.directive.mjs +25 -0
  6. package/esm2020/lib/directives/ng-jvx-options-template.directive.mjs +26 -0
  7. package/esm2020/lib/directives/ng-jvx-selection-template.directive.mjs +25 -0
  8. package/esm2020/lib/interfaces/ng-jvx-group-mapper.mjs +2 -0
  9. package/esm2020/lib/interfaces/ng-jvx-option-mapper.mjs +2 -0
  10. package/esm2020/lib/interfaces/ng-jvx-search-mapper.mjs +2 -0
  11. package/esm2020/lib/ng-jvx-multiselect.component.mjs +589 -0
  12. package/esm2020/lib/ng-jvx-multiselect.module.mjs +92 -0
  13. package/esm2020/lib/ng-jvx-multiselect.service.mjs +42 -0
  14. package/esm2020/lib/ng-jvx-option/ng-jvx-option.component.mjs +31 -0
  15. package/esm2020/lib/ng-jvx-panel/ng-jvx-panel.component.mjs +41 -0
  16. package/esm2020/ng-jvx-multiselect.mjs +5 -0
  17. package/esm2020/public-api.mjs +15 -0
  18. package/fesm2015/ng-jvx-multiselect.mjs +924 -0
  19. package/fesm2015/ng-jvx-multiselect.mjs.map +1 -0
  20. package/fesm2020/ng-jvx-multiselect.mjs +918 -0
  21. package/fesm2020/ng-jvx-multiselect.mjs.map +1 -0
  22. package/lib/directives/ng-jvx-disabled-option.directive.d.ts +14 -0
  23. package/lib/directives/ng-jvx-disabled-option.directive.d.ts.map +1 -0
  24. package/lib/directives/ng-jvx-focus.directive.d.ts +11 -0
  25. package/lib/directives/ng-jvx-focus.directive.d.ts.map +1 -0
  26. package/lib/directives/ng-jvx-group-header.directive.d.ts +10 -0
  27. package/lib/directives/ng-jvx-group-header.directive.d.ts.map +1 -0
  28. package/lib/directives/ng-jvx-options-template.directive.d.ts +11 -0
  29. package/lib/directives/ng-jvx-options-template.directive.d.ts.map +1 -0
  30. package/lib/directives/ng-jvx-selection-template.directive.d.ts +10 -0
  31. package/lib/directives/ng-jvx-selection-template.directive.d.ts.map +1 -0
  32. package/lib/interfaces/ng-jvx-group-mapper.d.ts +8 -0
  33. package/lib/interfaces/ng-jvx-group-mapper.d.ts.map +1 -0
  34. package/lib/interfaces/ng-jvx-option-mapper.d.ts +7 -0
  35. package/lib/interfaces/ng-jvx-option-mapper.d.ts.map +1 -0
  36. package/lib/interfaces/ng-jvx-search-mapper.d.ts +7 -0
  37. package/lib/interfaces/ng-jvx-search-mapper.d.ts.map +1 -0
  38. package/lib/ng-jvx-multiselect.component.d.ts +144 -0
  39. package/lib/ng-jvx-multiselect.component.d.ts.map +1 -0
  40. package/lib/ng-jvx-multiselect.module.d.ts +26 -0
  41. package/lib/ng-jvx-multiselect.module.d.ts.map +1 -0
  42. package/lib/ng-jvx-multiselect.service.d.ts +20 -0
  43. package/lib/ng-jvx-multiselect.service.d.ts.map +1 -0
  44. package/lib/ng-jvx-option/ng-jvx-option.component.d.ts +14 -0
  45. package/lib/ng-jvx-option/ng-jvx-option.component.d.ts.map +1 -0
  46. package/lib/ng-jvx-panel/ng-jvx-panel.component.d.ts +16 -0
  47. package/lib/ng-jvx-panel/ng-jvx-panel.component.d.ts.map +1 -0
  48. package/ng-jvx-multiselect.d.ts +5 -0
  49. package/ng-jvx-multiselect.d.ts.map +1 -0
  50. package/package.json +48 -0
  51. package/public-api.d.ts +11 -0
  52. package/public-api.d.ts.map +1 -0
  53. package/src/lib/mixins.scss +6 -0
  54. package/src/lib/ng-jvx-multiselect.component.scss +234 -0
  55. package/src/lib/ng-jvx-option/ng-jvx-option.component.scss +40 -0
  56. package/src/lib/ng-jvx-panel/ng-jvx-panel.component.scss +0 -0
@@ -0,0 +1,918 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Component, ViewChild, Input, Directive, Injectable, EventEmitter, forwardRef, ChangeDetectionStrategy, Optional, Self, HostBinding, ViewChildren, ContentChild, Output, ViewEncapsulation, Inject, NgModule } from '@angular/core';
3
+ import * as i1 from '@angular/material/list';
4
+ import { MatListModule } from '@angular/material/list';
5
+ import * as i9 from '@angular/common';
6
+ import { CommonModule } from '@angular/common';
7
+ import { Subject, fromEvent, of, noop, timer, forkJoin } from 'rxjs';
8
+ import { takeUntil, debounceTime, map, switchMap, tap, distinctUntilChanged } from 'rxjs/operators';
9
+ import * as i1$1 from '@angular/common/http';
10
+ import { HttpParams, HttpHeaders, HttpClientModule } from '@angular/common/http';
11
+ import * as i1$2 from '@angular/forms';
12
+ import { FormControl, ReactiveFormsModule, FormsModule } from '@angular/forms';
13
+ import { MatFormFieldControl } from '@angular/material/form-field';
14
+ import { coerceBooleanProperty } from '@angular/cdk/coercion';
15
+ import * as i3 from '@angular/material/menu';
16
+ import { _MatMenuBase, MAT_MENU_DEFAULT_OPTIONS, MAT_MENU_PANEL, MatMenu, matMenuAnimations, MatMenuModule } from '@angular/material/menu';
17
+ import * as i4 from 'ngx-scrollbar';
18
+ import { NgScrollbarModule } from 'ngx-scrollbar';
19
+ import * as i7 from '@angular/material/icon';
20
+ import { MatIconModule } from '@angular/material/icon';
21
+ import * as i8 from '@angular/material/chips';
22
+ import { MatChipsModule } from '@angular/material/chips';
23
+ import * as i11 from 'ngx-scrollbar/smooth-scroll';
24
+ import { SmoothScrollModule } from 'ngx-scrollbar/smooth-scroll';
25
+ import { MatButtonModule } from '@angular/material/button';
26
+ import { MatOptionModule } from '@angular/material/core';
27
+ import { MatSelectModule } from '@angular/material/select';
28
+
29
+ class NgJvxOptionComponent {
30
+ constructor() {
31
+ this.isSelected = false;
32
+ }
33
+ ngOnInit() {
34
+ }
35
+ ngDoCheck() {
36
+ if (this.isSelected !== this.listOption.selected) {
37
+ this.isSelected = this.listOption.selected;
38
+ }
39
+ }
40
+ deselect() {
41
+ this.listOption.selected = false;
42
+ }
43
+ }
44
+ NgJvxOptionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
45
+ NgJvxOptionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.2", type: NgJvxOptionComponent, selector: "ng-jvx-option", inputs: { value: "value" }, viewQueries: [{ propertyName: "listOption", first: true, predicate: ["listOption"], descendants: true, static: true }], ngImport: i0, template: "<mat-list-option [value]=\"value\" [ngClass]=\"{'ng-jvx-option': true, 'mat-list-single-selected-option': isSelected}\" #listOption>\r\n <ng-content></ng-content>\r\n <div class=\"list-option-background\"></div>\r\n</mat-list-option>\r\n", styles: [""], components: [{ type: i1.MatListOption, selector: "mat-list-option", inputs: ["disableRipple", "checkboxPosition", "color", "value", "disabled", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }], directives: [{ type: i9.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
46
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxOptionComponent, decorators: [{
47
+ type: Component,
48
+ args: [{ selector: 'ng-jvx-option', template: "<mat-list-option [value]=\"value\" [ngClass]=\"{'ng-jvx-option': true, 'mat-list-single-selected-option': isSelected}\" #listOption>\r\n <ng-content></ng-content>\r\n <div class=\"list-option-background\"></div>\r\n</mat-list-option>\r\n", styles: [""] }]
49
+ }], ctorParameters: function () { return []; }, propDecorators: { listOption: [{
50
+ type: ViewChild,
51
+ args: ['listOption', { static: true }]
52
+ }], value: [{
53
+ type: Input
54
+ }] } });
55
+
56
+ class NgJvxOptionsTemplateDirective {
57
+ constructor(el, template, vcRef) {
58
+ this.el = el;
59
+ this.template = template;
60
+ this.vcRef = vcRef;
61
+ }
62
+ set ngJvxOptionsTemplateOf(source) {
63
+ for (const item of source) {
64
+ this.vcRef.createEmbeddedView(this.template, { $implicit: item });
65
+ }
66
+ }
67
+ }
68
+ NgJvxOptionsTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxOptionsTemplateDirective, deps: [{ token: i0.ElementRef }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
69
+ NgJvxOptionsTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.0.2", type: NgJvxOptionsTemplateDirective, selector: "[ngJvxOptionsTemplate]", inputs: { ngJvxOptionsTemplateOf: "ngJvxOptionsTemplateOf" }, ngImport: i0 });
70
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxOptionsTemplateDirective, decorators: [{
71
+ type: Directive,
72
+ args: [{
73
+ // tslint:disable-next-line:directive-selector
74
+ selector: '[ngJvxOptionsTemplate]'
75
+ }]
76
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }]; }, propDecorators: { ngJvxOptionsTemplateOf: [{
77
+ type: Input
78
+ }] } });
79
+
80
+ class NgJvxSelectionTemplateDirective {
81
+ constructor(template, vcRef) {
82
+ this.template = template;
83
+ this.vcRef = vcRef;
84
+ }
85
+ set ngJvxSelectionTemplateOf(source) {
86
+ for (const item of source) {
87
+ this.vcRef.createEmbeddedView(this.template, { $implicit: item });
88
+ }
89
+ }
90
+ }
91
+ NgJvxSelectionTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxSelectionTemplateDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
92
+ NgJvxSelectionTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.0.2", type: NgJvxSelectionTemplateDirective, selector: "[ngJvxSelectionTemplate]", inputs: { ngJvxSelectionTemplateOf: "ngJvxSelectionTemplateOf" }, ngImport: i0 });
93
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxSelectionTemplateDirective, decorators: [{
94
+ type: Directive,
95
+ args: [{
96
+ // tslint:disable-next-line:directive-selector
97
+ selector: '[ngJvxSelectionTemplate]'
98
+ }]
99
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }]; }, propDecorators: { ngJvxSelectionTemplateOf: [{
100
+ type: Input
101
+ }] } });
102
+
103
+ class NgJvxGroupHeaderDirective {
104
+ constructor(template, vcRef) {
105
+ this.template = template;
106
+ this.vcRef = vcRef;
107
+ }
108
+ set ngJvxGroupHeaderOf(source) {
109
+ for (const item of source) {
110
+ this.vcRef.createEmbeddedView(this.template, { $implicit: item });
111
+ }
112
+ }
113
+ }
114
+ NgJvxGroupHeaderDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxGroupHeaderDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
115
+ NgJvxGroupHeaderDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.0.2", type: NgJvxGroupHeaderDirective, selector: "[ngJvxGroupHeader]", inputs: { ngJvxGroupHeaderOf: "ngJvxGroupHeaderOf" }, ngImport: i0 });
116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxGroupHeaderDirective, decorators: [{
117
+ type: Directive,
118
+ args: [{
119
+ // tslint:disable-next-line:directive-selector
120
+ selector: '[ngJvxGroupHeader]'
121
+ }]
122
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }]; }, propDecorators: { ngJvxGroupHeaderOf: [{
123
+ type: Input
124
+ }] } });
125
+
126
+ class NgJvxDisabledOptionDirective {
127
+ constructor(el) {
128
+ this.el = el;
129
+ this.isDisabled = false;
130
+ this.originalOpacity = 1;
131
+ this.unsubs = new Subject();
132
+ this.originalOpacity = el.nativeElement.style.opacity;
133
+ }
134
+ set ngJvxDisabledOption(source) {
135
+ this.isDisabled = source;
136
+ if (this.isDisabled) {
137
+ this.el.nativeElement.style.opacity = this.originalOpacity ? this.originalOpacity / 2 : 0.5;
138
+ }
139
+ else {
140
+ this.el.nativeElement.style.opacity = this.originalOpacity;
141
+ }
142
+ }
143
+ ngOnInit() {
144
+ fromEvent(this.el.nativeElement.closest('.mat-list-item-content'), 'click', {
145
+ capture: true,
146
+ }).pipe(takeUntil(this.unsubs)).subscribe((e) => {
147
+ if (this.isDisabled) {
148
+ e.stopImmediatePropagation();
149
+ e.stopPropagation();
150
+ e.preventDefault();
151
+ }
152
+ });
153
+ }
154
+ ngOnDestroy() {
155
+ this.unsubs.next();
156
+ this.unsubs.complete();
157
+ }
158
+ }
159
+ NgJvxDisabledOptionDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxDisabledOptionDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
160
+ NgJvxDisabledOptionDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.0.2", type: NgJvxDisabledOptionDirective, selector: "[ngJvxDisabledOption]", inputs: { ngJvxDisabledOption: "ngJvxDisabledOption" }, ngImport: i0 });
161
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxDisabledOptionDirective, decorators: [{
162
+ type: Directive,
163
+ args: [{
164
+ // tslint:disable-next-line:directive-selector
165
+ selector: '[ngJvxDisabledOption]'
166
+ }]
167
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { ngJvxDisabledOption: [{
168
+ type: Input
169
+ }] } });
170
+
171
+ class NgJvxMultiselectService {
172
+ constructor(http) {
173
+ this.http = http;
174
+ }
175
+ getList({ url, ignorePagination = false, currentPage, pageSize, requestType = 'get', requestHeaders, search, searchProp = 'search', data }) {
176
+ let params = new HttpParams();
177
+ if (search && search.length > 0) {
178
+ params = params.set(searchProp, search);
179
+ }
180
+ if (!ignorePagination) {
181
+ params = params.set('page', currentPage.toString())
182
+ .set('size', pageSize.toString());
183
+ }
184
+ const options = {
185
+ mode: 'no-cors',
186
+ headers: requestHeaders,
187
+ // withCredentials: true,
188
+ // credentials: 'same-origin', // cache: 'default',
189
+ data,
190
+ params
191
+ };
192
+ if (requestType === 'get') {
193
+ return this.http.get(url, options);
194
+ }
195
+ else {
196
+ return this.http.post(url, options);
197
+ }
198
+ }
199
+ }
200
+ NgJvxMultiselectService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxMultiselectService, deps: [{ token: i1$1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
201
+ NgJvxMultiselectService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxMultiselectService, providedIn: 'root' });
202
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxMultiselectService, decorators: [{
203
+ type: Injectable,
204
+ args: [{
205
+ providedIn: 'root'
206
+ }]
207
+ }], ctorParameters: function () { return [{ type: i1$1.HttpClient }]; } });
208
+
209
+ class NgJvxFocusDirective {
210
+ constructor(el) {
211
+ this.el = el;
212
+ }
213
+ ngOnInit() {
214
+ if (this.ngJvxFocus) {
215
+ this.el.nativeElement.focus();
216
+ }
217
+ }
218
+ ngOnChanges(changes) {
219
+ if (changes.hasOwnProperty('ngJvxFocus') && changes.ngJvxFocus.currentValue === true) {
220
+ this.el.nativeElement.focus();
221
+ }
222
+ }
223
+ }
224
+ NgJvxFocusDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxFocusDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
225
+ NgJvxFocusDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.0.2", type: NgJvxFocusDirective, selector: "[ngJvxFocus]", inputs: { ngJvxFocus: "ngJvxFocus" }, usesOnChanges: true, ngImport: i0 });
226
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxFocusDirective, decorators: [{
227
+ type: Directive,
228
+ args: [{
229
+ // tslint:disable-next-line:directive-selector
230
+ selector: '[ngJvxFocus]'
231
+ }]
232
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { ngJvxFocus: [{
233
+ type: Input
234
+ }] } });
235
+
236
+ class NgJvxMultiselectComponent {
237
+ constructor(formBuilder, service, elementRef, changeDetectorRef, ngControl, fb) {
238
+ this.formBuilder = formBuilder;
239
+ this.service = service;
240
+ this.elementRef = elementRef;
241
+ this.changeDetectorRef = changeDetectorRef;
242
+ this.ngControl = ngControl;
243
+ this.id = `jvx-multiselect-${NgJvxMultiselectComponent.nextId++}`;
244
+ this.optionsTemplate = null;
245
+ this.selectionTemplate = null;
246
+ this.groupHeaderTemplate = null;
247
+ // @ContentChild(NgJvxOptionComponent) optionComp: NgJvxOptionComponent;
248
+ // @ContentChild(TemplateRef) optionsTemplate: TemplateRef<any> | null = null;
249
+ this.options = [];
250
+ this.multi = false;
251
+ this.url = '';
252
+ this.requestType = 'get';
253
+ this.itemValue = 'value';
254
+ this.itemText = 'text';
255
+ this.ignorePagination = false;
256
+ this.clearable = false;
257
+ this.closeOnClick = true;
258
+ this.hasErrors = false;
259
+ this.searchMode = null;
260
+ this.searchInput = false;
261
+ this.searchLabel = 'search';
262
+ this.listProp = '';
263
+ this.totalRowsProp = '';
264
+ this.panelClass = '';
265
+ this.searchProp = 'search';
266
+ this.mapper = {
267
+ mapOption(source) {
268
+ return of(source);
269
+ }
270
+ };
271
+ this.searchMapper = {
272
+ mapSearch: (source, options) => {
273
+ return of(options.filter(o => o[this.itemText].toString().toLowerCase().includes(source.toString().toLowerCase())));
274
+ }
275
+ };
276
+ this.requestHeaders = new HttpHeaders();
277
+ // tslint:disable-next-line:variable-name
278
+ this._required = false;
279
+ // tslint:disable-next-line:variable-name
280
+ this._disabled = false;
281
+ this.valueChange = new EventEmitter();
282
+ this.jvxMultiselectOpen = new EventEmitter();
283
+ this.jvxMultiselectOpened = new EventEmitter();
284
+ this.jvxMultiselectClose = new EventEmitter();
285
+ this.jvxMultiselectClosed = new EventEmitter();
286
+ this.scrollEnd = new EventEmitter();
287
+ this.controlType = 'ng-jvx-multiselect';
288
+ this.document = document;
289
+ this.window = window;
290
+ this.isOpen = false;
291
+ this.isLoading = false;
292
+ this.showList = true;
293
+ this.asyncOptions = [];
294
+ this.selectableOptions = [];
295
+ this.orderedOptions = [];
296
+ this.searchValue = '';
297
+ this.yPosition = 'above';
298
+ this.stateChanges = new Subject();
299
+ this.currentPage = 0;
300
+ this.listContainerSize = { height: 'auto', minHeight: '0', width: '100%' };
301
+ this.touched = false;
302
+ this.focused = false;
303
+ this.multiContainerWidth = 100;
304
+ this.searchValueSubject = new Subject();
305
+ this.searchValue$ = this.searchValueSubject.asObservable();
306
+ this.pValue = [];
307
+ this.shouldLoadMore = true;
308
+ this.pageSize = 15;
309
+ this.unsubscribe = new Subject();
310
+ this.unsubscribe$ = this.unsubscribe.asObservable();
311
+ this.onTouched = () => {
312
+ };
313
+ if (this.ngControl != null) {
314
+ // Setting the value accessor directly (instead of using
315
+ // the providers) to avoid running into a circular import.
316
+ this.ngControl.valueAccessor = this;
317
+ }
318
+ this.parts = fb.group({
319
+ area: '',
320
+ exchange: '',
321
+ subscriber: '',
322
+ });
323
+ this.form = this.formBuilder.group({
324
+ selectionValue: new FormControl(this.selectionValue)
325
+ });
326
+ }
327
+ get shouldLabelFloat() {
328
+ return this.focused || !this.empty;
329
+ }
330
+ set value(value) {
331
+ this.pValue = value ?? [];
332
+ if (value) {
333
+ this.form.get('selectionValue').setValue(this.pValue.map(v => v[this.itemValue]));
334
+ }
335
+ else {
336
+ this.form.get('selectionValue').setValue(value);
337
+ }
338
+ this.stateChanges.next();
339
+ }
340
+ get value() {
341
+ return this.pValue;
342
+ }
343
+ get required() {
344
+ return this._required;
345
+ }
346
+ set required(req) {
347
+ this._required = coerceBooleanProperty(req);
348
+ this.stateChanges.next();
349
+ }
350
+ get disabled() {
351
+ return this._disabled;
352
+ }
353
+ set disabled(value) {
354
+ this._disabled = coerceBooleanProperty(value);
355
+ this._disabled ? this.parts.disable() : this.parts.enable();
356
+ this.stateChanges.next();
357
+ }
358
+ get errorState() {
359
+ if (this.ngControl != null) {
360
+ return this.ngControl.invalid && this.ngControl.touched;
361
+ }
362
+ else {
363
+ return false;
364
+ }
365
+ }
366
+ ngOnInit() {
367
+ this.stateChange$.pipe(takeUntil(this.unsubscribe)).subscribe(() => {
368
+ this.changeDetectorRef.markForCheck();
369
+ });
370
+ this.selectableOptions = [...this.options];
371
+ this.updateOrderedOptions(this.selectableOptions).subscribe(noop);
372
+ fromEvent(window, 'resize').pipe(takeUntil(this.unsubscribe), debounceTime(100), map(() => {
373
+ return this.listContainerSize.width = this.jvxMultiselect.nativeElement.offsetWidth + 'px';
374
+ }), switchMap(() => timer(100)), tap(() => {
375
+ this.multiContainerWidth = this.multiContainer?.nativeElement?.offsetWidth ?? 100;
376
+ this.yPosition = window.innerHeight - this.jvxMultiselect.nativeElement?.getBoundingClientRect()?.top < 260 ? 'above' : 'below';
377
+ this.changeDetectorRef.markForCheck();
378
+ })).subscribe(noop);
379
+ this.searchValue$.pipe(takeUntil(this.unsubscribe), debounceTime(300), distinctUntilChanged((prev, curr) => {
380
+ return curr === this.searchValue;
381
+ }), switchMap((val) => {
382
+ this.searchValue = val;
383
+ this.currentPage = 0;
384
+ if (this.searchMode === 'client') {
385
+ return this.clientSearch();
386
+ }
387
+ else if (this.url && this.url.length > 0) {
388
+ return this.serverSearch();
389
+ }
390
+ })).subscribe((val) => {
391
+ this.changeDetectorRef.markForCheck();
392
+ });
393
+ }
394
+ clientSearch() {
395
+ let obs;
396
+ if (this.url && this.url.length > 0) {
397
+ this.selectableOptions = [];
398
+ this.updateOrderedOptions(this.selectableOptions).subscribe(noop);
399
+ this.shouldLoadMore = true;
400
+ obs = this.getList().pipe(map(() => {
401
+ return this.selectableOptions;
402
+ }));
403
+ }
404
+ else {
405
+ obs = of(this.options);
406
+ }
407
+ return obs.pipe(switchMap((val) => this.searchMapper.mapSearch(this.searchValue, val)), tap((res) => {
408
+ this.selectableOptions = [];
409
+ this.selectableOptions.push(...res);
410
+ }), switchMap(() => this.updateOrderedOptions(this.selectableOptions)));
411
+ }
412
+ serverSearch() {
413
+ this.shouldLoadMore = true;
414
+ this.selectableOptions = [];
415
+ this.shouldLoadMore = true;
416
+ return this.getList();
417
+ }
418
+ ngOnDestroy() {
419
+ this.unsubscribe.next();
420
+ this.stateChanges.complete();
421
+ }
422
+ ngAfterViewInit() {
423
+ timer(0).subscribe(() => {
424
+ this.listContainerSize.width = this.jvxMultiselect.nativeElement.offsetWidth + 'px';
425
+ });
426
+ if (this.scrollbar) {
427
+ this.scrollbar.scrolled.pipe(takeUntil(this.unsubscribe$)).subscribe((e) => {
428
+ this.onScrolled(e);
429
+ });
430
+ }
431
+ timer(0).pipe(tap(() => {
432
+ this.multiContainerWidth = this.multiContainer?.nativeElement?.offsetWidth ?? 100;
433
+ this.yPosition = window.innerHeight - this.jvxMultiselect.nativeElement?.getBoundingClientRect()?.top < 260 ? 'above' : 'below';
434
+ this.changeDetectorRef.markForCheck();
435
+ })).subscribe(noop);
436
+ }
437
+ ngOnChanges(changes) {
438
+ if (changes.options) {
439
+ this.selectableOptions = [...this.options];
440
+ this.updateOrderedOptions(this.selectableOptions).subscribe(noop);
441
+ }
442
+ }
443
+ get selectionValue() {
444
+ return this.value.map((v) => {
445
+ return v[this.itemValue];
446
+ });
447
+ }
448
+ get empty() {
449
+ const n = this.parts.value;
450
+ return !n.area && !n.exchange && !n.subscriber;
451
+ }
452
+ onCLickOnMenu(e) {
453
+ if (this.multi || this.closeOnClick === false) {
454
+ e.stopPropagation();
455
+ }
456
+ }
457
+ propagateChange(_) {
458
+ }
459
+ // this is the initial value set to the component
460
+ writeValue(obj) {
461
+ this.value = obj;
462
+ }
463
+ // registers 'fn' that will be fired when changes are made
464
+ // this is how we emit the changes back to the form
465
+ registerOnChange(fn) {
466
+ this.propagateChange = fn;
467
+ }
468
+ registerOnTouched(fn) {
469
+ this.onTouched = fn;
470
+ }
471
+ onChange(e) {
472
+ let vals = e.source.selectedOptions.selected.map(o => o.value);
473
+ vals = this.selectableOptions.filter(o => vals.includes(o[this.itemValue]));
474
+ console.log(vals);
475
+ const selectableIds = this.selectableOptions.map(s => s[this.itemValue]);
476
+ console.log(selectableIds);
477
+ if (this.multi) {
478
+ // if search is active, probably some of the already selected values are not included in the selectable options,
479
+ // so we have to push them in the selected values of the list;
480
+ for (const v of this.value) {
481
+ if (!selectableIds.includes(v[this.itemValue])) {
482
+ vals = [v, ...vals];
483
+ }
484
+ }
485
+ }
486
+ vals.sort((a, b) => {
487
+ return typeof a[this.itemValue] === 'string' ?
488
+ a[this.itemValue].localeCompare(b[this.itemValue]) : a[this.itemValue] - b[this.itemValue];
489
+ });
490
+ console.log(vals);
491
+ this.value = [...vals];
492
+ this.form.get('selectionValue').setValue(this.value.map(v => v[this.itemValue]));
493
+ this.valueChange.emit(this.value);
494
+ this.propagateChange(this.value);
495
+ this.changeDetectorRef.markForCheck();
496
+ }
497
+ onFocusIn(event) {
498
+ if (!this.focused) {
499
+ this.focused = true;
500
+ this.stateChanges.next();
501
+ }
502
+ }
503
+ onFocusOut(event) {
504
+ if (!this.elementRef.nativeElement.contains(event.relatedTarget)) {
505
+ this.touched = true;
506
+ this.focused = false;
507
+ this.onTouched();
508
+ this.stateChanges.next();
509
+ }
510
+ }
511
+ onMenuOpen() {
512
+ this.isOpen = true;
513
+ this.jvxMultiselectOpen.emit();
514
+ }
515
+ onMenuClose() {
516
+ this.isOpen = false;
517
+ this.jvxMultiselectClose.emit();
518
+ }
519
+ deselect(val) {
520
+ this.value = [...this.value.filter(v => v[this.itemValue] !== val[this.itemValue])];
521
+ // this.value.splice(this.value.findIndex(v => v[this.itemValue] === val[this.itemValue]), 1);
522
+ this.form.get('selectionValue').setValue(this.value.map(m => m.value));
523
+ this.valueChange.emit(this.value);
524
+ this.propagateChange(this.value);
525
+ this.changeDetectorRef.markForCheck();
526
+ }
527
+ setSelectionContainerSize() {
528
+ timer(0).subscribe(() => {
529
+ if (this.selectionContainer) {
530
+ this.listContainerSize.height = this.selectionContainer.nativeElement.offsetHeight > 260 ? '260px' : 'auto';
531
+ this.listContainerSize.minHeight = this.selectionContainer.nativeElement.offsetHeight <= 260 ?
532
+ this.selectionContainer.nativeElement.offsetHeight + 'px' : '260px';
533
+ this.listContainerSize.width = this.jvxMultiselect.nativeElement.offsetWidth + 'px';
534
+ }
535
+ this.changeDetectorRef.detectChanges();
536
+ });
537
+ }
538
+ clickOnMenuTrigger(e) {
539
+ if (!this.disabled) {
540
+ this.showList = false;
541
+ this.shouldLoadMore = true;
542
+ timer(0).subscribe(() => {
543
+ this.showList = true;
544
+ if (this.url.length > 0) {
545
+ e.preventDefault();
546
+ this.selectableOptions.length = 0;
547
+ this.updateOrderedOptions(this.selectableOptions);
548
+ this.getList().subscribe(noop);
549
+ this.setSelectionContainerSize();
550
+ }
551
+ else {
552
+ this.trigger.openMenu();
553
+ this.setSelectionContainerSize();
554
+ }
555
+ });
556
+ }
557
+ }
558
+ getList() {
559
+ this.isLoading = true;
560
+ return this.service.getList({
561
+ url: this.url,
562
+ requestType: this.requestType,
563
+ data: {},
564
+ currentPage: ++this.currentPage,
565
+ ignorePagination: this.ignorePagination,
566
+ requestHeaders: this.requestHeaders,
567
+ search: this.searchValue,
568
+ searchProp: this.searchProp,
569
+ pageSize: this.pageSize
570
+ }).pipe(switchMap((val) => {
571
+ let result = [];
572
+ if (this.listProp.length > 0) {
573
+ result = [...val[this.listProp]];
574
+ }
575
+ else {
576
+ result = [...val];
577
+ }
578
+ if (result.length === 0) {
579
+ this.shouldLoadMore = false;
580
+ this.isLoading = false;
581
+ return forkJoin([]);
582
+ }
583
+ else {
584
+ const newOptions = [];
585
+ for (const opt of result) {
586
+ const newOption = this.mapper.mapOption(opt);
587
+ newOptions.push(newOption);
588
+ }
589
+ return forkJoin(newOptions);
590
+ }
591
+ }), switchMap((finVal) => {
592
+ this.selectableOptions.push(...finVal);
593
+ return this.updateOrderedOptions(this.selectableOptions);
594
+ }), map((val) => {
595
+ this.isLoading = false;
596
+ this.trigger.openMenu();
597
+ this.setSelectionContainerSize();
598
+ this.changeDetectorRef.markForCheck();
599
+ return val;
600
+ }));
601
+ }
602
+ onScrolled(e) {
603
+ if (e.target.scrollTop + 220 + ((this.searchInput ? 0 : 1) * 40) === this.selectionContainer.nativeElement.offsetHeight
604
+ && !this.isLoading) {
605
+ this.scrollEnd.emit();
606
+ if (this.url && this.url.length > 0 && !this.ignorePagination && this.shouldLoadMore) {
607
+ this.getList().subscribe(noop);
608
+ }
609
+ }
610
+ }
611
+ onMenuOpened() {
612
+ this.jvxMultiselectOpened.emit();
613
+ }
614
+ onMenuClosed() {
615
+ if ((!this.url || this.url.length === 0) && this.searchMode === 'client') {
616
+ this.searchValueSubject.next('');
617
+ }
618
+ else {
619
+ this.searchValue = '';
620
+ this.currentPage = 0;
621
+ }
622
+ this.jvxMultiselectClosed.emit();
623
+ this.changeDetectorRef.markForCheck();
624
+ }
625
+ onSearchInputClick(e) {
626
+ e.stopPropagation();
627
+ }
628
+ onSearchValueChange(e) {
629
+ this.searchValueSubject.next(e.target.value);
630
+ }
631
+ clear(e) {
632
+ e.stopPropagation();
633
+ e.preventDefault();
634
+ this.value = [];
635
+ this.form.get('selectionValue').setValue(this.value.map(v => v[this.itemValue]));
636
+ this.propagateChange(this.value);
637
+ this.valueChange.emit(this.value);
638
+ this.changeDetectorRef.markForCheck();
639
+ }
640
+ setDescribedByIds(ids) {
641
+ const controlElement = this.elementRef.nativeElement
642
+ .querySelector('.ng-jvx-multiselect');
643
+ controlElement.setAttribute('aria-describedby', ids.join(' '));
644
+ }
645
+ onContainerClick(event) {
646
+ // if ((event.target as Element).tagName.toLowerCase() !== 'input') {
647
+ // this.elementRef.nativeElement.querySelector('input').focus();
648
+ // }
649
+ }
650
+ get stateChange$() {
651
+ return this.stateChanges.asObservable();
652
+ }
653
+ updateOrderedOptions(options) {
654
+ let obs = of(options);
655
+ if (this.groupBy) {
656
+ this.orderedOptions.length = 0;
657
+ const obsArr = [];
658
+ for (const option of options) {
659
+ if (typeof this.groupBy !== 'string') {
660
+ obsArr.push(this.groupBy.mapGroup(option));
661
+ }
662
+ else {
663
+ obsArr.push(of({ group: option[this.groupBy], option }));
664
+ }
665
+ }
666
+ obs = forkJoin(obsArr).pipe(map((res) => {
667
+ const groups = [...new Set(res.map(item => item.group))];
668
+ for (const group of groups) {
669
+ this.orderedOptions.push({
670
+ group,
671
+ options: res.filter(r => r.group === group).map(o => o.option)
672
+ });
673
+ }
674
+ return this.orderedOptions;
675
+ }));
676
+ }
677
+ return obs;
678
+ }
679
+ closeMenu() {
680
+ this.trigger.closeMenu();
681
+ }
682
+ }
683
+ NgJvxMultiselectComponent.nextId = 0;
684
+ NgJvxMultiselectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxMultiselectComponent, deps: [{ token: i1$2.FormBuilder }, { token: NgJvxMultiselectService }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1$2.NgControl, optional: true, self: true }, { token: i1$2.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
685
+ NgJvxMultiselectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.2", type: NgJvxMultiselectComponent, selector: "ng-jvx-multiselect", inputs: { options: "options", multi: "multi", url: "url", requestType: "requestType", itemValue: "itemValue", itemText: "itemText", ignorePagination: "ignorePagination", clearable: "clearable", closeOnClick: "closeOnClick", hasErrors: "hasErrors", searchMode: "searchMode", searchInput: "searchInput", searchLabel: "searchLabel", listProp: "listProp", totalRowsProp: "totalRowsProp", panelClass: "panelClass", searchProp: "searchProp", mapper: "mapper", searchMapper: "searchMapper", groupBy: "groupBy", value: "value", requestHeaders: "requestHeaders", required: "required", disabled: "disabled" }, outputs: { valueChange: "valueChange", jvxMultiselectOpen: "jvxMultiselectOpen", jvxMultiselectOpened: "jvxMultiselectOpened", jvxMultiselectClose: "jvxMultiselectClose", jvxMultiselectClosed: "jvxMultiselectClosed", scrollEnd: "scrollEnd" }, host: { properties: { "id": "this.id", "class.floating": "this.shouldLabelFloat" } }, providers: [
686
+ {
687
+ provide: MatFormFieldControl,
688
+ useExisting: forwardRef(() => NgJvxMultiselectComponent),
689
+ multi: true,
690
+ }
691
+ ], queries: [{ propertyName: "optionsTemplate", first: true, predicate: NgJvxOptionsTemplateDirective, descendants: true }, { propertyName: "selectionTemplate", first: true, predicate: NgJvxSelectionTemplateDirective, descendants: true }, { propertyName: "groupHeaderTemplate", first: true, predicate: NgJvxGroupHeaderDirective, descendants: true }], viewQueries: [{ propertyName: "jvxMultiselect", first: true, predicate: ["jvxMultiselect"], descendants: true, static: true }, { propertyName: "selectionContainer", first: true, predicate: ["selectionContainer"], descendants: true }, { propertyName: "selection", first: true, predicate: ["selection"], descendants: true, static: true }, { propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, static: true }, { propertyName: "scrollbar", first: true, predicate: ["scrollbar"], descendants: true }, { propertyName: "multiContainer", first: true, predicate: ["multiContainer"], descendants: true }, { propertyName: "optionComp", predicate: NgJvxOptionComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"ng-jvx-multiselect\" [ngClass]=\"{'disabled': disabled, 'has-errors': hasErrors}\" #jvxMultiselect>\r\n <!-- START MENU -->\r\n <div [matMenuTriggerFor]=\"menuRef\" (onMenuOpen)=\"onMenuOpen()\" (menuOpened)=\"onMenuOpened()\"\r\n (onMenuClose)=\"onMenuClose()\" (menuClosed)=\"onMenuClosed()\"\r\n #trigger=\"matMenuTrigger\">\r\n <mat-menu #menuRef=\"matMenu\" [class]=\"['jvx-multiselect-panel', panelClass].join(' ')\" [formGroup]=\"form\"\r\n\r\n [yPosition]=\"yPosition\">\r\n <div class=\"menu-list-container\"\r\n #menuLIstContainer\r\n [ngStyle]=\"{'overflow-y': 'hidden', 'width': listContainerSize.width, 'max-height': '260px', 'height': listContainerSize.height, 'min-height': listContainerSize.minHeight}\">\r\n <div class=\"search-input-container\" *ngIf=\"!!searchInput\" (click)=\"onSearchInputClick($event)\">\r\n <input type=\"text\" [placeholder]=\"searchLabel\" [ngModel]=\"searchValue\" [ngModelOptions]=\"{standalone: true}\"\r\n [ngJvxFocus]=\"isOpen\"\r\n (input)=\"onSearchValueChange($event)\"/>\r\n </div>\r\n <div [ngStyle]=\"{height: searchInput && selectionContainer.clientHeight > 220 || selectionContainer.clientHeight > 260? 260 - (searchInput? 40 : 0) + 'px': 'auto'}\">\r\n <ng-scrollbar style=\"width: 100%\"\r\n smoothScroll\r\n [visibility]=\"'hover'\"\r\n [appearance]=\"'compact'\"\r\n [sensorDisabled]=\"isLoading\"\r\n [autoHeightDisabled]=\"false\" #scrollbar>\r\n <div #selectionContainer (click)=\"onCLickOnMenu($event)\">\r\n <mat-selection-list #selection [multiple]=\"multi\"\r\n *ngIf=\"showList\"\r\n [ngStyle]=\"{'padding': 0, 'width': listContainerSize.width, 'min-width.px': 112}\"\r\n (selectionChange)=\"onChange($event)\"\r\n formControlName=\"selectionValue\">\r\n <ng-content></ng-content>\r\n <ng-container *ngIf=\"!!groupBy\">\r\n <ng-container *ngFor=\"let opt of orderedOptions\">\r\n <ng-container [ngTemplateOutlet]=\"groupHeaderTemplate? groupHeaderTemplate.template: defaultGroupHeaderTemplate\" [ngTemplateOutletContext]=\"{$implicit: opt}\"></ng-container>\r\n\r\n <ng-jvx-option *ngFor=\"let option of opt.options\" [value]=\"option[itemValue]\">\r\n <!-- <ng-container [ngTemplateOutlet]=\"optionsTemplate\" [ngTemplateOutletContext]=\"{$implicit: option}\"></ng-container>-->\r\n <span style=\"padding-inline: 10px\">\r\n <ng-container [ngTemplateOutlet]=\"optionsTemplate? optionsTemplate.template : defaultTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: option}\"></ng-container>\r\n </span>\r\n </ng-jvx-option>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!groupBy || groupBy.length === 0\">\r\n <ng-jvx-option *ngFor=\"let option of selectableOptions\" [value]=\"option[itemValue]\">\r\n <!-- <ng-container [ngTemplateOutlet]=\"optionsTemplate\" [ngTemplateOutletContext]=\"{$implicit: option}\"></ng-container>-->\r\n <ng-container [ngTemplateOutlet]=\"optionsTemplate? optionsTemplate.template : defaultTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: option}\"></ng-container>\r\n </ng-jvx-option>\r\n </ng-container>\r\n </mat-selection-list>\r\n </div>\r\n </ng-scrollbar>\r\n </div>\r\n\r\n </div>\r\n <div class=\"menu-footer\">\r\n <ng-content select=\"[ng-jvx-footer]\"></ng-content>\r\n </div>\r\n\r\n </mat-menu>\r\n </div>\r\n <!-- END MENU -->\r\n <!-- START INPUT -->\r\n <div [ngClass]=\"{'ng-jvx-multiselect-value-container': true, 'is-open': isOpen}\"\r\n (click)=\"clickOnMenuTrigger($event)\"\r\n #valueContainer>\r\n\r\n <div class=\"ng-jvx-multiselect__placeholder\" *ngIf=\"value.length === 0\">\r\n <ng-content select=\"[placeholder]\"></ng-content>\r\n </div>\r\n\r\n <div class=\"ng-jvx-multiselect-value multi-value-container\" *ngIf=\"multi\" #multiContainer>\r\n\r\n <ng-container [ngTemplateOutlet]=\"selectionTemplate? selectionTemplate.template : defaultMultiSelectionTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: value}\"></ng-container>\r\n\r\n\r\n </div>\r\n\r\n <div class=\"ng-jvx-multiselect-value single-value-container\" *ngIf=\"!multi\">\r\n <div *ngFor=\"let val of value\" style=\"width: 100%;\">\r\n <ng-container [ngTemplateOutlet]=\"selectionTemplate? selectionTemplate.template : defaultSelectionTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: val}\"></ng-container></div>\r\n </div>\r\n <div class=\"ng-jvx-multiselect__remove-button\" *ngIf=\"clearable && value.length > 0\" (click)=\"clear($event)\">\r\n <mat-icon style=\"font-size: 18px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\">clear\r\n </mat-icon>\r\n </div>\r\n <div class=\"ng-jvx-multiselect-arrow\">\r\n <mat-icon *ngIf=\"!isLoading\">expand_more</mat-icon>\r\n <div *ngIf=\"isLoading\" class=\"lds-ring\">\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- END INPUT -->\r\n</div>\r\n<ng-template #defaultTemplate let-option>\r\n <div style=\"max-width: 100%;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\">{{option[itemText]}}\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultSelectionTemplate let-value>\r\n {{value[itemText]}}\r\n</ng-template>\r\n\r\n<ng-template #defaultMultiSelectionTemplate let-value>\r\n <mat-chip-list #chipList [disabled]=\"this.disabled\">\r\n <mat-chip [color]=\"'primary'\" selected *ngFor=\"let val of value\" [selectable]=\"false\"\r\n class=\"ng-jvx-multiselect-chip\"\r\n [removable]=\"true\" (removed)=\"deselect(val)\">\r\n <span class=\"chip-content\"\r\n [ngStyle]=\"{'max-width': multiContainerWidth - 50 +'px'}\">{{val[itemText]}}</span>\r\n\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n </mat-chip-list>\r\n</ng-template>\r\n<ng-template #defaultGroupHeaderTemplate let-opt>\r\n <div style=\"padding-inline: 15px\"><strong>{{opt.group}}</strong></div>\r\n</ng-template>\r\n", styles: [""], components: [{ type: i3.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i4.NgScrollbar, selector: "ng-scrollbar", inputs: ["disabled", "sensorDisabled", "pointerEventsDisabled", "viewportPropagateMouseMove", "autoHeightDisabled", "autoWidthDisabled", "viewClass", "trackClass", "thumbClass", "minThumbSize", "trackClickScrollDuration", "pointerEventsMethod", "track", "visibility", "appearance", "position", "sensorDebounce", "scrollAuditTime"], outputs: ["updated"], exportAs: ["ngScrollbar"] }, { type: i1.MatSelectionList, selector: "mat-selection-list", inputs: ["disableRipple", "tabIndex", "color", "compareWith", "disabled", "multiple"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { type: NgJvxOptionComponent, selector: "ng-jvx-option", inputs: ["value"] }, { type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i8.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }], directives: [{ type: i9.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i9.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: NgJvxFocusDirective, selector: "[ngJvxFocus]", inputs: ["ngJvxFocus"] }, { type: i11.SmoothScroll, selector: "[smoothScroll], [smooth-scroll]", exportAs: ["smoothScroll"] }, { type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i8.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i8.MatChipRemove, selector: "[matChipRemove]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
692
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxMultiselectComponent, decorators: [{
693
+ type: Component,
694
+ args: [{ selector: 'ng-jvx-multiselect', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
695
+ {
696
+ provide: MatFormFieldControl,
697
+ useExisting: forwardRef(() => NgJvxMultiselectComponent),
698
+ multi: true,
699
+ }
700
+ ], template: "<div class=\"ng-jvx-multiselect\" [ngClass]=\"{'disabled': disabled, 'has-errors': hasErrors}\" #jvxMultiselect>\r\n <!-- START MENU -->\r\n <div [matMenuTriggerFor]=\"menuRef\" (onMenuOpen)=\"onMenuOpen()\" (menuOpened)=\"onMenuOpened()\"\r\n (onMenuClose)=\"onMenuClose()\" (menuClosed)=\"onMenuClosed()\"\r\n #trigger=\"matMenuTrigger\">\r\n <mat-menu #menuRef=\"matMenu\" [class]=\"['jvx-multiselect-panel', panelClass].join(' ')\" [formGroup]=\"form\"\r\n\r\n [yPosition]=\"yPosition\">\r\n <div class=\"menu-list-container\"\r\n #menuLIstContainer\r\n [ngStyle]=\"{'overflow-y': 'hidden', 'width': listContainerSize.width, 'max-height': '260px', 'height': listContainerSize.height, 'min-height': listContainerSize.minHeight}\">\r\n <div class=\"search-input-container\" *ngIf=\"!!searchInput\" (click)=\"onSearchInputClick($event)\">\r\n <input type=\"text\" [placeholder]=\"searchLabel\" [ngModel]=\"searchValue\" [ngModelOptions]=\"{standalone: true}\"\r\n [ngJvxFocus]=\"isOpen\"\r\n (input)=\"onSearchValueChange($event)\"/>\r\n </div>\r\n <div [ngStyle]=\"{height: searchInput && selectionContainer.clientHeight > 220 || selectionContainer.clientHeight > 260? 260 - (searchInput? 40 : 0) + 'px': 'auto'}\">\r\n <ng-scrollbar style=\"width: 100%\"\r\n smoothScroll\r\n [visibility]=\"'hover'\"\r\n [appearance]=\"'compact'\"\r\n [sensorDisabled]=\"isLoading\"\r\n [autoHeightDisabled]=\"false\" #scrollbar>\r\n <div #selectionContainer (click)=\"onCLickOnMenu($event)\">\r\n <mat-selection-list #selection [multiple]=\"multi\"\r\n *ngIf=\"showList\"\r\n [ngStyle]=\"{'padding': 0, 'width': listContainerSize.width, 'min-width.px': 112}\"\r\n (selectionChange)=\"onChange($event)\"\r\n formControlName=\"selectionValue\">\r\n <ng-content></ng-content>\r\n <ng-container *ngIf=\"!!groupBy\">\r\n <ng-container *ngFor=\"let opt of orderedOptions\">\r\n <ng-container [ngTemplateOutlet]=\"groupHeaderTemplate? groupHeaderTemplate.template: defaultGroupHeaderTemplate\" [ngTemplateOutletContext]=\"{$implicit: opt}\"></ng-container>\r\n\r\n <ng-jvx-option *ngFor=\"let option of opt.options\" [value]=\"option[itemValue]\">\r\n <!-- <ng-container [ngTemplateOutlet]=\"optionsTemplate\" [ngTemplateOutletContext]=\"{$implicit: option}\"></ng-container>-->\r\n <span style=\"padding-inline: 10px\">\r\n <ng-container [ngTemplateOutlet]=\"optionsTemplate? optionsTemplate.template : defaultTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: option}\"></ng-container>\r\n </span>\r\n </ng-jvx-option>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!groupBy || groupBy.length === 0\">\r\n <ng-jvx-option *ngFor=\"let option of selectableOptions\" [value]=\"option[itemValue]\">\r\n <!-- <ng-container [ngTemplateOutlet]=\"optionsTemplate\" [ngTemplateOutletContext]=\"{$implicit: option}\"></ng-container>-->\r\n <ng-container [ngTemplateOutlet]=\"optionsTemplate? optionsTemplate.template : defaultTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: option}\"></ng-container>\r\n </ng-jvx-option>\r\n </ng-container>\r\n </mat-selection-list>\r\n </div>\r\n </ng-scrollbar>\r\n </div>\r\n\r\n </div>\r\n <div class=\"menu-footer\">\r\n <ng-content select=\"[ng-jvx-footer]\"></ng-content>\r\n </div>\r\n\r\n </mat-menu>\r\n </div>\r\n <!-- END MENU -->\r\n <!-- START INPUT -->\r\n <div [ngClass]=\"{'ng-jvx-multiselect-value-container': true, 'is-open': isOpen}\"\r\n (click)=\"clickOnMenuTrigger($event)\"\r\n #valueContainer>\r\n\r\n <div class=\"ng-jvx-multiselect__placeholder\" *ngIf=\"value.length === 0\">\r\n <ng-content select=\"[placeholder]\"></ng-content>\r\n </div>\r\n\r\n <div class=\"ng-jvx-multiselect-value multi-value-container\" *ngIf=\"multi\" #multiContainer>\r\n\r\n <ng-container [ngTemplateOutlet]=\"selectionTemplate? selectionTemplate.template : defaultMultiSelectionTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: value}\"></ng-container>\r\n\r\n\r\n </div>\r\n\r\n <div class=\"ng-jvx-multiselect-value single-value-container\" *ngIf=\"!multi\">\r\n <div *ngFor=\"let val of value\" style=\"width: 100%;\">\r\n <ng-container [ngTemplateOutlet]=\"selectionTemplate? selectionTemplate.template : defaultSelectionTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: val}\"></ng-container></div>\r\n </div>\r\n <div class=\"ng-jvx-multiselect__remove-button\" *ngIf=\"clearable && value.length > 0\" (click)=\"clear($event)\">\r\n <mat-icon style=\"font-size: 18px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\">clear\r\n </mat-icon>\r\n </div>\r\n <div class=\"ng-jvx-multiselect-arrow\">\r\n <mat-icon *ngIf=\"!isLoading\">expand_more</mat-icon>\r\n <div *ngIf=\"isLoading\" class=\"lds-ring\">\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- END INPUT -->\r\n</div>\r\n<ng-template #defaultTemplate let-option>\r\n <div style=\"max-width: 100%;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\">{{option[itemText]}}\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultSelectionTemplate let-value>\r\n {{value[itemText]}}\r\n</ng-template>\r\n\r\n<ng-template #defaultMultiSelectionTemplate let-value>\r\n <mat-chip-list #chipList [disabled]=\"this.disabled\">\r\n <mat-chip [color]=\"'primary'\" selected *ngFor=\"let val of value\" [selectable]=\"false\"\r\n class=\"ng-jvx-multiselect-chip\"\r\n [removable]=\"true\" (removed)=\"deselect(val)\">\r\n <span class=\"chip-content\"\r\n [ngStyle]=\"{'max-width': multiContainerWidth - 50 +'px'}\">{{val[itemText]}}</span>\r\n\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n </mat-chip-list>\r\n</ng-template>\r\n<ng-template #defaultGroupHeaderTemplate let-opt>\r\n <div style=\"padding-inline: 15px\"><strong>{{opt.group}}</strong></div>\r\n</ng-template>\r\n", styles: [""] }]
701
+ }], ctorParameters: function () { return [{ type: i1$2.FormBuilder }, { type: NgJvxMultiselectService }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1$2.NgControl, decorators: [{
702
+ type: Optional
703
+ }, {
704
+ type: Self
705
+ }] }, { type: i1$2.FormBuilder }]; }, propDecorators: { id: [{
706
+ type: HostBinding
707
+ }], shouldLabelFloat: [{
708
+ type: HostBinding,
709
+ args: ['class.floating']
710
+ }], jvxMultiselect: [{
711
+ type: ViewChild,
712
+ args: ['jvxMultiselect', { static: true }]
713
+ }], selectionContainer: [{
714
+ type: ViewChild,
715
+ args: ['selectionContainer', { static: false }]
716
+ }], selection: [{
717
+ type: ViewChild,
718
+ args: ['selection', { static: true }]
719
+ }], trigger: [{
720
+ type: ViewChild,
721
+ args: ['trigger', { static: true }]
722
+ }], scrollbar: [{
723
+ type: ViewChild,
724
+ args: ['scrollbar', { static: false }]
725
+ }], multiContainer: [{
726
+ type: ViewChild,
727
+ args: ['multiContainer', { static: false }]
728
+ }], optionComp: [{
729
+ type: ViewChildren,
730
+ args: [NgJvxOptionComponent]
731
+ }], optionsTemplate: [{
732
+ type: ContentChild,
733
+ args: [NgJvxOptionsTemplateDirective]
734
+ }], selectionTemplate: [{
735
+ type: ContentChild,
736
+ args: [NgJvxSelectionTemplateDirective]
737
+ }], groupHeaderTemplate: [{
738
+ type: ContentChild,
739
+ args: [NgJvxGroupHeaderDirective]
740
+ }], options: [{
741
+ type: Input
742
+ }], multi: [{
743
+ type: Input
744
+ }], url: [{
745
+ type: Input
746
+ }], requestType: [{
747
+ type: Input
748
+ }], itemValue: [{
749
+ type: Input
750
+ }], itemText: [{
751
+ type: Input
752
+ }], ignorePagination: [{
753
+ type: Input
754
+ }], clearable: [{
755
+ type: Input
756
+ }], closeOnClick: [{
757
+ type: Input
758
+ }], hasErrors: [{
759
+ type: Input
760
+ }], searchMode: [{
761
+ type: Input
762
+ }], searchInput: [{
763
+ type: Input
764
+ }], searchLabel: [{
765
+ type: Input
766
+ }], listProp: [{
767
+ type: Input
768
+ }], totalRowsProp: [{
769
+ type: Input
770
+ }], panelClass: [{
771
+ type: Input
772
+ }], searchProp: [{
773
+ type: Input
774
+ }], mapper: [{
775
+ type: Input
776
+ }], searchMapper: [{
777
+ type: Input
778
+ }], groupBy: [{
779
+ type: Input
780
+ }], value: [{
781
+ type: Input
782
+ }], requestHeaders: [{
783
+ type: Input
784
+ }], required: [{
785
+ type: Input
786
+ }], disabled: [{
787
+ type: Input
788
+ }], valueChange: [{
789
+ type: Output
790
+ }], jvxMultiselectOpen: [{
791
+ type: Output
792
+ }], jvxMultiselectOpened: [{
793
+ type: Output
794
+ }], jvxMultiselectClose: [{
795
+ type: Output
796
+ }], jvxMultiselectClosed: [{
797
+ type: Output
798
+ }], scrollEnd: [{
799
+ type: Output
800
+ }] } });
801
+
802
+ /**
803
+ * @license
804
+ * Copyright Google LLC All Rights Reserved.
805
+ *
806
+ * Use of this source code is governed by an MIT-style license that can be
807
+ * found in the LICENSE file at https://angular.io/license
808
+ */
809
+ /** @docs-public MatMenu */
810
+ class NgJvxPanelComponent extends _MatMenuBase {
811
+ constructor(elementRef, ngZone, defaultOptions) {
812
+ super(elementRef, ngZone, defaultOptions);
813
+ }
814
+ }
815
+ NgJvxPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxPanelComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: MAT_MENU_DEFAULT_OPTIONS }], target: i0.ɵɵFactoryTarget.Component });
816
+ NgJvxPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.2", type: NgJvxPanelComponent, selector: "ngJvxPanel", host: { properties: { "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null" } }, providers: [
817
+ { provide: MAT_MENU_PANEL, useExisting: MatMenu },
818
+ ], exportAs: ["ngJvxPanel"], usesInheritance: true, ngImport: i0, template: "<ng-template>\r\n <div\r\n class=\"mat-menu-panel\"\r\n [id]=\"panelId\"\r\n [ngClass]=\"_classList\"\r\n (keydown)=\"_handleKeydown($event)\"\r\n (click)=\"closed.emit('click')\"\r\n [@transformMenu]=\"_panelAnimationState\"\r\n (@transformMenu.start)=\"_onAnimationStart($event)\"\r\n (@transformMenu.done)=\"_onAnimationDone($event)\"\r\n tabindex=\"-1\"\r\n role=\"menu\"\r\n [attr.aria-label]=\"ariaLabel || null\"\r\n [attr.aria-labelledby]=\"ariaLabelledby || null\"\r\n [attr.aria-describedby]=\"ariaDescribedby || null\">\r\n <div class=\"mat-menu-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: [""], directives: [{ type: i9.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], animations: [
819
+ matMenuAnimations.transformMenu,
820
+ matMenuAnimations.fadeInItems
821
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
822
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxPanelComponent, decorators: [{
823
+ type: Component,
824
+ args: [{ selector: 'ngJvxPanel', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, exportAs: 'ngJvxPanel', host: {
825
+ '[attr.aria-label]': 'null',
826
+ '[attr.aria-labelledby]': 'null',
827
+ '[attr.aria-describedby]': 'null',
828
+ }, animations: [
829
+ matMenuAnimations.transformMenu,
830
+ matMenuAnimations.fadeInItems
831
+ ], providers: [
832
+ { provide: MAT_MENU_PANEL, useExisting: MatMenu },
833
+ ], template: "<ng-template>\r\n <div\r\n class=\"mat-menu-panel\"\r\n [id]=\"panelId\"\r\n [ngClass]=\"_classList\"\r\n (keydown)=\"_handleKeydown($event)\"\r\n (click)=\"closed.emit('click')\"\r\n [@transformMenu]=\"_panelAnimationState\"\r\n (@transformMenu.start)=\"_onAnimationStart($event)\"\r\n (@transformMenu.done)=\"_onAnimationDone($event)\"\r\n tabindex=\"-1\"\r\n role=\"menu\"\r\n [attr.aria-label]=\"ariaLabel || null\"\r\n [attr.aria-labelledby]=\"ariaLabelledby || null\"\r\n [attr.aria-describedby]=\"ariaDescribedby || null\">\r\n <div class=\"mat-menu-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: [""] }]
834
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
835
+ type: Inject,
836
+ args: [MAT_MENU_DEFAULT_OPTIONS]
837
+ }] }]; } });
838
+
839
+ class NgJvxMultiselectModule {
840
+ }
841
+ NgJvxMultiselectModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxMultiselectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
842
+ NgJvxMultiselectModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxMultiselectModule, declarations: [NgJvxMultiselectComponent,
843
+ NgJvxOptionComponent,
844
+ NgJvxOptionsTemplateDirective,
845
+ NgJvxPanelComponent,
846
+ NgJvxSelectionTemplateDirective,
847
+ NgJvxDisabledOptionDirective,
848
+ NgJvxGroupHeaderDirective,
849
+ NgJvxFocusDirective], imports: [MatButtonModule,
850
+ MatOptionModule,
851
+ MatSelectModule,
852
+ MatMenuModule,
853
+ CommonModule,
854
+ MatIconModule,
855
+ MatListModule,
856
+ MatChipsModule,
857
+ ReactiveFormsModule,
858
+ HttpClientModule,
859
+ NgScrollbarModule,
860
+ SmoothScrollModule,
861
+ FormsModule], exports: [NgJvxMultiselectComponent, NgJvxOptionComponent, NgJvxOptionsTemplateDirective, NgJvxSelectionTemplateDirective, NgJvxDisabledOptionDirective, NgJvxGroupHeaderDirective] });
862
+ NgJvxMultiselectModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxMultiselectModule, imports: [[
863
+ MatButtonModule,
864
+ MatOptionModule,
865
+ MatSelectModule,
866
+ MatMenuModule,
867
+ CommonModule,
868
+ MatIconModule,
869
+ MatListModule,
870
+ MatChipsModule,
871
+ ReactiveFormsModule,
872
+ HttpClientModule,
873
+ NgScrollbarModule,
874
+ SmoothScrollModule,
875
+ FormsModule
876
+ ]] });
877
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: NgJvxMultiselectModule, decorators: [{
878
+ type: NgModule,
879
+ args: [{
880
+ declarations: [
881
+ NgJvxMultiselectComponent,
882
+ NgJvxOptionComponent,
883
+ NgJvxOptionsTemplateDirective,
884
+ NgJvxPanelComponent,
885
+ NgJvxSelectionTemplateDirective,
886
+ NgJvxDisabledOptionDirective,
887
+ NgJvxGroupHeaderDirective,
888
+ NgJvxFocusDirective
889
+ ],
890
+ imports: [
891
+ MatButtonModule,
892
+ MatOptionModule,
893
+ MatSelectModule,
894
+ MatMenuModule,
895
+ CommonModule,
896
+ MatIconModule,
897
+ MatListModule,
898
+ MatChipsModule,
899
+ ReactiveFormsModule,
900
+ HttpClientModule,
901
+ NgScrollbarModule,
902
+ SmoothScrollModule,
903
+ FormsModule
904
+ ],
905
+ exports: [NgJvxMultiselectComponent, NgJvxOptionComponent, NgJvxOptionsTemplateDirective, NgJvxSelectionTemplateDirective, NgJvxDisabledOptionDirective, NgJvxGroupHeaderDirective]
906
+ }]
907
+ }] });
908
+
909
+ /*
910
+ * Public API Surface of ng-jvx-multiselect
911
+ */
912
+
913
+ /**
914
+ * Generated bundle index. Do not edit.
915
+ */
916
+
917
+ export { NgJvxDisabledOptionDirective, NgJvxGroupHeaderDirective, NgJvxMultiselectComponent, NgJvxMultiselectModule, NgJvxMultiselectService, NgJvxOptionComponent, NgJvxOptionsTemplateDirective, NgJvxSelectionTemplateDirective };
918
+ //# sourceMappingURL=ng-jvx-multiselect.mjs.map