ShellZero ShellZero - 11 months ago 109
Javascript Question

How to set focus on the elements of the modal as soon as they are opened in Angular 2?

I am a newbie to Angular JS and with the new version of Angular 2 in place, I am facing trouble implementing the directive which can handle the force focus on the modal which is opened on clicking a button.

There are several similar questions which were asked in the past and the answers are in Angular 1 as follows:

function ($timeout) {
return {
link: {
pre: function preLink(scope, element, attr) {
// ...
post: function postLink(scope, element, attr) {
$timeout(function () {
}, 0);


I am trying to convert this same piece of code in Angular 2. But I am not sure how to achieve it. Could anyone point me in the right direction by giving me more information on how to achieve this.


I tried to implement the directive as follows and when I debug the code, I even see that this directive is being called, but I am still unable to get the focus on the elements on the modal dialog:

import { Directive, ElementRef } from "@angular/core";

selector: "[ModFocus]"

export class ModalFocus {

constructor(private _el: ElementRef) {



Am I doing something wrong here? Or do I have to do something else other than just calling focus() on the nativeElement?

HTML Modal:

<div class="modal-dialog modal-sm" tabindex="-1">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Are you sure?</h4>
<div class="modal-body">
<div class="modal-footer ok-cancel" ModFocus>
<button type="button" class="btn btn-default" (click)="cancel()">Cancel</button>
<button type="button" class="btn btn-primary" (click)="delete()" data-dismiss="modal">Delete</button>

Thank you.

Answer Source

When you create a component with Angular 2, you use a different syntax comparing to AngularJS. Your sample code might look like:

import { Component, ElementRef, ViewChild } from "@angular/core";

    selector: "whatever",
    template: `<input #myControl type='input'/>`
export class MyComponent {
    @ViewChild("myControl") myCtrl: ElementRef;

    constructor () {
        // This is wrong. It should be done in ngOnInit not in the
        // constructor as the element might not yet be available.

I was writing this from top of my mind without checking it, but this should give you a pretty good idea about the direction in which you should go.


As you updated the question, here is something that I think is wrong. In your new code you are setting the focus in the constructor. It might be the case that your view is still not generated and therefore the element to which you want to set the focus is still not available (in my previous example I misguided you as I instantiated it in the constructor, when I wanted OnInit. I apologize for that.). I would do the following:

import { Directive, ElementRef, OnInit } from "@angular/core";

    selector: "[ModFocus]"

export class ModalFocus implements OnInit {

    constructor(private _el: ElementRef) {


    ngOnInit(): any {
        // At this point, your element should be available.

OnInit is one of the lifecycle hooks that Angular 2 emits. I would suggest that you go through them to get the better understanding when they are invoked.


The problem is that Directives don't have templates. The act upon the element to which they were added. When a directives is created its constructor looks like:

constructor(private el: ElementRef, private renderer: Renderer) { }

The el should have access to this.el.nativeElement.focus()

Have a look at this article on about Attribute Directives