ngx-material-keyboard / core

Onscreen virtual keyboard for Angular ≥ 5 (https://angular.io/) using Angular Material (https://material.angular.io/).
https://ngx-material-keyboard.github.io/core/
98 stars 120 forks source link

Issue with mat-autocomplete #109

Open dhutaryan opened 3 years ago

dhutaryan commented 3 years ago

Hello,

I use keyboard with mat-autocomplete field. But when I click keyboard buttons, autocomplete options won't appear

ronan-guillamet commented 2 years ago

Hi! Did you find any way to solve this issue ? Have the same...

dhutaryan commented 2 years ago

@ronan-guillamet Hi, I opened autocomplete options manually.

<input
  #autocompleteTrigger="matAutocompleteTrigger"
/>
@ViewChild('autocompleteTrigger')
private autocompleteTrigger: MatAutocompleteTrigger;

So, and then I listened field changes, send request and opened options manually after getting result. Simple example:

this.users$ = this.checkInForm.get('name').valueChanges.pipe(
  switchMap((name) => {
    return this.usersService.search({ name }).pipe(
        tap(() => { this.autocompleteTrigger.openPanel(); }),
    );
  }),
);
seco-plr commented 2 years ago

Currently, I solved it by calling stopPropagation on the click event of the keyboard. The following code is a custom version of the MatKeyboardService which you can add as provider, replacing the original one:

@Injectable()
export class CustomKeyboardService extends MatKeyboardService {

  public override openFromComponent(layoutOrLocale: string, config: MatKeyboardConfig): MatKeyboardRef<MatKeyboardComponent> {
    const keyboardRef = super.openFromComponent(layoutOrLocale, config);
    this.setClickEventPropagation(true);
    const dismissFunction = keyboardRef.dismiss.bind(keyboardRef);
    keyboardRef.dismiss = () => {
      this.setClickEventPropagation(false);
      dismissFunction();
    }
    return keyboardRef;
  }

  private setClickEventPropagation(enabled: boolean): void {
    const action = (element: Element) => (enabled ? Element.prototype.addEventListener : Element.prototype.removeEventListener)
      .call(element, 'click', Function.prototype.apply.bind(Event.prototype.stopPropagation));
    Array.from(document.getElementsByClassName('mat-keyboard-wrapper'))
      .forEach(action);
  }
}

You might want to track the input-event of the input field. This service will not open the autocomplete popup if you're starting from an empty input field.