Vuejs - How to Focus Inputs Posted on January 08, 2016

Setting focus to inputs

I recently had to do this in a project. Searching the web I really didn't find too much about how to do this using simple methods. Every thing that I could find was way over the top and code that didn't need to be there.

I found that there are a ton of ways you can use Vue to set focus to any input that you want. The easiest way is to make your own directive.

What is a directive?

A directive allows you change the way that an element functions. This includes an initialize (when it loads), update (after initialization and any time the value changes) and unbind (clean up).

Now that we know what a directive is, lets take a look at creating one to send focus to an input.

Vue.directive('focus', {
    bind: function () {
        this.el.focus();
    }
});

If we break down this directive you can see we are calling it "focus" and when it is binded to an element, it calls the focus() method on that element.

If we want to use it all we need to do is something like this

<input v-focus type="text">

This is the easiest method, and quite frankly will fit in almost any project.

Now with that being said the one problem that you might run into, is if an input is hidden while Vue is rendering it is unable to apply focus to that element because well, it isn't there. This is where nextTick comes into play.

What is Vue.nextTick?

What nextTick does it is waits one DOM UPDATE CYCLE before firing. So to make things simple, it will wait for whatever process is happening to finish, and then run. So when we are displaying a modal to the user and we need to send focus to that input, we need to wait for our dom to finish updating before we can set focus to that element. If we don't wait the focus will not be set as the user cannot see it.

In these cases we can use this to our advantage. Let's pretend we have a click event that opens a modal called "showDialogBox". All this really does is set the show variable to true.

new Vue({
    el: '#vueApp',
    data: {
        showingDialogBox: false,
    },
    methods: {
        showDialogBox: function() {
            this.showingDialogBox = true;
        }
    }
});

So this means in our code we would have an element setup with a v-show assigned. So something like this

<div v-show="showingDialogBox"
    transition="modal">
    <!-- .. rest of modal code ... -->
</div>

If we were to run this, you would see that this does not work, here is a working example: http://codepen.io/tutelagesystems/pen/XXRqJN

Let's take a look at how to fix this.

The solution

Well remember when we talked about nextTick? Inside our "showDialogBox" call lets add some code.

showDialogBox: function() {
    this.showingDialogBox = true;
    // auto focus
    var object = this.$els.nameInput;
    Vue.nextTick(function() {
        object.focus();
    });
}

The next thing we need to do is if you read the code you will see that I am accessing the input by using this.$els this means we need to add a v-el into our input. Let's change that now

<input v-el:name-Input type="text" />

And we are done. You can read more about v-el and what it does by visiting http://vuejs.org/api/#el

Here you can find a full working copy of what we just tried out: http://codepen.io/tutelagesystems/pen/wMdjBZ

Share this post