@sumaris-net/ngx-components 1.6.3 → 1.6.7

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 (24) hide show
  1. package/bundles/sumaris-net.ngx-components.umd.js +241 -146
  2. package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
  3. package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
  4. package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
  5. package/doc/changelog.md +10 -1
  6. package/esm2015/src/app/shared/form/field.component.js +2 -2
  7. package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +72 -44
  8. package/esm2015/src/app/shared/material/autocomplete/testing/autocomplete.test.js +6 -6
  9. package/esm2015/src/app/shared/material/chips/material.chips.js +72 -51
  10. package/esm2015/src/app/shared/material/chips/testing/chips.test.js +49 -16
  11. package/esm2015/src/app/shared/material/datetime/material.date.js +2 -2
  12. package/esm2015/src/app/shared/material/datetime/material.dateshort.js +2 -2
  13. package/esm2015/src/app/shared/material/datetime/material.datetime.js +4 -4
  14. package/esm2015/src/app/shared/material/duration/material.duration.js +2 -2
  15. package/fesm2015/sumaris-net.ngx-components.js +229 -148
  16. package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
  17. package/package.json +1 -1
  18. package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +4 -3
  19. package/src/app/shared/material/autocomplete/testing/autocomplete.test.d.ts +4 -5
  20. package/src/app/shared/material/chips/material.chips.d.ts +9 -5
  21. package/src/app/shared/material/chips/testing/chips.test.d.ts +1 -1
  22. package/src/app/shared/material/datetime/material.datetime.d.ts +2 -2
  23. package/src/theme/_ngx-components.scss +3 -1
  24. package/sumaris-net.ngx-components.metadata.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, EventEmitter, Component, forwardRef, ChangeDetectionStrategy, ChangeDetectorRef, Optional, Input, Output, ViewChild, HostBinding, Pipe, Injectable, Directive, Inject, NgModule, ElementRef, ViewChildren, HostListener, ComponentFactoryResolver, ApplicationRef, Injector, Renderer2 } from '@angular/core';
2
+ import { InjectionToken, EventEmitter, Component, forwardRef, ChangeDetectionStrategy, ChangeDetectorRef, Optional, Input, Output, ViewChild, Pipe, Injectable, Directive, Inject, NgModule, ElementRef, ViewChildren, HostListener, ComponentFactoryResolver, ApplicationRef, Injector, Renderer2, ViewEncapsulation } from '@angular/core';
3
3
  import * as i1$3 from '@angular/common';
4
4
  import { CommonModule, DOCUMENT, Location } from '@angular/common';
5
5
  import { CdkTableModule } from '@angular/cdk/table';
@@ -36,7 +36,7 @@ import { MatAutocomplete, MatAutocompleteTrigger, MatAutocompleteModule, MAT_AUT
36
36
  import { __awaiter, __decorate } from 'tslib';
37
37
  import * as i1$6 from '@angular/forms';
38
38
  import { NG_VALUE_ACCESSOR, FormGroupDirective, AbstractControl, FormGroup, FormArray, FormControl, ReactiveFormsModule, Validators, FormBuilder } from '@angular/forms';
39
- import { timer, merge, fromEvent, BehaviorSubject, Subscription, Subject, isObservable, noop as noop$8, Observable, defer, of, from, combineLatest, EMPTY } from 'rxjs';
39
+ import { timer, merge, fromEvent, BehaviorSubject, Subscription, Subject, isObservable, noop as noop$9, Observable, defer, of, from, combineLatest, EMPTY } from 'rxjs';
40
40
  import { filter, first, map, takeUntil, switchMap, startWith, debounceTime, takeWhile, tap, distinctUntilChanged, mergeMap, catchError, throttleTime, skip } from 'rxjs/operators';
41
41
  import * as i1$1 from '@ngx-translate/core';
42
42
  import { TranslateService, TranslateModule } from '@ngx-translate/core';
@@ -976,10 +976,11 @@ class MatAutocompleteConfigHolder {
976
976
  const attributesOrFn = attributes.map((a, index) => typeof a === 'function' && options.attributes[index] || a);
977
977
  const filter = Object.assign({ searchAttribute: attributes.length === 1 ? attributes[0] : undefined, searchAttributes: attributes.length > 1 ? attributes : undefined }, options.filter);
978
978
  const displayWith = options.displayWith || ((obj) => obj && joinPropertiesPath(obj, attributes));
979
- const compareWith = options.equals || ((o1, o2) => o1 && o2 && o1.id === o2.id);
979
+ const equals = options.equals || ((o1, o2) => o1 && o2 && o1.id === o2.id);
980
980
  const config = Object.assign(Object.assign({}, options), { attributes: attributesOrFn, suggestFn,
981
981
  filter,
982
- displayWith, equals: compareWith });
982
+ displayWith,
983
+ equals });
983
984
  this.fields[fieldName] = config;
984
985
  return config;
985
986
  }
@@ -990,14 +991,14 @@ class MatAutocompleteConfigHolder {
990
991
  return this.fields[fieldName] || this.add(fieldName);
991
992
  }
992
993
  }
993
- const noop$7 = () => { };
994
- const ɵ0$a = noop$7;
994
+ const noop$8 = (_) => { };
995
+ const ɵ0$b = noop$8;
995
996
  class MatAutocompleteField {
996
997
  constructor(cd, formGroupDir) {
997
998
  this.cd = cd;
998
999
  this.formGroupDir = formGroupDir;
999
- this._onChangeCallback = noop$7;
1000
- this._onTouchedCallback = noop$7;
1000
+ this._onChangeCallback = noop$8;
1001
+ this._onTouchedCallback = noop$8;
1001
1002
  this.logPrefix = '[mat-autocomplete] ';
1002
1003
  this.formControlName = null;
1003
1004
  this.required = false;
@@ -1010,13 +1011,13 @@ class MatAutocompleteField {
1010
1011
  this.fetchMoreThreshold = '15%';
1011
1012
  this.suggestLengthThreshold = null;
1012
1013
  this.showLoadingSpinner = true;
1014
+ this.debug = false;
1013
1015
  this.clicked = new EventEmitter();
1014
1016
  this.blurred = new EventEmitter();
1015
1017
  this.focused = new EventEmitter();
1016
1018
  this.dropButtonClick = new EventEmitter(true);
1017
1019
  this.keydownEscape = new EventEmitter();
1018
1020
  this.keyupEnter = new EventEmitter();
1019
- this.animationsDisabled = true;
1020
1021
  this._readonly = false;
1021
1022
  this.$inputItems = new BehaviorSubject(undefined);
1022
1023
  this.$filteredItems = new BehaviorSubject(undefined);
@@ -1087,6 +1088,9 @@ class MatAutocompleteField {
1087
1088
  get enabled() {
1088
1089
  return !this._readonly && this.formControl.enabled;
1089
1090
  }
1091
+ get loading() {
1092
+ return isNil(this.$filteredItems.value);
1093
+ }
1090
1094
  ngOnInit() {
1091
1095
  var _a, _b;
1092
1096
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
@@ -1107,7 +1111,7 @@ class MatAutocompleteField {
1107
1111
  this.mobile = toBoolean(this.mobile, this.config.mobile);
1108
1112
  this.suggestLengthThreshold = toNumber(this.suggestLengthThreshold, this.config.suggestLengthThreshold || 0);
1109
1113
  this.showAllOnFocus = toBoolean(this.showAllOnFocus, toBoolean(this.config.showAllOnFocus, this.suggestLengthThreshold <= 0));
1110
- this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus));
1114
+ this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus, true));
1111
1115
  this.classList = this.classList || this.config.class;
1112
1116
  this.debounceTime = toNumber(this.debounceTime, this.config.debounceTime);
1113
1117
  this.highlightAccent = toBoolean(this.highlightAccent, toBoolean(this.config.highlightAccent));
@@ -1166,6 +1170,14 @@ class MatAutocompleteField {
1166
1170
  switchMap((filter) => this.suggest('*', filter)))
1167
1171
  .subscribe(items => this.$inputItems.next(items)));
1168
1172
  }
1173
+ // Send value to suggest when :
1174
+ // - is nil and '*', and no min length threshold
1175
+ // - is not nil and not a string type (e.g. object)
1176
+ // - is not nil and is a string, and has enough character
1177
+ const thresholdFilterFn = (value) => (isNilOrBlank(value) || (value === '*')
1178
+ ? (this.suggestLengthThreshold <= 0)
1179
+ : (!(typeof value === 'string')
1180
+ || value.length >= this.suggestLengthThreshold));
1169
1181
  const filteredItemsChanges = merge(
1170
1182
  // Reload event (no distinctUntilChanged() pipe, to force reload even if same value)
1171
1183
  this._reload$,
@@ -1177,15 +1189,15 @@ class MatAutocompleteField {
1177
1189
  // Filter if not enough character
1178
1190
  filter(value => value.length >= this.suggestLengthThreshold),
1179
1191
  // Wait a debounce time
1180
- debounceTime(this.debounceTime)
1192
+ debounceTime(this.debounceTime),
1181
1193
  // DEBUG
1182
- //tap((value) => console.debug(this.logPrefix + ' Search text changes:', value)),
1183
- ),
1194
+ tap((value) => console.debug(this.logPrefix + ' Search text changes:', value))),
1184
1195
  // Object set: use it (no distinctUntilChanged() pipe need)
1185
1196
  this.formControl.valueChanges
1186
1197
  .pipe(startWith(this.formControl.value), filter(value => (this.searchable && isNotNil(value) && typeof value === 'object')), tap(value => {
1187
1198
  // DEBUG
1188
- //console.debug(this.logPrefix + ' object changes:', value)
1199
+ if (this.debug)
1200
+ console.debug(this.logPrefix + ' object changes:', value);
1189
1201
  // Update the display value (if need)
1190
1202
  const displayValue = this.displayWith(value) || '';
1191
1203
  if (this.displayValue !== displayValue) {
@@ -1195,37 +1207,35 @@ class MatAutocompleteField {
1195
1207
  this.matInputText.nativeElement.value = this.displayValue;
1196
1208
  }
1197
1209
  }
1198
- })
1210
+ }),
1199
1211
  // DEBUG
1200
- //tap(value => console.debug(this.logPrefix + ' Received an object value: ', value))
1201
- ),
1212
+ tap(value => this.debug && console.debug(this.logPrefix + ' Received an object value: ', value))),
1213
+ // On dropdown button click (no distinctUntilChanged(), nor debounceTime)
1214
+ this.dropButtonClick
1215
+ .pipe(filter(event => this.searchable && this.enabled && (!event || !event.defaultPrevented)), map(_ => this.showAllOnFocus ? '*' : this.formControl.value),
1216
+ // Make enough characters
1217
+ filter(thresholdFilterFn)),
1202
1218
  // Merge some observables, with a common distinctUntilChanged() pipe, and NO debounceTime
1203
1219
  merge(
1204
1220
  // Focus or click => Load all
1205
1221
  merge(this.focused, this.clicked)
1206
- .pipe(filter(_ => this.enabled && this.searchable), map(_ => this.showAllOnFocus ? '*' : this.formControl.value)),
1207
- // On dropdown button click
1208
- this.dropButtonClick
1209
- .pipe(filter(event => this.searchable && this.enabled && (!event || !event.defaultPrevented)), map(_ => this.showAllOnFocus ? '*' : this.formControl.value)), merge(this.$inputItems, this._$filter)
1210
- .pipe(filter(_ => this.searchable && this.enabled), map(_ => this.formControl.value)))
1222
+ .pipe(filter(_ => this.enabled && this.searchable), map(_ => this.showAllOnFocus ? '*' : this.formControl.value),
1223
+ // DEBUG
1224
+ tap(value => this.debug && console.debug(this.logPrefix + ' Received focused or clicked event: ', value))), merge(this.$inputItems, this._$filter)
1225
+ .pipe(filter(_ => this.searchable && this.enabled), map(_ => this.formControl.value),
1226
+ // DEBUG
1227
+ tap(value => this.debug && console.debug(this.logPrefix + ' Received $inputItems or filter event: ', value))))
1211
1228
  .pipe(
1212
- // Start to suggest when :
1213
- // - '*'
1214
- // - is nil, and there is no min length threshold
1215
- // - is not nil and not a string type (e.g. object)
1216
- // - is not nil and is a string, and has enough character
1217
- filter(value => value === '*'
1218
- || (isNil(value)
1219
- ? (this.suggestLengthThreshold <= 0)
1220
- : (!(typeof value === 'string')
1221
- || value.length >= this.suggestLengthThreshold))),
1229
+ // Make sure there is enough characters
1230
+ filter(thresholdFilterFn),
1222
1231
  // Distinguish changes
1223
- distinctUntilChanged()))
1232
+ // - do NOT filter if loading, to force update after a blur event
1233
+ distinctUntilChanged((v1, v2) => !this.loading && (v1 === v2 || this.equals(v1, v2)))))
1224
1234
  .pipe(
1225
1235
  // Suggest values
1226
1236
  mergeMap(value => this.suggest(value, this.filter)),
1227
1237
  // DEBUG
1228
- //tap(items => console.debug(this.logPrefix + ' Received from suggest: ', items)),
1238
+ tap(items => this.debug && console.debug(this.logPrefix + ' Received from suggest: ', items)),
1229
1239
  // Store implicit value (will use it onBlur if not other value selected)
1230
1240
  tap(items => this.updateImplicitValue(items)));
1231
1241
  // Fetch more events
@@ -1258,7 +1268,9 @@ class MatAutocompleteField {
1258
1268
  this._subscription.add(this.blurred
1259
1269
  .pipe(
1260
1270
  // Skip if not searchable
1261
- filter(_ => this.searchable), map(_ => this.formControl.value))
1271
+ filter(_ => this.searchable), map(_ => this.formControl.value),
1272
+ // DEBUG
1273
+ tap(value => console.debug(this.logPrefix + ' Received blurred event: ', value)))
1262
1274
  .subscribe(value => {
1263
1275
  // When leave component without object, use implicit value if :
1264
1276
  // - an explicit value
@@ -1269,12 +1281,14 @@ class MatAutocompleteField {
1269
1281
  this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
1270
1282
  this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
1271
1283
  this.checkIfTouched();
1284
+ this.$filteredItems.next([this._implicitValue]);
1272
1285
  }
1273
1286
  else if (isNilOrBlank(value)) {
1274
1287
  this.writeValue(null);
1275
1288
  this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
1276
1289
  this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
1277
1290
  this.checkIfTouched();
1291
+ this.$filteredItems.next(undefined);
1278
1292
  }
1279
1293
  this._implicitValue = null; // reset the implicit value
1280
1294
  }));
@@ -1304,7 +1318,9 @@ class MatAutocompleteField {
1304
1318
  this._openedSubscription.unsubscribe();
1305
1319
  }
1306
1320
  this.$inputItems.complete();
1321
+ this.$inputItems.unsubscribe();
1307
1322
  this.$filteredItems.complete();
1323
+ this.$filteredItems.unsubscribe();
1308
1324
  this._reload$.complete();
1309
1325
  this._$filter.complete();
1310
1326
  this.dropButtonClick.complete();
@@ -1340,7 +1356,7 @@ class MatAutocompleteField {
1340
1356
  }
1341
1357
  writeValue(value) {
1342
1358
  // DEBUG
1343
- // console.debug(this.logPrefix + " Writing value: ", value);
1359
+ // console.debug(this.logPrefix + ' Writing value: ', value);
1344
1360
  if (value !== this.formControl.value) {
1345
1361
  this.formControl.patchValue(value, { emitEvent: false });
1346
1362
  this._onChangeCallback(value);
@@ -1377,15 +1393,20 @@ class MatAutocompleteField {
1377
1393
  if (event.stopPropagation)
1378
1394
  event.stopPropagation();
1379
1395
  event.returnValue = false;
1380
- //DEBUG console.debug(this.logPrefix + ' Cancelling focus event');
1396
+ // DEBUG
1397
+ if (this.debug)
1398
+ console.debug(this.logPrefix + ' Cancelling focus event');
1381
1399
  return false;
1382
1400
  }
1383
- const hasContent = selectInputContent(event);
1401
+ if (this.debug)
1402
+ console.debug(this.logPrefix + ' Select input content');
1403
+ const hasContent = true; // selectInputContent(event);
1384
1404
  // If combo is empty, or if has content but should force to show panel on focus
1385
- if (!hasContent || (this.showPanelOnFocus && this.showAllOnFocus)) {
1405
+ if (!hasContent || this.showPanelOnFocus || this.showAllOnFocus) {
1386
1406
  // DEBUG
1387
- //console.debug(this.logPrefix + ' Emit focus event');
1388
- this.focused.emit(event);
1407
+ if (this.debug)
1408
+ console.debug(this.logPrefix + ' Emit focus event');
1409
+ this.focused.emit();
1389
1410
  return true;
1390
1411
  }
1391
1412
  return false;
@@ -1399,11 +1420,14 @@ class MatAutocompleteField {
1399
1420
  if (event.stopPropagation)
1400
1421
  event.stopPropagation();
1401
1422
  event.returnValue = false;
1402
- //DEBUG console.debug(this.logPrefix + " Cancelling blur event");
1423
+ // DEBUG
1424
+ if (this.debug)
1425
+ console.debug(this.logPrefix + " Cancelling blur event");
1403
1426
  return false;
1404
1427
  }
1405
1428
  //DEBUG
1406
- //console.debug(this.logPrefix + ' Blur: move caret to the beginning');
1429
+ if (this.debug)
1430
+ console.debug(this.logPrefix + ' Blur: move caret to the beginning');
1407
1431
  // Move caret to the beginning (fix issue IMAGINE-469)
1408
1432
  selectInputRange(event.target, 0, 0);
1409
1433
  this.blurred.emit(event);
@@ -1514,6 +1538,7 @@ class MatAutocompleteField {
1514
1538
  /* -- private method -- */
1515
1539
  suggest(value, filter) {
1516
1540
  return __awaiter(this, void 0, void 0, function* () {
1541
+ // Call suggestion function
1517
1542
  let res = yield this.suggestFn(value, filter);
1518
1543
  // DEBUG
1519
1544
  //console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
@@ -1534,6 +1559,9 @@ class MatAutocompleteField {
1534
1559
  this._moreItemsCount = fetchMore && (this._itemCount - data.length) || 0;
1535
1560
  res = data;
1536
1561
  }
1562
+ // DEBUG
1563
+ if (this.debug)
1564
+ console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
1537
1565
  return res;
1538
1566
  });
1539
1567
  }
@@ -1605,14 +1633,14 @@ MatAutocompleteField.decorators = [
1605
1633
  { type: Component, args: [{
1606
1634
  // eslint-disable-next-line @angular-eslint/component-selector
1607
1635
  selector: 'mat-autocomplete-field',
1608
- template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field *ngIf=\"_readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n [title]=\"displayValue\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- readonly -->\n <ng-container>\n <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n </ng-container>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n </mat-form-field>\n\n <ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- Basic select -->\n <mat-select #matSelect\n *ngIf=\"!searchable; else searchableTemplate\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\"\n [tabindex]=\"_tabindex\"\n [panelClass]=\"classList\"\n [style.width]=\"panelWidth\"\n (focus)=\"filterMatSelectFocusEvent($event)\"\n (blur)=\"filterMatSelectBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n [compareWith]=\"equals\"\n [multiple]=\"multiple\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- header -->\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as isLast\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <!-- options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text>{{item | propertyGet: path }}</ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n </mat-select>\n\n\n <!--\n NOTE :\n - \"selectInputContent($event) || onFocus.emit($event)\" : call onFocus only when to the input is empty (nothing to select)\n -->\n <ng-template #searchableTemplate>\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.opened && dropButtonClick.emit($event)\">\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [class.cdk-visually-hidden]=\"!searchable\"\n [panelWidth]=\"panelWidth\">\n\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count\" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label><i>{{noResultMessage | translate}}</i></ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: formControl.value, withAccent: highlightAccent }\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n </ng-template>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"searchable\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix type=\"button\" mat-icon-button tabindex=\"-1\"\n *ngIf=\"enabled && mobile && !searchable && !multiple\"\n [title]=\"'COMMON.BTN_SEARCH'|translate\"\n (click)=\"toggleSearch($event)\">\n <mat-icon>search</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
1636
+ template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <!-- readonly -->\n <mat-form-field *ngIf=\"_readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n [title]=\"displayValue\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n </mat-form-field>\n\n <ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- Basic select -->\n <mat-select #matSelect\n *ngIf=\"!searchable; else searchableTemplate\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\"\n [tabindex]=\"_tabindex\"\n [panelClass]=\"classList\"\n [style.width]=\"panelWidth\"\n (focus)=\"filterMatSelectFocusEvent($event)\"\n (blur)=\"filterMatSelectBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n [compareWith]=\"equals\"\n [multiple]=\"multiple\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- header -->\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as isLast\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <!-- options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text>{{item | propertyGet: path }}</ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n </mat-select>\n\n\n <!--\n NOTE :\n - \"selectInputContent($event) || onFocus.emit($event)\" : call onFocus only when to the input is empty (nothing to select)\n -->\n <ng-template #searchableTemplate>\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"dropButtonClick.emit($event)\">\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [panelWidth]=\"panelWidth\">\n\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count\" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label><i>{{noResultMessage | translate}}</i></ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: formControl.value, withAccent: highlightAccent }\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n </ng-template>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"searchable\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix type=\"button\" mat-icon-button tabindex=\"-1\"\n *ngIf=\"enabled && mobile && !searchable && !multiple\"\n [title]=\"'COMMON.BTN_SEARCH'|translate\"\n (click)=\"toggleSearch($event)\">\n <mat-icon>search</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
1609
1637
  providers: [{
1610
1638
  provide: NG_VALUE_ACCESSOR,
1611
1639
  multi: true,
1612
1640
  useExisting: forwardRef(() => MatAutocompleteField)
1613
1641
  }],
1614
1642
  changeDetection: ChangeDetectionStrategy.OnPush,
1615
- styles: [":host{display:inline-block;position:relative}:host.ion-text-wrap ion-label{white-space:normal!important}button[hidden]{display:none}mat-icon.select-arrow{color:rgba(0,0,0,.47);font-size:150%}.fact-scroll-viewport{height:100%;width:100%}.fact-item{height:54px;display:flex}.fact-item .fact-date{min-width:100px;text-align:center;font-size:24pt}.fact-item .fact-date,.fact-item .fact-text{height:100%;align-items:center;justify-content:center;display:flex}.fact-item .fact-text{border-radius:10px}cdk-virtual-scroll-viewport{border:1px solid #000}cdk-virtual-scroll-viewport li{list-style:none}"]
1643
+ styles: [":host{display:inline-block;position:relative}:host.ion-text-wrap ion-label{white-space:normal!important}button[hidden]{display:none}mat-icon.select-arrow{color:rgba(0,0,0,.47);font-size:150%}"]
1616
1644
  },] }
1617
1645
  ];
1618
1646
  MatAutocompleteField.ctorParameters = () => [
@@ -1650,6 +1678,7 @@ MatAutocompleteField.propDecorators = {
1650
1678
  fetchMoreThreshold: [{ type: Input }],
1651
1679
  suggestLengthThreshold: [{ type: Input }],
1652
1680
  showLoadingSpinner: [{ type: Input }],
1681
+ debug: [{ type: Input }],
1653
1682
  clicked: [{ type: Output, args: ['click',] }],
1654
1683
  blurred: [{ type: Output, args: ['blur',] }],
1655
1684
  focused: [{ type: Output, args: ['focus',] }],
@@ -1660,7 +1689,6 @@ MatAutocompleteField.propDecorators = {
1660
1689
  matInputText: [{ type: ViewChild, args: ['matInputText',] }],
1661
1690
  autocomplete: [{ type: ViewChild, args: [MatAutocomplete,] }],
1662
1691
  autocompleteTrigger: [{ type: ViewChild, args: [MatAutocompleteTrigger,] }],
1663
- animationsDisabled: [{ type: HostBinding, args: ['@.disabled',] }],
1664
1692
  filter: [{ type: Input }],
1665
1693
  readonly: [{ type: Input }],
1666
1694
  tabindex: [{ type: Input }],
@@ -4078,9 +4106,9 @@ const MASKS = {
4078
4106
  DD: [/[+-]/, /\d/, /\d/, /\d/, '.', /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, '°']
4079
4107
  }
4080
4108
  };
4081
- const noop$6 = () => {
4109
+ const noop$7 = () => {
4082
4110
  };
4083
- const ɵ0$9 = noop$6;
4111
+ const ɵ0$a = noop$7;
4084
4112
  class MatLatLongField {
4085
4113
  constructor(platform, translate, formBuilder, cd, formGroupDir) {
4086
4114
  this.platform = platform;
@@ -4088,8 +4116,8 @@ class MatLatLongField {
4088
4116
  this.formBuilder = formBuilder;
4089
4117
  this.cd = cd;
4090
4118
  this.formGroupDir = formGroupDir;
4091
- this._onChangeCallback = noop$6;
4092
- this._onTouchedCallback = noop$6;
4119
+ this._onChangeCallback = noop$7;
4120
+ this._onTouchedCallback = noop$7;
4093
4121
  this._subscription = new Subscription();
4094
4122
  this.disabling = false;
4095
4123
  this.writing = false;
@@ -4431,8 +4459,8 @@ const DEFAULT_VALUE_ACCESSOR$5 = {
4431
4459
  multi: true
4432
4460
  };
4433
4461
  const DAY_MASK$2 = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/];
4434
- const noop$5 = () => { };
4435
- const ɵ0$8 = noop$5;
4462
+ const noop$6 = () => { };
4463
+ const ɵ0$9 = noop$6;
4436
4464
  class MatDate {
4437
4465
  constructor(platform, dateAdapter, translate, formBuilder, cd, keyboard, formGroupDir) {
4438
4466
  this.dateAdapter = dateAdapter;
@@ -4441,8 +4469,8 @@ class MatDate {
4441
4469
  this.cd = cd;
4442
4470
  this.keyboard = keyboard;
4443
4471
  this.formGroupDir = formGroupDir;
4444
- this._onChangeCallback = noop$5;
4445
- this._onTouchedCallback = noop$5;
4472
+ this._onChangeCallback = noop$6;
4473
+ this._onTouchedCallback = noop$6;
4446
4474
  this._subscription = new Subscription();
4447
4475
  this.writing = true;
4448
4476
  this.disabling = false;
@@ -4474,7 +4502,7 @@ class MatDate {
4474
4502
  ngOnInit() {
4475
4503
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
4476
4504
  if (!this.formControl)
4477
- throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-date-time-field>.');
4505
+ throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-date-field>.');
4478
4506
  this.required = toBoolean(this.required, this.formControl.validator === Validators.required);
4479
4507
  // Redirect errors from main control, into day sub control
4480
4508
  const $error = new BehaviorSubject(null);
@@ -4724,20 +4752,20 @@ const DEFAULT_VALUE_ACCESSOR$4 = {
4724
4752
  const DAY_MASK$1 = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/];
4725
4753
  const HOUR_REGEXP = /^[012][0-9][:][012345][0-9]$/;
4726
4754
  const HOUR_MASK$1 = [/[012]/, /\d/, ':', /[012345]/, /\d/];
4727
- const noop$4 = () => {
4755
+ const noop$5 = () => {
4728
4756
  };
4729
- const ɵ0$7 = noop$4;
4757
+ const ɵ0$8 = noop$5;
4730
4758
  class MatDateTime {
4731
- constructor(platform, dateAdapter, translate, formBuilder, keyboard, cd, formGroupDir) {
4759
+ constructor(platform, dateAdapter, translate, formBuilder, cd, keyboard, formGroupDir) {
4732
4760
  this.platform = platform;
4733
4761
  this.dateAdapter = dateAdapter;
4734
4762
  this.translate = translate;
4735
4763
  this.formBuilder = formBuilder;
4736
- this.keyboard = keyboard;
4737
4764
  this.cd = cd;
4765
+ this.keyboard = keyboard;
4738
4766
  this.formGroupDir = formGroupDir;
4739
- this._onChangeCallback = noop$4;
4740
- this._onTouchedCallback = noop$4;
4767
+ this._onChangeCallback = noop$5;
4768
+ this._onTouchedCallback = noop$5;
4741
4769
  this._subscription = new Subscription();
4742
4770
  this.writing = true;
4743
4771
  this.disabling = false;
@@ -5066,8 +5094,8 @@ MatDateTime.ctorParameters = () => [
5066
5094
  { type: DateAdapter },
5067
5095
  { type: TranslateService },
5068
5096
  { type: FormBuilder },
5069
- { type: Keyboard },
5070
5097
  { type: ChangeDetectorRef },
5098
+ { type: Keyboard, decorators: [{ type: Optional }] },
5071
5099
  { type: FormGroupDirective, decorators: [{ type: Optional }] }
5072
5100
  ];
5073
5101
  MatDateTime.propDecorators = {
@@ -5095,9 +5123,9 @@ const DEFAULT_VALUE_ACCESSOR$3 = {
5095
5123
  multi: true
5096
5124
  };
5097
5125
  const DAY_MASK = [/\d/, /\d/, /\d/, /\d/];
5098
- const noop$3 = () => {
5126
+ const noop$4 = () => {
5099
5127
  };
5100
- const ɵ0$6 = noop$3;
5128
+ const ɵ0$7 = noop$4;
5101
5129
  class MatDateShort {
5102
5130
  constructor(platform, dateAdapter, translate, formBuilder, cd, keyboard, formGroupDir) {
5103
5131
  this.dateAdapter = dateAdapter;
@@ -5106,8 +5134,8 @@ class MatDateShort {
5106
5134
  this.cd = cd;
5107
5135
  this.keyboard = keyboard;
5108
5136
  this.formGroupDir = formGroupDir;
5109
- this._onChangeCallback = noop$3;
5110
- this._onTouchedCallback = noop$3;
5137
+ this._onChangeCallback = noop$4;
5138
+ this._onTouchedCallback = noop$4;
5111
5139
  this.writing = true;
5112
5140
  this.disabling = false;
5113
5141
  this.dayMask = DAY_MASK;
@@ -5137,7 +5165,7 @@ class MatDateShort {
5137
5165
  ngOnInit() {
5138
5166
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
5139
5167
  if (!this.formControl)
5140
- throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-date-time-field>.');
5168
+ throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-date-short-field>.');
5141
5169
  // Redirect errors from main control, into day sub control
5142
5170
  const $error = new BehaviorSubject(null);
5143
5171
  this.required = toBoolean(this.required, this.formControl.validator === Validators.required);
@@ -5430,9 +5458,9 @@ const DEFAULT_VALUE_ACCESSOR$2 = {
5430
5458
  };
5431
5459
  const HOUR_TIME_PATTERN = /[0-9]\d\d:[0-5]\d/;
5432
5460
  const HOUR_MASK = [/\d/, /\d/, /\d/, ':', /[0-5]/, /\d/];
5433
- const noop$2 = () => {
5461
+ const noop$3 = () => {
5434
5462
  };
5435
- const ɵ0$5 = noop$2;
5463
+ const ɵ0$6 = noop$3;
5436
5464
  class MatDuration {
5437
5465
  constructor(platform, dateAdapter, translate, formBuilder, cd, formGroupDir) {
5438
5466
  this.dateAdapter = dateAdapter;
@@ -5441,8 +5469,8 @@ class MatDuration {
5441
5469
  this.cd = cd;
5442
5470
  this.formGroupDir = formGroupDir;
5443
5471
  this._subscription = new Subscription();
5444
- this._onChangeCallback = noop$2;
5445
- this._onTouchedCallback = noop$2;
5472
+ this._onChangeCallback = noop$3;
5473
+ this._onTouchedCallback = noop$3;
5446
5474
  this.writing = true;
5447
5475
  this.disabling = false;
5448
5476
  this.hourMask = HOUR_MASK;
@@ -5479,7 +5507,7 @@ class MatDuration {
5479
5507
  }
5480
5508
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
5481
5509
  if (!this.formControl)
5482
- throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-date-time-field>.');
5510
+ throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-duration-field>.');
5483
5511
  this.required = toBoolean(this.required, this.formControl.validator === Validators.required);
5484
5512
  // Redirect errors from main control, into day sub control
5485
5513
  const $error = new BehaviorSubject(null);
@@ -5687,17 +5715,17 @@ const DEFAULT_VALUE_ACCESSOR$1 = {
5687
5715
  useExisting: forwardRef(() => MatBooleanField),
5688
5716
  multi: true
5689
5717
  };
5690
- const noop$1 = () => {
5718
+ const noop$2 = () => {
5691
5719
  };
5692
- const ɵ0$4 = noop$1;
5720
+ const ɵ0$5 = noop$2;
5693
5721
  class MatBooleanField {
5694
5722
  constructor(translate, formBuilder, cd, formGroupDir) {
5695
5723
  this.translate = translate;
5696
5724
  this.formBuilder = formBuilder;
5697
5725
  this.cd = cd;
5698
5726
  this.formGroupDir = formGroupDir;
5699
- this._onChangeCallback = noop$1;
5700
- this._onTouchedCallback = noop$1;
5727
+ this._onChangeCallback = noop$2;
5728
+ this._onTouchedCallback = noop$2;
5701
5729
  this._writing = false;
5702
5730
  this.showRadio = false;
5703
5731
  this.disabled = false;
@@ -6480,8 +6508,8 @@ class MatSwipeField {
6480
6508
  constructor(cd, formGroupDir) {
6481
6509
  this.cd = cd;
6482
6510
  this.formGroupDir = formGroupDir;
6483
- this._onChangeCallback = noop$8;
6484
- this._onTouchedCallback = noop$8;
6511
+ this._onChangeCallback = noop$9;
6512
+ this._onTouchedCallback = noop$9;
6485
6513
  this._subscription = new Subscription();
6486
6514
  this._writing = false;
6487
6515
  this.showSlides = false;
@@ -6792,24 +6820,28 @@ SharedMatSwipeModule.decorators = [
6792
6820
  },] }
6793
6821
  ];
6794
6822
 
6823
+ const noop$1 = () => { };
6824
+ const ɵ0$4 = noop$1;
6795
6825
  class MatChipsField {
6796
6826
  constructor(cd, formGroupDir) {
6797
6827
  this.cd = cd;
6798
6828
  this.formGroupDir = formGroupDir;
6799
- this._onChangeCallback = (_) => { };
6800
- this._onTouchedCallback = () => { };
6829
+ this._onChangeCallback = noop$1;
6830
+ this._onTouchedCallback = noop$1;
6801
6831
  this.logPrefix = '[mat-chips] ';
6832
+ this.formControlName = null;
6802
6833
  this.required = false;
6803
6834
  this.readonly = false;
6804
6835
  this.clearable = false;
6805
6836
  this.debounceTime = null;
6806
6837
  this.i18nPrefix = 'REFERENTIAL.';
6807
6838
  this.noResultMessage = 'COMMON.NO_RESULT';
6808
- this.debug = false;
6809
6839
  this.itemSize = '48px';
6810
6840
  this.fetchMoreThreshold = '15%';
6811
6841
  this.suggestLengthThreshold = null;
6812
6842
  this.showLoadingSpinner = true;
6843
+ this.chipColor = null;
6844
+ this.debug = false;
6813
6845
  this.clicked = new EventEmitter();
6814
6846
  this.blurred = new EventEmitter();
6815
6847
  this.focused = new EventEmitter();
@@ -6878,6 +6910,9 @@ class MatChipsField {
6878
6910
  get enabled() {
6879
6911
  return !this.readonly && this.formControl.enabled;
6880
6912
  }
6913
+ get loading() {
6914
+ return isNil(this.$filteredItems.value);
6915
+ }
6881
6916
  ngOnInit() {
6882
6917
  var _a, _b;
6883
6918
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
@@ -6950,6 +6985,14 @@ class MatChipsField {
6950
6985
  return this.suggestFn(value, filter); // Loop
6951
6986
  });
6952
6987
  }
6988
+ // Send value to suggest when :
6989
+ // - is nil and '*', and no min length threshold
6990
+ // - is not nil and not a string type (e.g. object)
6991
+ // - is not nil and is a string, and has enough character
6992
+ const thresholdFilterFn = (value) => (isNilOrBlank(value) || (value === '*')
6993
+ ? (this.suggestLengthThreshold <= 0)
6994
+ : (!(typeof value === 'string')
6995
+ || value.length >= this.suggestLengthThreshold));
6953
6996
  const filteredItemsChanges = merge(
6954
6997
  // Reload event (no distinctUntilChanged() pipe, to force reload even if same value)
6955
6998
  this._reload$, this.inputControl.valueChanges
@@ -6965,39 +7008,23 @@ class MatChipsField {
6965
7008
  ),
6966
7009
  // Object set: use it (no distinctUntilChanged() pipe need)
6967
7010
  this.inputControl.valueChanges
6968
- .pipe(startWith(this.inputControl.value), filter(value => isNotNil(value) && typeof value === 'object'), tap(value => {
6969
- // DEBUG
6970
- //console.debug(this.logPrefix + ' object changes:', value)
6971
- // Update the display value (if need)
6972
- const displayValue = this.displayWith(value) || '';
6973
- // Apply to the input[type=text] field
6974
- if (this.matInputText && this.matInputText.nativeElement) {
6975
- this.matInputText.nativeElement.value = displayValue;
6976
- }
6977
- })
7011
+ .pipe(startWith(this.inputControl.value), filter(value => isNotNil(value) && typeof value === 'object'),
6978
7012
  // DEBUG
6979
- //tap(value => console.debug(this.logPrefix + ' Received an object value: ', value))
6980
- ),
7013
+ tap(value => this.debug && console.debug(this.logPrefix + ' Received an object value: ', value))),
7014
+ // On dropdown button click (no distinctUntilChanged(), nor debounceTime)
7015
+ this.dropButtonClick
7016
+ .pipe(filter(event => this.enabled && (!event || !event.defaultPrevented)), tap(_ => this.matInputText.nativeElement.focus()), map(_ => this.showAllOnFocus ? '*' : this.formControl.value),
7017
+ // Make sure there is enough characters
7018
+ filter(thresholdFilterFn)),
6981
7019
  // Merge some observables, with a common distinctUntilChanged() pipe, and NO debounceTime
6982
7020
  merge(
6983
7021
  // Focus or click => Load all
6984
7022
  merge(this.focused, this.clicked)
6985
- .pipe(filter(_ => this.enabled), map((_) => this.showAllOnFocus ? '*' : this.inputControl.value)),
6986
- // On dropdown button click
6987
- this.dropButtonClick
6988
- .pipe(filter(event => this.enabled && (!event || !event.defaultPrevented)), map(_ => this.showAllOnFocus ? '*' : this.inputControl.value)), merge(this.$inputItems, this._$filter)
7023
+ .pipe(filter(_ => this.enabled), map((_) => this.showAllOnFocus ? '*' : this.inputControl.value)), merge(this.$inputItems, this._$filter)
6989
7024
  .pipe(filter(_ => this.enabled), map(_ => this.inputControl.value)))
6990
7025
  .pipe(
6991
- // Start to suggest when :
6992
- // - '*'
6993
- // - is nil, and there is no min length threshold
6994
- // - is not nil and not a string type (e.g. object)
6995
- // - is not nil and is a string, and has enough character
6996
- filter(value => value === '*'
6997
- || (isNil(value)
6998
- ? (this.suggestLengthThreshold <= 0)
6999
- : (!(typeof value === 'string')
7000
- || value.length >= this.suggestLengthThreshold))),
7026
+ // Make sure there is enough characters
7027
+ filter(thresholdFilterFn),
7001
7028
  // Distinguish changes
7002
7029
  distinctUntilChanged()))
7003
7030
  .pipe(
@@ -7036,15 +7063,24 @@ class MatChipsField {
7036
7063
  this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
7037
7064
  this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
7038
7065
  this.checkIfTouched();
7066
+ this.$filteredItems.next([this._implicitValue]);
7039
7067
  }
7040
7068
  else if (isNilOrBlank(value)) {
7041
7069
  this.writeValue(null);
7042
7070
  this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
7043
7071
  this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
7044
7072
  this.checkIfTouched();
7073
+ this.$filteredItems.next(undefined);
7045
7074
  }
7046
7075
  this._implicitValue = null; // reset the implicit value
7047
7076
  }));
7077
+ // Listen form control status change
7078
+ this._subscription.add(this.formControl.statusChanges
7079
+ .pipe(
7080
+ //filter(() => this.enabled),
7081
+ distinctUntilChanged())
7082
+ // Update component state
7083
+ .subscribe(() => this.checkIfTouched()));
7048
7084
  this._subscription.add(this.keydownEscape.subscribe(event => {
7049
7085
  if (this.isOpen) {
7050
7086
  event === null || event === void 0 ? void 0 : event.stopPropagation();
@@ -7064,7 +7100,9 @@ class MatChipsField {
7064
7100
  this._openedSubscription.unsubscribe();
7065
7101
  }
7066
7102
  this.$inputItems.complete();
7103
+ this.$inputItems.unsubscribe();
7067
7104
  this.$filteredItems.complete();
7105
+ this.$filteredItems.unsubscribe();
7068
7106
  this._reload$.complete();
7069
7107
  this._$filter.complete();
7070
7108
  this.dropButtonClick.complete();
@@ -7126,12 +7164,18 @@ class MatChipsField {
7126
7164
  this._reload$.next(value || '*');
7127
7165
  }
7128
7166
  writeValue(value) {
7129
- if (this.debug)
7130
- console.debug(this.logPrefix + ' Writing value: ', value);
7167
+ if (value && !Array.isArray(value)) {
7168
+ value = [value];
7169
+ }
7131
7170
  if (value !== this.formControl.value) {
7171
+ if (this.debug)
7172
+ console.debug(this.logPrefix + ' Writing value: ', value);
7132
7173
  this.formControl.patchValue(value, { emitEvent: false });
7133
7174
  this._onChangeCallback(value);
7134
7175
  }
7176
+ else {
7177
+ this.markForCheck();
7178
+ }
7135
7179
  }
7136
7180
  registerOnChange(fn) {
7137
7181
  this._onChangeCallback = fn;
@@ -7195,6 +7239,7 @@ class MatChipsField {
7195
7239
  // DEBUG
7196
7240
  if (this.debug)
7197
7241
  console.debug(this.logPrefix + ' Focus in chips list', event);
7242
+ // Ignore event in button
7198
7243
  this.matInputText.nativeElement.focus();
7199
7244
  }
7200
7245
  clearValue(event) {
@@ -7239,7 +7284,7 @@ class MatChipsField {
7239
7284
  // Call suggestion function
7240
7285
  let res = yield this.suggestFn(value, filter);
7241
7286
  // DEBUG
7242
- // console.debug(this.logPrefix + " Filtered items by suggestFn:", value, res);
7287
+ //console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
7243
7288
  if (!res) {
7244
7289
  this._itemCount = 0;
7245
7290
  res = [];
@@ -7249,14 +7294,17 @@ class MatChipsField {
7249
7294
  this._itemCount = res.length || 0;
7250
7295
  }
7251
7296
  else {
7252
- const { data, total } = res;
7253
- res = data;
7297
+ const { data, total, fetchMore } = res;
7254
7298
  this._itemCount = toNumber(total, data && data.length || 0);
7299
+ this._onFetchMoreCallback = fetchMore;
7300
+ this._moreItemsCount = fetchMore && (this._itemCount - data.length) || 0;
7301
+ res = data;
7255
7302
  }
7256
7303
  // Filter out existing items
7257
7304
  const filteredData = (res || []).slice().filter(item1 => this.value.findIndex(item2 => this.equals(item1, item2)) === -1);
7258
- // Update items count
7259
- this._itemCount = this._itemCount - (((res === null || res === void 0 ? void 0 : res.length) || 0) - ((filteredData === null || filteredData === void 0 ? void 0 : filteredData.length) || 0));
7305
+ const removedItemCount = (((res === null || res === void 0 ? void 0 : res.length) || 0) - ((filteredData === null || filteredData === void 0 ? void 0 : filteredData.length) || 0));
7306
+ // Decrease the item count, with delta
7307
+ this._itemCount -= removedItemCount;
7260
7308
  if (this.debug)
7261
7309
  console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
7262
7310
  return res;
@@ -7286,6 +7334,12 @@ class MatChipsField {
7286
7334
  this._implicitValue = undefined;
7287
7335
  }
7288
7336
  }
7337
+ checkIfTouched() {
7338
+ if (this.formControl.touched) {
7339
+ this.cd.markForCheck();
7340
+ this._onTouchedCallback();
7341
+ }
7342
+ }
7289
7343
  getAutocompletePanel() {
7290
7344
  var _a, _b;
7291
7345
  const ele = (_b = (_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.options.last) === null || _b === void 0 ? void 0 : _b._getHostElement().parentElement;
@@ -7295,12 +7349,6 @@ class MatChipsField {
7295
7349
  }
7296
7350
  return ele;
7297
7351
  }
7298
- checkIfTouched() {
7299
- if (this.formControl.touched) {
7300
- this.cd.markForCheck();
7301
- this._onTouchedCallback();
7302
- }
7303
- }
7304
7352
  markForCheck() {
7305
7353
  this.cd.markForCheck();
7306
7354
  }
@@ -7319,16 +7367,15 @@ MatChipsField.decorators = [
7319
7367
  { type: Component, args: [{
7320
7368
  // eslint-disable-next-line @angular-eslint/component-selector
7321
7369
  selector: 'mat-chips-field',
7322
- template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\" class=\"material-chips\" [class.mat-form-field-disabled]=\"disabled\">\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n <mat-label>{{placeholder}}</mat-label>\n <mat-chip-list #chipList (focus)=\"matInputText.focus()\">\n <mat-chip\n *ngFor=\"let item of value\"\n [selectable]=\"false\"\n [removable]=\"!disabled\"\n (removed)=\"remove(item)\">\n {{displayWith(item)}}\n <mat-icon matChipRemove *ngIf=\"!disabled\">cancel</mat-icon>\n </mat-chip>\n\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"inputControl\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [readonly]=\"disabled\"\n [hidden]=\"disabled\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.showPanel && dropButtonClick.emit($event)\"\n [matChipInputFor]=\"chipList\"\n >\n </mat-chip-list>\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n (optionSelected)=\"add($event)\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [panelWidth]=\"panelWidth\">\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count\" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: inputControl.value, withAccent: highlightAccent } \"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
7323
- providers: [
7324
- {
7370
+ template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\" class=\"material-chips\" [class.mat-form-field-disabled]=\"disabled\">\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n <mat-label>{{placeholder}}</mat-label>\n <mat-chip-list #chipList\n (focus)=\"filterChipsFocusEvent($event)\" >\n <mat-chip\n *ngFor=\"let item of value\"\n [selectable]=\"false\"\n [removable]=\"!disabled\"\n (removed)=\"remove(item)\"\n [color]=\"chipColor\"\n >\n {{displayWith(item)}}\n <mat-icon matChipRemove *ngIf=\"!disabled\">cancel</mat-icon>\n </mat-chip>\n\n <input #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"inputControl\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [readonly]=\"disabled\"\n [hidden]=\"disabled\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.showPanel && dropButtonClick.emit($event)\"\n [matChipInputFor]=\"chipList\"\n >\n </mat-chip-list>\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n (optionSelected)=\"add($event)\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [panelWidth]=\"panelWidth\">\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i; last as last\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n <ion-text color=\"light\" *ngIf=\"last && itemCount; let count\" class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async; else loadingTemplate; let items\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: inputControl.value, withAccent: highlightAccent } \"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button mat-icon-button tabindex=\"-1\"\n type=\"button\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
7371
+ providers: [{
7325
7372
  provide: NG_VALUE_ACCESSOR,
7326
7373
  multi: true,
7327
7374
  useExisting: forwardRef(() => MatChipsField)
7328
- }
7329
- ],
7375
+ }],
7376
+ encapsulation: ViewEncapsulation.None,
7330
7377
  changeDetection: ChangeDetectionStrategy.OnPush,
7331
- styles: [":host{position:relative}:host.ion-text-wrap ion-label{white-space:normal!important}button[hidden]{display:none}mat-icon.select-arrow{color:rgba(0,0,0,.47);font-size:150%}"]
7378
+ styles: [":host{width:100%;display:inline-block;position:relative}:host.ion-text-wrap ion-label{white-space:normal!important}button[hidden]{display:none}mat-icon.select-arrow{color:rgba(0,0,0,.47);font-size:150%}.mat-form-field-suffix{position:absolute!important;right:0!important;top:calc(100% - 50px)!important}.mat-chip.mat-standard-chip.mat-primary{background-color:var(--ion-color-primary);color:var(--ion-color-primary-contrast)}.mat-chip.mat-standard-chip.mat-secondary{background-color:var(--ion-color-secondary);color:var(--ion-color-secondary-contrast)}.mat-chip.mat-standard-chip.mat-tertiary{background-color:var(--ion-color-tertiary);color:var(--ion-color-tertiary-contrast)}.mat-chip.mat-standard-chip.mat-accent{background-color:var(--ion-color-accent);color:var(--ion-color-accent-contrast)}.mat-chip.mat-standard-chip.mat-warning{background-color:var(--ion-color-warning);color:var(--ion-color-warning-contrast)}"]
7332
7379
  },] }
7333
7380
  ];
7334
7381
  MatChipsField.ctorParameters = () => [
@@ -7362,11 +7409,12 @@ MatChipsField.propDecorators = {
7362
7409
  classList: [{ type: Input, args: ['class',] }],
7363
7410
  panelWidth: [{ type: Input }],
7364
7411
  matAutocompletePosition: [{ type: Input }],
7365
- debug: [{ type: Input }],
7366
7412
  itemSize: [{ type: Input }],
7367
7413
  fetchMoreThreshold: [{ type: Input }],
7368
7414
  suggestLengthThreshold: [{ type: Input }],
7369
7415
  showLoadingSpinner: [{ type: Input }],
7416
+ chipColor: [{ type: Input }],
7417
+ debug: [{ type: Input }],
7370
7418
  clicked: [{ type: Output }],
7371
7419
  blurred: [{ type: Output }],
7372
7420
  focused: [{ type: Output }],
@@ -8087,7 +8135,7 @@ class AppFormField {
8087
8135
  AppFormField.decorators = [
8088
8136
  { type: Component, args: [{
8089
8137
  selector: 'app-form-field',
8090
- template: "<ng-container [ngSwitch]=\"type\">\n\n <!-- integer -->\n <mat-form-field *ngSwitchCase=\"'integer'\" [floatLabel]=\"floatLabel\" [class]=\"classList\">\n <input matInput #matInput\n type=\"number\"\n autocomplete=\"off\"\n [readonly]=\"readonly\"\n [min]=\"definition.minValue\"\n [max]=\"definition.maxValue\"\n pattern=\"-?[0-9]*\"\n step=\"1\"\n [appAutofocus]=\"autofocus\"\n [placeholder]=\"placeholder\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\"\n (keypress)=\"filterNumberInput($event, false)\"\n [formControl]=\"formControl\"\n [required]=\"required\"\n [tabIndex]=\"tabindex\"\n (click)=\"selectInputContent($event)\">\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('min')\">\n {{(compact ? 'ERROR.FIELD_MIN_COMPACT' : 'ERROR.FIELD_MIN') | translate:formControl.errors['min'] }}</mat-error>\n <mat-error *ngIf=\"formControl.hasError('max')\">\n {{(compact ? 'ERROR.FIELD_MAX_COMPACT' : 'ERROR.FIELD_MAX') | translate:formControl.errors['max'] }}</mat-error>\n <mat-error *ngIf=\"formControl.hasError('pattern')\">\n {{'ERROR.FIELD_NOT_VALID_INTEGER'| translate }}</mat-error>\n <mat-error *ngIf=\"formControl.hasError('integer')\">\n {{'ERROR.FIELD_NOT_VALID_INTEGER'| translate }}</mat-error>\n\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-form-field>\n\n <!-- double -->\n <mat-form-field *ngSwitchCase=\"'double'\" [floatLabel]=\"floatLabel\" [class]=\"classList\">\n\n <input matInput #matInput\n type=\"number\"\n decimal=\"true\"\n autocomplete=\"off\"\n [min]=\"definition.minValue\"\n [max]=\"definition.maxValue\"\n [appAutofocus]=\"autofocus\"\n [readonly]=\"readonly\"\n [placeholder]=\"placeholder\"\n [step]=\"numberInputStep\"\n (keypress)=\"filterNumberInput($event, true)\"\n [formControl]=\"formControl\"\n [required]=\"required\"\n [tabIndex]=\"tabindex\"\n (click)=\"selectInputContent($event)\">\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('min')\">\n {{ (compact ? 'ERROR.FIELD_MIN_COMPACT' : 'ERROR.FIELD_MIN')| translate:formControl.errors['min'] }}</mat-error>\n <mat-error *ngIf=\"formControl.hasError('max')\">\n {{(compact ? 'ERROR.FIELD_MAX_COMPACT' : 'ERROR.FIELD_MAX') | translate:formControl.errors['max'] }}</mat-error>\n <mat-error *ngIf=\"formControl.hasError('maxDecimals')\">\n {{ (compact ? 'ERROR.FIELD_MAXIMUM_DECIMALS_COMPACT' : 'ERROR.FIELD_MAXIMUM_DECIMALS')| translate:{max:\n definition.maximumNumberDecimals} }}</mat-error>\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-form-field>\n\n <!-- boolean -->\n <mat-boolean-field *ngSwitchCase=\"'boolean'\" #matInput\n [class]=\"classList\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [floatLabel]=\"floatLabel\"\n [required]=\"required\"\n [compact]=\"compact\"\n [tabindex]=\"tabindex\"\n [readonly]=\"readonly\">\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-boolean-field>\n\n <!-- date -->\n <mat-date-field *ngSwitchCase=\"'date'\" #matInput\n [class]=\"classList\"\n [formControl]=\"formControl\"\n [placeholder]=\"compact ? ('COMMON.DATE_PLACEHOLDER'|translate): placeholder\"\n [floatLabel]=\"floatLabel\"\n [required]=\"required\"\n [readonly]=\"readonly\"\n [compact]=\"compact\"\n [tabindex]=\"tabindex\"\n [autofocus]=\"autofocus\">\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-date-field>\n\n <!-- date time -->\n <mat-date-time-field *ngSwitchCase=\"'dateTime'\"\n [class]=\"classList\"\n [formControl]=\"formControl\"\n [placeholder]=\"compact ? ('COMMON.DATE_TIME_PLACEHOLDER'|translate): placeholder\"\n [floatLabel]=\"floatLabel\"\n [required]=\"required\"\n [readonly]=\"readonly\"\n [compact]=\"compact\"\n [tabindex]=\"tabindex\"\n [autofocus]=\"autofocus\">\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-date-time-field>\n\n <!-- enum -->\n <mat-form-field *ngSwitchCase=\"'enum'\" [floatLabel]=\"floatLabel\" [class]=\"classList\">\n <mat-select [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\">\n <mat-option *ngFor=\"let item of definition.values\" [value]=\"item.key || item\">{{ (item.value || item) | translate }}</mat-option>\n </mat-select>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-form-field>\n\n <!-- color -->\n <mat-form-field *ngSwitchCase=\"'color'\" [floatLabel]=\"floatLabel\" [class]=\"classList\">\n\n <ion-icon margin-right name=\"color-fill\" matPrefix></ion-icon>\n\n <input matInput autocomplete=\"off\"\n [appAutofocus]=\"autofocus\"\n [formControl]=\"formControl\"\n [style.color]=\"getColorContrast(formControl.value)\"\n [style.background]=\"formControl.value\"\n [colorPicker]=\"formControl.value\"\n (colorPickerChange)=\"writeValue($event)\"\n [cpSaveClickOutside]=\"true\"\n cpPosition=\"top\"\n cpOutputFormat=\"hex\"\n [cpOKButton]=\"false\"\n [required]=\"required\"/>\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n\n <!-- string -->\n <mat-form-field *ngSwitchCase=\"'string'\" [floatLabel]=\"floatLabel\" [class]=\"classList\">\n <input matInput #matInput\n autocomplete=\"off\"\n [appAutofocus]=\"autofocus\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [readonly]=\"readonly\"\n [tabIndex]=\"tabindex\"\n (click)=\"selectInputContent($event)\"\n (keypress)=\"filterAlphanumericalInput($event)\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\">\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-form-field>\n\n <!-- auto-complete -->\n <mat-autocomplete-field *ngSwitchCase=\"'entity'\"\n [class]=\"classList\"\n [autofocus]=\"autofocus\"\n [placeholder]=\"placeholder\"\n [floatLabel]=\"floatLabel\"\n [formControl]=\"formControl\"\n [config]=\"definition.autocomplete\"\n [required]=\"required\"\n [displayWith]=\"getDisplayValueFn(definition)\">\n <ng-content select=\"[matPrefix]\"></ng-content>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </mat-autocomplete-field>\n\n <!-- multi auto-complete -->\n <mat-chips-field *ngSwitchCase=\"'entities'\"\n [class]=\"classList\"\n [placeholder]=\"placeholder\"\n [floatLabel]=\"floatLabel\"\n [formControl]=\"formControl\"\n [config]=\"definition.autocomplete\"\n [required]=\"required\"\n [displayWith]=\"getDisplayValueFn(definition)\">\n <ng-content select=\"[matPrefix]\"></ng-content>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </mat-chips-field>\n\n <!-- other -->\n <div *ngSwitchDefault>\n <mat-error *ngIf=\"type\">Unknown type {{type}} for option {{definition.key}}. Please report this error.</mat-error>\n <mat-error *ngIf=\"!type\">Error on option field. Please check console log for details.</mat-error>\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </div>\n\n</ng-container>\n",
8138
+ template: "<ng-container [ngSwitch]=\"type\">\n\n <!-- integer -->\n <mat-form-field *ngSwitchCase=\"'integer'\" [floatLabel]=\"floatLabel\" [class]=\"classList\">\n <input matInput #matInput\n type=\"number\"\n autocomplete=\"off\"\n [readonly]=\"readonly\"\n [min]=\"definition.minValue\"\n [max]=\"definition.maxValue\"\n pattern=\"-?[0-9]*\"\n step=\"1\"\n [appAutofocus]=\"autofocus\"\n [placeholder]=\"placeholder\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\"\n (keypress)=\"filterNumberInput($event, false)\"\n [formControl]=\"formControl\"\n [required]=\"required\"\n [tabIndex]=\"tabindex\"\n (click)=\"selectInputContent($event)\">\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('min')\">\n {{(compact ? 'ERROR.FIELD_MIN_COMPACT' : 'ERROR.FIELD_MIN') | translate:formControl.errors['min'] }}</mat-error>\n <mat-error *ngIf=\"formControl.hasError('max')\">\n {{(compact ? 'ERROR.FIELD_MAX_COMPACT' : 'ERROR.FIELD_MAX') | translate:formControl.errors['max'] }}</mat-error>\n <mat-error *ngIf=\"formControl.hasError('pattern')\">\n {{'ERROR.FIELD_NOT_VALID_INTEGER'| translate }}</mat-error>\n <mat-error *ngIf=\"formControl.hasError('integer')\">\n {{'ERROR.FIELD_NOT_VALID_INTEGER'| translate }}</mat-error>\n\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-form-field>\n\n <!-- double -->\n <mat-form-field *ngSwitchCase=\"'double'\" [floatLabel]=\"floatLabel\" [class]=\"classList\">\n\n <input matInput #matInput\n type=\"number\"\n decimal=\"true\"\n autocomplete=\"off\"\n [min]=\"definition.minValue\"\n [max]=\"definition.maxValue\"\n [appAutofocus]=\"autofocus\"\n [readonly]=\"readonly\"\n [placeholder]=\"placeholder\"\n [step]=\"numberInputStep\"\n (keypress)=\"filterNumberInput($event, true)\"\n [formControl]=\"formControl\"\n [required]=\"required\"\n [tabIndex]=\"tabindex\"\n (click)=\"selectInputContent($event)\">\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('min')\">\n {{ (compact ? 'ERROR.FIELD_MIN_COMPACT' : 'ERROR.FIELD_MIN')| translate:formControl.errors['min'] }}</mat-error>\n <mat-error *ngIf=\"formControl.hasError('max')\">\n {{(compact ? 'ERROR.FIELD_MAX_COMPACT' : 'ERROR.FIELD_MAX') | translate:formControl.errors['max'] }}</mat-error>\n <mat-error *ngIf=\"formControl.hasError('maxDecimals')\">\n {{ (compact ? 'ERROR.FIELD_MAXIMUM_DECIMALS_COMPACT' : 'ERROR.FIELD_MAXIMUM_DECIMALS')| translate:{max:\n definition.maximumNumberDecimals} }}</mat-error>\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-form-field>\n\n <!-- boolean -->\n <mat-boolean-field *ngSwitchCase=\"'boolean'\" #matInput\n [class]=\"classList\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [floatLabel]=\"floatLabel\"\n [required]=\"required\"\n [compact]=\"compact\"\n [tabindex]=\"tabindex\"\n [readonly]=\"readonly\">\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-boolean-field>\n\n <!-- date -->\n <mat-date-field *ngSwitchCase=\"'date'\" #matInput\n [class]=\"classList\"\n [formControl]=\"formControl\"\n [placeholder]=\"compact ? ('COMMON.DATE_PLACEHOLDER'|translate): placeholder\"\n [floatLabel]=\"floatLabel\"\n [required]=\"required\"\n [readonly]=\"readonly\"\n [compact]=\"compact\"\n [tabindex]=\"tabindex\"\n [autofocus]=\"autofocus\">\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-date-field>\n\n <!-- date time -->\n <mat-date-time-field *ngSwitchCase=\"'dateTime'\" #matInput\n [class]=\"classList\"\n [formControl]=\"formControl\"\n [placeholder]=\"compact ? ('COMMON.DATE_TIME_PLACEHOLDER'|translate): placeholder\"\n [floatLabel]=\"floatLabel\"\n [required]=\"required\"\n [readonly]=\"readonly\"\n [compact]=\"compact\"\n [tabindex]=\"tabindex\"\n [autofocus]=\"autofocus\">\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-date-time-field>\n\n <!-- enum -->\n <mat-form-field *ngSwitchCase=\"'enum'\" [floatLabel]=\"floatLabel\" [class]=\"classList\">\n <mat-select [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\">\n <mat-option *ngFor=\"let item of definition.values\" [value]=\"item.key || item\">{{ (item.value || item) | translate }}</mat-option>\n </mat-select>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-form-field>\n\n <!-- color -->\n <mat-form-field *ngSwitchCase=\"'color'\" [floatLabel]=\"floatLabel\" [class]=\"classList\">\n\n <ion-icon margin-right name=\"color-fill\" matPrefix></ion-icon>\n\n <input matInput autocomplete=\"off\"\n [appAutofocus]=\"autofocus\"\n [formControl]=\"formControl\"\n [style.color]=\"getColorContrast(formControl.value)\"\n [style.background]=\"formControl.value\"\n [colorPicker]=\"formControl.value\"\n (colorPickerChange)=\"writeValue($event)\"\n [cpSaveClickOutside]=\"true\"\n cpPosition=\"top\"\n cpOutputFormat=\"hex\"\n [cpOKButton]=\"false\"\n [required]=\"required\"/>\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n\n <!-- string -->\n <mat-form-field *ngSwitchCase=\"'string'\" [floatLabel]=\"floatLabel\" [class]=\"classList\">\n <input matInput #matInput\n autocomplete=\"off\"\n [appAutofocus]=\"autofocus\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [required]=\"required\"\n [readonly]=\"readonly\"\n [tabIndex]=\"tabindex\"\n (click)=\"selectInputContent($event)\"\n (keypress)=\"filterAlphanumericalInput($event)\"\n (keyup.enter)=\"onKeyupEnter.emit($event)\">\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </mat-form-field>\n\n <!-- auto-complete -->\n <mat-autocomplete-field *ngSwitchCase=\"'entity'\"\n [class]=\"classList\"\n [autofocus]=\"autofocus\"\n [placeholder]=\"placeholder\"\n [floatLabel]=\"floatLabel\"\n [formControl]=\"formControl\"\n [config]=\"definition.autocomplete\"\n [required]=\"required\"\n [displayWith]=\"getDisplayValueFn(definition)\">\n <ng-content select=\"[matPrefix]\"></ng-content>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </mat-autocomplete-field>\n\n <!-- multi auto-complete -->\n <mat-chips-field *ngSwitchCase=\"'entities'\"\n [class]=\"classList\"\n [placeholder]=\"placeholder\"\n [floatLabel]=\"floatLabel\"\n [formControl]=\"formControl\"\n [config]=\"definition.autocomplete\"\n [required]=\"required\"\n [displayWith]=\"getDisplayValueFn(definition)\">\n <ng-content select=\"[matPrefix]\"></ng-content>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </mat-chips-field>\n\n <!-- other -->\n <div *ngSwitchDefault>\n <mat-error *ngIf=\"type\">Unknown type {{type}} for option {{definition.key}}. Please report this error.</mat-error>\n <mat-error *ngIf=\"!type\">Error on option field. Please check console log for details.</mat-error>\n <div matSuffix>\n <ng-content select=\"[matSuffix]\"></ng-content>\n </div>\n </div>\n\n</ng-container>\n",
8091
8139
  providers: [
8092
8140
  {
8093
8141
  provide: NG_VALUE_ACCESSOR,
@@ -16488,7 +16536,7 @@ class AutocompleteTestPage {
16488
16536
  constructor(formBuilder) {
16489
16537
  this.formBuilder = formBuilder;
16490
16538
  this._items = deepCopy$1(FAKE_ENTITIES$1, 100);
16491
- this.$items = new BehaviorSubject(undefined);
16539
+ this._$items = new BehaviorSubject(undefined);
16492
16540
  this.autocompleteFields = new MatAutocompleteConfigHolder();
16493
16541
  this.memoryHide = false;
16494
16542
  this.memoryMobile = true;
@@ -16517,7 +16565,7 @@ class AutocompleteTestPage {
16517
16565
  });
16518
16566
  // From $items observable
16519
16567
  this.autocompleteFields.add('entity-$items', {
16520
- items: this.$items,
16568
+ items: this._$items,
16521
16569
  attributes: ['label', 'name'],
16522
16570
  displayWith: this.entityToString
16523
16571
  });
@@ -16555,7 +16603,7 @@ class AutocompleteTestPage {
16555
16603
  }
16556
16604
  loadItems() {
16557
16605
  return __awaiter(this, void 0, void 0, function* () {
16558
- this.$items.next(this._items.slice());
16606
+ this._$items.next(this._items.slice());
16559
16607
  });
16560
16608
  }
16561
16609
  entityToString(item) {
@@ -16585,7 +16633,7 @@ class AutocompleteTestPage {
16585
16633
  doSubmit(event) {
16586
16634
  console.debug('Validate form: ', this.form.value);
16587
16635
  }
16588
- compareWithFn(o1, o2) {
16636
+ equals(o1, o2) {
16589
16637
  return o1 && o2 && o1.id === o2.id;
16590
16638
  }
16591
16639
  toggleMode(value) {
@@ -16616,7 +16664,7 @@ class AutocompleteTestPage {
16616
16664
  AutocompleteTestPage.decorators = [
16617
16665
  { type: Component, args: [{
16618
16666
  selector: 'app-autocomplete-test',
16619
- template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Autocomplete field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n\n <!-- Tab nav - mobile/desktop mode -->\n <nav mat-tab-nav-bar>\n <a mat-tab-link\n [active]=\"mode==='mobile'\"\n (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='desktop'\"\n (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='memory'\"\n (click)=\"toggleMode('memory')\">\n <mat-label>Memory leak debug</mat-label>\n </a>\n <a mat-tab-link\n [active]=\"mode==='temp'\"\n (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <!--<ion-grid *ngIf=\"mode === 'temp'\">\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable&lt;any[]&gt;</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n </ion-row>\n\n\n </ion-grid>-->\n\n\n <ion-grid *ngIf=\"mode === 'memory'\">\n\n <!-- debugging memory leak -->\n <ion-row>\n <ion-col>\n <ion-text><h4>Debug memory leak</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Items type\">\n <mat-select (selectionChange)=\"memoryAutocompleteFieldName=$event.value\" [value]=\"memoryAutocompleteFieldName\">\n <mat-option value=\"entity-$items\">Observable</mat-option>\n <mat-option value=\"entity-suggestFn\">Suggest function</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n <ion-col size=\"1\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Mobile ?\">\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [checked]=\"memoryMobile\">\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\" color=\"tertiary\">Start</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\" color=\"tertiary\">Stop</ion-button>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n *ngIf=\"!memoryHide && memoryAutocompleteFieldName\"\n [config]=\"autocompleteFields.get(memoryAutocompleteFieldName)\"\n [mobile]=\"memoryMobile\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-memory-leak]'\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <!-- Mobile mode -->\n <ion-grid *ngIf=\"mode === 'mobile'\">\n\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, suggestFn: (searchText, filter) =&gt; any[]</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-1]'\"\n [required]=\"true\"\n placeholder=\"Suggest field\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Items is an Observable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-observable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Change filter\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <ion-button (click)=\"updateFilter('entity-items-filter')\">Filter on: {{autocompleteFields.get('entity-items-filter').filter?.searchAttribute }}</ion-button>\n </ion-col>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-filter]'\"\n ></mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"min-width-large\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"true\"\n class=\"min-width-large\"\n panelWidth=\"400px\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-mobile-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col>\n <ion-text><h4>Desktop mode</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n items from suggest function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult&lt;any&gt;\nsuggestLengthThreshold: '3'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"compareWithFn\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggest]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an array\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [logPrefix]=\"'[combo-desktop-array-1]'\"\n [equals]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [equals]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-missing]'\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size panel\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [equals]=\"compareWithFn\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-disable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"mat-autocomplete-panel-full-size\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n class=\"mat-autocomplete-panel-full-size\"\n panelWidth=\"100vw\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>panelWidth: string</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n panelWidth=\"400px\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n <ion-col size=\"3\">\n <mat-checkbox #showIcons [checked]=\"false\">\n Icons ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n <mat-icon matPrefix *ngIf=\"showIcons.checked\">keyboard_arrow_right</mat-icon>\n <mat-icon matSuffix *ngIf=\"showIcons.checked\">keyboard_arrow_left</mat-icon>\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
16667
+ template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Autocomplete field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content>\n\n <!-- Tab nav - mobile/desktop mode -->\n <nav mat-tab-nav-bar>\n <a mat-tab-link\n [active]=\"mode==='mobile'\"\n (click)=\"toggleMode('mobile')\">\n <mat-label>Mobile</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='desktop'\"\n (click)=\"toggleMode('desktop')\">\n <mat-label>Desktop</mat-label>\n </a>\n <a mat-tab-link [active]=\"mode==='memory'\"\n (click)=\"toggleMode('memory')\">\n <mat-label>Memory leak debug</mat-label>\n </a>\n <a mat-tab-link\n [active]=\"mode==='temp'\"\n (click)=\"toggleMode('temp')\">\n <mat-label>Temporary</mat-label>\n </a>\n </nav>\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <!--<ion-grid *ngIf=\"mode === 'temp'\">\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>items: Observable&lt;any[]&gt;</pre></small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [compareWith]=\"compareWithFn\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n </ion-row>\n\n\n </ion-grid>-->\n\n\n <ion-grid *ngIf=\"mode === 'memory'\">\n\n <!-- debugging memory leak -->\n <ion-row>\n <ion-col>\n <ion-text><h4>Debug memory leak</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"2\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Items type\">\n <mat-select (selectionChange)=\"memoryAutocompleteFieldName=$event.value\" [value]=\"memoryAutocompleteFieldName\">\n <mat-option value=\"entity-$items\">Observable</mat-option>\n <mat-option value=\"entity-suggestFn\">Suggest function</mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n <ion-col size=\"1\" class=\"ion-no-padding\">\n <mat-form-field floatLabel=\"always\">\n <input matInput type=\"text\" hidden placeholder=\"Mobile ?\">\n <mat-checkbox (change)=\"memoryMobile=$event.checked\" [checked]=\"memoryMobile\">\n </mat-checkbox>\n </mat-form-field>\n </ion-col>\n\n <ion-col size=\"2\">\n <ion-button *ngIf=\"!memoryTimer\" (click)=\"startMemoryTimer()\" color=\"tertiary\">Start</ion-button>\n <ion-button *ngIf=\"memoryTimer\" (click)=\"stopMemoryTimer()\" color=\"tertiary\">Stop</ion-button>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n *ngIf=\"!memoryHide && memoryAutocompleteFieldName\"\n [config]=\"autocompleteFields.get(memoryAutocompleteFieldName)\"\n [mobile]=\"memoryMobile\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-memory-leak]'\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n <!-- Mobile mode -->\n <ion-grid *ngIf=\"mode === 'mobile'\">\n\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, suggestFn: (searchText, filter) =&gt; any[]</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-1]'\"\n [required]=\"true\"\n placeholder=\"Suggest field\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Items is an Observable\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-observable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>mobile: true, items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-2]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Change filter\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre></pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <ion-button (click)=\"updateFilter('entity-items-filter')\">Filter on: {{autocompleteFields.get('entity-items-filter').filter?.searchAttribute }}</ion-button>\n </ion-col>\n <ion-col>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-filter]'\"\n ></mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"min-width-large\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"true\"\n class=\"min-width-large\"\n panelWidth=\"400px\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"true\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-mobile-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Desktop mode -->\n <ion-grid *ngIf=\"mode === 'desktop'\">\n <ion-row>\n <ion-col>\n <ion-text><h4>Desktop mode</h4></ion-text>\n </ion-col>\n </ion-row>\n <ion-row>\n\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n items from suggest function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult&lt;any&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-suggest]'\">\n </mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n search with a suggestLengthThreshold\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small><pre>suggest: (value, filter) => LoadResult&lt;any&gt;\nsuggestLengthThreshold: '3'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n suggestLengthThreshold=\"3\"\n [logPrefix]=\"'[combo-desktop-suggest]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an array\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: [], value: {{stringify(form.controls.entity.value)}}</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items')\"\n [logPrefix]=\"'[combo-desktop-array-1]'\"\n [equals]=\"equals\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Items is an Observable\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [logPrefix]=\"'[combo-desktop-2]'\"\n [equals]=\"equals\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Control value if missing in items\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>items: Observable&lt;any[]&gt;</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"missingEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-missing]'\"\n [mobile]=\"false\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size panel\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class: 'mat-autocomplete-panel-full-size'</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [class]=\"'mat-autocomplete-panel-full-size'\"\n [matAutocompletePosition]=\"'above'\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n [debug]=\"true\"\n [showAllOnFocus]=\"true\"\n [showPanelOnFocus]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-disable]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-$items')\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n <ion-row>\n <ion-col size=\"9\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Full size combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>class=\"mat-autocomplete-panel-full-size\"</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n class=\"mat-autocomplete-panel-full-size\"\n panelWidth=\"100vw\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-full-size]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"3\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Large combo\n </ion-label>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <small>\n <pre>panelWidth: string</pre>\n </small>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-autocomplete-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-large')\"\n [mobile]=\"false\"\n panelWidth=\"400px\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-large]'\"\n ></mat-autocomplete-field>\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col size=\"6\">\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Readonly toggle\n </ion-text>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-grid>\n <ion-row>\n <ion-col size=\"3\">\n <mat-checkbox (change)=\"readonlyField.readonly=$event.checked\" [checked]=\"readonlyField.readonly\">\n Readonly ?\n </mat-checkbox>\n </ion-col>\n <ion-col size=\"3\">\n <mat-checkbox #showIcons [checked]=\"false\">\n Icons ?\n </mat-checkbox>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <mat-autocomplete-field #readonlyField formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-items-filter')\"\n [placeholder]=\"'Entity'\"\n [mobile]=\"false\"\n [equals]=\"equals\"\n [logPrefix]=\"'[combo-desktop-readonly]'\"\n [readonly]=\"true\"\n [clearable]=\"!readonlyField.readonly\">\n <mat-icon matPrefix *ngIf=\"showIcons.checked\">keyboard_arrow_right</mat-icon>\n <mat-icon matSuffix *ngIf=\"showIcons.checked\">keyboard_arrow_left</mat-icon>\n </mat-autocomplete-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
16620
16668
  },] }
16621
16669
  ];
16622
16670
  AutocompleteTestPage.ctorParameters = () => [
@@ -16877,15 +16925,30 @@ class EntityTestClass {
16877
16925
  const FAKE_ENTITIES = [
16878
16926
  { id: 1, label: 'AAA', name: 'Item A' },
16879
16927
  { id: 2, label: 'BBB', name: 'Item B' },
16880
- { id: 3, label: 'CCC', name: 'Item C' }
16928
+ { id: 3, label: 'CCC', name: 'Item C' },
16929
+ { id: 4, label: 'DDD', name: 'Item D' },
16930
+ { id: 5, label: 'EEE', name: 'Item E' },
16931
+ { id: 6, label: 'FFF', name: 'Item F' },
16932
+ { id: 7, label: 'GGG', name: 'Item G' }
16881
16933
  ];
16882
- function deepCopy(values) {
16883
- return (values || FAKE_ENTITIES).map(entity => Object.assign({}, entity));
16934
+ function deepCopy(values, size) {
16935
+ if (isNil(size)) {
16936
+ return (values || FAKE_ENTITIES).map(entity => Object.assign({}, entity));
16937
+ }
16938
+ let result = [];
16939
+ let i = 1;
16940
+ while (result.length < size) {
16941
+ result = result.concat((values || FAKE_ENTITIES).map(entity => {
16942
+ const name = entity.name + ' #' + i;
16943
+ return Object.assign(Object.assign({}, entity), { id: i++, name });
16944
+ }));
16945
+ }
16946
+ return result.slice(0, size);
16884
16947
  }
16885
16948
  class ChipsTestPage {
16886
16949
  constructor(formBuilder) {
16887
16950
  this.formBuilder = formBuilder;
16888
- this._items = deepCopy(FAKE_ENTITIES);
16951
+ this._items = deepCopy(FAKE_ENTITIES, 100);
16889
16952
  this._$items = new BehaviorSubject(undefined);
16890
16953
  this.autocompleteFields = new MatAutocompleteConfigHolder();
16891
16954
  this.form = formBuilder.group({
@@ -16905,12 +16968,12 @@ class ChipsTestPage {
16905
16968
  });
16906
16969
  // From items
16907
16970
  this.autocompleteFields.add('entity-items', {
16908
- items: FAKE_ENTITIES.slice(),
16971
+ items: this._items.slice(),
16909
16972
  attributes: ['label', 'name'],
16910
16973
  displayWith: this.entityToString,
16911
16974
  equals: (o1, o2) => EntityUtils.compare(o1, o2, 1, 'id') === 0
16912
16975
  });
16913
- // From items
16976
+ // From $items observable
16914
16977
  this.autocompleteFields.add('entity-$items', {
16915
16978
  items: this._$items,
16916
16979
  attributes: ['label', 'name'],
@@ -16924,18 +16987,20 @@ class ChipsTestPage {
16924
16987
  // Load the form with data
16925
16988
  loadData() {
16926
16989
  return __awaiter(this, void 0, void 0, function* () {
16990
+ const items = deepCopy(FAKE_ENTITIES);
16927
16991
  const data = {
16928
- entity: [],
16929
- // THis item is NOT in the items list => i should be displayed anyway
16930
- entityInitial: FAKE_ENTITIES.slice(1, 2),
16931
- disableEntity: FAKE_ENTITIES.slice(1, 2)
16992
+ entity: items.slice(0, 1),
16993
+ entityInitial: items.slice(1, 2),
16994
+ disableEntity: items.slice(1, 2)
16932
16995
  };
16933
16996
  this.form.setValue(data);
16997
+ // Load observables
16998
+ setTimeout(() => this.loadItems(), 1000);
16934
16999
  });
16935
17000
  }
16936
17001
  loadItems() {
16937
17002
  return __awaiter(this, void 0, void 0, function* () {
16938
- this._$items.next(deepCopy(FAKE_ENTITIES));
17003
+ this._$items.next(this._items.slice());
16939
17004
  });
16940
17005
  }
16941
17006
  entityToString(item) {
@@ -16943,13 +17008,29 @@ class ChipsTestPage {
16943
17008
  }
16944
17009
  suggest(value, filter) {
16945
17010
  return __awaiter(this, void 0, void 0, function* () {
16946
- return suggestFromArray(this._items, value, Object.assign(Object.assign({}, filter), { searchAttributes: ['label', 'name'] }));
17011
+ filter = Object.assign({ offset: 0, size: 30 }, filter);
17012
+ const res = suggestFromArray(this._items, value, Object.assign(Object.assign({}, filter), { searchAttributes: ['label', 'name'] }));
17013
+ // Simulate a size = 30
17014
+ const total = res.total || res.data.length;
17015
+ const nextOffset = filter.offset + res.data.length;
17016
+ if (nextOffset < total) {
17017
+ filter = Object.assign(Object.assign({}, filter), { offset: nextOffset });
17018
+ return {
17019
+ total,
17020
+ data: res.data,
17021
+ fetchMore: (variables) => __awaiter(this, void 0, void 0, function* () {
17022
+ yield sleep(1000);
17023
+ return this.suggest(value, Object.assign(Object.assign({}, filter), variables));
17024
+ })
17025
+ };
17026
+ }
17027
+ return res;
16947
17028
  });
16948
17029
  }
16949
17030
  doSubmit(event) {
16950
17031
  console.debug('Validate form: ', this.form.value);
16951
17032
  }
16952
- compareWithFn(o1, o2) {
17033
+ equals(o1, o2) {
16953
17034
  return o1 && o2 && o1.id === o2.id;
16954
17035
  }
16955
17036
  /* -- protected methods -- */
@@ -16960,7 +17041,7 @@ class ChipsTestPage {
16960
17041
  ChipsTestPage.decorators = [
16961
17042
  { type: Component, args: [{
16962
17043
  selector: 'app-chips-test',
16963
- template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Chips field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <ion-grid>\n\n <ion-row>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Suggest() function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <pre><small>suggestFn: (searchText, filter) =&gt; any[]</small></pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [logPrefix]=\"'[mat-chips-empty] '\"\n [equals]=\"compareWithFn\"\n ></mat-chips-field>\n {{stringify(form.controls.entity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function with initial value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <pre><small>suggestFn: (searchText, filter) =&gt; any[]</small></pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entityInitial\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[mat-chips-initialized] '\"\n ></mat-chips-field>\n {{stringify(form.controls.entityInitial.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[mat-chips-disabled] '\"\n ></mat-chips-field>\n {{stringify(form.controls.disableEntity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"compareWithFn\"\n [logPrefix]=\"'[mat-chips-readonly] '\"\n [readonly]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.entity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
17044
+ template: "<ion-header>\n <ion-toolbar color=\"primary\">\n\n <ion-buttons slot=\"start\">\n <ion-back-button></ion-back-button>\n </ion-buttons>\n\n <ion-title>Chips field test page</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n\n <form class=\"form-container\" [formGroup]=\"form\" (ngSubmit)=\"doSubmit($event)\">\n\n <ion-grid>\n\n <ion-row>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-text color=\"primary\">\n Suggest() function\n </ion-text>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <pre><small>suggestFn: (searchText, filter) =&gt; any[]</small></pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [logPrefix]=\"'[mat-chips-empty] '\"\n chipColor=\"accent\"\n [debug]=\"false\"\n ></mat-chips-field>\n {{stringify(form.controls.entity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Suggest() function with initial value\n </ion-label>\n </ion-card-title>\n <ion-card-subtitle>\n <ion-text color=\"medium\">\n <pre><small>suggestFn: (searchText, filter) =&gt; any[]</small></pre>\n </ion-text>\n </ion-card-subtitle>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entityInitial\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [logPrefix]=\"'[mat-chips-initialized] '\"\n chipColor=\"primary\"\n [debug]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.entityInitial.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Disabled control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"disableEntity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[mat-chips-disabled] '\"\n chipColor=\"warning\"\n [debug]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.disableEntity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-card-title>\n <ion-label color=\"primary\">\n Readonly control\n </ion-label>\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <mat-chips-field formControlName=\"entity\"\n [config]=\"autocompleteFields.get('entity-suggestFn')\"\n [equals]=\"equals\"\n [logPrefix]=\"'[mat-chips-readonly] '\"\n [readonly]=\"true\"\n ></mat-chips-field>\n {{stringify(form.controls.entity.value)}}\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </form>\n\n</ion-content>\n"
16964
17045
  },] }
16965
17046
  ];
16966
17047
  ChipsTestPage.ctorParameters = () => [
@@ -24896,5 +24977,5 @@ const ErrorCodes = {
24896
24977
  * Generated bundle index. Do not edit.
24897
24978
  */
24898
24979
 
24899
- export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CryptoService, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileService, FileSizePipe, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialChipsModule, MaterialTestingModule, MaterialTestingPage, MathAbsPipe, MenuComponent, MenuItems, MenuService, ModalToolbarComponent, NetworkService, NgInitDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialRef, ReferentialUtils, RegisterConfirmPage, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, SettingsPage, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedValidators, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UserEvent, UserEventFilter, UserEventService, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isControlHasInput, isEmptyArray, isInputElement, isInstanceOf, isInt, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForTrue, waitIdle, waitWhilePending, ɵ0$5 as ɵ0, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, SharedMatBadgeIconModule as ɵc, MatBadgeIconDirective as ɵd, isFocusableElement as ɵe, MatBadgeIconTestPage as ɵf, RegisterForm as ɵg, AccountValidatorService as ɵh, RegisterModal as ɵi, UserSettingsValidatorService as ɵj, LocalSettingsValidatorService as ɵk, AppIconComponent as ɵl };
24980
+ export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_MENU_ITEMS, APP_TESTING_PAGES, AboutModal, Account, AccountPage, AccountService, AccountToStringPipe, ActionsColumnComponent, AdminModule, AdminRoutingModule, Alerts, AnimationState, AppEditor, AppEditorOptions, AppEntityEditor, AppForm, AppFormField, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppInMemoryTable, AppInstallUpgradeCard, AppListForm, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppTabEditor, AppTabEditorOptions, AppTable, AppTableDataSourceOptions, AppTableUtils, AppValidatorService, AppendToInputDirective, ArrayFilterPipe, ArrayFirstPipe, ArrayIncludesPipe, ArrayLengthPipe, ArrayPluckPipe, AudioProvider, AuthForm, AuthGuardService, AuthModal, AutocompleteTestPage, AutofocusDirective, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, CORE_CONFIG_OPTIONS, CellValueChangeListener, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigService, Configuration, CoreModule, CryptoService, DATE_ISO_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFromNowPipe, DateTimeTestPage, DateUtils, Department, DepartmentToStringPipe, DurationPipe, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesService, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, ErrorCodes, EvenPipe, FileService, FileSizePipe, FormArrayHelper, FormButtonsBarComponent, FormButtonsBarToken, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, Fragments, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, InMemoryEntitiesService, IsLoginAccountPipe, IsNilOrBlankPipe, IsNotNilOrBlankPipe, IsNotOnFieldModePipe, IsOnFieldModePipe, JobUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LongitudeFormatPipe, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MapGetPipe, MapKeysPipe, MapValuesPipe, MatAutocompleteConfigHolder, MatAutocompleteField, MatBooleanField, MatChipsField, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatNumpadComponent, MatNumpadContainerComponent, MatNumpadContent, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialChipsModule, MaterialTestingModule, MaterialTestingPage, MathAbsPipe, MenuComponent, MenuItems, MenuService, ModalToolbarComponent, NetworkService, NgInitDirective, NotEmptyArrayPipe, NumberFormatPipe, NumpadDirective, OddPipe, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialRef, ReferentialUtils, RegisterConfirmPage, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SPACE_PLACEHOLDER_CHAR, SelectPeerModal, SettingsPage, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatNumpadModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedValidators, SocialModule, Software, StartableService, StatusById, StatusIds, StatusList, StrLengthPipe, SwipeTestPage, TableSelectColumnsComponent, ToStringPipe, Toasts, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, UserEvent, UserEventFilter, UserEventService, UserEventTypes, UserEventsTable, UserSettings, UsersPage, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayGroupBy, arraySize, asInputElement, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, fadeInAnimation, fadeInOutAnimation, filterFalse, filterNotNil, filterNumberInput, filterTrue, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, hexToRgb, hexToRgbArray, isControlHasInput, isEmptyArray, isInputElement, isInstanceOf, isInt, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, joinProperties, joinPropertiesPath, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, noTrailingSlash, notNilOrDefault, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setTabIndex, sleep, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, updateValueAndValidity, waitFor, waitForTrue, waitIdle, waitWhilePending, CustomReuseStrategy as ɵa, MatNumpadDomService as ɵb, SharedMatBadgeIconModule as ɵc, MatBadgeIconDirective as ɵd, isFocusableElement as ɵe, MatBadgeIconTestPage as ɵf, RegisterForm as ɵg, AccountValidatorService as ɵh, RegisterModal as ɵi, UserSettingsValidatorService as ɵj, LocalSettingsValidatorService as ɵk, AppIconComponent as ɵl };
24900
24981
  //# sourceMappingURL=sumaris-net.ngx-components.js.map