in this SO you has a method, in this another SO can serve as "inspiration"
Well, Using the last. the idea is to has a directive that has three variables prev,self and next
@Directive({
selector: "[next-tab]"
})
export class NextTabDirective {
self: any;
next: any;
prev: any;
@HostListener("keydown.arrowup", ["$event"])
onUp(event: KeyboardEvent) {
if (this.prev && this.prev.focus) {
this.prev.focus();
this.prev.select();
event.preventDefault();
return false;
}
}
@HostListener("keydown.arrowdown", ["$event"])
onDown(event: KeyboardEvent) {
if (this.next && this.next.focus) {
this.next.focus();
this.next.select();
event.preventDefault();
return false;
}
}
constructor(private control: ElementRef) {
this.self = control.nativeElement;
}
}
Well, we are going to create a new directive that take account the inner "next-tab"
export class ManageArrowDirective implements AfterViewInit {
@ContentChildren(NextTabDirective) controls: QueryList<NextTabDirective>;
ngAfterViewInit() {
const controls=this.controls.toArray()
controls.forEach((x, index) => {
x.prev = index ? controls[index - 1].self : null;
x.next =
index < controls.length - 1 ? controls[index + 1].self : null;
});
this.controls.changes.subscribe(ctrls => {
const controls=ctrls.toArray();
controls.forEach((x, index) => {
x.prev = index ? controls[index - 1].self : null;
x.next =
index < controls.length - 1 ? controls[index + 1].self : null;
});
});
}
}
You use
<div mannage-arrow>
<input next-tab ...>
<input next-tab ...>
</div>
The directive "NextTabDirective" can be applied to ngControls, so we can control if it's disabled or not
Here we go!
First inject in constructor of our directive the ngControl as public
constructor(private control: ElementRef,@Optional()public ngControl:NgControl) {
this.self = control.nativeElement;
}
And then, implements a few complex directive to take accont can be controls disabled
export class ManageControlDirective implements AfterViewInit {
@ContentChildren(NgControlDirective,{descendants:true}) controls: QueryList<NgControlDirective>;
ngAfterViewInit() {
this.rearrange();
this.controls.changes.subscribe(ctrls => {
this.rearrange(ctrls.toArray())
});
}
rearrange(controls:NgControlDirective[]=null)
{
setTimeout(()=>{
controls=controls||this.controls.toArray()
controls.forEach((x, index) => {
x.prev = this.getPrevControlEnabled(index,controls)
x.next = this.getNextControlEnabled(index,controls)
});
})
}
getPrevControlEnabled(index,controls:NgControlDirective[]){
if (index)
return controls[index-1].ngControl.enabled?controls[index-1].self:this.getPrevControlEnabled(index-1,controls)
return null;
}
getNextControlEnabled(index,controls:NgControlDirective[]){
if (index<controls.length-1)
return controls[index+1].ngControl.enabled?controls[index+1].self:this.getNextControlEnabled(index+1,controls)
return null;
}
}
See a example of both examples in this stackbliz