Vanilla JavaScript Projects

Dark Modal: preventDefault Method

Anjana Vakil

Anjana Vakil

Software Engineer & Educator
Vanilla JavaScript Projects

Check out a free preview of the full Vanilla JavaScript Projects course

The "Dark Modal: preventDefault Method" Lesson is part of the full, Vanilla JavaScript Projects course featured in this preview video. Here's what you'd learn in this lesson:

Anjana debugs and has an issue with the Dark Modal where the selected theme is not saved when the Modal is closed. This is due to the form refreshing the page on submission. The preventDefault method will prevent the refresh from happening.


Transcript from the "Dark Modal: preventDefault Method" Lesson

>> Debugging, it's all part of the game. There's a lot happening with the browser, so sometimes we get unexpected results. For example, our toggle button works, right? But when I click this close button, If it was in light mode, it goes back to dark mode. It's like, I don't know, is this trying to tell us something about the dark side of the force and how evil always wins?

I don't know, maybe this is sort of an Easter egg for philosophical contemplation by the user. Probably we want the page to do what the user expects it to do, which would be stay in light mode if I change the toggle to light mode, yeah? Okay, so let us inspect to find out what's happening here.

Now our toggle is supposed to be changing the value of this data theme. So if I refresh the page, this page starts out on dark mode, right? And keep in mind that all of the code that we're writing, this is like code that is just running in the current, View of the page.

So, new Window that loads the page is just gonna get the exact same original HTML. That we got first without any of the manipulations that we've done in JavaScript, which is another reason why it's great to [LAUGH] avoid JavaScript. But, the idea is that at least while I am still in this same page I want that toggle to stay put.

So let's see what happens when we interact. Okay, right now it's in dark mode the toggle works, it does its job of changing the data theme to light. It goes back and forth as needed but when I close the form, It goes back to dark. And did we notice this, Blinking in the dev tools here?

Okay, so the brilliant community of co-developers that we have here of put our heads together and figured out what is happening. And this is related to, Where did we have it? That submit button that we have in the dialogue here. Now remember, we didn't attach our own event listener to the call close button in the form class.

So we're just letting the browser do its default behavior for button type equals submit. Which is to submit the form and then refresh the page, right? Which now in like our JavaScript DeLanda of like basically doing all of the behavior that the browser was expecting us to submit some data to go somewhere else to mess with things.

In this case, we're just doing things client side with JavaScript. And so the default behavior of this submit, Clicking on the button submitting the form is not what we want, really. We can stop that behavior with a handy dandy method on the, Event that we get when we have an event listener.

Now, this is a different button, but just as an example, when we add an event listener, we pass in this callback. This callback can take an argument which the browser is going to pass in. This can take a parameter that the browser is gonna pass in an argument of the event, in this case, click event that fired that caused this callback to run.

So what we can do is instead of trying to save ourselves some JavaScript and try to do things as natively browser-like as possible, is totally mess with it. So, what can do this in like another method we can have like a setup close button or something like that.

But for just in the interest of time, what we can do is set an event listener on the CloseButton, That addEventListener it's gonna be listening for the click event. Or I think we could also listen for the submit event on the form, yeah? We could also do that.

So for example, we could do like this.element, set, no, addEventListener. Am I ever gonna remember what that method is called? No. [LAUGH] No matter how many hundreds of times I've typed it. Okay, the event on, sorry, so the element is the form element? The form element has a submit event.

And that it gets a handler that we can pass and we can capture after the event, which the browser is gonna pass into this callback, just by magic. We can do stuff with this event, like, for example, often we're looking at stuff. What was the event target? Meaning, like, what was the element that was interacted with that triggered this event.

But we also have a prevent default method that, lets us prevent whatever the default behavior of that event was gonna be. And if we try this out, let's try this out and see what happens, then we're not going to do anything else in our handler right now. But if we try this out, and we go back to our dark modal, and so yes, we were really make sure we got, okay, all right.

So now we press close and I'm pressing close. You may clicking, but I'm clicking and nothing happening. Yeah, well, the browser's like, yeah, you told me not to do anything. You told me to not do the thing that I usually do, which is like, do a bunch of work for you all the time, constantly.

And you don't even appreciate me [LAUGH]. So now that we've prevented the default behavior, we need to do some. And that's where we're gonna need to now, in this case, close our dialogue. So that means we have a little bit of an abstraction problem here, if we wanna be preventing the default from within our form constructor.

That means that any form dialogue or not dialogue it's not the close button is not going to work, right? But maybe what we wanna do is since we know that in this case we're actually interested in the fact that this is a modal and that this is being submitted.

And what we want the submission to do is actually just close the modal. What we could do is, oops, In the form, we don't have any dialogue element because the form is just a form. It doesn't know that it's inside of a dialogue. The modal class is where we put the form inside of the dialogue.

And we create a, Dialogue type form deliberately as users of the form class. All right, but other people might be not having dialogues, they might just have regular forms in their page. So in this case, we might want to do that event handling, Inside of our place where we are actually instantiating the form.

So that we're not doing this for every single form that gets created ever, but we're only doing it for this one instance of form that we just made to be in a dialogue. So that we can decide if we're preventing the default behavior, we're probably gonna need to supply some non-standard behavior.

So that the user doesn't just have a super frustrating experience of being stuck in a modal for eternity. All right, so now let's see, oops, what did I do? Form.addEventListener is not a function because I need to access the element [LAUGH] of the form. Okay, let's see if that makes, okay, all right, all right.

So now, okay, this form still works and the close button still does not work. But somebody else who called a instantiated a different form object is not also gonna have their close button broken. Cuz this is just special to me and my modal use case. So now what we need to do is do the thing that we want the close button to do.

So, yeah, dialogue is the dialogue element, okay, this, nope, nope, nope, nope. Well, all right, let's try it, let's do it. This.dialogue.close, would be how we manually close an open dialog. See what happens. Okay, well now it's backwards but all right. Okay. Okay, so in this case, this actually did do what we thought it should do.

But I believe, so this is a, like, a super detailed thing about the difference between. So far we've essentially been using arrow functions and function keyword functions as if they're exactly the same. But they're not. Because why would JavaScript be predictable? Where would the fun be in that?

When we have an arrow function, let's go to our friend MDN and find out. Arrow function expressions [COUGH]. Arrow functions don't have their own bindings to this or arguments or super or some other like fancy things that we can do with functions. So JavaScript would also accept an anonymous function here with the function keyword, or a named function if I wanted to.

See what happens if I do it that way. Okay, so toggle works cool, it's changing up this dialog is undefined. What? Because and this is why again, like in general this is not my friend. I don't know if it's your friend maybe you're better at remembering which, whether it's the arrow function, has its own this or that function, that has its own this?

I don't. So this is why I reassign stuff all the time. But in this case, I would need to capture, do something like dialogue. Is this dialogue? And then I'll be able to close over that value with my little closure function, hopefully. And, okay, well, it's backwards, but that's because of something fancy happening behind the scenes.

Okay, so now, hopefully, it worked because of closures, because of that scope fossilizing that we talked about [LAUGH] before. All right, great, so, we have successfully debugged a super broken page that was not finished, I lied to you. And we have also come upon a very often, like, if you may have already used and seen this prevent default, like, all over the place.

And sometimes, especially I remember when I was starting out, I was just like, all right, I don't exactly know why we're preventing defaults all over the place. But all of my colleagues are writing their new event handlers with prevent defaults and so on and so forth. So I'm just gonna copy that.

But so this is a good example of when we really do need to override the default behavior. Because we are messing with how the user will be interacting. We're taking advantage of one convenience of the browser, which is that if you submit a form within a dialogue, it will close the dialogue.

But we are, Getting around the other default behavior of form submission in general, which is to reload the page. Just goes to show how much our just hard-working browsers are doing for us. Every millisecond of [LAUGH] the day that we are poking around on the internet looking at cat memes and GIFs.

So thank you browsers for all that you do. Grateful to have you and grateful that JavaScript lets us totally mess with you and confuse our users and break their pages and so on and so forth. So, victory.

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