Wednesday, 5 September 2007

RedBox Rules!

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).



Digg Technorati del.icio.us Stumbleupon Reddit Blinklist Furl Spurl Yahoo Simpy

Please also visit the Swirrl blog

20 comments:

Anonymous said...

Thanks for the writeup Rich. :)

Although you say "no obvious bugs", it is the case that redbox has some "limitations", which a few people have bumped up against, probably as a result of it being a bit too simple for some people's needs. Good to see your list of other available options, I've met a few people who have such plugins but I've never seen a good list.

regards,

Craig (redbox author)

Richard Roberts said...

One of the reasons I like RedBox is that it doesn't try to do anything fancy. All I wanted was a reliable modal dialog that I could use with rails without too much messing about. If I want anything extra, I can add it myself.

fred said...

I found it very easy to use.
but I came across this problem with the CSS, the modal windows shows in the top of the page.
If I have a page list with many entries and if i click at the bottom item, I would have to scroll up to see the modal windows.

anyone has a nicer CSS to drop in?
thanks.

bparanj said...

Hi Rich,

Nice post. I found it very useful. Could you please give me some pointers on how to handle multi-step process using redbox?

Thanks,
Bala

Anonymous said...

Hi,

thanks for the tutorial, needed some code examples to understand how it works (a bit too minimal for me on craigambrose website)

but I got a really weird error with link_to_remote_redbox

I call my link like this:

link_to_remote_redbox(article.title, :url => {:controller=>'articles', :action=>'show',:id=>article.id})


but for some reason, the url called is
/articles/ID and not /articles/show/id

if I remove the id:
link_to_remote_redbox(article.title, :url => {:controller=>'articles', :action=>'show'})

the url called is correct: /articles/show
but indeed the ID isn't passed to the controller.

it all seems so easy to implement, but I'm stucked for 2 hours now.... :(

thanks for your help

Richard Roberts said...

juju,

How are your routes configures for your rails app? The way that your app interprets url arguments will depend on your config/routes.rb file.

Hope this helps,
Rich

Richard Roberts said...

bparanj,

Sorry I've not responded sooner. What aspects are you having trouble with?

I've supplied a code snippet in the post for doing multi-step processes. Whatever the next url renders will replace the contents of the redbox.

Cheers,
Rich

Anonymous said...

wow, that's a fast answer :)

I just got into that actually, figured out my RESTfull routes might bring an error..

I use a ressource route
map.resources :articles, :collection => {:admin => :get}

it's my first project using RESTfull, I must say I'm still not very comfortable with this...

I found a trick to display the content as I wished, using this link:

link_to_remote_redbox(article.title, :url => {:controller=>'articles', :action=>"show/"+article.id.to_s} )

but that certainly looks really ugly

also it brings me the "show" with the full page layout, I think I missed something fundamental again...

thanks for your help

Richard Roberts said...

juju,

Regarding layout, you might want to render the action with a special layout i.e. in your action's code, use something like render :layout=>'modal'. You'll obviously need to make a modal layout first :).

Without knowing how your routes are set up, I can't help you with those I'm afraid! The routing chapter in the Pragmatic Programmers' book: 'Agile Web Development with Rails' is a good place to start.

Rich.

Anonymous said...

thanks a lot, created a modal layout, works good now.

for the routes...
I have the "agile web developpment with rails" right on my desk, also have a few screencasts from peepcode and railscast, but it's really a hard topic for me.

I'll study more, for the moment I'll just use a regular link to the article with "article_url(article)" and will implement the redbox when I'll understand how to setup my routes correctly.

Anonymous said...

pfiouf... after all I didn't give up, defined my routes correctly, fixed my modal layout to add the close link...
and it works all good.

thanks a lot for putting me into the good direction !!

cheers
julien

bparanj said...

Rich, I used the link_to_remote helper inside a form_for with form elements, when it goes to the next page, params does not have the values for the form elements. How do you submit the form values? TIA.

bparanj said...

Rich, I am using link_to_remote inside form_form, when the second page loads the params hash does not have the values of the form elements. How to fix this problem? TIA.

Richard Roberts said...

bparanj,

How are you submitting the form? I'm not doing anything particularly fancy here - you still need to do somehthing submit the form (you'll probably want to do this asynchronously).

You could either change the link to the next redbox page to be your submit button, and load up the next page after submit, or change the link so it submits before loading the next page. I'll leave that up to you.

Cheers,
Rich.

amiteshks said...

Thanks for the cool article.
However I could not get redbox work for form validation. How to handle Validation Error on the redbox

Do you have an example to show how form validation works for redbox?

Thanks,
Elvis

Anonymous said...

thanx For Information

Ravi Vardhan said...

Hi,

i have used redbox in my rails app,its working fine but it is displaying left top of the page.it should display center of the page.

give me solution for this,

thanks

Richard Roberts said...

Ravi,

Without any info about how you're using redbox, I'm afraid I can't help you.

Anyway, I'm not using redbox any more due to some cross-browser compatibility issues.

Please keep an eye on my blog for other modal dialog solutions. (btw, my blog has moved to ricroberts.com.

Cheers.

Anonymous said...

Hi Craig,

I just got a requirement that it looks like RedBox will fill perfectly. I'm having a problem getting it to display anything inside the redbox though and figure I'm misunderstanding something basic. So here's a newbie question.

I put a link_to_remote_redbox in application.rhtml to launch a redbox.

I put an empty method in purchases_controller.rb
def redbox_test
end

Now here's where I get confused. I see in Firebug that the link_to_remote_redbox is POSTing an XHR.

So I first created an RJS view: redbox_test.rjs that contains one line:
page.alert "something tasty!"

This throws an error: No such file or directory ... redbox_test.rhtml

Why is Rails looking for .rhtml instead of .rjs, I ask myself. Oh well, try a simple .rhtml. Oh yeah, the example shows an erb link to close the window. Ok. So I create redbox_test.rhtml. It's got one line...

link_to_close_redbox "Cancel"

So now I don't get an error when I use the first link, and a Redbox is displayed and looks like it's loading something. But no "Cancel" link shows up. Just the grey overlay.

So.... a couple of questions...

Why is Rails looking for a rhtml template to respond to an XHR?

What am I doing wrong wrt displaying the link inside the redbox?

Thanks,
Bill

Richard Roberts said...

Hi, Bill. By the way, I'm not Craig - he's the author of Redbox. I've not used redbox for a while, so I'm probably not the best person to help you out. Try posting a question on Craig's site.

Also, this blog has moved to www.ricroberts.com. There's a recent post on there about using lightview for modal windows, which you might find interesting.