@tft/crispr-forms 12.2.11 → 12.2.15

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 (36) hide show
  1. package/bundles/tft-crispr-forms.umd.js +57 -50
  2. package/bundles/tft-crispr-forms.umd.js.map +1 -1
  3. package/esm2015/lib/abstracts/autocomplete-field.abstract.js +4 -4
  4. package/esm2015/lib/abstracts/autocomplete-field.abstract.js.map +1 -1
  5. package/esm2015/lib/crispr-forms.module.ngfactory.js.map +1 -1
  6. package/esm2015/lib/form-group-list/form-group-list.component.js +1 -1
  7. package/esm2015/lib/form-group-list/form-group-list.component.js.map +1 -1
  8. package/esm2015/lib/form-group-list/form-group-list.component.metadata.json +1 -1
  9. package/esm2015/lib/form.helpers.js +4 -9
  10. package/esm2015/lib/form.helpers.js.map +1 -1
  11. package/esm2015/lib/form.helpers.metadata.json +1 -1
  12. package/esm2015/lib/material/autocomplete-chiplist-field/autocomplete-chiplist-field.component.js +28 -10
  13. package/esm2015/lib/material/autocomplete-chiplist-field/autocomplete-chiplist-field.component.js.map +1 -1
  14. package/esm2015/lib/material/autocomplete-chiplist-field/autocomplete-chiplist-field.component.metadata.json +1 -1
  15. package/esm2015/lib/material/autocomplete-field/autocomplete-field.component.js +7 -17
  16. package/esm2015/lib/material/autocomplete-field/autocomplete-field.component.js.map +1 -1
  17. package/esm2015/lib/material/autocomplete-field/autocomplete-field.component.metadata.json +1 -1
  18. package/esm2015/lib/material/datepicker-field/datepicker-field.component.js +9 -3
  19. package/esm2015/lib/material/datepicker-field/datepicker-field.component.js.map +1 -1
  20. package/esm2015/lib/material/datepicker-field/datepicker-field.component.metadata.json +1 -1
  21. package/esm2015/lib/material/material.module.ngfactory.js.map +1 -1
  22. package/esm2015/lib/models/autocomplete-chiplist-field.config.js.map +1 -1
  23. package/esm2015/lib/models/datepicker-field.config.js.map +1 -1
  24. package/esm2015/lib/pipes/initial-control-value.pipe.js +2 -2
  25. package/esm2015/lib/pipes/initial-control-value.pipe.js.map +1 -1
  26. package/fesm2015/tft-crispr-forms.js +51 -44
  27. package/fesm2015/tft-crispr-forms.js.map +1 -1
  28. package/lib/form.helpers.d.ts +1 -1
  29. package/lib/material/autocomplete-chiplist-field/autocomplete-chiplist-field.component.d.ts +11 -4
  30. package/lib/material/autocomplete-field/autocomplete-field.component.d.ts +0 -6
  31. package/lib/models/autocomplete-chiplist-field.config.d.ts +9 -1
  32. package/lib/models/datepicker-field.config.d.ts +4 -1
  33. package/package.json +1 -1
  34. package/tft-crispr-forms-12.2.15.tgz +0 -0
  35. package/tft-crispr-forms.metadata.json +1 -1
  36. package/tft-crispr-forms-12.2.11.tgz +0 -0
@@ -4,6 +4,7 @@ import { map, startWith, debounceTime, distinctUntilChanged, switchMap, tap } fr
4
4
  import { Directive, Component, ChangeDetectionStrategy, ViewChild, Optional, Self, Input, EventEmitter, Output, HostListener, NgModule, ComponentFactoryResolver, ViewContainerRef, Renderer2, Pipe } from '@angular/core';
5
5
  import { MatSelectModule } from '@angular/material/select';
6
6
  import { MatAutocompleteTrigger, MatAutocompleteModule } from '@angular/material/autocomplete';
7
+ import { ENTER } from '@angular/cdk/keycodes';
7
8
  import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
8
9
  import { CommonModule } from '@angular/common';
9
10
  import { MatButtonModule } from '@angular/material/button';
@@ -183,7 +184,7 @@ function callOptionsIfFunction(options, parentGroup, searchString) {
183
184
  * @param options the options passed in from the config
184
185
  * @param emptyMessageOption the message to display when the array is empty
185
186
  */
186
- function observablifyOptions(options, parentGroup, searchString, emptyOptionsMessage) {
187
+ function observablifyOptions(options, parentGroup, searchString) {
187
188
  const calledOptions = callOptionsIfFunction(options, parentGroup, searchString);
188
189
  // if options are a promise
189
190
  return calledOptions instanceof Promise
@@ -197,13 +198,8 @@ function observablifyOptions(options, parentGroup, searchString, emptyOptionsMes
197
198
  : isObservable(calledOptions)
198
199
  // return it
199
200
  ? calledOptions
200
- // else return empty option
201
- : of([
202
- {
203
- label: emptyOptionsMessage || DEFAULT_EMPTY_OPTIONS_MESSAGE,
204
- value: null
205
- }
206
- ]);
201
+ // else an empty array
202
+ : of([]);
207
203
  }
208
204
  /**
209
205
  * Determines if the field config is for a form control (not a divider, heading or other non-control field)
@@ -309,9 +305,9 @@ class AbstractAutocompleteComponent extends AbstractAutocompleteFieldMixin {
309
305
  super.ngOnInit();
310
306
  this.group.addControl(this.config.controlName, new FormControl());
311
307
  // filter options by the search string using either the default filter function or one passed in through config
312
- this.options$ = this.autocompleteInputControl.valueChanges.pipe(debounceTime(this.config.typeDebounceTime), distinctUntilChanged(), map(searchText => searchText || ''), switchMap((searchText) => {
313
- return observablifyOptions(this.config.options, this.group, searchText, this.config.emptyOptionsMessage);
314
- }));
308
+ this.options$ = this.autocompleteInputControl.valueChanges.pipe(
309
+ // this is needed to have the options panel to open on focus
310
+ startWith(''), debounceTime(this.config.typeDebounceTime), distinctUntilChanged(), map(searchText => searchText || ''), switchMap((searchText) => observablifyOptions(this.config.options, this.group, searchText)));
315
311
  }
316
312
  }
317
313
  AbstractAutocompleteComponent.decorators = [
@@ -386,7 +382,8 @@ SelectFieldComponent.propDecorators = {
386
382
 
387
383
  const defaultConfig$8 = {
388
384
  autoActiveFirstOption: true,
389
- typeDebounceTime: 500
385
+ typeDebounceTime: 500,
386
+ emptyOptionsMessage: DEFAULT_EMPTY_OPTIONS_MESSAGE
390
387
  };
391
388
  class AutocompleteFieldComponent extends AbstractAutocompleteComponent {
392
389
  constructor() {
@@ -395,13 +392,12 @@ class AutocompleteFieldComponent extends AbstractAutocompleteComponent {
395
392
  }
396
393
  ngOnInit() {
397
394
  super.ngOnInit();
398
- this.setControlValue(this.value);
399
395
  }
400
396
  setControlValue(value) {
401
- if (value && this.control) {
397
+ if (this.control && value) {
402
398
  // sets the initial value on the control if one is passed
403
- this.control.setValue(value.value); // value.value :)
404
- this.autocompleteInputControl.setValue(value.label);
399
+ this.control.setValue(value.value || '');
400
+ this.autocompleteInputControl.setValue(value.label || '');
405
401
  }
406
402
  }
407
403
  /**
@@ -423,22 +419,11 @@ class AutocompleteFieldComponent extends AbstractAutocompleteComponent {
423
419
  this.control.setValue(event.option.value);
424
420
  this.autoInputRef.nativeElement.blur();
425
421
  }
426
- /**
427
- * To follow ARIA standards we want to select the active option on blur.
428
- * We do this by selecting the MatAutoCompleteTrigger, which triggers the select event
429
- * @param event blur event that triggers the handle blur, TODO: remove this parameter if not used by 7/4/19
430
- */
431
- handleTab(_event) {
432
- if (this.autoInput.activeOption) {
433
- this.autoInput.activeOption.select();
434
- this.control.setValue(this.autoInput.activeOption.value);
435
- }
436
- }
437
422
  }
438
423
  AutocompleteFieldComponent.decorators = [
439
424
  { type: Component, args: [{
440
425
  selector: 'crispr-autocomplete-field',
441
- template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matAutocomplete]=\"auto\"\n (keydown.tab)=\"handleTab($event)\"\n role=\"textbox\"\n type=\"textbox\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput>\n\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"displayLabel(options$ | async)\">\n\n <mat-option\n *ngFor=\"let option of options$ | async\"\n [value]=\"option.value\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n\n </mat-autocomplete>\n </mat-form-field>\n</crispr-field-container>\n",
426
+ template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matAutocomplete]=\"auto\"\n role=\"textbox\"\n type=\"textbox\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput>\n\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"displayLabel(options$ | async)\">\n\n <ng-container *ngIf=\"options$ | async as options; else emptyOption\">\n <ng-container *ngIf=\"options.length > 0; else emptyOption\">\n <mat-option\n *ngFor=\"let option of options$ | async\"\n [value]=\"option.value\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n </ng-container>\n\n </ng-container>\n <ng-template #emptyOption>\n <mat-option disabled=\"true\">\n {{config.emptyOptionsMessage}}\n </mat-option>\n </ng-template>\n\n </mat-autocomplete>\n </mat-form-field>\n</crispr-field-container>\n",
442
427
  changeDetection: ChangeDetectionStrategy.OnPush,
443
428
  styles: [""]
444
429
  },] }
@@ -451,11 +436,13 @@ AutocompleteFieldComponent.propDecorators = {
451
436
  const defaultConfig$7 = {
452
437
  chipsSelectable: true,
453
438
  areChipsRemovable: true,
454
- addChipOnBlur: true,
455
- autoActiveFirstOption: true,
439
+ tabToSelect: true,
440
+ autoActiveFirstOption: false,
456
441
  imageUrlParam: 'image',
457
442
  typeDebounceTime: 500,
458
- allowDuplicates: false
443
+ allowDuplicates: false,
444
+ separatorKeyCodes: [ENTER],
445
+ emptyOptionsMessage: DEFAULT_EMPTY_OPTIONS_MESSAGE,
459
446
  };
460
447
  class AutocompleteChiplistFieldComponent extends AbstractAutocompleteComponent {
461
448
  constructor() {
@@ -474,7 +461,7 @@ class AutocompleteChiplistFieldComponent extends AbstractAutocompleteComponent {
474
461
  ]).pipe(map(([chips, options]) => {
475
462
  return this.config.allowDuplicates
476
463
  ? options
477
- : options.filter(option => {
464
+ : options === null || options === void 0 ? void 0 : options.filter(option => {
478
465
  return !chips.some(chip => chip.value === option.value);
479
466
  });
480
467
  }));
@@ -484,20 +471,37 @@ class AutocompleteChiplistFieldComponent extends AbstractAutocompleteComponent {
484
471
  this.chips$.next(value);
485
472
  }
486
473
  }
474
+ // handles mat selecting
487
475
  handleSelect(event) {
488
476
  const selectedOption = event.option.value;
489
477
  this.chips$.next([...this.chips$.value, selectedOption]);
490
478
  this.chipInputRef.nativeElement.value = '';
491
479
  this.autocompleteInputControl.setValue('');
480
+ // setTimeout needed because the panel thinks it's still open at this point
481
+ setTimeout(() => this.chipInput.openPanel());
492
482
  }
493
483
  /**
494
484
  * To follow ARIA standards we want to select the active option on blur.
495
- * @param event blur event that triggers the handle blur, TODO: remove this parameter if not used by 7/4/19
485
+ * matChipInputAddOnBlur should do this but it causes buggy behaviour
486
+ * @param event blur event that triggers the handle blur
496
487
  */
497
488
  handleTab(_event) {
489
+ if (this.chipInput.activeOption && (this.config.tabToSelect || this.config.addChipOnBlur)) {
490
+ const chip = this.chipInput.activeOption.value;
491
+ this.chips$.next([...this.chips$.value, chip]);
492
+ }
493
+ }
494
+ /**
495
+ * Handles selection via key tokens passed through separatorKeyCodes propert
496
+ * NOTE: If TAB is used focus does not move on to next component
497
+ * @param event
498
+ */
499
+ handleTokenEnd(event) {
500
+ var _a;
498
501
  if (this.chipInput.activeOption) {
499
502
  this.chipInput.activeOption.select();
500
503
  }
504
+ (_a = event.chipInput) === null || _a === void 0 ? void 0 : _a.clear();
501
505
  }
502
506
  mapToLabel(option) {
503
507
  return option ? option.label : '';
@@ -506,16 +510,13 @@ class AutocompleteChiplistFieldComponent extends AbstractAutocompleteComponent {
506
510
  const remainingChips = this.chips$.value.filter(chip => chip !== removedChip);
507
511
  this.chips$.next(remainingChips);
508
512
  }
509
- inputFilter(stringToCheck, searchString) {
510
- return stringToCheck.toLowerCase().includes(searchString.trim().toLowerCase());
511
- }
512
513
  }
513
514
  AutocompleteChiplistFieldComponent.decorators = [
514
515
  { type: Component, args: [{
515
516
  selector: 'crispr-autocomplete-chiplist-field',
516
- template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n\n <mat-chip-list\n #chipList>\n <mat-chip\n class=\"refinement-chip\"\n *ngFor=\"let chip of controlValue$ | async\"\n [selectable]=\"config.chipsSelectable\"\n [removable]=\"config.areChipsRemovable\"\n (removed)=\"removeChip(chip)\">\n {{chip.label}}\n <mat-icon\n matChipRemove\n *ngIf=\"config.areChipsRemovable\">\n cancel\n </mat-icon>\n </mat-chip>\n\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n (keydown.tab)=\"handleTab($event)\"\n role=\"textbox\"\n type=\"text\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput/>\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n </mat-chip-list>\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"this.config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"mapToLabel\">\n\n <mat-option\n *ngFor=\"let option of remainingOptions$ | async\"\n [value]=\"option\">\n\n <img\n *ngIf=\"option[config.imageUrlParam]\"\n [src]=\"option[config.imageUrlParam]\"\n style=\"vertical-align:middle;\"\n aria-hidden\n height=\"25\"/>\n {{ option.label }}\n </mat-option>\n </mat-autocomplete>\n\n\n </mat-form-field>\n</crispr-field-container>\n",
517
+ template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n\n <mat-chip-list\n #chipList>\n <mat-chip\n class=\"refinement-chip\"\n *ngFor=\"let chip of controlValue$ | async\"\n [selectable]=\"config.chipsSelectable\"\n [removable]=\"config.areChipsRemovable\"\n (removed)=\"removeChip(chip)\">\n <span *ngIf=\"chip.imageUrl as imageUrl\" class=\"image-container\">\n <img [src]=\"imageUrl\" alt=\"\">\n </span>\n {{chip.label}}\n <mat-icon\n matChipRemove\n *ngIf=\"config.areChipsRemovable\">\n cancel\n </mat-icon>\n </mat-chip>\n\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n (keydown.tab)=\"handleTab($event)\"\n [matChipInputSeparatorKeyCodes]=\"config.separatorKeyCodes\"\n (matChipInputTokenEnd)=\"handleTokenEnd($event)\"\n role=\"searchbox\"\n type=\"text\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput/>\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n </mat-chip-list>\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"this.config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"mapToLabel\">\n <ng-container *ngIf=\"remainingOptions$ | async as remainingOptions; else emptyOption\">\n <ng-container *ngIf=\"remainingOptions.length > 0; else emptyOption\">\n <mat-option\n *ngFor=\"let option of remainingOptions$ | async\"\n [value]=\"option\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n </ng-container>\n\n </ng-container>\n <ng-template #emptyOption>\n <mat-option disabled=\"true\">\n {{config.emptyOptionsMessage}}\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n\n </mat-form-field>\n</crispr-field-container>\n",
517
518
  changeDetection: ChangeDetectionStrategy.OnPush,
518
- styles: [""]
519
+ styles: [".refinement-chip .image-container{width:26px;height:26px;border-radius:50%;overflow:hidden;margin:-2px 4px -2px -8px}.refinement-chip .image-container img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}"]
519
520
  },] }
520
521
  ];
521
522
  AutocompleteChiplistFieldComponent.propDecorators = {
@@ -625,6 +626,12 @@ class DatepickerFieldComponent extends DatepickerFieldMixin {
625
626
  constructor() {
626
627
  super(...arguments);
627
628
  this.defaultConfig = defaultConfig$3;
629
+ // handleSelectedChange(event, picker: MatDatepicker<unknown>) {
630
+ // console.log({event, picker})
631
+ // if(this.config.selectedChange) {
632
+ // this.config.selectedChange(event, picker);
633
+ // }
634
+ // }
628
635
  }
629
636
  ngOnInit() {
630
637
  var _a, _b;
@@ -638,15 +645,15 @@ class DatepickerFieldComponent extends DatepickerFieldMixin {
638
645
  this.dateClass$ = this.config.dateClass ? (_b = this.config) === null || _b === void 0 ? void 0 : _b.dateClass(this.group) : of(() => '');
639
646
  }
640
647
  ngAfterContentInit() {
641
- if (this.config.calendarFooterComponent) {
642
- this.calendarFooterPortal = new ComponentPortal(this.config.calendarFooterComponent);
648
+ if (this.config.datepickerActions) {
649
+ this.calendarFooterPortal = new ComponentPortal(this.config.datepickerActions);
643
650
  }
644
651
  }
645
652
  }
646
653
  DatepickerFieldComponent.decorators = [
647
654
  { type: Component, args: [{
648
655
  selector: 'crispr-datepicker-field',
649
- template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <input\n matInput\n [formControlName]=\"config.controlName\"\n [min]=\"config.min\"\n [max]=\"config.max\"\n [matDatepicker]=\"picker\"\n [matDatepickerFilter]=\"config.datepickerFilter\">\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker\n [touchUi]=\"config.touchUi\"\n [startView]=\"config.startView\"\n [startAt]=\"startAt$ | async\"\n [dateClass]=\"dateClass || (dateClass$ | async)\"\n #picker>\n <mat-datepicker-actions>\n <ng-template [cdkPortalOutlet]=\"calendarFooterPortal\"></ng-template>\n </mat-datepicker-actions>\n </mat-datepicker>\n\n </mat-form-field>\n</crispr-field-container>\n\n",
656
+ template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <input\n matInput\n [formControlName]=\"config.controlName\"\n [min]=\"config.min\"\n [max]=\"config.max\"\n [matDatepicker]=\"picker\"\n [matDatepickerFilter]=\"config.datepickerFilter\">\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker\n [touchUi]=\"config.touchUi\"\n [startView]=\"config.startView\"\n [startAt]=\"startAt$ | async\"\n [dateClass]=\"dateClass || (dateClass$ | async)\"\n #picker>\n <mat-datepicker-actions *ngIf=\"calendarFooterPortal\">\n <ng-template [cdkPortalOutlet]=\"calendarFooterPortal\"></ng-template>\n </mat-datepicker-actions>\n </mat-datepicker>\n\n </mat-form-field>\n</crispr-field-container>\n\n",
650
657
  changeDetection: ChangeDetectionStrategy.OnPush,
651
658
  styles: [""]
652
659
  },] }
@@ -1106,7 +1113,7 @@ class FormGroupListComponent extends FormGroupListMixin {
1106
1113
  FormGroupListComponent.decorators = [
1107
1114
  { type: Component, args: [{
1108
1115
  selector: 'crispr-form-group-list',
1109
- template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [formGroup]=\"group\">\n\n <div [formArrayName]=\"config.controlName\">\n <!-- TODO: add sortBy function -->\n <div *ngFor=\"let control of formArray?.controls; let i = index;\">\n <!-- TODO: use content projection to allow custom item label component -->\n <span class=\"mat-h3\" *ngIf=\"config.itemLabelBuilder\"> {{ config.itemLabelBuilder(i) }} </span>\n <button\n mat-icon-button\n *ngIf=\"i + 1 > config.minListLength\">\n <mat-icon (click)=\"deleteGroup(i)\">delete</mat-icon>\n </button>\n <div\n [formGroupName]=\"i\">\n <ng-container\n *ngFor=\"let field of config.itemConfig.fields;\"\n crisprField\n [config]=\"field\"\n [value]=\"value | initialControlValue : field\"\n [group]=\"control\">\n </ng-container>\n </div>\n </div>\n </div>\n\n <button\n type=\"button\"\n mat-raised-button\n (click)=\"addGroup()\">\n {{config.addItemLabel}}\n </button>\n\n</crispr-field-container>\n",
1116
+ template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [formGroup]=\"group\">\n\n <div [formArrayName]=\"config.controlName\">\n <!-- TODO: add sortBy function -->\n <div *ngFor=\"let control of formArray?.controls; let i = index;\">\n <!-- TODO: use content projection to allow custom item label component -->\n <span class=\"mat-h3\" *ngIf=\"config.itemLabelBuilder\"> {{ config.itemLabelBuilder(i) }} </span>\n <button\n mat-icon-button\n *ngIf=\"i + 1 > config.minListLength\">\n <mat-icon (click)=\"deleteGroup(i)\">delete</mat-icon>\n </button>\n <div\n [formGroupName]=\"i\">\n <ng-container\n *ngFor=\"let field of config.itemConfig.fields;\"\n crisprField\n [config]=\"field\"\n [value]=\"value[i] | initialControlValue : field\"\n [group]=\"control\">\n </ng-container>\n </div>\n </div>\n </div>\n\n <button\n type=\"button\"\n mat-raised-button\n (click)=\"addGroup()\">\n {{config.addItemLabel}}\n </button>\n\n</crispr-field-container>\n",
1110
1117
  changeDetection: ChangeDetectionStrategy.OnPush,
1111
1118
  styles: [""]
1112
1119
  },] }
@@ -1205,8 +1212,8 @@ CrisprFieldDirective.propDecorators = {
1205
1212
  class InitialControlValuePipe {
1206
1213
  // TODO: does changing any to unknown break anything?
1207
1214
  transform(initialFormValue, fieldConfig) {
1208
- return initialFormValue && isControlConfig(fieldConfig) && initialFormValue[fieldConfig.controlName]
1209
- ? initialFormValue[fieldConfig.controlName]
1215
+ return (initialFormValue && isControlConfig(fieldConfig))
1216
+ ? initialFormValue[fieldConfig.controlName] || null
1210
1217
  : null;
1211
1218
  }
1212
1219
  }