fixed single autocomplete panel behavior

This commit is contained in:
Sofia Papacharalampous 2024-04-30 17:43:10 +03:00
parent 49d8df1894
commit e5af155b31
2 changed files with 47 additions and 33 deletions

View File

@ -4,45 +4,47 @@
<input matInput #autocompleteInput class="col-12" [name]="id" autocomplete="nope" #autocompleteTrigger="matAutocompleteTrigger" [placeholder]="placeholder" [matAutocomplete]="autocomplete" [value]="inputValue" (keyup)="onKeyUp($event)" [disabled]="disabled" (focus)="_onInputFocus()" (blur)="onBlur($event)"> -->
<mat-icon *ngIf="!disabled" class="align-arrow-right" matSuffix>arrow_drop_down</mat-icon>
<mat-autocomplete #autocomplete="matAutocomplete" [displayWith]="_displayFn.bind(this)" (optionSelected)="_optionSelected($event)">
<span *ngIf="_groupedItems">
<mat-optgroup *ngFor="let group of _groupedItems | async" [label]="group.title">
<mat-option *ngFor="let item of group.items" [value]="item" [class.two-line-mat-option]="_subtitleFn(item) && !_optionTemplate(item)">
<!-- <img style="vertical-align:middle;" aria-hidden src="{{state.flag}}" height="25" /> -->
<ng-template #cellTemplate *ngIf="_optionTemplate(item)" [ngTemplateOutlet]="_optionTemplate(item)" [ngTemplateOutletContext]="{
item: item
}"></ng-template>
<div *ngIf="!_optionTemplate(item)">
<span class="title-text">{{_titleFn(item)}}</span>
<br *ngIf="_subtitleFn(item)">
<small *ngIf="_subtitleFn(item)" class="subtitle-text">{{_subtitleFn(item)}}</small>
<span *ngIf="popupItemActionIcon" class="option-icon" (click)="_optionActionClick(item, $event)"><mat-icon>{{popupItemActionIcon}}</mat-icon></span>
</div>
</mat-option>
</mat-optgroup>
</span>
<span *ngIf="!_groupedItems">
<div *ngIf="_items | async as autocompleteItems; else loading">
<ng-container *ngIf="autocompleteItems.length; else noItems">
<mat-option *ngFor="let item of autocompleteItems" [value]="item" [class.two-line-mat-option]="_subtitleFn(item) && !_optionTemplate(item)">
<div (mouseover)="isMouseOverPanel=true" (mouseout)="isMouseOverPanel=false">
<span *ngIf="_groupedItems">
<mat-optgroup *ngFor="let group of _groupedItems | async" [label]="group.title">
<mat-option *ngFor="let item of group.items" [value]="item" [class.two-line-mat-option]="_subtitleFn(item) && !_optionTemplate(item)">
<!-- <img style="vertical-align:middle;" aria-hidden src="{{state.flag}}" height="25" /> -->
<ng-template #cellTemplate *ngIf="_optionTemplate(item)" [ngTemplateOutlet]="_optionTemplate(item)" [ngTemplateOutletContext]="{
item: item
}"></ng-template>
item: item
}"></ng-template>
<div *ngIf="!_optionTemplate(item)">
<span *ngIf="!_optionTemplate(item)" class="title-text">{{_titleFn(item)}}</span>
<span class="title-text">{{_titleFn(item)}}</span>
<br *ngIf="_subtitleFn(item)">
<small *ngIf="_subtitleFn(item)" class="subtitle-text">{{_subtitleFn(item)}}</small>
<span *ngIf="popupItemActionIcon" class="option-icon" (click)="_optionActionClick(item, $event)"><mat-icon>{{popupItemActionIcon}}</mat-icon></span>
</div>
</mat-option>
</ng-container>
<ng-template #noItems>
<mat-option disabled="true">No results found!</mat-option>
</mat-optgroup>
</span>
<span *ngIf="!_groupedItems">
<div *ngIf="_items | async as autocompleteItems; else loading">
<ng-container *ngIf="autocompleteItems.length; else noItems">
<mat-option *ngFor="let item of autocompleteItems" [value]="item" [class.two-line-mat-option]="_subtitleFn(item) && !_optionTemplate(item)">
<!-- <img style="vertical-align:middle;" aria-hidden src="{{state.flag}}" height="25" /> -->
<ng-template #cellTemplate *ngIf="_optionTemplate(item)" [ngTemplateOutlet]="_optionTemplate(item)" [ngTemplateOutletContext]="{
item: item
}"></ng-template>
<div *ngIf="!_optionTemplate(item)">
<span *ngIf="!_optionTemplate(item)" class="title-text">{{_titleFn(item)}}</span>
<br *ngIf="_subtitleFn(item)">
<small *ngIf="_subtitleFn(item)" class="subtitle-text">{{_subtitleFn(item)}}</small>
<span *ngIf="popupItemActionIcon" class="option-icon" (click)="_optionActionClick(item, $event)"><mat-icon>{{popupItemActionIcon}}</mat-icon></span>
</div>
</mat-option>
</ng-container>
<ng-template #noItems>
<mat-option disabled="true">No results found!</mat-option>
</ng-template>
</div>
<ng-template #loading>
<mat-option disabled="true">loading...</mat-option>
</ng-template>
</div>
<ng-template #loading>
<mat-option disabled="true">loading...</mat-option>
</ng-template>
</span>
</span>
</div>
</mat-autocomplete>
</div>

View File

@ -8,7 +8,7 @@ import { MatFormFieldControl } from '@angular/material/form-field';
import { AutoCompleteGroup } from '@app/library/auto-complete/auto-complete-group';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { BaseComponent } from '@common/base/base.component';
import { Observable, Subject, of as observableOf, of } from 'rxjs';
import { Observable, Subject, Subscription, of as observableOf, of } from 'rxjs';
import { catchError, debounceTime, distinctUntilChanged, map, mergeMap, startWith, switchMap, takeUntil, tap } from 'rxjs/operators';
@ -31,6 +31,9 @@ export const _CustomComponentMixinBase = mixinErrorState(CustomComponentBase);
})
export class SingleAutoCompleteComponent extends _CustomComponentMixinBase implements OnInit, MatFormFieldControl<string>, ControlValueAccessor, OnDestroy, DoCheck, OnChanges {
isMouseOverPanel: boolean = false;
panelClosedSubscription: Subscription;
static nextId = 0;
@ViewChild('autocomplete', { static: true }) autocomplete: MatAutocomplete;
@ViewChild('autocompleteTrigger', { static: true }) autocompleteTrigger: MatAutocompleteTrigger;
@ -115,6 +118,10 @@ export class SingleAutoCompleteComponent extends _CustomComponentMixinBase imple
fm.monitor(elRef.nativeElement, true).pipe(takeUntil(this._destroyed)).subscribe((origin) => {
this.focused = !!origin;
this.stateChanges.next();
if (!this.isMouseOverPanel && !this.focused) {
this.autocompleteTrigger?.closePanel();
}
});
if (this.ngControl != null) {
@ -124,7 +131,11 @@ export class SingleAutoCompleteComponent extends _CustomComponentMixinBase imple
}
}
ngOnInit() { }
ngOnInit() {
this.panelClosedSubscription = this.autocomplete.closed.subscribe((next) => {
this.isMouseOverPanel = false;
});
}
ngDoCheck(): void {
if (this.ngControl) {
@ -292,6 +303,7 @@ export class SingleAutoCompleteComponent extends _CustomComponentMixinBase imple
}
ngOnDestroy() {
this.panelClosedSubscription.unsubscribe();
this.stateChanges.complete();
this.fm.stopMonitoring(this.elRef.nativeElement);
}