Check out a free preview of the full TypeScript and Vue 3 course

The "Autofocus Form Elements" Lesson is part of the full, TypeScript and Vue 3 course featured in this preview video. Here's what you'd learn in this lesson:

Ben demonstrates how to consistently add autofocus to forms by defining a reference to the HTML input element.

Preview
Close

Transcript from the "Autofocus Form Elements" Lesson

[00:00:00]
>> Here's what we wanna try to solve first. When you go to a new form, what do we typically wanna do? We want to autofocus on the first text input, that's fairly common. But the question of course is, how do we do that thing? And so typically what you might do is you might throw an autofocus on the development, that sometimes works, but then we know that with JavaScript loading and stuff, things get a little bit funky.

[00:00:21]
So what we're gonna learn right now is how to actually add autofocus to forms in a way that is consistent and works. What we want is the name to be the first thing that we focus on. And so the thing about reactive references is that they work both in the data context, and they work in the template context.

[00:00:37]
So in other words, if we want an actual HTML element to be a reference, we just tell it what the reference is going to be called. So in this case, I usually like to preface any element that's gonna be an actual element with EL. So this is kind of back to the jQuery days where you might prefix it with a dollar symbol, I just prefer to keep it consistent that way.

[00:00:55]
And then I'll call this NameInput, for example. And the way this works is up here inside of our reactive data though, we do you need to define it though. And how do we define that? Well, we have this element called NameInput, and it's going to be a reactive reference, just like the ref is in the template.

[00:01:11]
But we can actually tell it that it's going to be an HTMLInputElement. Or we can say it's, I think null is the one that's typically an option. Because here's the thing, when JavaScript is loading, this thing does not exist, so it has to be able to be null.

[00:01:26]
However, we do know once it's loaded, it will basically put an input element in there. And so that's why, believe it or not, that's all it takes for this thing to exist. So if I log right now, log, whoops, that was the wrong, elNameInput, save it. So you'll see that if I go to the new page.

[00:01:46]
You'll see that it's already fetching that input automatically. I don't have to go on mounted, check to see if that element exists, assign it to the ref, just it's there, it works. And that's kind of a little bit of the magic sprinkling that Vue does for us by assigning that ref to here.

[00:02:05]
So it looks to map those two things. So that's a key thing to understand. Okay, now that we have this, we can say when everything has been mounted properly, so we'll call our onMounted life cycle hook, there we go. So when you have it mounted, your initial thought is probably going to say, okay, well I have NameInput, and I'm just gonna run focus on it.

[00:02:26]
But as we see here, TypeScript is yelling at us because, again, we've said that it might be null, it might not be defined. So what I tried to do earlier here is I was, okay, well, we can check, right? You typically would say, if it exists, then just run this thing.

[00:02:40]
But it's kind of being finicky because I think it's either the way the HTML element is being populated, like truthy value. So the way this actually works is you actually wanna provide a question mark at it. So we wanna actually unpack the value, cuz don't forget, element name input is a reactive reference.

[00:03:00]
It's still a reactive reference, even though it's referring to a div element. But more importantly this value here, it could be null. So by putting the question mark here, I wanna say this is just vanilla JavaScript. Basically optional chaining, checks to make sure this thing is valid before doing the next thing.

[00:03:18]
Although it makes me wonder now real quick, I wanna test this cuz if elNameInput.value, would that have done it? That works too. So that's the key. So this is where the unwrapping, that's why I say I wanted people to get used to seeing that, is because it's easy to forget this, to be honest.

[00:03:36]
And so I was just like, yeah, it's definitely elName value, no it's .value, this works. But I gotta say, there is something clean about just saying, whenever this thing is available, just use it. So the optional chain here is a pretty nice solution for this. Now, when we refresh the page and go to new, you can see, automatically focused.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now