thoughtbot-sortable_table 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Dan Croak
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,140 @@
1
+ h1. Sortable Table
2
+
3
+ Sort HTML tables in your Rails app.
4
+
5
+ h2. Install
6
+
7
+ script/plugin install git://github.com/thoughtbot/sortable_table.git
8
+
9
+ In app/controllers/application_controller.rb:
10
+
11
+ class ApplicationController < ActionController::Base
12
+ include SortableTable::App::Controllers::ApplicationController
13
+ end
14
+
15
+ In app/helpers/application_helper.rb:
16
+
17
+ module ApplicationHelper
18
+ include SortableTable::App::Helpers::ApplicationHelper
19
+ end
20
+
21
+ h2. Testing
22
+
23
+ <pre><code>
24
+ context "enough Users to sort" do
25
+ setup do
26
+ 5.times { Factory :user }
27
+ end
28
+
29
+ should_sort_by_attributes :name, :email, :age, :group => "groups.name"
30
+
31
+ context "GET to #index" do
32
+ setup { get :index }
33
+
34
+ should_display_sortable_table_header_for :name, :email, :age, :group
35
+ end
36
+ end
37
+ </code></pre>
38
+
39
+ This is the common case for a RESTful UsersController.
40
+
41
+ * should_sort_by_attributes tests that the controller's index action can sort by the attributes.
42
+ * should_display_sortable_header_for tests that a sortable header displays for the attributes.
43
+
44
+ h2. Controller
45
+
46
+ <pre><code>
47
+ class UsersController < Admin::BaseController
48
+ sortable_attributes :name, :email, :age, :group => "groups.name"
49
+
50
+ def index
51
+ @users = User.paginate :page => params[:page], :order => sort_order
52
+ end
53
+ end
54
+ </code></pre>
55
+
56
+ sortable_attributes defines a sort_order method that gets called in your action.
57
+
58
+ If the index action is rendered without a params[:sort] option, @users will be sorted by :name, the first option in the list of sortable_attributes.
59
+
60
+ h2. View
61
+
62
+ <pre><code>
63
+ <h1>Users</h1>
64
+ <table>
65
+ <tr>
66
+ <%= sortable_table_header :name => "Name", :sort => "name" %>
67
+ <%= sortable_table_header :name => "Email", :sort => "email" %>
68
+ <%= sortable_table_header :name => "Age", :sort => "age" %>
69
+ <%= sortable_table_header :name => "Group", :sort => "group" %>
70
+ </tr>
71
+ <% @users.each do |user| %>
72
+ <tr>
73
+ <td><%= html_escape(user.name) %></td>
74
+ <td><%= html_escape(user.email) %></td>
75
+ <td><%= html_escape(user.age) %></td>
76
+ <td><%= html_escape(user.group.name) %></td>
77
+ </tr>
78
+ <% end %>
79
+ </table>
80
+ </code></pre>
81
+
82
+ sortable_table_header creates a table header containing a link with the correct :sort and :order params. It also has a class of "ascending" or "descending" so you can add styles with arrows. You can add your own styles as well.
83
+
84
+ h2. Example styles
85
+
86
+ th.ascending a {
87
+ background: url(/images/sort-ascending-arrow.gif) 0% 50% no-repeat;
88
+ padding-left: 15px;
89
+ }
90
+
91
+ th.descending a {
92
+ background: url(/images/sort-descending-arrow.gif) 0% 50% no-repeat;
93
+ padding-left: 15px;
94
+ }
95
+
96
+ h2. Overriding defaults
97
+
98
+ h3. should_sort_by_attributes
99
+
100
+ Opinionated defaults:
101
+
102
+ * GET to :index
103
+ * collection same name as controller (@users for UsersController)
104
+ * model name same name as controller (User for UsersController
105
+
106
+ If you need to test another action (or a nested controller), pass a block:
107
+
108
+ should_sort_by_attributes :age do |sort, order|
109
+ get :show, :sort => sort, :order => order, :group_id => @group.id
110
+ end
111
+
112
+ If you need to test another collection or model name, use should_sort_by.
113
+
114
+ h3. should_sort_by
115
+
116
+ The :collection, :model_name, and :action options of should_sort_by.
117
+
118
+ context "with a non-standard collection name" do
119
+ action = lambda { |sort, order| get :members, :sort => sort, :order => order }
120
+ should_sort_by :name, { :collection => "members",
121
+ :model_name => "user",
122
+ :action => action } do |user|
123
+ user.name
124
+ end
125
+ end
126
+
127
+ h3. sort_order
128
+
129
+ The default sort order is descending. This applies to the first time you click on a table header. You can override this to be ascending:
130
+
131
+ def index
132
+ @users = User.find :all, :order => sort_order("ascending")
133
+ end
134
+
135
+ Authors
136
+ -------
137
+
138
+ Dan Croak, Joe Ferris, Jason Morrison and Boston.rb.
139
+
140
+ Copyright (c) 2008 Dan Croak, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'date'
4
+
5
+ test_files_pattern = 'test/rails_root/test/{unit,functional,other}/**/*_test.rb'
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'lib'
8
+ t.pattern = test_files_pattern
9
+ t.verbose = false
10
+ end
11
+
12
+ desc "Run the test suite"
13
+ task :default => :test
14
+
15
+ spec = Gem::Specification.new do |s|
16
+ s.version = '0.0.5'
17
+ s.name = "sortable_table"
18
+ s.summary = "Sort HTML tables in a Rails app."
19
+ s.email = "dcroak@thoughtbot.com"
20
+ s.homepage = "http://github.com/dancroak/sortable_table"
21
+ s.description = "Sort HTML tables in a Rails app."
22
+ s.authors = ["Dan Croak", "Joe Ferris", "Jon Yurek", "Boston.rb"]
23
+ s.files = FileList["[A-Z]*", "{lib,rails}/**/*"]
24
+ end
25
+
26
+ desc "Generate a gemspec file"
27
+ task :gemspec do
28
+ File.open("#{spec.name}.gemspec", 'w') do |f|
29
+ f.write spec.to_yaml
30
+ end
31
+ end
data/TODO.textile ADDED
@@ -0,0 +1,2 @@
1
+ * replace created_on with created_at
2
+
@@ -0,0 +1,2 @@
1
+ require "sortable_table/app/controllers/application_controller"
2
+ require "sortable_table/app/helpers/application_helper"
@@ -0,0 +1,95 @@
1
+ module SortableTable
2
+ module App
3
+ module Controllers
4
+ module ApplicationController
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ include InstanceMethods
9
+ extend ClassMethods
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ def sortable_attributes(*args)
15
+ mappings = pop_hash_from_list(args)
16
+ acceptable_columns = join_array_and_hash_values(args, mappings)
17
+ define_sort_order(acceptable_columns, mappings)
18
+ end
19
+
20
+ def pop_hash_from_list(*args)
21
+ if args.last.is_a?(Hash)
22
+ args.pop
23
+ else
24
+ {}
25
+ end
26
+ end
27
+
28
+ def join_array_and_hash_values(array, hash)
29
+ array.collect { |each| each.to_s } +
30
+ hash.values.collect { |each| each.to_s }
31
+ end
32
+
33
+ def define_sort_order(acceptable_columns, mappings)
34
+ define_method(:default_sort_column) do
35
+ acceptable_columns.first
36
+ end
37
+
38
+ attr_accessor :sortable_table_direction
39
+
40
+ define_method(:sort_order) do |*default|
41
+ default = default.first
42
+ direction = default_sort_direction(params[:order], default)
43
+ column = params[:sort] || default_sort_column
44
+ self.sortable_table_direction = direction
45
+ if params[:sort] && acceptable_columns.include?(column)
46
+ column = mappings[column.to_sym] || column
47
+ handle_compound_sorting(column, sql_sort_direction(direction))
48
+ else
49
+ "#{acceptable_columns.first} #{sql_sort_direction(direction)}"
50
+ end
51
+ end
52
+
53
+ helper_method :sort_order, :default_sort_column, :sortable_table_direction
54
+ end
55
+ end
56
+
57
+ module InstanceMethods
58
+ def default_sort_direction(order, default)
59
+ case
60
+ when ! order.blank? then normalize_direction(order)
61
+ when default.is_a?(Hash) && default[:default] then normalize_direction(default[:default])
62
+ else "descending"
63
+ end
64
+ end
65
+
66
+ def sql_sort_direction(direction)
67
+ case direction
68
+ when "ascending", "asc" then "asc"
69
+ when "descending", "desc" then "desc"
70
+ end
71
+ end
72
+
73
+ def normalize_direction(direction)
74
+ case direction
75
+ when "ascending", "asc" then "ascending"
76
+ when "descending", "desc" then "descending"
77
+ else raise RuntimeError.new("Direction must be ascending, asc, descending, or desc")
78
+ end
79
+ end
80
+
81
+ def handle_compound_sorting(column, direction)
82
+ if column.is_a?(Array)
83
+ column.collect { |each| "#{each} #{direction}" }.join(',')
84
+ else
85
+ "#{column} #{direction}"
86
+ end
87
+ end
88
+ end
89
+
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+
@@ -0,0 +1,64 @@
1
+ module SortableTable
2
+ module App
3
+ module Helpers
4
+ module ApplicationHelper
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ include InstanceMethods
9
+ end
10
+ end
11
+
12
+ module InstanceMethods
13
+ def sortable_table_header(opts = {})
14
+ raise ArgumentError if opts[:name].nil? || opts[:sort].nil?
15
+ anchor = opts[:anchor].blank? ? "" : "##{opts[:anchor]}"
16
+ content_tag :th,
17
+ link_to(opts[:name],
18
+ sortable_url(opts) + anchor,
19
+ :title => opts[:title]),
20
+ :class => sortable_table_header_classes(opts)
21
+ end
22
+
23
+ def sortable_table_header_classes(opts)
24
+ class_names = []
25
+ class_names << sortable_table_header_class(opts)
26
+ class_names << opts[:class]
27
+ class_names.compact.blank? ? nil : class_names.compact.join(" ")
28
+ end
29
+
30
+ def sortable_table_header_class(opts)
31
+ if re_sort?(opts) || sorting_default?(opts)
32
+ sortable_table_direction
33
+ end
34
+ end
35
+
36
+ def sorting_default?(opts)
37
+ params[:sort].nil? && opts[:sort] == default_sort_column
38
+ end
39
+
40
+ def re_sort?(opts)
41
+ params[:sort] == opts[:sort]
42
+ end
43
+
44
+ def reverse_order(order)
45
+ order == 'ascending' ? 'descending' : 'ascending'
46
+ end
47
+
48
+ def sortable_url(opts)
49
+ url_for(params.merge(:sort => opts[:sort], :order => link_sort_order(opts), :page => 1))
50
+ end
51
+
52
+ def link_sort_order(opts)
53
+ if re_sort? opts
54
+ reverse_order params[:order]
55
+ else
56
+ reverse_order sortable_table_direction
57
+ end
58
+ end
59
+ end
60
+
61
+ end
62
+ end
63
+ end
64
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require "sortable_table"
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thoughtbot-sortable_table
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ platform: ruby
6
+ authors:
7
+ - Dan Croak
8
+ - Joe Ferris
9
+ - Jon Yurek
10
+ - Boston.rb
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+
15
+ date: 2009-02-26 21:00:00 -08:00
16
+ default_executable:
17
+ dependencies: []
18
+
19
+ description: Sort HTML tables in a Rails app.
20
+ email: dcroak@thoughtbot.com
21
+ executables: []
22
+
23
+ extensions: []
24
+
25
+ extra_rdoc_files: []
26
+
27
+ files:
28
+ - MIT-LICENSE
29
+ - Rakefile
30
+ - README.textile
31
+ - TODO.textile
32
+ - lib/sortable_table
33
+ - lib/sortable_table/app
34
+ - lib/sortable_table/app/controllers
35
+ - lib/sortable_table/app/controllers/application_controller.rb
36
+ - lib/sortable_table/app/helpers
37
+ - lib/sortable_table/app/helpers/application_helper.rb
38
+ - lib/sortable_table.rb
39
+ - rails/init.rb
40
+ has_rdoc: false
41
+ homepage: http://github.com/dancroak/sortable_table
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.2.0
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: Sort HTML tables in a Rails app.
66
+ test_files: []
67
+