Building Settings UI Markup0:00
The first thing that I want to implement for the UI is the settings for our game, and I've noticed that I put the div that has our play game button and everything in the wrong spot. That is inside of this div element that's at the top, and we don't want that. We want that afterwards. But I'm going to replace everything anyway, and I'm going to paste in our new markup. And I don't want to type this out on screen because it's boring, and I don't want to bore you more than I already do, so I'm just going to paste it in, and this is what it looks like in the browser, but the text is not the right color. So in the body, I need to add text-white, and refresh, and there we go. So this is going to be the UI.
So in the body, I need to add text white, and refresh, and there we go. So this is going to be the UI. So our game settings are going to be up here, and then whenever we start playing a game, there will be more things added to the bottom of the page here. Notice that we have four fields, one for the title, the min range, max range, and attempts, and then we have two buttons, one to play the game based upon the settings that we input, and then we have a clear button to essentially clear all of the settings and clear the game completely, so that we can start completely over. But we need to talk about the markup here. So the form itself is contained inside of a form element.
Form Structure and IDs1:11
But we need to talk about the markup here. So the form itself is contained inside of a form element. Now, when it comes to working with forms and form controls in JavaScript, you don't actually have to have a form, because if all you are going to do is retrieve information from those elements, there's no need to have an actual form element. But if you want to be semantically correct and things like that, then you would want to put all of your form controls inside of a form. So that is the pattern that I'm following, because in a lot of applications, that's what would be done. Just know that in order to work with input elements, or select elements,
because in a lot of applications, that's what would be done. Just know that in order to work with input elements, or select elements, or any other kind of form control element, you don't have to actually have them inside of a form, because it's just an element. You can use JavaScript to retrieve those elements, work with them, and all of that stuff. But in this case, we have a form, it has an ID, and then each one of these input elements of type text have an ID as well. This is just to make it easier to find these elements and get the values for those elements, that's all it is. And the IDs themselves are arbitrary.
get the values for those elements, that's all it is. And the IDs themselves are arbitrary. I don't really follow a standard, and I probably should, but I wanted to differentiate between what would be considered input and what would be considered output. So all of these fields start with input, and then whatever type of value that we were working with. So title, minRange, maxRange, and maxAttempts. There are two buttons, each of which have a name attribute and an ID attribute. And when it comes to working with JavaScript, the name attribute isn't necessary. However, I wanted to have at least one example of using name attributes,
Reading Input Values2:52
And when it comes to working with JavaScript, the name attribute isn't necessary. However, I wanted to have at least one example of using name attributes, because even though we're not actually submitting this to the server, we can still use name attributes. And that's it, it's just a normal form. But of course, whenever we click on the play button, we want to take that information and we want to create a game based upon that information, so that we can actually play that game. So the first thing we need to do is get the information from the page. And the first thing we need to do is find the element with the ID of input_title.
So the first thing we need to do is get the information from the page. And the first thing we need to do is find the element with the ID of inputTitle. Now, these are input elements, and there are a lot of types when it comes to input elements. There's text, there's password, there's email, there's, well, there's a lot. So the input element itself has basically the same API, regardless of what type that you are working with. So to get the value that was typed into the text box or the input element, we use the value property. So then we just need to get all of the other information, like the min range,
the input element, we use the value property. So then we just need to get all of the other information, like the min range, which once again, we will call getElementById. That was input min range, and then we want to get the value of that input element. Then we have the max range, which we just need to make a couple of changes. And then finally, we have the max attempts, which was input max attempts. So that's going to get the values that were typed into our form fields. But the user could just click on the Play Game button without inputting anything, in which case, I guess we could create a game with some default values,
Validating Required Fields4:30
But the user could just click on the Play Game button without inputting anything, in which case, I guess we could create a game with some default values, but I want the user to have to type this in. So we need to do at least some kind of validation. Now, when there isn't anything typed into a form field, the value is actually an empty string. So we could do this, we could check if the title is an empty string. If minRange is an empty string, and all the others, but empty strings are falsy. So one thing we could do is just say, if not title, or if not minRange,
but empty strings are falsy. So one thing we could do is just say, if not title, or if not minRange, or if not maxRange, or if not maxAttempts, then we need to tell the user, hey, you need to supply all of the settings. So please enter all settings, and then we just return. Because there's nothing else to do, we're just going to exit out of the event handler. So that's going to be fine. Otherwise, we want to create a Game object based upon this information. In which case, we just have to pass in an object that has minRange, maxRange, and maxAttempts.
In which case, we just have to pass in an object that has minRange, maxRange, and maxAttempts. And there we go. So let's go to the browser, let's pull up the developer tools. And yes, there's one other thing that I changed. The ID of our playGame button is now just playGame. It's not playGameButton. So I need to change this when we set up the click event listener. So we are fetching that button, still setting up the click event handler. And then we are getting the information from the form,
So we are fetching that button, still setting up the click event handler. And then we are getting the information from the form, checking if we have information. And if not, we alert a message and then exit out. Otherwise, we create the game and play it. So whenever we refresh, if we click on Play Game, we get a message. Please enter all settings. We'll click OK. But if you'll notice, there was something going on. The form was actually submitted.
But if you'll notice, there was something going on. The form was actually submitted. We'll talk about that here in a moment. But let's go ahead and fill this out. So the title will be My Game, Min Range 1, Max Range 10. And then let's have 5 for our max attempts. We will play the game and we are prompted. Please enter a number between 1 and 10. So we'll do 5. That's too high.
Preventing Form Submission6:51
So we'll do 5. That's too high. I guessed 3. But now notice our form fields are all empty. And if we look at the URL, it was actually submitted. Of course, there's no server that's going to receive this information. But the form was submitted. So of course, this is default behavior for a button. A button by itself isn't going to do anything. You click it, it does nothing.
A button by itself isn't going to do anything. You click it, it does nothing. When you put a button inside of a form, well, then that button is going to submit the form. So the default behavior of a button inside of a form is to submit the form. We don't want to submit the form because there's nothing to submit. There's no server to submit to. This is all a game inside of the browser. So whenever we click on this button element, and really whenever we implement the clear button, we want to say,
So whenever we click on this button element, and really whenever we implement the clear button, we want to say, don't submit the form. Don't do your default behavior. And that's easy enough to do. Because our event object that we briefly talked about in the previous episode, we have a method called preventDefault. That is going to prevent the default behavior of whatever event is occurring. So this is a click event on a button element that is inside of a form. So the default behavior is to submit the form.
So this is a click event on a button element that is inside of a form. So the default behavior is to submit the form. Well, we are telling it to prevent that form from being submitted. And we are doing that at the very first. Because if there were any error that occurred before we call preventDefault, then that form is going to be submitted, and we don't want that. We want to always prevent the form from being submitted. So that's the very first thing I'm going to do here. So now back inside of the browser, let's clear out everything from the URL. Let's do a hard refresh just to make sure everything is loaded.
So now back inside of the browser, let's clear out everything from the URL. Let's do a hard refresh just to make sure everything is loaded. Now, whenever we provide information like MyGame, minRange, maxRange, and attempts, and we play the game, we'll guess five, that's too low, eight. Okay, I got it in two. Again, we can see that the form was not submitted, because for one, our form fields all have the same values that they did before. And then two, the URL definitely doesn't look like that the form was submitted either, so there we go. We've just prevented the form from being submitted, and
Clear Button Handler9:11
either, so there we go. We've just prevented the form from being submitted, and that is the type of behavior that we want. But now I want to implement the code for clearing the game. So let's set up a clickEventListener for the Clear button. I believe the ID was clearGame. Let's just take a look and make sure. Yes, it is clearGame. And then once again, we call addEventListener. We want to handle the clickEvent.
And then once again, we call addEventListener. We want to handle the clickEvent. We need the event object, because the first thing that we are going to do is prevent the default, because once again, this is a button inside of a form. Its default behavior is to submit the form. And now we just want to clear everything. So we still need to fetch all of these elements, because we need to change the value of these elements. So not only can we get the value of an input element, we can also set it. So to reset it, it's just going to be an empty string.
So not only can we get the value of an input element, we can also set it. So to reset it, it's just going to be an empty string. So in each one of these cases, we retrieve the element, we use the value property, and assign it an empty string. That is going to clear those elements. And in our case, we also want to clear the console. Eventually, whenever our UI lets us play the game here inside of the browser instead of the console, we will clear the results that way. But let's refresh. It kept the values in those fields, so we can just click on Clear.
But let's refresh. It kept the values in those fields, so we can just click on Clear. And we can see everything was cleared out. The console was cleared out, because the browser puts in that message that the console was cleared. So we have the basic settings functionality all ready to go. There are, of course, some things that I want to do with it, which we will, of course, look at over the next few episodes. But for right now, this works. But we used two event handlers to do that.
Handling Form Submit Event10:56
But for right now, this works. But we used two event handlers to do that. We are listening for the click event on the PlayGame button, and we are listening for the click event on the Clear button. To be clear, there's nothing wrong with that. It works, it's fine. But there's another way that we could approach this. Instead of using two event handlers, we could use just one. And that would be for our form element. Because whenever a form is being submitted, it fires a submit event,
And that would be for our form element. Because whenever a form is being submitted, it fires a submit event, which gives us the opportunity to do whatever it is that we need to do. So let's look at that approach. The first thing that we need to do is set up an event listener. So we will get the element by ID. It's called settings_form, and we want to call addEventListener. The event is submit, and then we have our function that will handle the event. Now the default behavior of a form that is being submitted is to submit the form.
Now the default behavior of a form that is being submitted is to submit the form. We want to prevent that, so we will call preventDefault. And then from there, we just need to either fetch the information and create the game, or clear all of the information. So what I want to do is this. First of all, let's just retrieve all of the elements that we need. This is going to save us on typing. And eventually, we will get to the point to where we are just going to store these to begin with, and not have to fetch them except for ones.
And eventually, we will get to the point to where we are just going to store these to begin with, and not have to fetch them except for ones. Which is actually the best approach, but we will get there. So I'm going to call these elements titleElement, minRangeElement, maxRangeElement, and then maxAttemptsElement. And then notice that we are just fetching those elements. We are not using the value property. Because then we need to do one of two things. We need to either create the game or clear the game settings. And the only way that we know how to do that is by the button that was clicked.
We need to either create the game or clear the game settings. And the only way that we know how to do that is by the button that was clicked. So we need to reach into our event object, because it has a property called submitter. The submitter is the element object that actually submitted the form. So since we have two buttons inside of a form, both of those buttons can submit the form. Therefore, this is going to let us know which button was used to submit the form. In which case, we need to check the name property. This is where we're gonna use that name attribute.
In which case, we need to check the name property. This is where we're gonna use that name attribute. But we don't have to do that, because we could also use the id property. Every element has an id property, and every form control has a name property. So let's do this as well. Let's just say submitter equals e to get to our event object. We'll use the submitter property, and then we'll get the name, which will give us the name attribute of that submitter. Let's do this, submitter name. That's very clear as to what we're doing.
Let's do this, submitterName. That's very clear as to what we're doing. So then we can check if the submitterName is equal to playGame, then we know that we need to play our game. So in that case, we will retrieve all of our information. We will check the information, and then we will play the game. So let's just copy all of that code. Of course, we will need to make a few changes, because we already have these element objects. So here we'll just say titleElements.value, minRangeElements.value,
because we already have these element objects. So here we'll just say titleElements.value, minRangeElements.value, maxRangeElement.value, and then maxAttemptElement.value. So it's the same functionality and the exact same logic. We're just using these variables now to get to the value. So then we could check else if submitterName is clearGame, but we don't need to do that because there's only one other option. In which case, we want to set the values. So let's just lift that code out. We'll paste that in here, so
So let's just lift that code out. We'll paste that in here, so that then once again, we just need our element variables. So we'll say titleElement.value equals an empty string, minRange.value equals empty string. Then we will do the same thing for the maxRangeElement and the maxAttemptElement. Now that we are handling this submit event, we don't need to handle the click events for our buttons. So we can comment those out.
we don't need to handle the click events for our buttons. So we can comment those out. Ideally, we would remove them, but I'm gonna leave them just for the code download. So that now, inside of the browser, we see an error. document.getElementsById is null. That's on line 139, so settingsForm, not settingsForms. All right, so now we refresh. Our game title is My Game, minRange, 1, max10, 5 attempts. We can play the game, which cleared the game.
Our game title is My Game, minRange, 1, maxRange, 5 attempts. We can play the game, which cleared the game. And that was not what we wanted. And once again, it's because for whatever reason, I'm in a plural mindset. So instead of e.submitter.names, it should be just simply name. So let's try this again. My Game, minRange, maxRange, attempts, play game. And there we go. Five is too low, eight is too low, nine.
And there we go. Five is too low, eight is too low, nine. Let's try to clear the game. That works. And our settings functionality is now mostly ready to go. But we have looked at just one kind of form control. There are many other kinds. And so we will look at those over the next few episodes.
