Merge pull request #5684 from tsiegleauq/vscroll-selection-bugs
Fix a bug where vscroll select lists lost content
This commit is contained in:
commit
22f9108b49
@ -3,7 +3,17 @@
|
|||||||
[multiple]="multiple"
|
[multiple]="multiple"
|
||||||
[panelClass]="{ 'os-search-value-selector': multiple }"
|
[panelClass]="{ 'os-search-value-selector': multiple }"
|
||||||
[errorStateMatcher]="errorStateMatcher"
|
[errorStateMatcher]="errorStateMatcher"
|
||||||
|
(openedChange)="openSelect($event)"
|
||||||
>
|
>
|
||||||
|
<!-- Custom display of selected items -->
|
||||||
|
<mat-select-trigger>
|
||||||
|
<ng-container *ngIf="selectedItems?.length">
|
||||||
|
<span *ngFor="let item of selectedItems; let i = index">
|
||||||
|
{{ item.getTitle() | translate }}<span *ngIf="i < selectedItems.length - 1">, </span>
|
||||||
|
</span>
|
||||||
|
</ng-container>
|
||||||
|
</mat-select-trigger>
|
||||||
|
|
||||||
<mat-option>
|
<mat-option>
|
||||||
<ngx-mat-select-search [formControl]="searchValue"></ngx-mat-select-search>
|
<ngx-mat-select-search [formControl]="searchValue"></ngx-mat-select-search>
|
||||||
</mat-option>
|
</mat-option>
|
||||||
@ -14,7 +24,7 @@
|
|||||||
<mat-chip
|
<mat-chip
|
||||||
*ngFor="let item of selectedItems"
|
*ngFor="let item of selectedItems"
|
||||||
[removable]="true"
|
[removable]="true"
|
||||||
(removed)="removeItem(item.id)"
|
(removed)="removeChipItem(item)"
|
||||||
[disableRipple]="true"
|
[disableRipple]="true"
|
||||||
>
|
>
|
||||||
{{ item.getTitle() | translate }}
|
{{ item.getTitle() | translate }}
|
||||||
@ -36,8 +46,12 @@
|
|||||||
</mat-option>
|
</mat-option>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<cdk-virtual-scroll-viewport class="vscroll-viewport" minBufferPx="200" maxBufferPx="300" [itemSize]="50">
|
<cdk-virtual-scroll-viewport class="vscroll-viewport" minBufferPx="400" maxBufferPx="600" [itemSize]="50">
|
||||||
<mat-option *cdkVirtualFor="let selectedItem of getFilteredItems()" [value]="selectedItem.id">
|
<mat-option
|
||||||
|
*cdkVirtualFor="let selectedItem of getFilteredItems()"
|
||||||
|
[value]="selectedItem.id"
|
||||||
|
(onSelectionChange)="onSelectionChange($event)"
|
||||||
|
>
|
||||||
{{ selectedItem.getTitle() | translate }}
|
{{ selectedItem.getTitle() | translate }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</cdk-virtual-scroll-viewport>
|
</cdk-virtual-scroll-viewport>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { FocusMonitor } from '@angular/cdk/a11y';
|
import { FocusMonitor } from '@angular/cdk/a11y';
|
||||||
|
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
@ -12,6 +13,7 @@ import {
|
|||||||
ViewEncapsulation
|
ViewEncapsulation
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { FormBuilder, FormControl, NgControl } from '@angular/forms';
|
import { FormBuilder, FormControl, NgControl } from '@angular/forms';
|
||||||
|
import { MatOptionSelectionChange } from '@angular/material/core';
|
||||||
import { MatFormFieldControl } from '@angular/material/form-field';
|
import { MatFormFieldControl } from '@angular/material/form-field';
|
||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
@ -19,6 +21,7 @@ import { Observable } from 'rxjs';
|
|||||||
import { auditTime } from 'rxjs/operators';
|
import { auditTime } from 'rxjs/operators';
|
||||||
|
|
||||||
import { BaseFormControlComponentDirective } from 'app/shared/models/base/base-form-control';
|
import { BaseFormControlComponentDirective } from 'app/shared/models/base/base-form-control';
|
||||||
|
import { Identifiable } from 'app/shared/models/base/identifiable';
|
||||||
import { ParentErrorStateMatcher } from 'app/shared/parent-error-state-matcher';
|
import { ParentErrorStateMatcher } from 'app/shared/parent-error-state-matcher';
|
||||||
import { Selectable } from '../selectable';
|
import { Selectable } from '../selectable';
|
||||||
|
|
||||||
@ -55,6 +58,9 @@ export class SearchValueSelectorComponent extends BaseFormControlComponentDirect
|
|||||||
@ViewChild('chipPlaceholder', { static: false })
|
@ViewChild('chipPlaceholder', { static: false })
|
||||||
public chipPlaceholder: ElementRef<HTMLElement>;
|
public chipPlaceholder: ElementRef<HTMLElement>;
|
||||||
|
|
||||||
|
@ViewChild(CdkVirtualScrollViewport, { static: true })
|
||||||
|
public cdkVirtualScrollViewPort: CdkVirtualScrollViewport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decide if this should be a single or multi-select-field
|
* Decide if this should be a single or multi-select-field
|
||||||
*/
|
*/
|
||||||
@ -134,6 +140,8 @@ export class SearchValueSelectorComponent extends BaseFormControlComponentDirect
|
|||||||
*/
|
*/
|
||||||
private selectableItems: Selectable[];
|
private selectableItems: Selectable[];
|
||||||
|
|
||||||
|
public selectedIds: number[] = [];
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
protected translate: TranslateService,
|
protected translate: TranslateService,
|
||||||
formBuilder: FormBuilder,
|
formBuilder: FormBuilder,
|
||||||
@ -144,6 +152,13 @@ export class SearchValueSelectorComponent extends BaseFormControlComponentDirect
|
|||||||
super(formBuilder, focusMonitor, element, ngControl);
|
super(formBuilder, focusMonitor, element, ngControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public openSelect(event: boolean): void {
|
||||||
|
if (event) {
|
||||||
|
this.cdkVirtualScrollViewPort.scrollToIndex(0);
|
||||||
|
this.cdkVirtualScrollViewPort.checkViewportSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to get a list filtered by the entered search value.
|
* Function to get a list filtered by the entered search value.
|
||||||
*
|
*
|
||||||
@ -167,15 +182,30 @@ export class SearchValueSelectorComponent extends BaseFormControlComponentDirect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeItem(itemId: number): void {
|
public removeChipItem(item: Selectable): void {
|
||||||
const items = <number[]>this.contentForm.value;
|
this.addRemoveId(item.id);
|
||||||
items.splice(
|
|
||||||
items.findIndex(item => item === itemId),
|
|
||||||
1
|
|
||||||
);
|
|
||||||
this.contentForm.setValue(items);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private addRemoveId(item: number): void {
|
||||||
|
const idx = this.selectedIds.indexOf(item);
|
||||||
|
if (idx > -1) {
|
||||||
|
this.selectedIds.splice(idx, 1);
|
||||||
|
} else {
|
||||||
|
this.selectedIds.push(item);
|
||||||
|
}
|
||||||
|
this.contentForm.setValue(this.selectedIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public onSelectionChange(change: MatOptionSelectionChange): void {
|
||||||
|
if (change.isUserInput) {
|
||||||
|
const value = change.source.value;
|
||||||
|
this.addRemoveId(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Satisfy parent
|
||||||
|
*/
|
||||||
public onContainerClick(event: MouseEvent): void {
|
public onContainerClick(event: MouseEvent): void {
|
||||||
if ((event.target as Element).tagName.toLowerCase() !== 'select') {
|
if ((event.target as Element).tagName.toLowerCase() !== 'select') {
|
||||||
// this.element.nativeElement.querySelector('select').focus();
|
// this.element.nativeElement.querySelector('select').focus();
|
||||||
@ -197,5 +227,16 @@ export class SearchValueSelectorComponent extends BaseFormControlComponentDirect
|
|||||||
|
|
||||||
protected updateForm(value: Selectable[] | null): void {
|
protected updateForm(value: Selectable[] | null): void {
|
||||||
this.contentForm.setValue(value);
|
this.contentForm.setValue(value);
|
||||||
|
if (value?.length) {
|
||||||
|
/**
|
||||||
|
* Hack:
|
||||||
|
* for loaded or preselected form, add existing values to selected IDs.
|
||||||
|
* These are usually always numbers,
|
||||||
|
* Would be easier to absolutely always use Selectable and never use IDs,
|
||||||
|
* Could save some work, but every second form has to change for that.
|
||||||
|
* -> os4 todo
|
||||||
|
*/
|
||||||
|
this.selectedIds = value as any;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user