Home > OS >  Form values from custom HTML element input field not displaying when using on-screen keyboard
Form values from custom HTML element input field not displaying when using on-screen keyboard

Time:03-29

I am trying to get values that I type using an on-screen keyboard into a custom HTML element input field to display.

However I am currently getting empty strings. If I use a normal input field then it works fine.

Here is a snippet of my code and a stackblitz example which will have detailed code.

HTML

<form-input
    appOskInput
    [formStatus]="formStatus"
    [parentFormGroup]="setupForm"
    [data]="{
             formControlName: 'email',
             name: 'email'
            }">
</form-input>

<app-keyboard></app-keyboard> 

Keyboard directive

 private onKey(key: string) {
    let element = this.el.nativeElement;
    let inputEl = element.querySelector('input');
    let start = inputEl.selectionStart;
    let end = inputEl.selectionEnd;
    this.measure.textContent = inputEl.value.substr(0, start)   key;
    inputEl.value = inputEl.value.substr(0, start)   key   inputEl.value.substr(end);
    if (this.control)
    this.control.control.setValue(inputEl.value)
    inputEl.focus();
    inputEl.selectionStart = inputEl.selectionEnd = start   1;
    this.updateScrollPosition();
 }

Here is the stackblitz https://stackblitz.com/edit/onscreen-keyboard-hlmkvv?file=src/app/app.component.ts

You will see that the values are displaying when inputted from a normal input field but I can't get the same to happen when using my custom HTML element input field. I have commented out the custom HTML input field in the code on the HTML page. Can anyone help please?

CodePudding user response:

Issue:

You are adding the directive to a custom element & listening the events on the custom element instead of actual input field. Since, you have @HostListener for focus & blur events inside the directive, these events don't fire in case of custom component. Because your custom component doesn't fire focus and blur events. (If we want any custom element to be focusable, we add tabindex=0 to make it focusable in the natural tabbing order of the webpage).

Why it work on native input elements?

Because native input elements emit focus & blur events. Therefore, you are able to see the virtual keyboard when you apply the directive to native input.

Solution:

You need to add event listeners to the native input field inside your custom component. Since, the directive is generic, you can use querySelector() on the nativeElement inside OskInputDirective to access the particular input field.

In OskInputDirective, add focus & blur listeners in ngAfterViewInit:

 ngAfterViewInit(){
    this.inputEl=this.el.nativeElement.querySelector('input');
    this.inputEl?.addEventListener('focus',this.onFocus.bind(this));
    this.inputEl?.addEventListener('blur',this.onBlur.bind(this));
  }

Now, you can use this.inputEl to refer to the input element inside your onKey() method.

Note 1: Here, we are binding the callbacks with the context of OskInputDirective. Else, this will refer to the DOM event.

Note 2: Since we are manually subscribing to the DOM event, Angular won't be able to detect changes & update your FormControl value. You need to emit an event when you change the input value from virtual keyboard.

In onKey(), call event emitter at the end. Now, listen to this event in the parent & update the corresponding form control value:

this.inputChanged.emit(element.value);
    this.updateScrollPosition();

Here is the forked stackblitz with a custom input element created for reference. https://stackblitz.com/edit/onscreen-keyboard-na5kqr?file=src/app/app.component.ts

  • Related