fixed multiple autocomplete panel behavior

This commit is contained in:
Sofia Papacharalampous 2024-04-29 18:31:50 +03:00
parent 30d338bbbd
commit 7022de0bc8
3 changed files with 64 additions and 70 deletions

View File

@ -21,10 +21,11 @@
<div class="col-12"> <div class="col-12">
<input matInput #autocompleteInput [name]="id" autocomplete="nope" #autocompleteTrigger="matAutocompleteTrigger" autocomplete="off" [placeholder]="placeholder" [matAutocomplete]="autocomplete" [value]="inputValue" (keyup)="onKeyUp($event)" [disabled]="disabled" (focus)="_onInputFocus()" (blur)="onBlur($event)" [matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="autoSelectFirstOptionOnBlur" (matChipInputTokenEnd)="_addItem($event)"> <input matInput #autocompleteInput [name]="id" autocomplete="nope" #autocompleteTrigger="matAutocompleteTrigger" autocomplete="off" [placeholder]="placeholder" [matAutocomplete]="autocomplete" [value]="inputValue" (keyup)="onKeyUp($event)" [disabled]="disabled" (focus)="_onInputFocus()" (blur)="onBlur($event)" [matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="autoSelectFirstOptionOnBlur" (matChipInputTokenEnd)="_addItem($event)">
</div> </div>
<mat-autocomplete #autocomplete="matAutocomplete" [displayWith]="_displayFn.bind(this)" (optionSelected)="_optionSelected($event)"> <mat-autocomplete #autocomplete="matAutocomplete" [displayWith]="_displayFn.bind(this)" (optionSelected)="_optionSelected($event)" [classList]="['myClass']">
<div (mouseover)="isMouseOverPanel=true" (mouseout)="isMouseOverPanel=false">
<span *ngIf="_groupedItems"> <span *ngIf="_groupedItems">
<mat-optgroup *ngFor="let group of _groupedItems | async" [label]="group.title"> <mat-optgroup *ngFor="let group of _groupedItems | async" [label]="group.title">
<mat-option *ngFor="let item of group.items" [value]="item" class="option" [class.two-line-mat-option]="_subtitleFn(item) && !_optionTemplate(item) && !_optionComponent(item)"> <mat-option *ngFor="let item of group.items" [value]="item" class="option" [class.two-line-mat-option]="_subtitleFn(item) && !_optionTemplate(item) && !_optionComponent(item)" (optionActivated)="clickedOnPanel()">
<!-- <img style="vertical-align:middle;" aria-hidden src="{{state.flag}}" height="25" /> --> <!-- <img style="vertical-align:middle;" aria-hidden src="{{state.flag}}" height="25" /> -->
<ng-container *ngIf="_optionComponent(item)"> <ng-container *ngIf="_optionComponent(item)">
<ng-container *ngComponentOutlet="_optionComponent(item); inputs: { item };" /> <ng-container *ngComponentOutlet="_optionComponent(item); inputs: { item };" />
@ -53,7 +54,7 @@
<span *ngIf="!_groupedItems"> <span *ngIf="!_groupedItems">
<div *ngIf="_items | async as autocompleteItems; else loading"> <div *ngIf="_items | async as autocompleteItems; else loading">
<ng-container *ngIf="autocompleteItems.length; else noItems"> <ng-container *ngIf="autocompleteItems.length; else noItems">
<mat-option *ngFor="let item of autocompleteItems" class="option" [value]="item" [class.two-line-mat-option]="_subtitleFn(item) && !_optionTemplate(item) && !_optionComponent(item)"> <mat-option *ngFor="let item of autocompleteItems" class="option" [value]="item" [class.two-line-mat-option]="_subtitleFn(item) && !_optionTemplate(item) && !_optionComponent(item)" (optionActivated)="clickedOnPanel()">
<!-- <img style="vertical-align:middle;" aria-hidden src="{{state.flag}}" height="25" /> --> <!-- <img style="vertical-align:middle;" aria-hidden src="{{state.flag}}" height="25" /> -->
<ng-container *ngIf="_optionComponent(item)"> <ng-container *ngIf="_optionComponent(item)">
<ng-container *ngComponentOutlet="_optionComponent(item); inputs: { item };" /> <ng-container *ngComponentOutlet="_optionComponent(item); inputs: { item };" />
@ -77,6 +78,7 @@
<mat-option disabled="true">loading...</mat-option> <mat-option disabled="true">loading...</mat-option>
</ng-template> </ng-template>
</span> </span>
</div>
</mat-autocomplete> </mat-autocomplete>
</div> </div>
</div> </div>

View File

@ -1,22 +1,6 @@
import { FocusMonitor } from '@angular/cdk/a11y'; import { FocusMonitor } from '@angular/cdk/a11y';
import { ENTER } from '@angular/cdk/keycodes'; import { ENTER } from '@angular/cdk/keycodes';
import { import { Component, DoCheck, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Optional, Output, Self, SimpleChanges, TemplateRef, Type, ViewChild } from '@angular/core';
Component,
DoCheck,
ElementRef,
EventEmitter,
Input,
OnChanges,
OnDestroy,
OnInit,
Optional,
Output,
Self,
SimpleChanges,
TemplateRef,
Type,
ViewChild
} from '@angular/core';
import { ControlValueAccessor, FormGroupDirective, NgControl, NgForm } from '@angular/forms'; import { ControlValueAccessor, FormGroupDirective, NgControl, NgForm } from '@angular/forms';
import { MatAutocomplete, MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete'; import { MatAutocomplete, MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { MatChipInputEvent } from '@angular/material/chips'; import { MatChipInputEvent } from '@angular/material/chips';
@ -27,7 +11,7 @@ import {
MultipleAutoCompleteConfiguration MultipleAutoCompleteConfiguration
} from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { BehaviorSubject, Observable, Subject, interval, of as observableOf, of } from 'rxjs'; import { BehaviorSubject, Observable, Subject, Subscription, interval, of as observableOf, of } from 'rxjs';
import { catchError, debounceTime, delayWhen, distinctUntilChanged, map, mergeMap, startWith, switchMap, take, takeUntil } from 'rxjs/operators'; import { catchError, debounceTime, delayWhen, distinctUntilChanged, map, mergeMap, startWith, switchMap, take, takeUntil } from 'rxjs/operators';
export class CustomComponentBase extends BaseComponent { export class CustomComponentBase extends BaseComponent {
@ -98,6 +82,9 @@ export class MultipleAutoCompleteComponent extends _CustomComponentMixinBase imp
selectable = false; selectable = false;
selected: boolean = false; selected: boolean = false;
isMouseOverPanel: boolean = false;
panelClosedSubscription: Subscription;
get empty() { get empty() {
return (!this.value || this.value.length === 0) && (!this.inputValue || this.inputValue.length === 0); return (!this.value || this.value.length === 0) && (!this.inputValue || this.inputValue.length === 0);
} }
@ -182,9 +169,9 @@ export class MultipleAutoCompleteComponent extends _CustomComponentMixinBase imp
this.focused = !!origin; this.focused = !!origin;
this.stateChanges.next(); this.stateChanges.next();
// if (!this.focused) { if (!this.isMouseOverPanel && !this.focused) {
// this.autocompleteTrigger?.closePanel(); this.autocompleteTrigger?.closePanel();
// } }
}); });
if (this.ngControl != null) { if (this.ngControl != null) {
@ -194,7 +181,11 @@ export class MultipleAutoCompleteComponent extends _CustomComponentMixinBase imp
} }
} }
ngOnInit() { } ngOnInit() {
this.panelClosedSubscription = this.autocomplete.closed.subscribe((next) => {
this.isMouseOverPanel=false;
})
}
ngDoCheck(): void { ngDoCheck(): void {
if (this.ngControl) { if (this.ngControl) {
@ -358,6 +349,7 @@ export class MultipleAutoCompleteComponent extends _CustomComponentMixinBase imp
this.stateChanges.complete(); this.stateChanges.complete();
this.fm.stopMonitoring(this.elRef.nativeElement); this.fm.stopMonitoring(this.elRef.nativeElement);
this.gettingSelectedItem$.complete(); this.gettingSelectedItem$.complete();
this.panelClosedSubscription.unsubscribe();
} }
//Configuration getters //Configuration getters

View File

@ -395,7 +395,7 @@
.stepper-actions { .stepper-actions {
display: flex; display: flex;
padding-left: 1rem; // padding-left: 1rem;
margin-top: auto; margin-top: auto;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
// margin-top: 5rem; // margin-top: 5rem;