Allows drag-n-drop reordering of ActiveRecord model items when using MySQL or PostgreSQL and jQuery.
Add the following to your Gemfile:
gem 'reorderable', "~> 0.2"
Add a file called
reorderable.rb to your
config/initializers directory with one of the following lines (depending on your database adapter):
require 'reorderable/active_record/mysql' require 'reorderable/active_record/postgresql'
Add the 'reoderable' declaration to any model you want to be reorderable, e.g.
# app/models/page.rb class Page < ActiveRecord::Base reorderable end
This gem depends on the sortable gem; the options you can pass to 'reorderable' are the same that you can pass to 'sortable'. The 'reorderable' delcaration further sets up a default scope for your model, so that items are properly ordered by default.
Add a 'reorder' entry to your routes
# config/routes.rb namespace :admin do resources :pages do post :reorder, :on => :collection end end
It's possible to dynamically add a route (see: http://openhood.com/rails/rails%203/2010/07/20/add-routes-at-runtime-rails-3/ for one such solution) or to have a reorderings_controller in this gem, but it wasn't clear whether either of those options were really worth it.
Add the following to any controller you want to have reordering facilities:
# app/controllers/admin/pages_controller.rb class Admin::PagesController < Admin::BaseController include Reorderable::ActionController end
You probably want something like this:
# app/views/admin/pages/index.html.erb <table> <thead> <tr> <th> </th> <th>Name</th> </tr> </thead> <tbody<%= reorderable_attributes(@pages, 'position')%>> <% @pages.each do |page| %> <tr id='<%= dom_id(page) %>'> <td class='move'>↕</td> <td><%= page.name %></td> </tr> <% end %> </tbody> </table>
The key bit is the "reorderable_attributes" helper method, which adds the proper HTML attributes to theelement such that the jQuery code can do an Ajax request to the server to reorder the items in the table.
Add the following to your layout file:
Note that you must already have jQuery included for this to work!