14. Project - Modal with custom events


We're now going to take what we've learned about events and build our own simple modal functionality. So we click a button and it opens a modal. And within this, what we're also going to do is discuss dispatching our own custom events
which we can pick up from anywhere on the page. That's pretty much what we want to do with modals. We want some sort of button which triggers a global modal that we have on our page. Now this is really, really simple functionality, but with this example, you'll get the general
idea and you'll be able to expand on it as you learn more about Alpine. So we've got nothing on the page at the moment. Let's first of all look at the markup and the actual styling. So we're going to have a kind of overall wrapper for our modal, so let's give this a class
of modal wrapper. Again, we're just going to implement really simple styling here. And inside of this is going to be the actual modal window itself. Let's go ahead and just add some really quick styles just at the top here, just to get this
started. So modal wrapper, let's go ahead and add the styles in for this now. This is going to have a position of absolute, so we can fix it to the very top and very bottom and left and right.
And we'll set a width of 100%, a height of 100%. And let's go ahead and set a background color to this. And let's just use RGBA here and say black with an alpha of 0.5, so that's just half the opacity.
So let's go over and just give that a refresh. And it doesn't look like anything's showing, so yeah, we just spelt modal wrong. Let's go ahead and update that, give that a refresh, and there we go. So that's our kind of modal wrapper.
Now just to make this a little bit better, let's set the margin on the body to 0. And there we go. So that's our background for our modal. Now the modal content itself, let's go ahead and add this in, spell it properly this time.
Let's just set a width of 100% by default to this. And let's go ahead and set a max width on this of, let's just say, 30%. We'll set the background color here to white. And let's go ahead and set some padding on this to 20 pixels.
So let's go over and just give this a refresh. And there we go. So there is our actual modal. Now to make this in the center, let's just add a display of flex to our overall modal
wrapper. And let's align these items centrally. And let's justify this content in the center as well. So we basically just end up with a modal in the middle.
Great. So let's add some just content to our modal. It doesn't really matter what it is. So I'm a modal.
And there we go. Great. So that's our modal. Very, very simple.
So let's hide this by default. And of course, we want to hide the entire thing. So let's add some X data onto this. And let's say open and false.
So what we can do now, if we just pull each of these lines down just to make this a little bit tidier, we can go ahead and add an X show to this and say if it's open. By default, it's not. So we just won't see anything.
But we'll have some kind of button outside of this component, which will go ahead and trigger that modal. So let's go ahead and add that in now. And we'll look at that in a minute because that involves dispatching a custom event and
picking that up on the window object, which sounds more complicated than it is with Alpine. Now if we go ahead and just focus on the modal itself, first of all, let's set open to true. And let's figure out how we would close this modal.
Now typically within a modal, you would have two methods of closing this. You'd either click outside anywhere in this dark area, outside of the main modal content. So I could click here or here to close this off. Or I would press Escape on my keyboard, which I've just done.
But of course, at the moment, nothing is happening. So let's focus on clicking outside. We covered that in the last episode. So what we can do is on the actual modal itself, the white box, we can say X on and click,
use the outside modifier, and set open to false. So if we come over and give this a refresh, clicking inside of the modal does nothing. Anywhere outside of that closes it off. So already, just with, again, a couple of events here and a property to show whether
this is open, we've got some really nice modal functionality. Now what we want to do is add the escape event. We kind of already know how to do this. So let's go ahead and do this on the overall modal wrapper.
And let's say on key up, use the escape modifier, and set open to false. Let's check it out. So let's go over, give this a refresh. I'm going to click outside just to make sure that's still working.
I'm going to press escape on my keyboard, and nothing is actually happening. So by pressing escape on my keyboard, which I'm doing repeatedly right now, it's still not doing anything. Let's find out why that is.
So when we do press on key up escape, remember that this is a div. It's not actually an input. So if this was a text area, that would work because we are currently inputting content into that text area.
So what we're going to do is look at a further modifier, which is on the window object. So if we get a global escape key down, this will listen globally, then do what we ask. So if you're applying keys or events anywhere, globally, you need to use this window modifier. Let's give this a refresh.
I'm going to hit escape on my keyboard. And there we go. The modal has been closed. So we can kind of use what we've learned about that window modifier to trigger the
modal. And what do I mean by that? Well, let's go ahead and on this button, use x data. So we can actually use this as an Alpine component.
Bear in mind at this point, this is a separate component to this modal. We wouldn't want this button inside of the actual modal itself. So we're having this completely separate. So let's go ahead and say on click.
Now this is where we want to trigger the modal. How would we do that? Because we're not within this component. We can't say something like open true, because there's no open property on this button.
We could add that in there, but it would be useless. We want to control this component, regardless of where this button that triggers the modal is. So what we can actually do with an Alpine is we can dispatch an event globally.
So let's go ahead and just call this open modal. You can call that whatever you want. It doesn't matter what you use. So let's go over and try this out.
Now let's first of all make sure we set open to false, so we don't have that by default. And by clicking on that, we have now triggered an event. We can't see anything happening, but we can pick up on this event from any of the Alpine components or even within native JavaScript.
So we're going to go ahead and say x on. Now we have a custom event name. We can say open modal. So that's our custom event.
Now let's go ahead and again say open to true, and guess whether this is going to work or not. You probably already guessed. It's not.
Clicking on this does absolutely nothing. That's again because we have dispatched an event on the window object, which means we need that window modifier. So let's try this out.
I'm going to go ahead and hit trigger modal. That opens. And now we have built some very simple modal functionality with just a few events. Now this doesn't directly relate to this modal, but I'm going to give you an example
of sending data along with your events as well, which could be really important. So let's say that we had just a wrapper. I'm just going to have a contrived example here where we had some kind of message that we wanted to show.
By default, that was empty. And actually, this could be some kind of pop-up like a message in the bottom of the screen telling a user that they've performed some sort of action. We might actually cover this as a practical example.
I think that would be good. But let's go ahead and just get this working for now. So with this message, what I want is some sort of button. It doesn't matter.
It doesn't have to be a button. To go ahead and say, well, when I click this, I want to dispatch an event called message. And I want to send some data along with this to be set inside of here. So how would we do that?
Well, simply with dispatch, we can send data as a second argument. So I can say, hello there. So let's just go ahead and say set message on this button. Let's go over.
The goal of this is when I click on this, it sets the message within this other component and outputs it in here. So let's output the message, which is at the moment just empty. So let's say x text message.
And just to double check that that actually is outputting, there it is. Now we want to pick up this event on here. So we're going to say x on message window, remember. Now we want to set the message to the data that we get here.
So how do we do that? Well, let's go ahead and console log on the event object, first of all, that we get through from any event that we have in Alpine. And let's see where that data is actually being sent through to.
So let's give that a hard refresh, hit set message. And it's not actually working. So let's have a look here. And yeah, we didn't add x data to our button.
So that's not actually an Alpine component, and it's not being triggered. So by clicking set message, we get a custom event. So that's what's going to be created when Alpine uses the dispatch method. Now in here, you can see you've got detail, which is at the moment just a string.
Now that could be an object. We'll take a look at that in just a second. But in this case, we can just go ahead and set the message from that event property. So we can say message equals and assign event detail.
And let's go over, hit set message. And there we go. So effectively, from another location, we've sent a message across to another component and set the message there.
And like I said, you can use objects here. So for example, I could say message is hello there. And you might have some other data like the type of message. For example, that could be an error.
So we'll just keep the message in there for now. But let's go ahead and say event.detail.message, because that's now an object that exists within detail. Let's go over, give that a refresh.
And you can see it works in exactly the same way. So a practical example plus a taste of dispatching your own events inside of one component and picking them up in another component, which can be really useful aside from Alpine state management functionality to share data between different components.
19 episodes2 hrs 10 mins


Alpine.js is a refreshingly minimal JavaScript framework that gives you the reactive nature of Vue and React, but with much more simplicity. This course will get you up to speed on how to use it, with plenty of practical examples along the way.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!


No comments, yet. Be the first to leave a comment.