Check out a free preview of the full Complete Intro to Web Development, v3 course
The "JavaScript Project: Setup & Event Handling" 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 HTML, CSS, and event handling setup solution for the calculator exercise.
Transcript from the "JavaScript Project: Setup & Event Handling" Lesson
[00:00:00]
>> Let's do this together. So this is the JavaScript portion of the course. So I'm gonna assume that you did the HTML and CSS yourself. If not, you can go ahead and check out my, in fact we'll go through maybe a little bit of like some of the highlights of how I chose to do it.
[00:00:18]
But just know that there's a bunch of different correct ways to do this, right? So what I want you to do, is we're gonna go back to my desktop and we can close this one, gonna make a new folder. New folder. We're gonna call this one, calculator. Okay and I'm gonna drag and drop this onto my VS code and I now have this calculator project I'm going to make a new.
[00:00:55]
We'll make this an index.html and I'm just going to grab this directly from here. So just to kind of go over what I did here. We'll make this called style.css. I chose to do this I have the little screen class up here, right, which has the number 0 to start out with.
[00:01:22]
I put it all into like a calc div, you could have called it whatever you wanted. And I put this into rows of buttons. You could have totally done this with grid it would have been very acceptable to do this with grid. I chose to end up doing with flex.
[00:01:36]
That's because I very familiar to flex and I could do flex in my sleep I still have to look up grid every time that I use it. But yeah, this ends up just being rows of buttons. And if you look over here, It's every one of these rows is in a div.
[00:01:54]
And then you can see down here my 0 has a triple class, which makes it span all of that. So, great. Let's make another file here we're gonna call this style.css. And we're gonna grab the CSS here, Paste that all in here, And it's basically what I just told you.
[00:02:26]
I did it in flex in the different rows. And I think it just basically did these widths and I just guessed and checked to make sure that everything was correct. And you can see here, this is flex it's stretch, it's space between. Nothing too surprising here. Awesome, now you and I are going to code calculator.js together.
[00:02:54]
Let me make sure that that is the correct yep calculator.js. So, Let's go over how I would handle this. So again, just looking at our project here. You could attach an individual event listener to every one of these buttons. I would get really sick of that really quickly.
[00:03:23]
But the nice thing about doing it that way is you could say, all right, if someone clicks the 7 button, then run whatever the seventh function is, and you can make every event listener very specific. Honestly, it's a super valid way of doing this. I don't know how many buttons do I have here, 15 or something like that.
[00:03:41]
I don't know, I'm not going to count. But it wouldn't be that many event listeners. Still, at the end of the day, I chose to do this with one event listener and then I just have an event listener that delegates to various other things. So let's go ahead and do it that way.
[00:04:00]
I think the first thing I'm going to do here is I'm going to make a function. It'll be the last function on here, called init. This is just like a personal choice of doing code. I always have a function that inits everything initialized. So this is gonna say document.querySelector.
[00:04:22]
I'm going to pick up .calc-buttons which if you remember correctly is this section here. So I'm gonna add one event listener that listens to all of the buttons up here, which will work because of event bubbling. So .calc-buttons. So with that, I'm going to add an event listener, listen for clicks, and then I'm gonna add a function that takes in the event.
[00:04:53]
And all I'm gonna do is I'm just going to call a buttonClick with event.target.value. Or not even the value but inner text rather. So may let's maybe put that on multiple lines. So just be kind of clear. So I'm gonna find the .calc-buttons. I'm going to add an event listener that every time someone clicks on it, it's just gonna run some function called buttonClick with the innerText, right?
[00:05:34]
And the innerText is gonna be C, or back arrow, or divide, or 9 or 8, right? So it's gonna be the whatever is the text of the event.target. The event.target if you remember, is going to be whatever is the div that was clicked, right? Or in this case, the button All right, because if I remember correctly the way I did this, these are all buttons.
[00:06:00]
They are all buttons. And one of the beneficial things about doing that. It's kind of hard to see but you can see there's like a little blue outline. I can tab through all of these now. That's just the natural things that buttons allow you to do, is they're tapable.
[00:06:17]
This is helpful for people that don't have mice. So it's another accessibility thing that you should use a button here as opposed to something like a div. Okay, so I invented a function here called buttonClick that doesn't exist yet. You'll find that I do this very frequently when I code, is I'll just say like, hey, I'll write this function here called button click, it's gonna do what I want it to do, and then I'll come back later.
[00:06:44]
And I'll code button click. So I'm gonna make a function here called button click, and it's going to take in the innerText here. So, let's see yeah, I think I called it value here. So this will be 8 or 9 or divide or something like that. And then here I'm going to make like a routing function that it's going to either handle the math or handle the number or something like that.
[00:07:16]
Okay, So the first thing I need to figure out, I can handle 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 all the, exactly the same way, right? They're all just numbers. All it does is append to the calculator. And let's actually open this here, so I'm gonna open calculator > index.html.
[00:07:46]
So this is mine. We'll just make this a little bigger, so you can see, and then I'm gonna open my console here to the side. Okay, so let's just make sure it works, right? So I'm gonna say console.log value. Now, if I refresh the page and I click it's now working.
[00:08:09]
One of the dangers of doing init function. So I wrote this function called a init, right? That's supposed to initialize my code. You have to call it, right? This I just created the function and never actually ran. But now if I do this and I refresh the page, I have hi right so that got run here.
[00:08:33]
9, 8, 7, 5, 0, equals, divides, back, all that kind of stuff all works. Okay. Cool, good so far, so we're getting the correct value over here. So, the way I'm mentally parsing this out is I have symbols. So all of these things here are basically along the sides.
[00:09:03]
And I have numbers. And those get handled differently. The symbols have to do something and then the numbers do a different thing. So I think I'm gonna create a function here called function handleNumbers, or number right and we'll put a number here. I'll create another function here called handleSymbol or something like that and this will be a symbol.
[00:09:34]
So I'm gonna do something and I'm gonna check is value a number, so, Let's see how I could do that. There's a couple of ways you could figure out if something is a number or not, but let's talk about the thing called parseInt. If I give it a string, right?
[00:09:56]
With a 5 in it. It'll give me back 5, right? It'll give me back the number 5, as opposed to the string 5, right? Or I don't know if some long number it'll give me back the number. What happens if I give it a string? I get this thing back called NaN, which stands for not a number.
[00:10:18]
I think that makes sense, right? So there is a function called isNaN and is not a number, not a number. That's true is not a number is 5 not a number no 5 is definitely a number, right? So I can kind of combine those two So parseInt which will return me 5, right?
[00:10:47]
Is that not a number, no 5 is a number. Is lol not a number, right? It is not a number, right? So I can take this thought process over here and say if value is not a number, right? Then I know I have a symbol. So I can say handleSymbol with value.
[00:11:15]
Otherwise it's a number. So I can say handleNumber with value. So now let's just make sure that I'm working here console.log number and console.log symbol. So refresh the page here, I can get rid of that. If I press 8 I expect that to say number number if I press C, I expect it to symbol, number, number, number.
[00:11:54]
You can see that every time I press this, this number 3 goes up, right? Symbol, number, symbol, number, symbol. All right, cool. So everything's working the way I expect it I'm now routing different ways based on if it's number or symbol. So that's positive. Let's just go with numbers, right?
[00:12:16]
That's probably what I would do next make sure that the typing of numbers works okay So the next thing I'll do is I have to keep track of what number is up here. Now you could use the DOM as a source of truth and I could query the DOM every single time that's burdensome, I'd rather not do it that way.
[00:12:40]
But I could say like document.screen, so .getelement or document.queryselector.screen, and then get the innerText out of that and then use that every single time. I don't wanna do that. So what I'm going to do is I'm going to create just a variable here. I'm going to call it buffer.
[00:13:00]
You can call it screen. You can call it whatever you want. But key here, I'm going to keep it as a string. And I'll show you why in just a second. Okay, so now I'm gonna ask myself, if I press 8, what do I expect to happen? I expect that 8 is going to replace the 0, right?
[00:13:26]
So it'll be just 8 on the screen. So I'm gonna say here in number I'll delete this and I'll say if buffer triple equals 0. Then buffer is just assigned the number, right? All right, they end up being the same thing. Else so let's say press 8, and then I press 9.
[00:13:58]
What do I expect to happen? I don't expect it to replace it. I expect it to be 89. So it's just going to add to the end. So I'm just gonna do that. I'm gonna say buffer += number. And again, just remember, this is the same as buffer = buffer + number.
[00:14:17]
You can do these with strings in case that wasn't obvious. It's probably not obvious, so that's okay. But this is the exact same thing. Line 15 line 16, do the same thing. I'm just adding number onto the end. Okay, so I'm not rerendering this yet, so the screen's not updating, this buffer is.
[00:14:42]
So let's just console.log that and see what that looks like over time. So, If I refresh this, now, I expect I hit 8, I'll see 8 logged out, I do. If I just hit 5, I expect to see 85 logged out. Now if I press 0, I expect 850.
[00:15:04]
Cool, right? It's doing what I expect it to do. Now I need something that's going to update this over time, right? So I'm going to write a function here called rerender. It's going to be a really dumb function. But now I'll have some ability to make this rerender whenever I want.
[00:15:23]
This is actually going to end up just being a one liner which is totally fine. I'm gonna say screen and I'll go make screen later, .inner text is assigned buffer. Okay, so I have this and then up here at the top, I'm just going to go create that variable, which I'm going to call screen because that's what I called it.
[00:15:48]
Const screen is assigned document.querySelector and I called it .screen I did okay Okay, so now I have screen here I have this function down here called rerender. So now anytime I call rerender, it'll just make buffer and screen be the same thing. You could do this in any number of places, but basically every time that someone clicks the button, you wanna rerender.
[00:16:21]
So I'm just gonna make that happen at the end of, Every time someone interacts with it at the end of buttonClick here. Okay, now I can drop this. That was the console.log here. We don't need that anymore. Refresh, so now if I press 5 actually expect it to see it expressed here.
[00:16:49]
5, 56, 562, 561, awesome, right working the way we expect it to. Very cool, very happy with that. And kind of just by benefit of this logic here, if I keep pressing zero what do I expect to happen? Nothing, right, which is exactly what's happening, correct, right? Because what's happening here?
[00:17:20]
If I press 0, it's asking, hey, if buffer is equal to 0, which it is, didn't replace it and replaces it with 0, right? So next time around, it'll work just the way that we expect it to. So that's works That's called like looking for edge cases, right, like that's something like QA engineers are very good at doing like they'll try everything to make it break.
[00:17:44]
That's a good kind of mindset to get into of like how can I break this, right? How can I throw a wrench into this? Okay, cool we are now done with all of the number parts of this, right? So that's all working the way we expect it to.
[00:18:01]
So now we have to go do the symbol part of this. So we'll go code up the stub that's what I would call this here this handleSymbol right now is a function stub. We're basically saying that here's a function it's gonna work later. But for now we're just going to make a function that kind of holds its place.
[00:18:26]
My thing that I did with stubs is I always put a console.log here so that I know that this stub is being called correctly, right? So, that later if I come back tomorrow and start working on this, I know that if I press this, the stub is just going to log out, hey, you called the stub, right?
[00:18:41]
So, it's kind of like communication with your future self.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops