Note: The RichText blog has moved to www.ricroberts.com
As you might have noticed from previous posts in this blog, I'm somewhat interested in modal dialogs in Ruby On Rails.
Up until now, I've been happily using the Prototype Window Class. However, it's quite a lot of js (a lot of which I don't use), and I've recently found a few small bugs in it. I'm not denying it's an impressive piece of work - it's just that there were a few niggles (Check out the forums).
Anyway, I've been investigating a few other options (namely: SubModal, ThickBox, LivePipe's Control.Modal, LightBox Gone Wild, StickyWin) and then I eventually found RedBox.
Most of the options I considered are variations on the LightBox theme, but RedBox stood out for me because of it's simplicity and ease of use with RoR. It doesn't do anything particularly fancy, but it ticked all my boxes (i.e. easily customisable, works well with Rails, small size of javascript, no obvious bugs).
It really couldn't be simpler to use RedBox with Rails.
To install the RedBox plugin, in Terminal just run:
script/plugin install svn://rubyforge.org/var/svn/ambroseplugins/redbox
...from your Rails project folder. This will stick stuff in your vendor folder. Then, from the vendor/plugins/redbox folder, you can run:
rake update_scripts
...to copy the files to the relevant places in your project. (i.e. the public/javascripts, stylesheets folders etc.).
Now all that's left is to stick the javascript and stylesheet links into your layout:
<%= stylesheet_link_tag 'redbox' %>
<%# we need to include prototype, etc... %>
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag 'redbox' %>
To create a link to a RedBox, you can use the helpers that the author provides, the most useful of which I found to be the 'link_to_remote_redbox' helper. This allows you to launch a RedBox with some content from another page. For example:
<%= link_to_remote_redbox("redbox",
:url => {:controller=>'my_controller', :action=>'my_action',
:id=>'my_id'}) %>
Then, in the resulting RedBox dialog, you need some way of closing the it. To just close is very simple...
<%= link_to_close_redbox "Cancel" %>
It's also pretty easy to get it to do stuff after closing. For example, you could call a rails action, via an ajax call...
<%= link_to_close_redbox "OK", {:onclick => remote_function(
:url => {:controller=>'my_controller', :action=>'my_action',
:id=>'my_id'},
:complete => "$('spinner').hide();",
:before => "$('spinner').show();")
} %>
If you want, the rails action could do some rjs to update some of the main page.
(Of course, you could use a similar technique to submit a form on the dialog too).
One of my additional requirements was to be able to guide the users through a two-step process, within the constrains of the modal dialog (something I found fiddly with other modal dialog solutions). Here's how I did this with RedBox...
<%# to link to another page inside RedBox %>
<%= link_to_remote( 'hello',
:url => url_for(
:controller => "my_controller",
:action => "my_action",
:id => "my_id"),
:update => 'modal_content', # the div used by default for the dialog
:complete => 'RedBox.setWindowPosition();'#make sure it's centered
) %>
Notice how I call the RedBox's setWindowPosition() function once the update is complete. This is because the new page being shown might be a different size to the first one, and although the dialog automatically resizes to fit the content (which is nice), it doesn't automatically recenter itself. (Without this step, the dialog's top-left corner just stays in the same position).