Sunday 6 May 2012

Sortable List in Ruby on Rails 3 – Unobtrusive jQuery

Sortable List in Ruby on Rails 3 – Unobtrusive jQuery

Step 1 – create app

$ rails new books -d mysql

Step 2 – replace contents in rails.js with following (switch from prototype to jquery)

http://github.com/rails/jquery-ujs/blob/master/src/rails.js

Step 3 – bundler

Go to gemfile
gem "rails"
gem "mysql2"
gem "acts_as_list"

# go to console:
$ bundle install

Step 4 – to be quick will scaffold a resource

$ cd books
$ rails g scaffold books name:string
# make sure your config/database.yml file is filled in correctly
$ rake db:create
$ rake db:migrate
Add acts_as_list to model
# book.rb
class Book < ActiveRecord::Base
  acts_as_list
end

Step 5 – add jquery to view and setup javascript content_for

Go to app/views/layouts/books.html.erb
Change this:
<%= javascript_include_tag :defaults %>
To this:
<%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js", "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js", "rails.js" %>
Also before /body add:
<%= yield :javascript %>

Step 6 – seed the db

Go to db/seeds.rb
#db/seeds.rb
book = Book.create([{ :name => 'Harry Potter' }, { :name => 'Twilight' }, { :name => 'Bible' }])

# back to console
$ rake db:seed
# doesn't work - need to add the position column to books in database
$ rails g migration add_position_to_books position:integer
$ rake db:migrate
$ rake db:seed

Step 7 – edit index for li – tables don’t work

<h1>Listing books</h1>
<ul id="books"> <% @books.each do |book| %>
  <li id="book_<%= book.id %>"><span class="handle">[drag]</span><%= book.name %></li>
<% end %></ul>
<%= link_to 'New book', new_book_path %>

Step 8 – add javascript in view

# index.html.erb
<% content_for :javascript do %>
<%= javascript_tag do %>
// Sorting the list

$(document).ready(function(){
$('#books').sortable({
axis: 'y',
dropOnEmpty: false,
handle: '.handle',
cursor: 'crosshair',
items: 'li',
opacity: 0.4,
scroll: true,
update: function(){
$.ajax({
type: 'post',
data: $('#books').sortable('serialize'),
dataType: 'script',
complete: function(request){
$('#books').effect('highlight');
},
url: '/books/sort'})
}
});
});
<% end %>
<% end %>

Step 9 – controller

#books_controller.rb
def index
@books = Book.order('books.position ASC')
end

def sort
@books = Book.all
@books.each do |book|
book.position = params['book'].index(book.id.to_s) + 1
book.save
end

render :nothing => true
end

Cursor

#style.css
.handle:hover{cursor: move;}

Final step – routes

root to: "books#index"
resources :books do
post :sort, on: :collection
# ruby 1.8 would go :on => :collection
end
PS: if you want an all-in-one resource to become an expert in ruby on rails 3, I wouldn’t bother with textbooks – just buy this video tutorial series (and if you get it through this link I get some commission): Ruby on Rails Tutorial


http://webtempest.com/sortable-list-in-ruby-on-rails-3-almost-unobtrusive-jquery/

No comments:

Post a Comment