In “Railscast 258”:http://railscasts.com/episodes/258-token-fields “Ryan Bates”:https://github.com/ryanb shows how to use “Token Fields”:http://loopj.com/jquery-tokeninput/, javascript plugin which helps adding entries for many
and many to many
association. In this article I will exetend railscast and show you how to create not existing entries with ajax.
You can “download”:https://github.com/slawosz/Add-resource-with-ajax-and-facebox-tutorial application for this tutorial from github or use it on “heroku”:http://add-new-resource-with-ajax.heroku.com/ to see how it works. I started with application created by Ryan in 258 episode.
To add authors we can go to /author/new
url, but when we already on /books/new
we rather want to render form with ajax. To render form we will use “facebox”:https://github.com/defunkt/facebox, writen in jquery by “Chris Wanstrath”:https://github.com/defunkt. So, simply download facebox from github, decompress and place facebox.css
in public/stylesheets
, facebox.js
in public/javascripts
and loading.gif
and closelabel.png
in public/images
Now, point write paths for images in public/javascripts/facebox.js
:
and place stylesheet and javascript in our layout app/views/layouts/application.html.erb
:
Now it is time to show form for new author resource on facebox.
Lets add link in app/views/books/_form.html.erb
partial:
It looks like a normal link, but with one exception: it has a remote option, indicating, that we want perform an ajax request with this link. This is new way in Rails 3 to generate ajax request and I think it is great. It simply adds a html data-remote='true'
attribute to our link. Javascript code located in public/javascripts/rails.js
binds onclick
event on such link. Whe link is clicked, an ajax request is performed to links url, in our case to new_author_path
. So now, we have rewrite new method in AuthorsController
, which is our link destination. You can read more about Rails 3 unobtrusive javascript in “Simone Carletti”:http://www.simonecarletti.com/blog/2010/06/unobtrusive-javascript-in-rails-3/ blog.
With Rails it is so simple :) We had to add only a new template in js format, app/views/authors/new.js.erb
. When we click link, method new will recognize that request is in js format and render js template. So now, in template we will write code, which will render new action on facebox:
Code above generate a form on facebox with app/views/books/new.html.erb
template. We have to add write new.html to generate html. Much more often in rich ajax Rails application we use partials, but I would like to show how to achieve our goal with minimal effort.
If you would like to know more about using facebox, see public/javascripts/facebox.js
. Every use case is described in this file.
Now, we want to send our form and create a new author. Normaly, we can use
option in our form, but we only use remote form in facebox. So, let’s add data-remote attribute to ajax form in facebox. To do it, we will add following to app/views/books/new.js.erb
:
This will add attribute data-remote='true'
to our form, and with this attribute, public/javascripts/rails.js
will process our form with ajax. After submiting, the request goes to method create in AuthorsController
and is looking for js template. In this template, we need only close facebok. So, we create file app/views/authors/create.js.erb
and write:
Thus we would like to perform other actions in html and js request in this method, we use respond_to
block and redirect on html format and render template on js format:
Now it works, but it need some more improvements. When @author
instance cannot be save, we should render form again in facebox. In app/models/author.rb
we add validadion:
Now we cannot add new no-name author. When we try, we got validation error, which we want to show in facebox.
At first we need to change create action to use js format in else section:
And finally change app/views/books/create.js.erb
:
Now we have fully working form on facebox, with minimal changes in our code. We can do last small improvement, remove link ‘Back to List’. In facebox link is completely unnecessary. After checking source of app/views/authors/new.html.erb
we simply need remove last <p>
tag. In jQuery, it’s simple:
We add this line at the end app/views/authors/new.js.erb
and at the end in else section in app/views/authors/create.js.erb
. Now we are done.
See our application working on “heroku”:http://add-new-resource-with-ajax.heroku.com/, and check the repo on “github”:https://github.com/slawosz/Add-resource-with-ajax-and-facebox-tutorial. All changes you can see in “cf13adacdff595059dc6eba0fcb33c0204ad6714”:https://github.com/slawosz/Add-resource-with-ajax-and-facebox-tutorial/commit/cf13adacdff595059dc6eba0fcb33c0204ad6714
I hope this tutorial will be helpfull for You. Any feedback is welcome.