Check out a free preview of the full Complete Intro to Web Development, v3 course

The "Project JavaScript: Handling Input" Lesson is part of the full, Complete Intro to Web Development, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Brian walks through a possible solution for adding letters, verifying the inputs are letters, verifying guess length, and implementing backspace.


Transcript from the "Project JavaScript: Handling Input" Lesson

>> I'm gonna go grab that little function that I told you we were gonna use, that is letter here. We're just gonna pop that one down here at the bottom somewhere, anywhere will do. And cool, let's go work on addLetter. I think that's a good one to work on first.

Write a function here, we're going to call it addLetter. And addLetter is gonna take in a letter, right? Remember we are passing in the letter that we got from the key press. So there's kind of two different states if we get here, one, we are already guaranteed that this letter is a single character, right, because we checked that here.

If we're in this block, guaranteed, it's a single letter. So I don't have to check again if it's a number, or a letter, or something else, I already know what it is. So there's two different behaviors here that we have to work on. One of them is if I press F right now, what do you expect to happen?

It shows up, right? Well, it will in a second. But for this one, if I press F right, well, if I press F right now, then the F shows up, right? But if I press A right now, what do you expect to happen? The last letter will actually turn into an A, right, it switches the last letter.

So we have to be able to handle that case as well. So if, We have to have some sort of buffer that we're keeping track of, and here, I just called it currentGuess. So I'm gonna call it currentGuess, and this is going to be equal to an empty string to start out with.

And we're gonna say if (currentGuess.length) is less than, and I could say 5 here cuz that's what it is. We call these magic numbers, because it's just a random number that you threw in there, like, why is it 5? What is 5? Sounds like a stoner question, like what even is 5, right?

No, it's the ANSWER_LENGTH, right? It's the max and ANSWER_LENGTH. So I'm gonna create a variable up here called ANSWER_LENGTH. And I'm gonna set that to this, and then I'm gonna copy and paste that here. Now, you can read this, right? Now, it's not magical anymore. You know exactly what it's asking, it's like, have I reached my maximum ANSWER_LENGTH or not?

Now, you might ask me, why is this in what we call screaming case, all capital letters? It's meant to be, this doesn't change, right? This is a constant. So ANSWER_LENGTH doesn't change over time, it's always 5, right? It just represents something that never changes. Okay, so if I have space to give, then I'm just gonna attach it on the end, right?

So I'm gonna say currentGuess += letter, Right, we're just tacking that on to the end of currentGuess. Otherwise, what we're gonna do is we're gonna have to take that substring. Do you remember that substring function that we worked on? We're gonna say, current, Guess, Interesting, okay, is assigned currentGuess.substring.

And we're gonna say, take from 0. And then we're gonna go from 1 from the end, so you're gonna say currentGuess.length -1, right. So one from the end, And then we're just gonna add letter to that, right? So what this is gonna do, this is going to lop off the last letter, and then we're gonna add letter on instead.

So it just does a little replace really quick. Okay, and then now what we gonna do with whatever we just updated, we're going to write that out to the DOM, right? So I have to be able to put the letters here into this. So I'm keeping track of what the word is with currentGuess, but I also need to write it out here so that the user can see what we're trying to do.

So I have letters. And let's just do the first row, and then we'll worry about the subsequent rows. We're gonna do currentGuess.length. Then if you remember, if I have a string that is five characters long, what's the? So, if I say, well, let's just do an example. Const string =, I don't know, BRIAN.

If I say string.length, what does that equal to? 5, right, it's 5 long. Strings are, you can also get the character at them, right? So if I say charAt, which would just give me the character, if I say charAt(0), what's the 0 with character here? B, right, cuz everything starts from 0 in programming.

If I say string.charAt(4), that's the last one, right, cuz it's length -1. So my point being here is we have to do length -1, To get that last one. Okay, that'll give me whatever square I'm trying to look at here. And I'm gonna say, length, I'm sorry, not length, .innerText is assigned letter.

All right, we can get rid of that stuff. All right, so now, let's try and see. Current, and I say const here. You have to say let, cuz I'm reassigning this over and over again. If you try and do const there, it'll break, force a habit. So there you go, very cool, right?

So now, we can type into it. Enter doesn't work, backspace doesn't work. But as long as we're on a fresh new thing, we can say that, right, and that all works. And it even works for you trying to overwrite the last thing. So good so far, any questions on addLetter?

So if this is confusing to you, and you're like, I couldn't read that letter, I'll just go leave comments for myself, add letter to the end, replace the last letter. Like this one, this is a little murky if I was trying to combat this as like, the hell was Brian trying to do with this?

So this is actually somewhere where I might leave myself a comment for future Brians like, hey, this line here replaces the last letter. Comments are super valuable, just get in a good habit of like, hey, this is kind of unclear, I'm gonna leave a comment for myself. Okay, So, Let's do backspace.

No, actually, let's go ahead and do, what happens if they hit Enter? So we're gonna do commit next. I'm gonna make this an async function. I know later, this is gonna be asynchronous cuz we have to go and request it, like, hey, is this a valid word? For now, it's just gonna be sync, but it doesn't really matter.

You can do that later if you want to. So if I type here B-R-I, and then I hit Enter, what would you expect it to do? Nothing, right, it doesn't have a valid guess. They don't have everything entered. So I would just do nothing. So if currentGuess.length is not equal to ANSWER_LENGTH, then do nothing.

And then return, right, cuz we don't wanna do anything else here. This is a condition where you're like, hey, they tried to hit Enter, but they're not ready for it yet, so I'm just gonna do nothing in return. Okay, So this is where we'd go and try and check if they were correct with the word of the day.

We'll get to that eventually. But for now, if they are at the end and let's assume that we validated their word, we're gonna help them move on to the next row, right? So if I have B-R-I-A-N and they hit Enter, here we would check, right, and then make sure we would do all the correct highlighting.

We'll do that in a little bit. We have to get the word of the day first before we can do that. But right now, I just want them to go to the next row, cuz I wanna be able to type all of that. So const, we're gonna have another thing up here, Where we're gonna keep track of what row they're on.

So let currentRow, and they're gonna to start on row 0. And then as soon as they're done with row 0, they're gonna go down to row 1, then row 2, then row 3, then row 4, then row 5, and then they're done. Okay, so we're gonna say currentRow++, increase it by one.

And then we're gonna set their currentGuess to be, again, it's a new row, so their guess is so far blank. Okay, But now, this kinda broke our addLetter function specifically here, right? Cuz we're no longer writing on this line, we have to start writing on this line. So how do we do that?

How do we find the correct box there? Well, we just have to add, for the second row, right, if we were just going to try and write on the second row, if we just did 5+ here, or let's say ANSWER_LENGTH +, and I go here and refresh. If I start typing right now, where is it gonna write?

It's gonna start writing on that one, okay? Cool, or what if I do times 2? Third row, right? So it's just gonna be the current ANSWER_LENGTH x currentGuess, sorry, currentRow rather. So if I refresh this and I say BRIAN, Right, and now as I'm able to go down row by row and type in each one of them, just by doing a little bit of math to make sure to that I'm on the correct row.

Again, no validation's going on here, but kinda incrementally breaking this down into smaller and smaller problems and building this up into overall solution. Questions so far? Okay, cool. Let's do Backspace. Yeah, let's do backspace, that one should be pretty quick. So we are not done, obviously not done with commit, right, we have to do a bunch of stuff in between.

So we'd have to validate the word, make sure that it's an actual word. And then underneath that, we have to do all the marking as correct, Close, or wrong, right, like making things green, or yellow, or gray. And then we also have to do, did they win or lose, right?

That all has to happen here every time that they hit Commit, right? So if they guess the word right, the game's over, you make the game win, right? So this is something that I'll do as well. And actually, I usually mark these with TODO, and so you'll find that's a really common thing to do.

It's basically like you're leaving your cell future TODOs. The reason why I do specifically with this weird formatting is I can search my entire codebase for TODOs, and then it'll show me all the stuff that I forgot to do, right? So that's just a little helpful tip. But now later, let's say I'm working on this over the span of a week, I can now come back a week later and say, okay, here's all the thing that past Brian knew that he needed to do.

So I just context-dump into comments, so that later, I can come back and check them out. So now, I can go work on backspace and know that I'm not gonna lose all the contexts that I have in my brain right now. Okay, function, backspace. So I'm gonna say CurrentGuess, We're basically just gonna do this, right, except not add a letter at the end, literally just copy and paste it.

Right, we're taking one off the end. So what happens if currentGuess is an empty string, right? What happens if I immediately hit Backspace? Nothing happens. If you try and take a substring of an empty string, still just an empty string, right? So I could check to say, does currentLength, or sorry, does currentGuess have any length?

But it's pointless, because no matter what, this will still return an empty string. So I don't have to be super defensive about that. Okay, and then all I have to do here is I say letters. Kinda mimicking this, we can even go as far as to copy and paste most of this as well and just modify it, except the only difference is, It's not gonna be -1, right, cuz we're gonna take the last thing off of it.

So we do the -1 here, right, because we're trying to get the last one. Whereas this one, we actually wanna go one past that once we delete something, and we're going to set that to be equal to empty string, right? So if I refresh this B-R-I-A-N, and I hit Backspace, you just wanna wipe out the last one, right?

So that's why you take out that -1, is cuz it's one past that one. And then there you go. And now, we have fully functioning backspace as well. So that's cool, that one was pretty fast, right? Okay, now what's really great about our approach now is all of the typing portions of this are done, right?

All of the adding new letters, taking away letters, moving to the next line, 100% finished, feel pretty good about it. Now, we can actually work on the game part of it, right? So we can go find out what the word of the day is, we can find out if it's a valid word, we can do all that stuff.

But this is how I chose to break down the problem in my brain, which is, I'm gonna worry about all the user interaction first, and then I'll worry about talking to the backend and all the validation and stuff like that. Works for me, it doesn't necessarily have to work for you.

It's all just kind of stream of consciousness anyway. In general, I just suggest you follow what occurs to you, right? If you wanna work on this thing next, you don't have to necessarily hold back on that, it's just however you work best.

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