Need to disable settings0:03
You know, the UI has come a long way. It's much easier to use and I appreciate that. But there are still some things that I want to address. Like for example, whenever we play a game, the settings form is still available. So as we are playing a game, we could just click play a game to start completely over. We can clear it, we can change settings. And I don't necessarily want to do that when a game is active.
And I don't necessarily want to do that when a game is active. I want to completely disable the settings form and we can of course do that. But when it comes to disabling a form, it's not as easy as just saying, Hey, disable this form and it's done. It would be nice if that's the case, but it's not. Instead what we have to do is go to each individual form control and disable it. That means the radio buttons, the checkbox,
to each individual form control and disable it. That means the radio buttons, the checkbox, the input elements, the select element, and even the buttons themselves, we have to go to each one of those elements and disable them. And we have access to those element objects. I mean we have fetched them from the DOM and we have them in memory, but I don't necessarily want to individually disable those things one line at a time.
but I don't necessarily want to individually disable those things one line at a time. Instead, what I want to do is well make it as painless as possible and we can do that. The first thing I want to do, however, is think about how we are going to do this in our code, or at least how we are going to initiate it. So whenever we start playing a game, which is inside of the submit event, you know, this is
Design UI disabled API1:30
So whenever we start playing a game, which is inside of the submit event, you know, this is where we create the game. So then we would disable the settings and you know, we could do something like this to where we just call disabledSettings. That is fine. Um, maybe something like this makes sense to where we have a property called settings and then it can have a property called disabled.
where we have a property called settings and then it can have a property called disabled and then we could just set it to true or false and then that disables the settings form. I kinda like that approach. So let's implement that. Let's go all the way back up to the UI and right here where we are returning that object that becomes the ui. Let's see. I kind of want to keep things in order, but once we get into the methods, I don't want
Implement form disabling2:12
Let's see. I kind of want to keep things in order, but once we get into the methods, I don't want to put properties there. So we have some getters up here. Then we start our methods. I'm going to define this settings property here. It's just another object and it will have a property called disabled, but this needs to be a setter. So we will have setDisabled, we'll get the value that we want to use.
So we will have set disabled, we'll get the value that we want to use and then we just need to disable the form controls. And the way that we are going to do that is by iterating over the elements property. Now we have talked about the elements property on a form object, it contains all of the form controls. It doesn't contain divs or even labels. It is strictly the form controls. So input elements, select elements, fieldsets, textareas,
It is strictly the form controls. So input elements, select elements, fieldsets, textareas, things like that. So if we want to disable the labels, because we do have a few labels, we would have to manually do those. I don't think we need to do that. We'll just stick with our elements here. And this is a collection, so that means we can iterate over it.
And this is a collection, so that means we can iterate over it. And one of the ways that we can do that is with the for loop. So we can get our counter all set up and ready to go so that as long as the counter is less than elements length and then we increment our counter, then all we have to do is say elements at the index of our counter. And then we would use the disabled property.
to do is say elements at the index of our counter. And then we would use the disabled property and then we would set it to whatever value was passed to the setter. Now, as far as HTML is concerned, disabled is an attribute, but it's one of those attributes that is, well, it, it's basically Boolean. It doesn't really have a value. If it's present, then the element is disabled. If it's not present, then the element is not disabled.
If it's present, then the element is disabled. If it's not present, then the element is not disabled. And so that is essentially what we are doing here because form controls have a disabled property and it maps directly to that disabled attribute. We can manipulate that using the setAttribute method, but for disabled, that's not really the best approach. So we could do something like this where disabled is true, but that's actually setting an actual value.
So we could do something like this where disabled is true, but that's actually setting an actual value for the disabled attribute. We don't wanna do that. We want to use this disabled property. So this is going to iterate over all of the form controls so that whenever we play a game, all of the form controls cannot be interacted with. I mean the hover still works for the play game and the clear buttons.
Style disabled controls4:49
I mean the hover still works for the play game and the clear buttons. So that's something that we need to address. And really from a visual standpoint, I want them to look different when they are disabled. So here is the play game button. When it is disabled, we'll have it a bg-blue-500. Basically its normal background color, but let's also set the opacity to 50. And we will essentially do the same thing.
but let's also set the opacity to 50. And we will essentially do the same thing for the clear button, except that we do need to use a different BG value, which in that case will be gray. But then, you know, I want to do the same thing for everything else, at least as far as the opacity is concerned. So for the select element, I want to set the opacity to 50 when it is disabled
So for the select element, I want to set the opacity to 50 when it is disabled and for all of the other elements as well. So it's just a matter of pasting this value in. And we'll do the same thing for all of our other form controls, which we don't have a class here. So let's just add a class with that disabled opacity. Then we will need to put that class for the other elements. And so once that is done back inside
Re-enable on end game5:50
Then we will need to put that class for the other elements. And so once that is done back inside of the browser, we play game. It's very clear now that the game settings form is disabled, we can't interact with anything. But then whenever we quit the game, we need to restore or enable the settings form. And that's easy enough to do. We just need to go to the click event listener. So that here is where we listen for the submit guess.
We just need to go to the click event listener. So that here is where we listen for the submit guess. We now need to check if the target's id is equal to endGame, then we want to set uiSettings disabled as false, in which case we can play the game, we can quit the game. And both of those actions toggle the disabled property for our game settings. Now we implemented our disabled property by essentially iterating over the elements inside of a form.
Compare iteration options6:40
Now we implemented our disabled property by essentially iterating over the elements inside of a form. And really this is the best approach, at least as far as performance is concerned, because in JavaScript, if you need to iterate over an array or a collection, there's nothing faster than using a built-in loop like for or while or do while. But there are other alternatives that might be a little easier to read.
But there are other alternatives that might be a little easier to read. Like for example, instead of using this for loop, we can take a different approach to where we would use the array foreach method, but it would look something like this to where we would spread out the form elements into an array so that then we could call foreach, we can work with each element to set its disabled property to the provided value.
with each element to set its disabled property to the provided value. Now you might think, why can't we just call form elements forEach? And the reason is very simple, it's because it's not an array. The elements and, and really any collection that comes from the DOM is not an array. It's what we call an array.
that comes from the dom is not an array. It's what we call an array. Like I typically use just the term collection because, well, it's a collection, but it is not an array. So therefore we cannot use array methods directly on a collection from the dom. We have to convert it into an array or we have to use some other tricks. So this is going to give us the same result. It's just going to execute a little bit slower, first
So this is going to give us the same result. It's just going to execute a little bit slower, first of all, because we have to spread the elements into an actual array. But two, the foreach method on an array doesn't execute as fast as a native loop. So there is that. We have another option, however, by using the array_from method, which I think we talked about.
however, by using the array\_from method, which I think we talked about. But here we would just pass in form elements. We would then call foreach so that we could work with each element to set its disabled property to the provided value. And this is essentially the same thing, it's just slightly different syntax. We are creating an array from a collection so that we can call the foreach method.
We are creating an array from a collection so that we can call the arrays for each method and then change the disabled property. Either way, it's going to give us the same result. There's another option, and it's one that I debated on sharing because it it, it involves things that we haven't necessarily talked about because at least with modern JavaScript, we now have tools that mask some
because at least with modern JavaScript, we now have tools that mask some of the more complex things about JavaScript. And one of those is something called a prototype, because JavaScript is a prototypal language. You know, we have this idea of a class, but it's not a classical language, it's a prototypal language. And the class masks around prototype. I'm getting into confusing things here,
And the class masks around prototype. I'm getting into confusing things here, but basically every type has what's called a prototype. The prototype is exactly what it is. It is the prototype of a particular type. So an array has a prototype. That prototype is where the methods are defined, like forEach and things like that. But what we want to do then is call the
for each and things like that. But what we want to do then is call the forEach method by using the call method. call is something else that we haven't talked about because in today's day and age, it's not as an important thing as it used to be. Modern JavaScript gives us the tools that we need to essentially not have to use call very often, but used to we did. And there's still a lot of code out there that uses call.
but used to we did. And there's still a lot of code out there that uses call. But the idea is that we want to call the forEach method on the array type, but we want to call it as if we were using form.elements so that then we could set the disabled property for each element to the provided value. So it's a lot more complex, but it gets down into the nitty gritty of what we used to have to do if we wanted to use, you know,
but it gets down into the nitty gritty of what we used to have to do if we wanted to use, you know, things like the forEach method for a collection. But I'm gonna stick with the for loop 'cause that's really the best option. It's not as pretty, it's arguably not as readable as some of the other options, but it's what I'm gonna do because it's, I'm old school. Now, there are a few things I want you to come away from this episode with.
Now, there are a few things I want you to come away from this episode with. The first is of course, how to disable a form. It's not as easy as just disabling a form. It would be nice, but it is what it is. It is easy to do. You just have to iterate over the elements inside of a form and set their disabled properties individually. But that's how it is. That's what we gotta do. The second thing is that JavaScript is a very flexible language.
The second thing is that JavaScript is a very flexible language. It's one of its strengths. It's also one of its weaknesses because it gives us several different ways to not necessarily do the same thing but end up with the same result. Or at least what seems like the same result. And you know, you and I are two different people. We think differently. We approach code differently.
And you know, you and I are two different people. We think differently. We approach code differently. I tend to approach code as what is the most performant thing to do. And that's the approach I take. Like in the case of disabling a form, I would use a for loop, but other people are willing to sacrifice a few milliseconds to have code that's a little bit easier to read or code that is more elegant. So when it comes to looking at other people's code,
to read or code that is more elegant. So when it comes to looking at other people's code, when it comes to writing your own code or writing with a team, you are going to see many different ways to essentially get to the same end result. So I advise to of course, have your own personal opinion on what would be the best approach for you, but practice using other options just so that as you are reading other people's code
but practice using other options just so that as you are reading other people's code or having to maintain other people's code, it'll be much easier to read it, understand it, and know what's going on.
