Objective
- I have a form with some input elements (el1, el2 ...)
- el1 might have focus on beginning or not
- when keydown event fires, do the following:
- if none of the input elements have focus, set focus to the first non empty element
- if any of the input elements have focus, check if enter was pressed, if it was move to a next arbitrary element
- in any other case, just let the key do what its intention was
My current code
form.component.html
<form>
<input type="text" class="form-control" id="el1" name="el1"
required focus
[(ngModel)]="el1" #el1
(keydown)="processEl1KeyDown($event)"
>
<input type="text" class="form-control" id="el2" name="el2"
required
[(ngModel)]="el2" #el2
(keydown)="processEl2KeyDown($event)"
>
</form>
form.component.ts
@Component({
selector: 'my-form',
templateUrl: 'app/form.component.html'
})
export class FormComponent {
constructor(private renderer:Renderer) {
}
el1: string;
el2: string
@ViewChild("el1")
el1El: ElementRef;
@ViewChild("el2")
el2El: ElementRef;
@HostListener('document:keydown', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (!this.el1) {
this.setFocus(this.el1El);
} else {
this.setFocus(this.el2El);
}
}
processEl1KeyDown(event: KeyboardEvent) {
event.stopPropagation();
if (event.keyCode == 13) {
this.setFocus(this.el2El);
}
}
processEl2KeyDown(event: KeyboardEvent) {
event.stopPropagation();
if (event.keyCode == 13) {
this.submitForm();
}
}
submitForm() {
console.log("submit form");
}
setFocus(element: ElementRef) {
this.renderer.invokeElementMethod(element.nativeElement, 'focus');
}
}
Questions
- How can I get template variable name of a focused element (eg #el1, #el2) from within FormComponent class?
document.activeElement
returns DOM element. - Can I get Angular2 object from a DOM? something like
ElementRef.create('<div></div>')
- If I want to pass arbitrary string to my
setFocus('el1')
function, how can I build ElementRef from that? I can use@ViewChild
decorator, but I need something which can be defined during runtime? like newViewChild('el1')
- What would be more "Angular2" way of solving my problem? With a BehaviorSubject as mentioned in this answer - Delegation: EventEmitter or Observable in Angular2?
Edit
Maybe questions are not clear enough. To sum up: If I have n input elements (el1, el2 ... eln), how do I know in module which element has focus (maybe via template variable) and then move focus to a different element (via a string, which corresponds to another template variable again). I think I am looking at angular.element equivalent - Get ComponentRef from DOM element, but I believe this might not be the right way.