Reputation: 2461
I am working with input
s but I am not really sure about how is the configuration of the navigation done (I guess that it are predefined behaviours).
I am not in the last input
the enter key goes to the next one. This one is working as I want.
Nevertheless, when I am on the last input
, when I press enter, it automatically clicks on the next button
.
This is what I am trying to avoid. Is there any way to change this behaviour? Just to close the keyboard or to click on another button
?
I have tried with keyup.enter
and it pseudo works. It calls to the method but also clicks on the next button
HTML
<input
type="text"
class="form-control"
id="validationCustomSurname"
placeholder="e.g. Lopez"
required
(keyup.enter)="onNavigate(1, 'forward')"
[(ngModel)]="values.store.surname"
name="surname"
/>
This method should work on a phone, so I guess that keydown
is not an option since $event.code
does not give me any code in the phone.
Upvotes: 1
Views: 4253
Reputation: 4044
Here's a very simple approach, with just a few lines of code:
First, in your Template
when you dynamically create your Input
elements: 1. populate the tabIndex
attribute with a unique number, 2. populate a super-simple custom "Tag" Directive with the same unique number as the tabIndex
, and 3. set up a Keydown "Enter" event listener:
Template:
<ng-container *ngFor="let row in data">
<input tabindex ="{{row[tabCol]}}" [appTag]="{{row[tabCol]}}" (keydown.enter)="onEnter($event)" . . . />
</ng-container>
In your component
, your super-simple event-listener onEnter()
:
@ViewChildren(TagDirective) ipt!: QueryList<ElementRef>;
onEnter(e: Event) {
this.ipt["_results"][(<HTMLInputElement>e.target).tabIndex%(+this.ipt["_results"].length-1)+1].el.nativeElement.focus();
}
Note: The modulus (%) operation is just to make sure that if you're at the last Input
, you'll get cycled back to the first input.
Super-simple, bare-minimum "Tag" Directive
import { Directive, ElementRef, Input } from '@angular/core';
@Directive({
selector: '[appTag]'
})
export class TagDirective {
@Input('appTag') id: number;
constructor(public el: ElementRef) { }
}
There's probably even a way to get rid of the "Tag" `Directive altogether and make it even more simple, but I haven't had time to figure out how to do that yet . . .
Upvotes: 0
Reputation: 57929
Some time ago I make a directive see stackblitz that you apply in a div (or in a form) in the way
<form [formGroup]="myForm" (submit)="submit(myForm)" enter-tab>
Each input or button add a reference variable #nextTab like
<input name="input1" formControlName="input1" #nextTab/>
<button type="button" #nextTab/>
</form>
The directive use ContentChildren to add a keydown.enter to all the components that have #nextTab to focus to the next control
export class EnterTabDirective {
@ContentChildren("nextTab") controls: QueryList<any>
nextTab
constructor(private renderer: Renderer2, private el: ElementRef) {
}
ngAfterViewInit(): void {
this.controls.changes.subscribe(controls => {
this.createKeydownEnter(controls);
})
if (this.controls.length) {
this.createKeydownEnter(this.controls);
}
}
private createKeydownEnter(querycontrols) {
querycontrols.forEach(c => {
this.renderer.listen(c.nativeElement, 'keydown.enter', (event) => {
if (this.controls.last != c) {
let controls = querycontrols.toArray();
let index = controls.findIndex(d => d == c);
if (index >= 0) {
let nextControl = controls.find((n, i) => n && !n.nativeElement.attributes.disabled && i > index)
if (nextControl) {
nextControl.nativeElement.focus();
event.preventDefault();
}
}
}
})
})
}
Upvotes: 4