From c8f9966d5d5a28a51f43a4f74e232e538bf0240e Mon Sep 17 00:00:00 2001 From: Dylan Date: Thu, 23 Jul 2020 08:48:03 -0700 Subject: [PATCH] NRPT-167: Autocomplete multiselect fixes (#510) * NRPT-167: Autocomplete multiselect fixes * NRPT-167: CSS override to prevent chips from displaying inline * NRPT-167: Defaulting autocompletes to useChips = true --- .../autocomplete-multi-select.component.html | 30 ++++++----- .../autocomplete-multi-select.component.scss | 9 ++++ .../autocomplete-multi-select.component.ts | 52 +++++++++++++++---- .../search-filter-template/filter-object.ts | 2 +- .../src/app/search-filter-template/readme.md | 4 +- 5 files changed, 70 insertions(+), 27 deletions(-) diff --git a/angular/projects/common/src/app/autocomplete-multi-select/autocomplete-multi-select.component.html b/angular/projects/common/src/app/autocomplete-multi-select/autocomplete-multi-select.component.html index 2714387c2..d32c1a676 100644 --- a/angular/projects/common/src/app/autocomplete-multi-select/autocomplete-multi-select.component.html +++ b/angular/projects/common/src/app/autocomplete-multi-select/autocomplete-multi-select.component.html @@ -1,5 +1,18 @@ - + + {{option.displayValue}} cancel - + = new Subject(); + public updatedPaceholderText = ''; + constructor(public _changeDetectionRef: ChangeDetectorRef) { } ngOnInit() { + this.updatedPaceholderText = this.placeholderText; this.initializeFormControlValue(); if (this.reset) { this.reset.pipe(takeUntil(this.ngUnsubscribe)).subscribe(() => this.resetComponent()); } + this.updatePlaceholderTextValue(); + this._changeDetectionRef.detectChanges(); } @@ -146,17 +151,27 @@ export class AutoCompleteMultiSelectComponent implements OnInit, OnChanges, OnDe // Can't seem to assign the IMultiSelectOption object as the mat-option value, so reconstruct it here to pass on. // This is only a problem when selecting an option using the keyboard (enter). - const option: IMutliSelectOption = { - value: event.target.value, - displayValue: null, - selected: false, - display: true - }; - - // clear the input field, as selected options shouldn't be displayed there - this.multiAutocompleteFilter.nativeElement.value = ''; - this.toggleSelection(option); + // Select the top option as the closest match + // But only handle if it isn't selected, otherwise it will be toggled off? + // ignore the process if the user hits enter without actually typing anything + if (event.target.value.length > 0) { + const topOption = this.getOptionsFromKeywords(event.target.value).find(op => op.display && !op.selected); + + const option: IMutliSelectOption = { + value: topOption.value, + displayValue: null, + selected: false, + display: true + }; + + this.toggleSelection(option); + + // clear the input field, as selected options shouldn't be displayed there + this.multiAutocompleteFilter.nativeElement.value = ''; + // reset the selected options list + this.options = this.getOptionsFromKeywords(''); + } } } @@ -176,9 +191,23 @@ export class AutoCompleteMultiSelectComponent implements OnInit, OnChanges, OnDe this.setFormControlValue(); + this.updatePlaceholderTextValue(); + this._changeDetectionRef.detectChanges(); } + public updatePlaceholderTextValue() { + // update the placeholder text + if (!this.useChips && this.options.filter(op => op.selected).length > 0) { + this.updatedPaceholderText = ''; + for (const displayedOption of this.options.filter(op => op.selected)) { + this.updatedPaceholderText += displayedOption.displayValue + ', '; + } + this.updatedPaceholderText = this.updatedPaceholderText.slice(0, -2); + } else { + this.updatedPaceholderText = this.placeholderText; + } + } /** * Un-selects all options. * @@ -192,6 +221,8 @@ export class AutoCompleteMultiSelectComponent implements OnInit, OnChanges, OnDe this.setFormControlValue(); + this.updatePlaceholderTextValue(); + this._changeDetectionRef.detectChanges(); } @@ -272,6 +303,7 @@ export class AutoCompleteMultiSelectComponent implements OnInit, OnChanges, OnDe removeChip(option) { option.selected = false; + this.setFormControlValue(); } // for callback pipe filter diff --git a/angular/projects/common/src/app/search-filter-template/filter-object.ts b/angular/projects/common/src/app/search-filter-template/filter-object.ts index e4a9cfc6d..1b6bbc8dc 100644 --- a/angular/projects/common/src/app/search-filter-template/filter-object.ts +++ b/angular/projects/common/src/app/search-filter-template/filter-object.ts @@ -193,7 +193,7 @@ export class MultiSelectDefinition extends FilterDefinition { public options: IMutliSelectOption[] = [], public placeholder: string = 'Begin typing to filter', public subtext: string = 'Select all that apply...', - public useChips: boolean = false + public useChips: boolean = true ) { super(); } } diff --git a/angular/projects/common/src/app/search-filter-template/readme.md b/angular/projects/common/src/app/search-filter-template/readme.md index 498fa3494..a1a5f88bc 100644 --- a/angular/projects/common/src/app/search-filter-template/readme.md +++ b/angular/projects/common/src/app/search-filter-template/readme.md @@ -303,7 +303,7 @@ The `CheckOrRadioFilerDefinition` is a coponent that allows you to define a grou options: IMutliSelectOption[] = [], placeholder: string = 'Begin typing to filter', subtext: string = 'Select all that apply...' - useChips: boolean = false; + useChips: boolean = true; } ``` @@ -313,7 +313,7 @@ The `CheckOrRadioFilerDefinition` is a coponent that allows you to define a grou `subtext` is a text string to display beside the title. Defaults to `Select all that apply...`. -`useChips` is a boolean that indicates if the selected options from the multiselect should display as a list of chips above the dropdown component. Defaults to `false` +`useChips` is a boolean that indicates if the selected options from the multiselect should display as a list of chips above the dropdown component. Defaults to `true` ### DropdownDefinition