For a while, I’ve been thinking about how best to handle showing modal dialog boxes for my applications while utilizing Backbone views. A lot of interesting ideas passed through my head, but none of them seemed exactly right. Then I saw a post by Derick Bailey where he described how he uses Marionette’s Regions to handle the work. His post is a bit on the old side and Regions have changed a bit since, so I decided to look into how to do it myself.
There are several issues surrounding creating modal dialogs just with a view. As Derick talks about in his article, most plugins for creating these dialogs will remove (or just move) the actual element from DOM, so any events that you set up in the view will be lost.
Along with that, we lose reusability. By making the view handle the work of controlling the modal, it can’t be used in a place where you don’t want a modal window. By moving the modal functionality out of the view, it can be used anywhere in the application.
Now that we know we need to pull the modal functionality out of the views, it’s just a matter or figuring out where to put it. Marionette’s Regions are perfect for this. Regions are objects that represent a place that already exists in the DOM and they handle adding and removing views to/from that place in the DOM. Simply call
show on a Region to add a view there and call
close to remove it.
All we need to do is augment a Region to call the plugin’s method for showing the modal when the view is shown, make sure to hide the modal when the view is closed, and close the view when the modal is hidden.
Here I’ve developed a
ModalRegion that uses Twitter Bootstrap’s modal plugin:
There are a few things worth noting here:
- I created a
constructorfunction instead of
initialize. This is because if someone extends this Region, they’ll override the
initializefunction with theirs. This way, it won’t be overridden.
- I call
this.ensureEl(). This is a Region’s method for caching the jQuery object for the Regions element to
this.$el. Normally, this method is called in its
showmethod, but we needed
this.$elto be set up before that.
- There’s some strange things happening in that event handler:
- The ‘hidden’ event is fired by Twitter Bootstrap after it hides the modal.
- The object that is passed in as the second parameter to
onis a data object that is attached to
dataproperty. This isn’t commonly used, so many people don’t know it exists. If this is new to you, check out the API. I passed in this object as a way to make sure that the
closemethod was called on the region with the right context. There are several alternative ways to do this, and this probably isn’t the best way, but it avoids a closure and it helps me to teach you something you not have known about before.
onCloseare called immediately after the
closemethods are finished. This is a simple way for us to augment the
closemethods to do more than they normally do without overriding the functions.
Now it’s simple to use:
As simple as that. This can be changed pretty easily to use other plugins such as jQueryUI, KendoUI, Wijmo, etc. Also, now that the modal functionality is in one place, if you end up switching the plugin that you use, you only have to change the code in this region and everything should work fine. The only thing you’ll need to work at is getting all the modal-specific markup in there. God bless and happy coding.