Skip to content

Commit

Permalink
NRPT-167: Autocomplete multiselect fixes (#510)
Browse files Browse the repository at this point in the history
* NRPT-167: Autocomplete multiselect fixes

* NRPT-167: CSS override to prevent chips from displaying inline

* NRPT-167: Defaulting autocompletes to useChips = true
  • Loading branch information
dhlevi authored Jul 23, 2020
1 parent ae37cb1 commit c8f9966
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
<mat-chip-list #chipList *ngIf="useChips">
<mat-chip
<div class="mat-chip-list-wrapper-override">
<input
#multiAutocompleteFilter
name="multiAutocompleteFilter"
type="text"
class="form-control multi-box-width"
placeholder="{{ updatedPaceholderText }}"
matInput
(keyup)="filterPicklist($event)"
(keydown)="handleEnter($event)"
[matAutocomplete]="multiAutocomplete"
[matChipInputFor]="chipList"
/>
<mat-chip
*ngFor="let option of options | callback: filterOptions"
[selectable]="true"
[removable]="true"
(removed)="removeChip(option)">
<span class="chip-text-style">{{option.displayValue}}</span>
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input
#multiAutocompleteFilter
name="multiAutocompleteFilter"
type="text"
class="form-control"
placeholder="{{ placeholderText }}"
matInput
(keyup)="filterPicklist($event)"
(keydown)="handleEnter($event)"
[matAutocomplete]="multiAutocomplete"
[matChipInputFor]="chipList"
/>
</div>
</mat-chip-list>
<input *ngIf="!useChips"
#multiAutocompleteFilter
name="multiAutocompleteFilter"
type="text"
class="form-control"
placeholder="{{ placeholderText }}"
placeholder="{{ updatedPaceholderText }}"
matInput
(keyup)="filterPicklist($event)"
(keydown)="handleEnter($event)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@
overflow: hidden;
text-overflow: ellipsis;
}

.mat-chip-list-wrapper-override {
display: block;
width: 100%;
}

.multi-box-width {
width: 100% !important;
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,20 @@ export class AutoCompleteMultiSelectComponent implements OnInit, OnChanges, OnDe

private ngUnsubscribe: Subject<boolean> = new Subject<boolean>();

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();
}

Expand Down Expand Up @@ -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('');
}
}
}

Expand All @@ -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.
*
Expand All @@ -192,6 +221,8 @@ export class AutoCompleteMultiSelectComponent implements OnInit, OnChanges, OnDe

this.setFormControlValue();

this.updatePlaceholderTextValue();

this._changeDetectionRef.detectChanges();
}

Expand Down Expand Up @@ -272,6 +303,7 @@ export class AutoCompleteMultiSelectComponent implements OnInit, OnChanges, OnDe

removeChip(option) {
option.selected = false;
this.setFormControlValue();
}

// for callback pipe filter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(); }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
```

Expand All @@ -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

Expand Down

0 comments on commit c8f9966

Please sign in to comment.