Style Select and Hide0:03
I want to change our UI just a little bit so that instead of having these input elements for the game parameters, what I want to do is temporarily hide them. Because yes, we will want to use them at some point in time, but for right now I want to look at the select element. So let's start by giving it some of the same CSS as the other form fields. So we'll have the width of 40 and then bg-gray-900. And even though the name is arbitrary, because once again we're not submitting this to a server,
And even though the name is arbitrary, because once again we're not submitting this to a server, we're just doing everything in JavaScript. The name really doesn't need to be used here, but we have it. I'm gonna go ahead and use it and I'll use the same value for the id. So the idea here is that instead of having all of these precise values for midrange, maxRange, and maxAttempts, what we'll do is have three options to
Add Difficulty Options0:49
of these precise values for midrange max range and Max attempts, what we'll do is have three options to where we'll have an easy game and then we will have a medium game and then a hard game. And one of the great things about this particular approach is that if we wanted to add more modes or more levels, we could very easily do that. We just have to add another option and then we'd be good to go. So we end up with this single select element.
Select Element in JS1:13
and then we'd be good to go. So we end up with this single select element. Let's make sure that it looks okay in the browser. It does. So then we just need to go back to our JavaScript and work with that element. So right here inside of our submit event listener, we are retrieving the input elements and we still want to do that because we are still going to use those later. But for right now, let's have gameLevelElement and we want to get that element by id.
But for right now, let's have gameLevel element and we want to get that element by id. The idea was simply gameLevel and that will get our select element. Now if you plan on using just pure DOM, then you're going to find yourself repeating a lot. Just like here where we have retrieved five elements from the document we call document.getElementById five times. That's a lot of typing. And the DOM is,
dot Get element by ID five times. That's a lot of typing. And the DOM is, I'm gonna say verbose. There is a lot of typing when it comes to working with the DOM. So you're gonna be tempted to make your life a little bit easier by, you know, writing some helper functions or making your own API that kind of wraps around the DOM API, in which case
Create DOM Helper2:19
or making your own API that kind of wraps around the DOM API, in which case I wholeheartedly support you in doing that. So what we can do here to make our lives just a little bit easier is to write a function to get an element. We could call it getElement or getL, or we could just say getBy and then we could pass in a CSS selector so that then we will return document.querySelector, pass in
and then we could pass in a CSS selector so that then we will return document.querySelector, pass in that CSS selector and that will get our element. Now I know that so far I have said if you have an id, that is the quickest way to get the element to use document.getElementById. I get it. But when it starts to be something that you do regularly to retrieve elements, the trade off isn't going to be that our code is going to be very slow by not using that, it's not,
the the trade off isn't going to be that our code is going to be very slow By not using that, it's not, it's still gonna be fast. And the, the more I'm retrieving elements from the DOM, the more I want an easy way to do that. And by using getBy that gives us the opportunity to retrieve an element with one function using one approach. And that would be CSS selectors. So let's change this so that we use the ID CSS selector here and that's going to be okay so
So let's change this so that we use the ID CSS selector here and that's going to be okay so that then we have this game level element. Um, let's see submitterName playGame here though we want to bypass this because this is where we are checking if we have a title, a midRange, a maxRange, and all of that stuff. We don't have that because we are using that select element. So let's comment out this check here. And now we just want
Read Selected Value4:01
So let's comment out this check here. And now we just want to get the value from our select element. So we have that gameLevel element and it has a value property which is going to return the value of the selected option. So if we select medium, then the value property is going to have this medium value. So if we wanted to simply alert that, then of course instead of the browser, whenever we select easy
So if we wanted to simply alert that, then of course instead of the browser, whenever we select easy and we click play game, we see easy. If we select hard, we see the value of the hard option, which is hard. And this is perfectly fine. This means that now inside of our JavaScript we would have to take, you know, those primitive values, the easy, medium and hard, and then essentially create a game based upon those values.
Store Settings in Data4:46
and hard, and then essentially create a game based upon those values. Or we could do something like this to where the values are part of the HTML itself because we can have custom attributes, they just have to begin with data-. And then, you know, in this case we can have data-min-range, which would be one. Then we could have data-max-range, which could be 10. And then we could have data-attempts, which would be what,
Then we could have dataDashMaxRange, which could be 10. And then we could have dataAttempts, which would be what, 10 because that would be a very easy game. And then we could just take these attributes and then paste them in the other options, just making a few changes. So for a medium game, we can say that it would be from 1 to 20 with 7 attempts, and then the hard game will be 1 to 100 with uh, 5 attempts.
and then the hard game will be one to 100 with uh, five attempts. So this gives us a lot more flexibility because now if we want to change any of the game parameters, then we can do that inside of the HTML. We won't have to dig into our JavaScript to make any changes whatsoever. So in a way, we are using our HTML as a data store, which is perfectly acceptable. But of course the value property isn't going to help us
Get Selected Option5:50
which is perfectly acceptable. But of course the value property isn't going to help us because that just gives us the value of the option. Instead, we need the option element object itself, which we can get in a couple of different ways. The select element has a property called selectedIndex. This is going to return the index of the option that is selected. So the options are in, well, just like any other collection in JavaScript,
So the options are in, well, just like any other collection in JavaScript, they begin at the index of zero. So if we select Easy, then the index is gonna be zero. If we select Medium, it will be one. If we select Hard, it will be two. So this means that we could use this selected index to get the selected option so that we would still need our gameLevel element. But it has a property called options, which is a collection.
that we would still need our game level element. But it has a property called Options, which is a collection of all of the options in that element. So then we can get it at the selected index. And that gives us our option so that then all we need to do is get the minRange, the maxRange, and all of that other stuff, which we have those variables here. Uh, I'm just gonna leave this code here and then we'll change the values here.
Read Data Attributes7:02
Uh, I'm just gonna leave this code here and then we'll change the values here. So we want our minRange to come from the selected option, but we need to get the value of that data-min-range attribute. We can do that in a couple of different ways. The first is to use a method called getAttribute as the name implies this gets the attribute of an element. So we just pass in the attribute name, which was data-min-range,
So we just pass in the attribute name, which was dataMinRange, and that will return the value of that attribute. And this works for any attribute, it's not just for the data attributes. So if you want to get the value of any attribute, you can use the getAttribute method. But since this is a data attribute, we have a different API that we can use, like to get the maxRange, we still need our selected option,
that we can use, like to get the Max range, we still need our selected option, but then we have a property called dataset. This dataset essentially maps all of the data attributes into this single property so that then all we need to do is reference the attribute name, but in camelCase, so of course our attribute names use dashes. So data-min-range would be minRange.
So data-dash-min-range would be min-range. The data-dash-max-range would be simply max-range. And then of course we have max-attempts, which we could then get the selected option data-set. And I think I just called it attempts. So we essentially have two ways to get to the value of a data attribute. We can use the getAttribute method, which works just fine, or we could use the data-set property.
We can use the getAttribute method, which works just fine, or we could use the data set property and then we can get the value of whatever data attribute that we need. And so now that we have all of that necessary information, we can create our game and play it. So let's go back to the browser. Let's refresh, let's select an easy game. We'll play it and we get an error SelectionOption is not defined and that's because yeah, I mistyped that.
We'll play it and we get an error selection option is not defined and that's because yeah, I mistyped that. So we'll go back now, we should be able to play and please enter a number between 1 and 10. We could play this, but let's not, let's uh, select hard and play the game and please enter number 1 to 10. That's not, um, that's not gonna work, is it? Because it's not 1 to 10. So we need to change this so that the numbers that are prompted are representative of the actual game.
Fix Prompt Range Text9:19
So we need to change this so that the numbers that are prompted are representative of the actual game. So let's change this to a ` so that we can include this min range. And then we want to change this to this max range, and we want to do that down here as well, whenever the user doesn't type in a valid number. So we need to change that to a ` string. And yeah, okay, so going back to the browser, it's refresh if we play the game one to a hundred.
And yeah, okay, so going back to the browser, it's refresh if we play the game one to a hundred. Okay, so that's good. Let's start at 50, 30 is too high, 15 is too low, 23 is too low. I'm not gonna win this, but it's a hard game. So there we go. But then the question becomes, what about those select boxes that have the multiple attributes, allowing us to choose multiple values from the box, in which case
Use selectedOptions API10:04
that have the multiple attributes, allowing us to choose multiple values from the box, in which case we have a different property and, and really we could use the same property here and this is arguably easier to use anyway. So we have selectedOption, we still need our gameLevel element, but then we have a selectedOptions property. This returns a collection of all of these selected options and with a multiple select box, all
This returns a collection of all of these selected options and with a multiple select box, all of those options would be there. Since we have a single select box, well, we just want the first one at index 0 and that is still going to give us essentially the same functionality that we had before, but it's a lot easier to read, which I'm all for. And we can of course prove that by going back to the browser, we can select whatever gameMode.
And we can of course prove that by going back to the browser, we can select whatever game mode that we want and start playing. We can see that the appropriate min and max ranges are being displayed. If we go to hard, you'll see 1, 2, 100. So even though we use a slightly different API, we still end up with the same result. So working with select elements is a little more involved than working with input elements because
So working with select elements is a little more involved than working with input elements because after all, input elements are just what single values, they're very easy to work with. It has a value, and that's it. Select elements have multiple values. All of those are based upon the options that they have. And of course, if all you need is the value of the selected option, you can use the value property. But if you need to work
of the selected option, you can use the value property. But if you need to work with the actual option element itself, you can use the options collection to get the selected option, or you can use the selectedOptions property. Either way, it's going to get you the information that you need.
