@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
@@ -1262,10 +1262,11 @@
1262
1262
  var attributesOrFn = attributes.map(function (a, index) { return typeof a === 'function' && options.attributes[index] || a; });
1263
1263
  var filter = Object.assign({ searchAttribute: attributes.length === 1 ? attributes[0] : undefined, searchAttributes: attributes.length > 1 ? attributes : undefined }, options.filter);
1264
1264
  var displayWith = options.displayWith || (function (obj) { return obj && joinPropertiesPath(obj, attributes); });
1265
- var compareWith = options.equals || (function (o1, o2) { return o1 && o2 && o1.id === o2.id; });
1265
+ var equals = options.equals || (function (o1, o2) { return o1 && o2 && o1.id === o2.id; });
1266
1266
  var config = Object.assign(Object.assign({}, options), { attributes: attributesOrFn, suggestFn: suggestFn,
1267
1267
  filter: filter,
1268
- displayWith: displayWith, equals: compareWith });
1268
+ displayWith: displayWith,
1269
+ equals: equals });
1269
1270
  this.fields[fieldName] = config;
1270
1271
  return config;
1271
1272
  };
@@ -1277,14 +1278,14 @@
1277
1278
  };
1278
1279
  return MatAutocompleteConfigHolder;
1279
1280
  }());
1280
- var noop$7 = function () { };
1281
- var ɵ0$a = noop$7;
1281
+ var noop$8 = function (_) { };
1282
+ var ɵ0$b = noop$8;
1282
1283
  var MatAutocompleteField = /** @class */ (function () {
1283
1284
  function MatAutocompleteField(cd, formGroupDir) {
1284
1285
  this.cd = cd;
1285
1286
  this.formGroupDir = formGroupDir;
1286
- this._onChangeCallback = noop$7;
1287
- this._onTouchedCallback = noop$7;
1287
+ this._onChangeCallback = noop$8;
1288
+ this._onTouchedCallback = noop$8;
1288
1289
  this.logPrefix = '[mat-autocomplete] ';
1289
1290
  this.formControlName = null;
1290
1291
  this.required = false;
@@ -1297,13 +1298,13 @@
1297
1298
  this.fetchMoreThreshold = '15%';
1298
1299
  this.suggestLengthThreshold = null;
1299
1300
  this.showLoadingSpinner = true;
1301
+ this.debug = false;
1300
1302
  this.clicked = new i0.EventEmitter();
1301
1303
  this.blurred = new i0.EventEmitter();
1302
1304
  this.focused = new i0.EventEmitter();
1303
1305
  this.dropButtonClick = new i0.EventEmitter(true);
1304
1306
  this.keydownEscape = new i0.EventEmitter();
1305
1307
  this.keyupEnter = new i0.EventEmitter();
1306
- this.animationsDisabled = true;
1307
1308
  this._readonly = false;
1308
1309
  this.$inputItems = new rxjs.BehaviorSubject(undefined);
1309
1310
  this.$filteredItems = new rxjs.BehaviorSubject(undefined);
@@ -1411,6 +1412,13 @@
1411
1412
  enumerable: false,
1412
1413
  configurable: true
1413
1414
  });
1415
+ Object.defineProperty(MatAutocompleteField.prototype, "loading", {
1416
+ get: function () {
1417
+ return isNil(this.$filteredItems.value);
1418
+ },
1419
+ enumerable: false,
1420
+ configurable: true
1421
+ });
1414
1422
  MatAutocompleteField.prototype.ngOnInit = function () {
1415
1423
  var _this = this;
1416
1424
  var _a, _b;
@@ -1432,7 +1440,7 @@
1432
1440
  this.mobile = toBoolean(this.mobile, this.config.mobile);
1433
1441
  this.suggestLengthThreshold = toNumber(this.suggestLengthThreshold, this.config.suggestLengthThreshold || 0);
1434
1442
  this.showAllOnFocus = toBoolean(this.showAllOnFocus, toBoolean(this.config.showAllOnFocus, this.suggestLengthThreshold <= 0));
1435
- this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus));
1443
+ this.showPanelOnFocus = toBoolean(this.showPanelOnFocus, toBoolean(this.config.showPanelOnFocus, true));
1436
1444
  this.classList = this.classList || this.config.class;
1437
1445
  this.debounceTime = toNumber(this.debounceTime, this.config.debounceTime);
1438
1446
  this.highlightAccent = toBoolean(this.highlightAccent, toBoolean(this.config.highlightAccent));
@@ -1501,6 +1509,14 @@
1501
1509
  operators.switchMap(function (filter) { return _this.suggest('*', filter); }))
1502
1510
  .subscribe(function (items) { return _this.$inputItems.next(items); }));
1503
1511
  }
1512
+ // Send value to suggest when :
1513
+ // - is nil and '*', and no min length threshold
1514
+ // - is not nil and not a string type (e.g. object)
1515
+ // - is not nil and is a string, and has enough character
1516
+ var thresholdFilterFn = function (value) { return (isNilOrBlank(value) || (value === '*')
1517
+ ? (_this.suggestLengthThreshold <= 0)
1518
+ : (!(typeof value === 'string')
1519
+ || value.length >= _this.suggestLengthThreshold)); };
1504
1520
  var filteredItemsChanges = rxjs.merge(
1505
1521
  // Reload event (no distinctUntilChanged() pipe, to force reload even if same value)
1506
1522
  this._reload$,
@@ -1512,15 +1528,15 @@
1512
1528
  // Filter if not enough character
1513
1529
  operators.filter(function (value) { return value.length >= _this.suggestLengthThreshold; }),
1514
1530
  // Wait a debounce time
1515
- operators.debounceTime(this.debounceTime)
1531
+ operators.debounceTime(this.debounceTime),
1516
1532
  // DEBUG
1517
- //tap((value) => console.debug(this.logPrefix + ' Search text changes:', value)),
1518
- ),
1533
+ operators.tap(function (value) { return console.debug(_this.logPrefix + ' Search text changes:', value); })),
1519
1534
  // Object set: use it (no distinctUntilChanged() pipe need)
1520
1535
  this.formControl.valueChanges
1521
1536
  .pipe(operators.startWith(this.formControl.value), operators.filter(function (value) { return (_this.searchable && isNotNil(value) && typeof value === 'object'); }), operators.tap(function (value) {
1522
1537
  // DEBUG
1523
- //console.debug(this.logPrefix + ' object changes:', value)
1538
+ if (_this.debug)
1539
+ console.debug(_this.logPrefix + ' object changes:', value);
1524
1540
  // Update the display value (if need)
1525
1541
  var displayValue = _this.displayWith(value) || '';
1526
1542
  if (_this.displayValue !== displayValue) {
@@ -1530,37 +1546,35 @@
1530
1546
  _this.matInputText.nativeElement.value = _this.displayValue;
1531
1547
  }
1532
1548
  }
1533
- })
1549
+ }),
1534
1550
  // DEBUG
1535
- //tap(value => console.debug(this.logPrefix + ' Received an object value: ', value))
1536
- ),
1551
+ operators.tap(function (value) { return _this.debug && console.debug(_this.logPrefix + ' Received an object value: ', value); })),
1552
+ // On dropdown button click (no distinctUntilChanged(), nor debounceTime)
1553
+ this.dropButtonClick
1554
+ .pipe(operators.filter(function (event) { return _this.searchable && _this.enabled && (!event || !event.defaultPrevented); }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; }),
1555
+ // Make enough characters
1556
+ operators.filter(thresholdFilterFn)),
1537
1557
  // Merge some observables, with a common distinctUntilChanged() pipe, and NO debounceTime
1538
1558
  rxjs.merge(
1539
1559
  // Focus or click => Load all
1540
1560
  rxjs.merge(this.focused, this.clicked)
1541
- .pipe(operators.filter(function (_) { return _this.enabled && _this.searchable; }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; })),
1542
- // On dropdown button click
1543
- this.dropButtonClick
1544
- .pipe(operators.filter(function (event) { return _this.searchable && _this.enabled && (!event || !event.defaultPrevented); }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; })), rxjs.merge(this.$inputItems, this._$filter)
1545
- .pipe(operators.filter(function (_) { return _this.searchable && _this.enabled; }), operators.map(function (_) { return _this.formControl.value; })))
1561
+ .pipe(operators.filter(function (_) { return _this.enabled && _this.searchable; }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; }),
1562
+ // DEBUG
1563
+ operators.tap(function (value) { return _this.debug && console.debug(_this.logPrefix + ' Received focused or clicked event: ', value); })), rxjs.merge(this.$inputItems, this._$filter)
1564
+ .pipe(operators.filter(function (_) { return _this.searchable && _this.enabled; }), operators.map(function (_) { return _this.formControl.value; }),
1565
+ // DEBUG
1566
+ operators.tap(function (value) { return _this.debug && console.debug(_this.logPrefix + ' Received $inputItems or filter event: ', value); })))
1546
1567
  .pipe(
1547
- // Start to suggest when :
1548
- // - '*'
1549
- // - is nil, and there is no min length threshold
1550
- // - is not nil and not a string type (e.g. object)
1551
- // - is not nil and is a string, and has enough character
1552
- operators.filter(function (value) { return value === '*'
1553
- || (isNil(value)
1554
- ? (_this.suggestLengthThreshold <= 0)
1555
- : (!(typeof value === 'string')
1556
- || value.length >= _this.suggestLengthThreshold)); }),
1568
+ // Make sure there is enough characters
1569
+ operators.filter(thresholdFilterFn),
1557
1570
  // Distinguish changes
1558
- operators.distinctUntilChanged()))
1571
+ // - do NOT filter if loading, to force update after a blur event
1572
+ operators.distinctUntilChanged(function (v1, v2) { return !_this.loading && (v1 === v2 || _this.equals(v1, v2)); })))
1559
1573
  .pipe(
1560
1574
  // Suggest values
1561
1575
  operators.mergeMap(function (value) { return _this.suggest(value, _this.filter); }),
1562
1576
  // DEBUG
1563
- //tap(items => console.debug(this.logPrefix + ' Received from suggest: ', items)),
1577
+ operators.tap(function (items) { return _this.debug && console.debug(_this.logPrefix + ' Received from suggest: ', items); }),
1564
1578
  // Store implicit value (will use it onBlur if not other value selected)
1565
1579
  operators.tap(function (items) { return _this.updateImplicitValue(items); }));
1566
1580
  // Fetch more events
@@ -1593,7 +1607,9 @@
1593
1607
  this._subscription.add(this.blurred
1594
1608
  .pipe(
1595
1609
  // Skip if not searchable
1596
- operators.filter(function (_) { return _this.searchable; }), operators.map(function (_) { return _this.formControl.value; }))
1610
+ operators.filter(function (_) { return _this.searchable; }), operators.map(function (_) { return _this.formControl.value; }),
1611
+ // DEBUG
1612
+ operators.tap(function (value) { return console.debug(_this.logPrefix + ' Received blurred event: ', value); }))
1597
1613
  .subscribe(function (value) {
1598
1614
  // When leave component without object, use implicit value if :
1599
1615
  // - an explicit value
@@ -1604,12 +1620,14 @@
1604
1620
  _this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
1605
1621
  _this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
1606
1622
  _this.checkIfTouched();
1623
+ _this.$filteredItems.next([_this._implicitValue]);
1607
1624
  }
1608
1625
  else if (isNilOrBlank(value)) {
1609
1626
  _this.writeValue(null);
1610
1627
  _this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
1611
1628
  _this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
1612
1629
  _this.checkIfTouched();
1630
+ _this.$filteredItems.next(undefined);
1613
1631
  }
1614
1632
  _this._implicitValue = null; // reset the implicit value
1615
1633
  }));
@@ -1639,7 +1657,9 @@
1639
1657
  this._openedSubscription.unsubscribe();
1640
1658
  }
1641
1659
  this.$inputItems.complete();
1660
+ this.$inputItems.unsubscribe();
1642
1661
  this.$filteredItems.complete();
1662
+ this.$filteredItems.unsubscribe();
1643
1663
  this._reload$.complete();
1644
1664
  this._$filter.complete();
1645
1665
  this.dropButtonClick.complete();
@@ -1675,7 +1695,7 @@
1675
1695
  };
1676
1696
  MatAutocompleteField.prototype.writeValue = function (value) {
1677
1697
  // DEBUG
1678
- // console.debug(this.logPrefix + " Writing value: ", value);
1698
+ // console.debug(this.logPrefix + ' Writing value: ', value);
1679
1699
  if (value !== this.formControl.value) {
1680
1700
  this.formControl.patchValue(value, { emitEvent: false });
1681
1701
  this._onChangeCallback(value);
@@ -1712,15 +1732,20 @@
1712
1732
  if (event.stopPropagation)
1713
1733
  event.stopPropagation();
1714
1734
  event.returnValue = false;
1715
- //DEBUG console.debug(this.logPrefix + ' Cancelling focus event');
1735
+ // DEBUG
1736
+ if (this.debug)
1737
+ console.debug(this.logPrefix + ' Cancelling focus event');
1716
1738
  return false;
1717
1739
  }
1718
- var hasContent = selectInputContent(event);
1740
+ if (this.debug)
1741
+ console.debug(this.logPrefix + ' Select input content');
1742
+ var hasContent = true; // selectInputContent(event);
1719
1743
  // If combo is empty, or if has content but should force to show panel on focus
1720
- if (!hasContent || (this.showPanelOnFocus && this.showAllOnFocus)) {
1744
+ if (!hasContent || this.showPanelOnFocus || this.showAllOnFocus) {
1721
1745
  // DEBUG
1722
- //console.debug(this.logPrefix + ' Emit focus event');
1723
- this.focused.emit(event);
1746
+ if (this.debug)
1747
+ console.debug(this.logPrefix + ' Emit focus event');
1748
+ this.focused.emit();
1724
1749
  return true;
1725
1750
  }
1726
1751
  return false;
@@ -1734,11 +1759,14 @@
1734
1759
  if (event.stopPropagation)
1735
1760
  event.stopPropagation();
1736
1761
  event.returnValue = false;
1737
- //DEBUG console.debug(this.logPrefix + " Cancelling blur event");
1762
+ // DEBUG
1763
+ if (this.debug)
1764
+ console.debug(this.logPrefix + " Cancelling blur event");
1738
1765
  return false;
1739
1766
  }
1740
1767
  //DEBUG
1741
- //console.debug(this.logPrefix + ' Blur: move caret to the beginning');
1768
+ if (this.debug)
1769
+ console.debug(this.logPrefix + ' Blur: move caret to the beginning');
1742
1770
  // Move caret to the beginning (fix issue IMAGINE-469)
1743
1771
  selectInputRange(event.target, 0, 0);
1744
1772
  this.blurred.emit(event);
@@ -1880,6 +1908,9 @@
1880
1908
  this._moreItemsCount = fetchMore && (this._itemCount - data.length) || 0;
1881
1909
  res = data;
1882
1910
  }
1911
+ // DEBUG
1912
+ if (this.debug)
1913
+ console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
1883
1914
  return [2 /*return*/, res];
1884
1915
  }
1885
1916
  });
@@ -1961,14 +1992,14 @@
1961
1992
  { type: i0.Component, args: [{
1962
1993
  // eslint-disable-next-line @angular-eslint/component-selector
1963
1994
  selector: 'mat-autocomplete-field',
1964
- 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",
1995
+ 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",
1965
1996
  providers: [{
1966
1997
  provide: i1.NG_VALUE_ACCESSOR,
1967
1998
  multi: true,
1968
1999
  useExisting: i0.forwardRef(function () { return MatAutocompleteField; })
1969
2000
  }],
1970
2001
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
1971
- 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}"]
2002
+ 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%}"]
1972
2003
  },] }
1973
2004
  ];
1974
2005
  MatAutocompleteField.ctorParameters = function () { return [
@@ -2006,6 +2037,7 @@
2006
2037
  fetchMoreThreshold: [{ type: i0.Input }],
2007
2038
  suggestLengthThreshold: [{ type: i0.Input }],
2008
2039
  showLoadingSpinner: [{ type: i0.Input }],
2040
+ debug: [{ type: i0.Input }],
2009
2041
  clicked: [{ type: i0.Output, args: ['click',] }],
2010
2042
  blurred: [{ type: i0.Output, args: ['blur',] }],
2011
2043
  focused: [{ type: i0.Output, args: ['focus',] }],
@@ -2016,7 +2048,6 @@
2016
2048
  matInputText: [{ type: i0.ViewChild, args: ['matInputText',] }],
2017
2049
  autocomplete: [{ type: i0.ViewChild, args: [autocomplete.MatAutocomplete,] }],
2018
2050
  autocompleteTrigger: [{ type: i0.ViewChild, args: [autocomplete.MatAutocompleteTrigger,] }],
2019
- animationsDisabled: [{ type: i0.HostBinding, args: ['@.disabled',] }],
2020
2051
  filter: [{ type: i0.Input }],
2021
2052
  readonly: [{ type: i0.Input }],
2022
2053
  tabindex: [{ type: i0.Input }],
@@ -4639,9 +4670,9 @@
4639
4670
  DD: [/[+-]/, /\d/, /\d/, /\d/, '.', /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, '°']
4640
4671
  }
4641
4672
  };
4642
- var noop$6 = function () {
4673
+ var noop$7 = function () {
4643
4674
  };
4644
- var ɵ0$9 = noop$6;
4675
+ var ɵ0$a = noop$7;
4645
4676
  var MatLatLongField = /** @class */ (function () {
4646
4677
  function MatLatLongField(platform, translate, formBuilder, cd, formGroupDir) {
4647
4678
  this.platform = platform;
@@ -4649,8 +4680,8 @@
4649
4680
  this.formBuilder = formBuilder;
4650
4681
  this.cd = cd;
4651
4682
  this.formGroupDir = formGroupDir;
4652
- this._onChangeCallback = noop$6;
4653
- this._onTouchedCallback = noop$6;
4683
+ this._onChangeCallback = noop$7;
4684
+ this._onTouchedCallback = noop$7;
4654
4685
  this._subscription = new rxjs.Subscription();
4655
4686
  this.disabling = false;
4656
4687
  this.writing = false;
@@ -5007,8 +5038,8 @@
5007
5038
  multi: true
5008
5039
  };
5009
5040
  var DAY_MASK$2 = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/];
5010
- var noop$5 = function () { };
5011
- var ɵ0$8 = noop$5;
5041
+ var noop$6 = function () { };
5042
+ var ɵ0$9 = noop$6;
5012
5043
  var MatDate = /** @class */ (function () {
5013
5044
  function MatDate(platform, dateAdapter, translate, formBuilder, cd, keyboard, formGroupDir) {
5014
5045
  this.dateAdapter = dateAdapter;
@@ -5017,8 +5048,8 @@
5017
5048
  this.cd = cd;
5018
5049
  this.keyboard = keyboard;
5019
5050
  this.formGroupDir = formGroupDir;
5020
- this._onChangeCallback = noop$5;
5021
- this._onTouchedCallback = noop$5;
5051
+ this._onChangeCallback = noop$6;
5052
+ this._onTouchedCallback = noop$6;
5022
5053
  this._subscription = new rxjs.Subscription();
5023
5054
  this.writing = true;
5024
5055
  this.disabling = false;
@@ -5060,7 +5091,7 @@
5060
5091
  var _this = this;
5061
5092
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
5062
5093
  if (!this.formControl)
5063
- throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-date-time-field>.');
5094
+ throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-date-field>.');
5064
5095
  this.required = toBoolean(this.required, this.formControl.validator === i1.Validators.required);
5065
5096
  // Redirect errors from main control, into day sub control
5066
5097
  var $error = new rxjs.BehaviorSubject(null);
@@ -5332,20 +5363,20 @@
5332
5363
  var DAY_MASK$1 = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/];
5333
5364
  var HOUR_REGEXP = /^[012][0-9][:][012345][0-9]$/;
5334
5365
  var HOUR_MASK$1 = [/[012]/, /\d/, ':', /[012345]/, /\d/];
5335
- var noop$4 = function () {
5366
+ var noop$5 = function () {
5336
5367
  };
5337
- var ɵ0$7 = noop$4;
5368
+ var ɵ0$8 = noop$5;
5338
5369
  var MatDateTime = /** @class */ (function () {
5339
- function MatDateTime(platform, dateAdapter, translate, formBuilder, keyboard, cd, formGroupDir) {
5370
+ function MatDateTime(platform, dateAdapter, translate, formBuilder, cd, keyboard, formGroupDir) {
5340
5371
  this.platform = platform;
5341
5372
  this.dateAdapter = dateAdapter;
5342
5373
  this.translate = translate;
5343
5374
  this.formBuilder = formBuilder;
5344
- this.keyboard = keyboard;
5345
5375
  this.cd = cd;
5376
+ this.keyboard = keyboard;
5346
5377
  this.formGroupDir = formGroupDir;
5347
- this._onChangeCallback = noop$4;
5348
- this._onTouchedCallback = noop$4;
5378
+ this._onChangeCallback = noop$5;
5379
+ this._onTouchedCallback = noop$5;
5349
5380
  this._subscription = new rxjs.Subscription();
5350
5381
  this.writing = true;
5351
5382
  this.disabling = false;
@@ -5719,8 +5750,8 @@
5719
5750
  { type: i1$3.DateAdapter },
5720
5751
  { type: i1$2.TranslateService },
5721
5752
  { type: i1.FormBuilder },
5722
- { type: ngx.Keyboard },
5723
5753
  { type: i0.ChangeDetectorRef },
5754
+ { type: ngx.Keyboard, decorators: [{ type: i0.Optional }] },
5724
5755
  { type: i1.FormGroupDirective, decorators: [{ type: i0.Optional }] }
5725
5756
  ]; };
5726
5757
  MatDateTime.propDecorators = {
@@ -5748,9 +5779,9 @@
5748
5779
  multi: true
5749
5780
  };
5750
5781
  var DAY_MASK = [/\d/, /\d/, /\d/, /\d/];
5751
- var noop$3 = function () {
5782
+ var noop$4 = function () {
5752
5783
  };
5753
- var ɵ0$6 = noop$3;
5784
+ var ɵ0$7 = noop$4;
5754
5785
  var MatDateShort = /** @class */ (function () {
5755
5786
  function MatDateShort(platform, dateAdapter, translate, formBuilder, cd, keyboard, formGroupDir) {
5756
5787
  this.dateAdapter = dateAdapter;
@@ -5759,8 +5790,8 @@
5759
5790
  this.cd = cd;
5760
5791
  this.keyboard = keyboard;
5761
5792
  this.formGroupDir = formGroupDir;
5762
- this._onChangeCallback = noop$3;
5763
- this._onTouchedCallback = noop$3;
5793
+ this._onChangeCallback = noop$4;
5794
+ this._onTouchedCallback = noop$4;
5764
5795
  this.writing = true;
5765
5796
  this.disabling = false;
5766
5797
  this.dayMask = DAY_MASK;
@@ -5800,7 +5831,7 @@
5800
5831
  var _this = this;
5801
5832
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
5802
5833
  if (!this.formControl)
5803
- throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-date-time-field>.');
5834
+ throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-date-short-field>.');
5804
5835
  // Redirect errors from main control, into day sub control
5805
5836
  var $error = new rxjs.BehaviorSubject(null);
5806
5837
  this.required = toBoolean(this.required, this.formControl.validator === i1.Validators.required);
@@ -6118,9 +6149,9 @@
6118
6149
  };
6119
6150
  var HOUR_TIME_PATTERN = /[0-9]\d\d:[0-5]\d/;
6120
6151
  var HOUR_MASK = [/\d/, /\d/, /\d/, ':', /[0-5]/, /\d/];
6121
- var noop$2 = function () {
6152
+ var noop$3 = function () {
6122
6153
  };
6123
- var ɵ0$5 = noop$2;
6154
+ var ɵ0$6 = noop$3;
6124
6155
  var MatDuration = /** @class */ (function () {
6125
6156
  function MatDuration(platform, dateAdapter, translate, formBuilder, cd, formGroupDir) {
6126
6157
  this.dateAdapter = dateAdapter;
@@ -6129,8 +6160,8 @@
6129
6160
  this.cd = cd;
6130
6161
  this.formGroupDir = formGroupDir;
6131
6162
  this._subscription = new rxjs.Subscription();
6132
- this._onChangeCallback = noop$2;
6133
- this._onTouchedCallback = noop$2;
6163
+ this._onChangeCallback = noop$3;
6164
+ this._onTouchedCallback = noop$3;
6134
6165
  this.writing = true;
6135
6166
  this.disabling = false;
6136
6167
  this.hourMask = HOUR_MASK;
@@ -6177,7 +6208,7 @@
6177
6208
  }
6178
6209
  this.formControl = this.formControl || this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName);
6179
6210
  if (!this.formControl)
6180
- throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-date-time-field>.');
6211
+ throw new Error('Missing mandatory attribute \'formControl\' or \'formControlName\' in <mat-duration-field>.');
6181
6212
  this.required = toBoolean(this.required, this.formControl.validator === i1.Validators.required);
6182
6213
  // Redirect errors from main control, into day sub control
6183
6214
  var $error = new rxjs.BehaviorSubject(null);
@@ -6391,17 +6422,17 @@
6391
6422
  useExisting: i0.forwardRef(function () { return MatBooleanField; }),
6392
6423
  multi: true
6393
6424
  };
6394
- var noop$1 = function () {
6425
+ var noop$2 = function () {
6395
6426
  };
6396
- var ɵ0$4 = noop$1;
6427
+ var ɵ0$5 = noop$2;
6397
6428
  var MatBooleanField = /** @class */ (function () {
6398
6429
  function MatBooleanField(translate, formBuilder, cd, formGroupDir) {
6399
6430
  this.translate = translate;
6400
6431
  this.formBuilder = formBuilder;
6401
6432
  this.cd = cd;
6402
6433
  this.formGroupDir = formGroupDir;
6403
- this._onChangeCallback = noop$1;
6404
- this._onTouchedCallback = noop$1;
6434
+ this._onChangeCallback = noop$2;
6435
+ this._onTouchedCallback = noop$2;
6405
6436
  this._writing = false;
6406
6437
  this.showRadio = false;
6407
6438
  this.disabled = false;
@@ -7619,24 +7650,28 @@
7619
7650
  },] }
7620
7651
  ];
7621
7652
 
7653
+ var noop$1 = function () { };
7654
+ var ɵ0$4 = noop$1;
7622
7655
  var MatChipsField = /** @class */ (function () {
7623
7656
  function MatChipsField(cd, formGroupDir) {
7624
7657
  this.cd = cd;
7625
7658
  this.formGroupDir = formGroupDir;
7626
- this._onChangeCallback = function (_) { };
7627
- this._onTouchedCallback = function () { };
7659
+ this._onChangeCallback = noop$1;
7660
+ this._onTouchedCallback = noop$1;
7628
7661
  this.logPrefix = '[mat-chips] ';
7662
+ this.formControlName = null;
7629
7663
  this.required = false;
7630
7664
  this.readonly = false;
7631
7665
  this.clearable = false;
7632
7666
  this.debounceTime = null;
7633
7667
  this.i18nPrefix = 'REFERENTIAL.';
7634
7668
  this.noResultMessage = 'COMMON.NO_RESULT';
7635
- this.debug = false;
7636
7669
  this.itemSize = '48px';
7637
7670
  this.fetchMoreThreshold = '15%';
7638
7671
  this.suggestLengthThreshold = null;
7639
7672
  this.showLoadingSpinner = true;
7673
+ this.chipColor = null;
7674
+ this.debug = false;
7640
7675
  this.clicked = new i0.EventEmitter();
7641
7676
  this.blurred = new i0.EventEmitter();
7642
7677
  this.focused = new i0.EventEmitter();
@@ -7738,6 +7773,13 @@
7738
7773
  enumerable: false,
7739
7774
  configurable: true
7740
7775
  });
7776
+ Object.defineProperty(MatChipsField.prototype, "loading", {
7777
+ get: function () {
7778
+ return isNil(this.$filteredItems.value);
7779
+ },
7780
+ enumerable: false,
7781
+ configurable: true
7782
+ });
7741
7783
  MatChipsField.prototype.ngOnInit = function () {
7742
7784
  var _this = this;
7743
7785
  var _a, _b;
@@ -7821,6 +7863,14 @@
7821
7863
  });
7822
7864
  }); };
7823
7865
  }
7866
+ // Send value to suggest when :
7867
+ // - is nil and '*', and no min length threshold
7868
+ // - is not nil and not a string type (e.g. object)
7869
+ // - is not nil and is a string, and has enough character
7870
+ var thresholdFilterFn = function (value) { return (isNilOrBlank(value) || (value === '*')
7871
+ ? (_this.suggestLengthThreshold <= 0)
7872
+ : (!(typeof value === 'string')
7873
+ || value.length >= _this.suggestLengthThreshold)); };
7824
7874
  var filteredItemsChanges = rxjs.merge(
7825
7875
  // Reload event (no distinctUntilChanged() pipe, to force reload even if same value)
7826
7876
  this._reload$, this.inputControl.valueChanges
@@ -7836,39 +7886,23 @@
7836
7886
  ),
7837
7887
  // Object set: use it (no distinctUntilChanged() pipe need)
7838
7888
  this.inputControl.valueChanges
7839
- .pipe(operators.startWith(this.inputControl.value), operators.filter(function (value) { return isNotNil(value) && typeof value === 'object'; }), operators.tap(function (value) {
7840
- // DEBUG
7841
- //console.debug(this.logPrefix + ' object changes:', value)
7842
- // Update the display value (if need)
7843
- var displayValue = _this.displayWith(value) || '';
7844
- // Apply to the input[type=text] field
7845
- if (_this.matInputText && _this.matInputText.nativeElement) {
7846
- _this.matInputText.nativeElement.value = displayValue;
7847
- }
7848
- })
7889
+ .pipe(operators.startWith(this.inputControl.value), operators.filter(function (value) { return isNotNil(value) && typeof value === 'object'; }),
7849
7890
  // DEBUG
7850
- //tap(value => console.debug(this.logPrefix + ' Received an object value: ', value))
7851
- ),
7891
+ operators.tap(function (value) { return _this.debug && console.debug(_this.logPrefix + ' Received an object value: ', value); })),
7892
+ // On dropdown button click (no distinctUntilChanged(), nor debounceTime)
7893
+ this.dropButtonClick
7894
+ .pipe(operators.filter(function (event) { return _this.enabled && (!event || !event.defaultPrevented); }), operators.tap(function (_) { return _this.matInputText.nativeElement.focus(); }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.formControl.value; }),
7895
+ // Make sure there is enough characters
7896
+ operators.filter(thresholdFilterFn)),
7852
7897
  // Merge some observables, with a common distinctUntilChanged() pipe, and NO debounceTime
7853
7898
  rxjs.merge(
7854
7899
  // Focus or click => Load all
7855
7900
  rxjs.merge(this.focused, this.clicked)
7856
- .pipe(operators.filter(function (_) { return _this.enabled; }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.inputControl.value; })),
7857
- // On dropdown button click
7858
- this.dropButtonClick
7859
- .pipe(operators.filter(function (event) { return _this.enabled && (!event || !event.defaultPrevented); }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.inputControl.value; })), rxjs.merge(this.$inputItems, this._$filter)
7901
+ .pipe(operators.filter(function (_) { return _this.enabled; }), operators.map(function (_) { return _this.showAllOnFocus ? '*' : _this.inputControl.value; })), rxjs.merge(this.$inputItems, this._$filter)
7860
7902
  .pipe(operators.filter(function (_) { return _this.enabled; }), operators.map(function (_) { return _this.inputControl.value; })))
7861
7903
  .pipe(
7862
- // Start to suggest when :
7863
- // - '*'
7864
- // - is nil, and there is no min length threshold
7865
- // - is not nil and not a string type (e.g. object)
7866
- // - is not nil and is a string, and has enough character
7867
- operators.filter(function (value) { return value === '*'
7868
- || (isNil(value)
7869
- ? (_this.suggestLengthThreshold <= 0)
7870
- : (!(typeof value === 'string')
7871
- || value.length >= _this.suggestLengthThreshold)); }),
7904
+ // Make sure there is enough characters
7905
+ operators.filter(thresholdFilterFn),
7872
7906
  // Distinguish changes
7873
7907
  operators.distinctUntilChanged()))
7874
7908
  .pipe(
@@ -7907,15 +7941,24 @@
7907
7941
  _this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
7908
7942
  _this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
7909
7943
  _this.checkIfTouched();
7944
+ _this.$filteredItems.next([_this._implicitValue]);
7910
7945
  }
7911
7946
  else if (isNilOrBlank(value)) {
7912
7947
  _this.writeValue(null);
7913
7948
  _this.formControl.markAsPending({ emitEvent: false, onlySelf: true });
7914
7949
  _this.formControl.updateValueAndValidity({ emitEvent: false, onlySelf: true });
7915
7950
  _this.checkIfTouched();
7951
+ _this.$filteredItems.next(undefined);
7916
7952
  }
7917
7953
  _this._implicitValue = null; // reset the implicit value
7918
7954
  }));
7955
+ // Listen form control status change
7956
+ this._subscription.add(this.formControl.statusChanges
7957
+ .pipe(
7958
+ //filter(() => this.enabled),
7959
+ operators.distinctUntilChanged())
7960
+ // Update component state
7961
+ .subscribe(function () { return _this.checkIfTouched(); }));
7919
7962
  this._subscription.add(this.keydownEscape.subscribe(function (event) {
7920
7963
  if (_this.isOpen) {
7921
7964
  event === null || event === void 0 ? void 0 : event.stopPropagation();
@@ -7935,7 +7978,9 @@
7935
7978
  this._openedSubscription.unsubscribe();
7936
7979
  }
7937
7980
  this.$inputItems.complete();
7981
+ this.$inputItems.unsubscribe();
7938
7982
  this.$filteredItems.complete();
7983
+ this.$filteredItems.unsubscribe();
7939
7984
  this._reload$.complete();
7940
7985
  this._$filter.complete();
7941
7986
  this.dropButtonClick.complete();
@@ -7997,12 +8042,18 @@
7997
8042
  this._reload$.next(value || '*');
7998
8043
  };
7999
8044
  MatChipsField.prototype.writeValue = function (value) {
8000
- if (this.debug)
8001
- console.debug(this.logPrefix + ' Writing value: ', value);
8045
+ if (value && !Array.isArray(value)) {
8046
+ value = [value];
8047
+ }
8002
8048
  if (value !== this.formControl.value) {
8049
+ if (this.debug)
8050
+ console.debug(this.logPrefix + ' Writing value: ', value);
8003
8051
  this.formControl.patchValue(value, { emitEvent: false });
8004
8052
  this._onChangeCallback(value);
8005
8053
  }
8054
+ else {
8055
+ this.markForCheck();
8056
+ }
8006
8057
  };
8007
8058
  MatChipsField.prototype.registerOnChange = function (fn) {
8008
8059
  this._onChangeCallback = fn;
@@ -8066,6 +8117,7 @@
8066
8117
  // DEBUG
8067
8118
  if (this.debug)
8068
8119
  console.debug(this.logPrefix + ' Focus in chips list', event);
8120
+ // Ignore event in button
8069
8121
  this.matInputText.nativeElement.focus();
8070
8122
  };
8071
8123
  MatChipsField.prototype.clearValue = function (event) {
@@ -8112,7 +8164,7 @@
8112
8164
  /* -- private method -- */
8113
8165
  MatChipsField.prototype.suggest = function (value, filter) {
8114
8166
  return __awaiter(this, void 0, void 0, function () {
8115
- var res, data, total, filteredData;
8167
+ var res, data, total, fetchMore, filteredData, removedItemCount;
8116
8168
  var _this = this;
8117
8169
  return __generator(this, function (_c) {
8118
8170
  switch (_c.label) {
@@ -8120,7 +8172,7 @@
8120
8172
  case 1:
8121
8173
  res = _c.sent();
8122
8174
  // DEBUG
8123
- // console.debug(this.logPrefix + " Filtered items by suggestFn:", value, res);
8175
+ //console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
8124
8176
  if (!res) {
8125
8177
  this._itemCount = 0;
8126
8178
  res = [];
@@ -8130,13 +8182,16 @@
8130
8182
  this._itemCount = res.length || 0;
8131
8183
  }
8132
8184
  else {
8133
- data = res.data, total = res.total;
8134
- res = data;
8185
+ data = res.data, total = res.total, fetchMore = res.fetchMore;
8135
8186
  this._itemCount = toNumber(total, data && data.length || 0);
8187
+ this._onFetchMoreCallback = fetchMore;
8188
+ this._moreItemsCount = fetchMore && (this._itemCount - data.length) || 0;
8189
+ res = data;
8136
8190
  }
8137
8191
  filteredData = (res || []).slice().filter(function (item1) { return _this.value.findIndex(function (item2) { return _this.equals(item1, item2); }) === -1; });
8138
- // Update items count
8139
- this._itemCount = this._itemCount - (((res === null || res === void 0 ? void 0 : res.length) || 0) - ((filteredData === null || filteredData === void 0 ? void 0 : filteredData.length) || 0));
8192
+ removedItemCount = (((res === null || res === void 0 ? void 0 : res.length) || 0) - ((filteredData === null || filteredData === void 0 ? void 0 : filteredData.length) || 0));
8193
+ // Decrease the item count, with delta
8194
+ this._itemCount -= removedItemCount;
8140
8195
  if (this.debug)
8141
8196
  console.debug(this.logPrefix + ' Filtered items by suggestFn:', value, res);
8142
8197
  return [2 /*return*/, res];
@@ -8175,6 +8230,12 @@
8175
8230
  this._implicitValue = undefined;
8176
8231
  }
8177
8232
  };
8233
+ MatChipsField.prototype.checkIfTouched = function () {
8234
+ if (this.formControl.touched) {
8235
+ this.cd.markForCheck();
8236
+ this._onTouchedCallback();
8237
+ }
8238
+ };
8178
8239
  MatChipsField.prototype.getAutocompletePanel = function () {
8179
8240
  var _a, _b;
8180
8241
  var ele = (_b = (_a = this.autocomplete) === null || _a === void 0 ? void 0 : _a.options.last) === null || _b === void 0 ? void 0 : _b._getHostElement().parentElement;
@@ -8184,12 +8245,6 @@
8184
8245
  }
8185
8246
  return ele;
8186
8247
  };
8187
- MatChipsField.prototype.checkIfTouched = function () {
8188
- if (this.formControl.touched) {
8189
- this.cd.markForCheck();
8190
- this._onTouchedCallback();
8191
- }
8192
- };
8193
8248
  MatChipsField.prototype.markForCheck = function () {
8194
8249
  this.cd.markForCheck();
8195
8250
  };
@@ -8209,16 +8264,15 @@
8209
8264
  { type: i0.Component, args: [{
8210
8265
  // eslint-disable-next-line @angular-eslint/component-selector
8211
8266
  selector: 'mat-chips-field',
8212
- 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",
8213
- providers: [
8214
- {
8267
+ 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",
8268
+ providers: [{
8215
8269
  provide: i1.NG_VALUE_ACCESSOR,
8216
8270
  multi: true,
8217
8271
  useExisting: i0.forwardRef(function () { return MatChipsField; })
8218
- }
8219
- ],
8272
+ }],
8273
+ encapsulation: i0.ViewEncapsulation.None,
8220
8274
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
8221
- 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%}"]
8275
+ 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)}"]
8222
8276
  },] }
8223
8277
  ];
8224
8278
  MatChipsField.ctorParameters = function () { return [
@@ -8252,11 +8306,12 @@
8252
8306
  classList: [{ type: i0.Input, args: ['class',] }],
8253
8307
  panelWidth: [{ type: i0.Input }],
8254
8308
  matAutocompletePosition: [{ type: i0.Input }],
8255
- debug: [{ type: i0.Input }],
8256
8309
  itemSize: [{ type: i0.Input }],
8257
8310
  fetchMoreThreshold: [{ type: i0.Input }],
8258
8311
  suggestLengthThreshold: [{ type: i0.Input }],
8259
8312
  showLoadingSpinner: [{ type: i0.Input }],
8313
+ chipColor: [{ type: i0.Input }],
8314
+ debug: [{ type: i0.Input }],
8260
8315
  clicked: [{ type: i0.Output }],
8261
8316
  blurred: [{ type: i0.Output }],
8262
8317
  focused: [{ type: i0.Output }],
@@ -9046,7 +9101,7 @@
9046
9101
  AppFormField.decorators = [
9047
9102
  { type: i0.Component, args: [{
9048
9103
  selector: 'app-form-field',
9049
- 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",
9104
+ 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",
9050
9105
  providers: [
9051
9106
  {
9052
9107
  provide: i1.NG_VALUE_ACCESSOR,
@@ -18931,7 +18986,7 @@
18931
18986
  function AutocompleteTestPage(formBuilder) {
18932
18987
  this.formBuilder = formBuilder;
18933
18988
  this._items = deepCopy$1(FAKE_ENTITIES$1, 100);
18934
- this.$items = new rxjs.BehaviorSubject(undefined);
18989
+ this._$items = new rxjs.BehaviorSubject(undefined);
18935
18990
  this.autocompleteFields = new MatAutocompleteConfigHolder();
18936
18991
  this.memoryHide = false;
18937
18992
  this.memoryMobile = true;
@@ -18961,7 +19016,7 @@
18961
19016
  });
18962
19017
  // From $items observable
18963
19018
  this.autocompleteFields.add('entity-$items', {
18964
- items: this.$items,
19019
+ items: this._$items,
18965
19020
  attributes: ['label', 'name'],
18966
19021
  displayWith: this.entityToString
18967
19022
  });
@@ -19005,7 +19060,7 @@
19005
19060
  AutocompleteTestPage.prototype.loadItems = function () {
19006
19061
  return __awaiter(this, void 0, void 0, function () {
19007
19062
  return __generator(this, function (_a) {
19008
- this.$items.next(this._items.slice());
19063
+ this._$items.next(this._items.slice());
19009
19064
  return [2 /*return*/];
19010
19065
  });
19011
19066
  });
@@ -19046,7 +19101,7 @@
19046
19101
  AutocompleteTestPage.prototype.doSubmit = function (event) {
19047
19102
  console.debug('Validate form: ', this.form.value);
19048
19103
  };
19049
- AutocompleteTestPage.prototype.compareWithFn = function (o1, o2) {
19104
+ AutocompleteTestPage.prototype.equals = function (o1, o2) {
19050
19105
  return o1 && o2 && o1.id === o2.id;
19051
19106
  };
19052
19107
  AutocompleteTestPage.prototype.toggleMode = function (value) {
@@ -19079,7 +19134,7 @@
19079
19134
  AutocompleteTestPage.decorators = [
19080
19135
  { type: i0.Component, args: [{
19081
19136
  selector: 'app-autocomplete-test',
19082
- 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"
19137
+ 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"
19083
19138
  },] }
19084
19139
  ];
19085
19140
  AutocompleteTestPage.ctorParameters = function () { return [
@@ -19367,15 +19422,30 @@
19367
19422
  var FAKE_ENTITIES = [
19368
19423
  { id: 1, label: 'AAA', name: 'Item A' },
19369
19424
  { id: 2, label: 'BBB', name: 'Item B' },
19370
- { id: 3, label: 'CCC', name: 'Item C' }
19425
+ { id: 3, label: 'CCC', name: 'Item C' },
19426
+ { id: 4, label: 'DDD', name: 'Item D' },
19427
+ { id: 5, label: 'EEE', name: 'Item E' },
19428
+ { id: 6, label: 'FFF', name: 'Item F' },
19429
+ { id: 7, label: 'GGG', name: 'Item G' }
19371
19430
  ];
19372
- function deepCopy(values) {
19373
- return (values || FAKE_ENTITIES).map(function (entity) { return Object.assign({}, entity); });
19431
+ function deepCopy(values, size) {
19432
+ if (isNil(size)) {
19433
+ return (values || FAKE_ENTITIES).map(function (entity) { return Object.assign({}, entity); });
19434
+ }
19435
+ var result = [];
19436
+ var i = 1;
19437
+ while (result.length < size) {
19438
+ result = result.concat((values || FAKE_ENTITIES).map(function (entity) {
19439
+ var name = entity.name + ' #' + i;
19440
+ return Object.assign(Object.assign({}, entity), { id: i++, name: name });
19441
+ }));
19442
+ }
19443
+ return result.slice(0, size);
19374
19444
  }
19375
19445
  var ChipsTestPage = /** @class */ (function () {
19376
19446
  function ChipsTestPage(formBuilder) {
19377
19447
  this.formBuilder = formBuilder;
19378
- this._items = deepCopy(FAKE_ENTITIES);
19448
+ this._items = deepCopy(FAKE_ENTITIES, 100);
19379
19449
  this._$items = new rxjs.BehaviorSubject(undefined);
19380
19450
  this.autocompleteFields = new MatAutocompleteConfigHolder();
19381
19451
  this.form = formBuilder.group({
@@ -19396,12 +19466,12 @@
19396
19466
  });
19397
19467
  // From items
19398
19468
  this.autocompleteFields.add('entity-items', {
19399
- items: FAKE_ENTITIES.slice(),
19469
+ items: this._items.slice(),
19400
19470
  attributes: ['label', 'name'],
19401
19471
  displayWith: this.entityToString,
19402
19472
  equals: function (o1, o2) { return EntityUtils.compare(o1, o2, 1, 'id') === 0; }
19403
19473
  });
19404
- // From items
19474
+ // From $items observable
19405
19475
  this.autocompleteFields.add('entity-$items', {
19406
19476
  items: this._$items,
19407
19477
  attributes: ['label', 'name'],
@@ -19415,15 +19485,18 @@
19415
19485
  // Load the form with data
19416
19486
  ChipsTestPage.prototype.loadData = function () {
19417
19487
  return __awaiter(this, void 0, void 0, function () {
19418
- var data;
19488
+ var items, data;
19489
+ var _this = this;
19419
19490
  return __generator(this, function (_a) {
19491
+ items = deepCopy(FAKE_ENTITIES);
19420
19492
  data = {
19421
- entity: [],
19422
- // THis item is NOT in the items list => i should be displayed anyway
19423
- entityInitial: FAKE_ENTITIES.slice(1, 2),
19424
- disableEntity: FAKE_ENTITIES.slice(1, 2)
19493
+ entity: items.slice(0, 1),
19494
+ entityInitial: items.slice(1, 2),
19495
+ disableEntity: items.slice(1, 2)
19425
19496
  };
19426
19497
  this.form.setValue(data);
19498
+ // Load observables
19499
+ setTimeout(function () { return _this.loadItems(); }, 1000);
19427
19500
  return [2 /*return*/];
19428
19501
  });
19429
19502
  });
@@ -19431,7 +19504,7 @@
19431
19504
  ChipsTestPage.prototype.loadItems = function () {
19432
19505
  return __awaiter(this, void 0, void 0, function () {
19433
19506
  return __generator(this, function (_a) {
19434
- this._$items.next(deepCopy(FAKE_ENTITIES));
19507
+ this._$items.next(this._items.slice());
19435
19508
  return [2 /*return*/];
19436
19509
  });
19437
19510
  });
@@ -19441,15 +19514,38 @@
19441
19514
  };
19442
19515
  ChipsTestPage.prototype.suggest = function (value, filter) {
19443
19516
  return __awaiter(this, void 0, void 0, function () {
19517
+ var res, total, nextOffset;
19518
+ var _this = this;
19444
19519
  return __generator(this, function (_a) {
19445
- return [2 /*return*/, suggestFromArray(this._items, value, Object.assign(Object.assign({}, filter), { searchAttributes: ['label', 'name'] }))];
19520
+ filter = Object.assign({ offset: 0, size: 30 }, filter);
19521
+ res = suggestFromArray(this._items, value, Object.assign(Object.assign({}, filter), { searchAttributes: ['label', 'name'] }));
19522
+ total = res.total || res.data.length;
19523
+ nextOffset = filter.offset + res.data.length;
19524
+ if (nextOffset < total) {
19525
+ filter = Object.assign(Object.assign({}, filter), { offset: nextOffset });
19526
+ return [2 /*return*/, {
19527
+ total: total,
19528
+ data: res.data,
19529
+ fetchMore: function (variables) { return __awaiter(_this, void 0, void 0, function () {
19530
+ return __generator(this, function (_a) {
19531
+ switch (_a.label) {
19532
+ case 0: return [4 /*yield*/, sleep(1000)];
19533
+ case 1:
19534
+ _a.sent();
19535
+ return [2 /*return*/, this.suggest(value, Object.assign(Object.assign({}, filter), variables))];
19536
+ }
19537
+ });
19538
+ }); }
19539
+ }];
19540
+ }
19541
+ return [2 /*return*/, res];
19446
19542
  });
19447
19543
  });
19448
19544
  };
19449
19545
  ChipsTestPage.prototype.doSubmit = function (event) {
19450
19546
  console.debug('Validate form: ', this.form.value);
19451
19547
  };
19452
- ChipsTestPage.prototype.compareWithFn = function (o1, o2) {
19548
+ ChipsTestPage.prototype.equals = function (o1, o2) {
19453
19549
  return o1 && o2 && o1.id === o2.id;
19454
19550
  };
19455
19551
  /* -- protected methods -- */
@@ -19461,7 +19557,7 @@
19461
19557
  ChipsTestPage.decorators = [
19462
19558
  { type: i0.Component, args: [{
19463
19559
  selector: 'app-chips-test',
19464
- 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"
19560
+ 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"
19465
19561
  },] }
19466
19562
  ];
19467
19563
  ChipsTestPage.ctorParameters = function () { return [
@@ -29203,7 +29299,6 @@
29203
29299
  exports.waitForTrue = waitForTrue;
29204
29300
  exports.waitIdle = waitIdle;
29205
29301
  exports.waitWhilePending = waitWhilePending;
29206
- exports["ɵ0"] = ɵ0$5;
29207
29302
  exports["ɵa"] = CustomReuseStrategy;
29208
29303
  exports["ɵb"] = MatNumpadDomService;
29209
29304
  exports["ɵc"] = SharedMatBadgeIconModule;