How-to: Fancybox 2 and Rails forms

What follows is a brief tutorial on adding Fancybox Version 2 lightboxes to a Rails app to handle data entry forms.

The starting point for this post is an already functioning Rails app. For the purposes of this post, I created an example Rails app that can be found on The New Address button opens a lightbox with a remote form. I’m working with Rails 4.1.7 and Ruby 2.1.4. (I haven’t tried it but the following would probably work with anything Rails 3.2+ and Ruby 1.9.3+.)

A word about Fancybox Version 2. I know it’s against the grain to pay actual money to use gems but please be respectful of their license choice and pay the small fee if you need to. (Think about it this way – we all like to get paid for our work.)

To get started, add the fancybox2-rails gem to the Gemfile, application.css and application.js as described in the fancybox2-rails README. Don’t forget to run bundle install and restart the Rails app.

To complete the gem installation, define how the lightbox should look and behave with some Coffeescript:

These are settings I’ve chosen for my basic form. There are many other settings which are well documented on the Version 2 website. I even found the docs (here and here) for Version 1 helpful.

For example, I thought the overlay was too dark so I modified it with:

Now for the fun part – connecting the dots in Rails.

In our example, we have a New Address entry form that appears in a fancybox lightbox when a button is clicked. The user navigates to the address index page, clicks on New Address, a lightbox opens, they enter the data, click on Save and the list on the index page is updated. The Address model has some validation so if there’s an error, the user stays on the lightbox with error messages.

In the address controller, we’re concerned with the new and create actions. We also need a view for the fancybox new.html.haml and the corresponding JS file for the create response, create.js.haml.

First the controller’s new action:

Notice that a separate layout specific for the lightbox is being used. You want a very plain layout for this instead of reloading the application layout with all its includes and other settings.

Next the view for the new action which displays the form in the lightbox:

What to notice is the data: {remote: true} on the form and the onClick event for the close button, onclick: '$.fancybox.close();'

Next the controller’s create action (standard stuff):

And the corresponding JS create.js.haml.

Notice, we need to close the fancybox after the list of addresses on the index page is updated.

The final connecting dot is the button on the index page:

Notice the fancybox class was added to the button link.

Another feature is the ability to set the width of the lightbox. This is accomplished with the data: {fancybox_width: 350} on the button link and the following lines in the fancybox JS settings:

(Not a typo. The underscore in the link_to data element is interpreted as a dash by HAML.)

And ta-da, you have a working Fancybox Version 2 lightbox.

A final thought. I want to once again thank all the devs that ask and answer questions on StackOverflow. Laid out in steps like this, it all seems so logical. However(!) there was a lot of trial and error to get everything just right. I wish I’d kept track so I could list specific references.