This episode is for members only

Sign up to access "Building Modals in Livewire" right now.

Get started
Already a member? Sign in to continue
Playing
07. Correctly layering multiple modals

Transcript

00:00
So we just implemented the ability to open a modal within another modal. And let's just remind ourselves what that looks like. If we open up this first modal, open up the second modal,
00:12
sure enough, we see it. But we're going to have a little bit of an issue based on the stacking order of the modals that we've registered globally in our app.
00:22
Let me show you what that looks like. So we're going to go and head over to the first modal. And we'll just grab the button here that opens the second modal.
00:32
And let's open the first modal from the second modal. So let's switch this to first modal and switch this to first modal. So we're now clicking on the second modal
00:43
and then we're going to open up the first modal. As you can see, this is opened behind the second modal. Why is that? Well, if we head back over to app.blade.php,
00:55
this is to do with the order that we've registered these on the page. So naturally, the first modal is always going to sit behind everything else
01:06
because it's registered first on the page. Now, of course, we can get around this by swapping over the order. And if we go ahead and open that first modal, it does work.
01:16
But then we're going to be back to square one with the first modal and opening the second modal. So that's been opened behind this. Now, the reason that this happens
01:25
is because of the CSS z-index. Now, we have set that, and I'm just going to move these back to the original order. If we open up our modal wrapper just over here,
01:35
you can see that we did set a z-index of 10. But that means that every single modal that we open has a z-index of 10. And in order for one to be on the front,
01:46
we need the z-index to be higher. So how are we going to get around this? Now, this is an incredibly tricky problem to solve because essentially what we want to find out
01:56
is which modal is the one that we want to show on top, which is the currently opened modal. Now, there's a variety of ways that we can achieve this. For example, what we can do is over in our isModal somewhere
02:11
when we show this, we could set some property here to always keep track of the last open modal. But we kind of want to make this as simple as possible. Kind of hacky, but as simple as possible.
02:25
So I'm going to show you a way that we can do that now by always setting the z-index to a higher value based on the last open modal. So we're going to do this all within the modal wrapper.
02:35
Let's go down here, and let's create out an x in it with Alpine. And in here, what we're going to do is just watch for when this becomes visible.
02:45
So let's take a look at that first in case you're new to Alpine. So we use this watch function here. We go ahead and give in the property
02:53
that we want to watch, which is visible. And we do that within a string. And then, of course, we have a closure here, which is going to be run when this becomes visible.
03:02
So let's just console log out here, and we'll get the value in here that we don't really need. But we'll just dump that to the page. So if you're new to Alpine, this is how it works.
03:12
Let's go ahead and open the first modal. We get true down here. When we close this, we get false. So basically, every single time this opens or a modal opens,
03:23
we're watching for this. And of course, we have the value. Now, what we want to do is find a number that's always higher over time that we can set as the z-index value.
03:34
Now, there's a couple of ways that we could do this. We could use date now. This gives out a Unix timestamp. So what we could technically do is divide this by some number.
03:44
And that's going to give us, say, 1. Now, obviously, the second timestamp is always increasing. So the next time someone opens a modal, this might be 2, 3, 4, 5, and so on and so on.
03:57
That means that we can basically take a value like this, which we know with time is always increasing, and we can use that as the z-index value. That means that if I open the first modal,
04:08
then open the second modal, the second modal, we can set the higher z-index. If I were to do it in reverse, whatever modal we open last is always going to be on the top,
04:18
because we're using this ever-increasing value to use the z-index. Now, there are other ways that you can do this. You can have a global counter to always increment
04:28
every time you open a modal. But that involves adding some global property, and I don't really want to do that. Now, we're not actually going to use date.now,
04:37
because that gives us a timestamp which is very difficult to manipulate. And then when we round this up, we can potentially have duplicate values.
04:46
So what we're going to do is store up here this now value. I'm going to set that to null to start with, because by default, we haven't opened any modals on the page. And then I'm going to go ahead and set this.
04:58
And I'm actually going to use the JavaScript performance interface. So let's go ahead and just dump that out there. And we're going to set that to now.
05:07
Now, let's console log this out before we actually do anything with it, just so you can see what this value looks like. If we head over here and open up the second modal,
05:15
and then open up the first modal, you can see this number here. So essentially, what this is is the amount of milliseconds that have happened since the page has been loaded.
05:25
And this is useful for profiling the page. That's why it's part of the JavaScript performance interface. But we're going to use this, divide it by 1,000
05:34
to get how many seconds the user has been on the page. So I'm going to go ahead and divide that by 1,000. And at this point, it's really important to round this up, not down.
05:44
So we're going to go ahead and use math seal to round this up. So now what we'll have is a second value. So when we land on the page, this is going to be 1. The next time we go ahead and toggle this visibility,
05:58
it's going to change not to 2 necessarily, unless we do that in the second second. But it will just keep increasing. So let's go ahead and just console log out this new value,
06:07
just so we can see this. And then we'll apply that to our z-index. So if I click on this, then click on this, we get 2 and 3.
06:14
Let's go ahead and open up the first modal again. Second modal, we get 7, 8. Wait a couple of seconds, and of course, we get 10, 12. So this is an ever-increasing number,
06:25
which we can now directly apply to our z-index. And we know that the last open modal will have the highest z-index, therefore showing that on the very top of our stack.
06:37
So how do we apply this z-index? Well, we just go ahead and bind this in with Alpine using style. So we're going to go ahead and say z-index.
06:47
And we can just put that now value directly into there. OK, let's go over and try this out. So I'm going to go ahead and hit open second modal, open first modal.
06:58
There we go. This has a higher z-index. I can close these off, open the first one and the second one. Again, because we're using that value now,
07:07
this now has a higher z-index. So that pretty much solves the problem. It's a bit of an odd solution, but I think this works really, really nicely.
07:17
There's no real performance impact on the page here. We're just basically taking a value here and setting it locally to this component. And we're not having to rely on global variables
07:27
to keep track of this or fire off any events that we will need to change any values around. So it's pretty straightforward, kept all within this modal wrapper, and more importantly, it works.
11 episodes1 hr 1 min

Overview

Build your own modal functionality in Livewire, completely from scratch!

We’ll cover creating a re-usable modal wrapper, transitions, triggering modals from anywhere with our own Alpine functionality, trapping focus inside modals, layering modals correctly, and more.

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

Episode discussion

No comments, yet. Be the first!