How to build a modal with htmx
So I'm working on taking an older site that I I have, and converting it over to use htmx. This is something that I've done a lot, Kind of bit by bit because HTMX kind of lends itself nicely to, being put into existing projects and just used as needed with the attributes. So this is like the 1 of the big selling points for me, because I do a lot of client work, I do a lot of my own work, and I have a bunch of different projects. So being able to kind of go between the different projects and use the same tech for all of them is a huge benefit. So I just wanted to kind of like I was working on something and it felt like a pattern, similar to I did an episode on the large table pattern.
Lazarus:And this is the modal. So modals are everywhere, and I think, you know, HTMX, modals are sort of a front end thing, right? Like they you you ideally want your modal to exist on the front end and not have to, you don't want to have to wait when you click to open a modal, to go to the server and come back, and fill in or whatever. Because people are just used to that front end kind of, animation of a modal opening, your background grays out, whatever it is that you, you know, however you want to set up your modal, whatever models you're used to. So I think that there's sort of this idea that, you know that's sort of not part of of the the deal when you're using something like h tmx, when you're using kind of a server side rendered thing.
Lazarus:So I just wanted to kind of like put in a pattern that this is this is how I do it. I create the modal, however I like modals. So for some projects that are old I have bootstrap modals, right? Like those were big for a while, it's just kind of like you have your your they have their own setup, a data element, or whatever, and you you create the modal. So I create the modal outside of the whole flow of, you know, like the thing you click.
Lazarus:The modal doesn't have to be right there. The modal, the code for the modal, can be anywhere on the page, right? Because as long as you are referencing it and opening it, then you can, you know, it doesn't it doesn't matter where in the flow in the HTML it is. Ultimately the modal is going to be absolute positioned. It's gonna cover your your whole screen, possibly lock the scroll behind it.
Lazarus:So step 1 is just to choose your modal. Whatever technology or whatever, package you're using, just use that modal. It's gonna have, you know, that might be tailwind, tailwind UI, that might be Alpine. Alpine has their own collection of modals. That might be Bootstrap, that might be just the dialog, you know, straight HTML dialogue, which is not ideal.
Lazarus:I wish it looked a little nicer. I think they could probably do a few things, but I think you can style it too. I've never actually tried. But modal is sort of a solved front end experience. You can find the modal you want.
Lazarus:So step 1 is just to make that modal, make that button, put just filler text into it. Yeah. It doesn't matter what it is, lorem ipsum, whatever you want to put in there. Have the modal pop up in the right place, you know, put the button there, put the modal there, you click the button, modal opens, you click elsewhere and modal closes. Get all that stuff sorted out.
Lazarus:You know, no HTMX. This is just that little front end experience is not a big deal. You can use whatever, you know, whatever feels best to use your modal. So once that's in place, you really only need 1. And maybe you'll have like, you know, 5 different modals for different parts of your app or whatever.
Lazarus:But let's say you have a list of a 100 items, and each 1 you click you want to load that modal with something from that particular item. So rather than creating, you know, putting in that loop all the modal code, you can put your modal code outside, put it at the root level, put it, you know, somewhere else on your page, so that only loads once. Then take out the middle of your modal code, and that will be the HTML, the snippet, you know, the body, the content, the footer. Whatever parts you want to be dynamic from that modal, strip those out and, you know, put a placeholder there with an ID, so that you can reference it. Now, you can go and put that snippet that you took out, put that into your, you know, your h x get equals, create a route, put that format, that HTML, into the response so that so that you're going, you're getting a snippet of HTML and it's gonna be the middle part, the content of that modal.
Lazarus:So make that whatever you want. So if it's a list of a 100 items, and you click see more details, edit, whatever you want your modal to do. Maybe it's a form that you can save, maybe it's, just a bunch of details, maybe it's an audit log of all the things that have happened. You There's all kinds of stuff you might want to put into a modal. But it can be anything.
Lazarus:That's the nice thing about this. It can be other actions, it can be you know, lots of data, it can be scrollable, you know, you'll have this nice modal of it. So put that into there, and then on your button, that's where you put your h x get. And you put your target of the ID where you had your modal. So where you put that placeholder for the modal.
Lazarus:So your target is inside your modal, your modal is already there on the front end. When you click it, right now it does nothing, it just pops up, it's empty, and you can close it. But what you want to do is do your h x get to a route that's going to fill that modal with what you want. And then for your HX trigger, put mouse over, right. So as soon as your mouse goes over, it's not opening the modal.
Lazarus:It's until you click it, that's gonna open the modal. But when you mouse over something, that's going to kick off that h x get, which is going to go to the server, fetch the contents of that modal, and put it into the modal. So, you know, there is a chance if you click fast, you, you know, move over and click fast that you will see a modal with nothing in it. So you can put something else there. You can put some other place holder, a little loading screen, or just the word loading.
Lazarus:You know, maybe there's a min height on the modal so it doesn't so it's like at least not changing sizes or something like that. But if you use that mouse over or mouse enter, I kind of forget which 1 it is, but the point is you load your h x get for the contents of that modal when the mouse is just hovering over it. There's usually, you know, humans just like they need to take a second, they move their mouse, and you can even make that like button pretty big or something like that, or have like an area around the button that is bigger than the button looks to be your hover. So that it just gives you that extra little thing. I mean, honestly users don't care at all if they click a model and it takes, you know, 200 milliseconds for something to inside it load.
Lazarus:So you could just put it on the click. But this is just a nice little pattern, you you get it for free. As you mouse over that button, you load the modal behind the scenes. Now nothing's happened, you haven't clicked it, nothing's shown up, you can't tell that the modal is now full of what you want to be in it, until you click it. And then you close it, do whatever you need to do within the modal, then you just the next time the user hovers over another 1 of these buttons, it has the same target, the inside of that modal, so you're just using that same modal over and over again.
Lazarus:Maybe you even you could add code to clear out, the target as well. You know, that's kind of an optional thing. But just in case so you don't like see a snippet of an old modal's content or something like that when you click. So this is just kind of a way it's very efficient for, you know, first of all you're not loading all those content of all those modals at once, but you're also not loading more than 1 modal itself. So you could have, you know, these modals can have a ton of HTML, especially if you're using something like tailwind, which really gets a little bit verbose.
Lazarus:So this is just kind of a very cool pattern. Use the modal you want to use from any other front end, you know, templates or framework or whatever it is that you want, you know, there's plenty of them out there. So find 1 you like, style it how you want, and then you can just use this sort of, you know, mouseover pattern for the button to load in just the content you want to that model. I think that's a really clean, efficient, really nice pattern for the user.