tvdeyen-handles_sortable_columns 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YzQzYWI5MjU4OTg2YTIwM2NjNmQ5YjJiNjU3NWYyMWIyMzJlMTRmNQ==
5
+ data.tar.gz: !binary |-
6
+ YTUwNzkyY2ExZjRlOWU1MDI3MjJhYWZmNzIwMGQzODNhZGIyM2NjOA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NTljZmQ1ZjdhYTY1Yzc1MzJkZmM4MTAxYmRhZWExMmMyODRlZmYyODZjZWM5
10
+ OTFjZDE1OWNhODMyNDk2MjVjOWI0NmY3YzhlMmE1OGFiZDI5NTAyZGNjMTk4
11
+ OTFmM2IwOTFlY2I2ZDg4NTNhZGQ1MDQ5YTcwNjVkNTBjOTY1NzA=
12
+ data.tar.gz: !binary |-
13
+ YjFiYzdjODQ4MDM2ZWY5MDcxYjQyMDIwOWIwNTVkYzAzN2ZiM2Y3OWUzYzY3
14
+ MjgzZGI3NjQ0ZTkzMDAzYWMwZDZhNTdmMTE5OWMxOTE5MDg2MjFlMGZjMjY1
15
+ ZDNmODE1OTM2Zjg3MDA5ZTRiYWI2M2M0YjgyNzQ1N2M0ZjMwZmI=
@@ -0,0 +1,9 @@
1
+ # General Ruby, sorted by first letter.
2
+ .old*
3
+ *-old*
4
+ .ref*
5
+
6
+ # Project-specific.
7
+ /doc/
8
+ /pkg/
9
+ /.rvmrc
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010-2011 Alex Fortuna
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.
@@ -0,0 +1,140 @@
1
+ <head>
2
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
3
+ <link href="dev/github.css" rel="stylesheet" type="text/css" />
4
+ </head>
5
+
6
+ <h1 id="sortable-table-columns">Sortable Table Columns</h1>
7
+
8
+ <h2 id="introduction">Introduction</h2>
9
+
10
+ <p>A simple yet flexible Rails gem/plugin to quickly add sortable table columns to your controller and views.</p>
11
+
12
+ <h2 id="setup-rails-3">Setup (Rails 3)</h2>
13
+
14
+ <p>In your app’s <code>Gemfile</code>, add:</p>
15
+
16
+ <pre><code>gem "handles_sortable_columns"
17
+ </code></pre>
18
+
19
+ <p>To install the gem with RDoc/ri documentation, do a:</p>
20
+
21
+ <pre><code>$ gem install handles_sortable_columns
22
+ </code></pre>
23
+
24
+ <p>Otherwise, do a <code>bundle install</code>.</p>
25
+
26
+ <h2 id="setup-rails-2">Setup (Rails 2)</h2>
27
+
28
+ <p>In your app’s <code>config/environment.rb</code> add:</p>
29
+
30
+ <pre><code>config.gem "handles_sortable_columns"
31
+ </code></pre>
32
+
33
+ <p>To install the gem, do a:</p>
34
+
35
+ <pre><code>$ gem sources --add http://rubygems.org
36
+ $ gem install handles_sortable_columns
37
+ </code></pre>
38
+
39
+ <p>, or use <code>rake gems:install</code>.</p>
40
+
41
+ <h2 id="basic-usage">Basic Usage</h2>
42
+
43
+ <p>Activate the feature in your controller class:</p>
44
+
45
+ <pre><code>class MyController &lt; ApplicationController
46
+ handles_sortable_columns
47
+ ...
48
+ </code></pre>
49
+
50
+ <p>In a view, mark up sortable columns by using the <tt>sortable_column</tt> helper:</p>
51
+
52
+ <pre><code>&lt;%= sortable_column "Product" %&gt;
53
+ &lt;%= sortable_column "Price" %&gt;
54
+ </code></pre>
55
+
56
+ <p>In controller action, fetch and use the order clause according to current state of sortable columns:</p>
57
+
58
+ <pre><code>def index
59
+ order = sortable_column_order
60
+ @records = Article.order(order) # Rails 3.
61
+ @records = Article.all(:order =&gt; order) # Rails 2.
62
+ end
63
+ </code></pre>
64
+
65
+ <p>That’s it for basic usage. Production usage may require passing additional parameters to listed methods.</p>
66
+
67
+ <h2 id="production-usage">Production Usage</h2>
68
+
69
+ <p>Please take time to read the gem’s full <a href="http://rdoc.info/projects/dadooda/handles_sortable_columns">RDoc documentation</a>. This README has a limited coverage.</p>
70
+
71
+ <h3 id="configuration">Configuration</h3>
72
+
73
+ <p>Change names of GET parameters used for sorting and pagination:</p>
74
+
75
+ <pre><code>class MyController &lt; ApplicationController
76
+ handles_sortable_columns do |conf|
77
+ conf.sort_param = "s"
78
+ conf.page_param = "p"
79
+ end
80
+ ...
81
+ </code></pre>
82
+
83
+ <p>Change CSS class of all sortable column <code>&lt;a&gt;</code> tags:</p>
84
+
85
+ <pre><code>handles_sortable_columns do |conf|
86
+ conf.class = "SortableLink"
87
+ conf.indicator_class = {:asc =&gt; "AscSortableLink", :desc =&gt; "DescSortableLink"}
88
+ end
89
+ </code></pre>
90
+
91
+ <p>Change how text-based sort indicator looks like:</p>
92
+
93
+ <pre><code>handles_sortable_columns do |conf|
94
+ conf.indicator_text = {:asc =&gt; "[asc]", :desc =&gt; "[desc]"}
95
+ end
96
+ </code></pre>
97
+
98
+ <p>Disable text-based sort indicator completely:</p>
99
+
100
+ <pre><code>handles_sortable_columns do |conf|
101
+ conf.indicator_text = {}
102
+ end
103
+ </code></pre>
104
+
105
+ <h3 id="helper-options">Helper Options</h3>
106
+
107
+ <p>Explicitly specify column name:</p>
108
+
109
+ <pre><code>&lt;%= sortable_column "Highest Price", :column =&gt; "max_price" %&gt;
110
+ </code></pre>
111
+
112
+ <p>Specify CSS class for this particular link:</p>
113
+
114
+ <pre><code>&lt;%= sortable_column "Name", :class =&gt; "SortableLink" %&gt;
115
+ </code></pre>
116
+
117
+ <p>Specify sort direction on first click:</p>
118
+
119
+ <pre><code>&lt;%= sortable_column "Created At", :direction =&gt; :asc %&gt;
120
+ </code></pre>
121
+
122
+ <h3 id="fetching-sort-order">Fetching Sort Order</h3>
123
+
124
+ <p>To fetch sort order <strong>securely</strong>, with <strong>column name validation</strong>, <strong>default values</strong> and <strong>multiple sort criteria</strong>, use the block form of <code>sortable_column_order</code>:</p>
125
+
126
+ <pre><code>order = sortable_column_order do |column, direction|
127
+ case column
128
+ when "name"
129
+ "#{column} #{direction}"
130
+ when "created_at", "updated_at"
131
+ "#{column} #{direction}, name ASC"
132
+ else
133
+ "name ASC"
134
+ end
135
+ end
136
+ </code></pre>
137
+
138
+ <h2 id="feedback">Feedback</h2>
139
+
140
+ <p>Send bug reports, suggestions and criticisms through <a href="http://github.com/dadooda/handles_sortable_columns">project’s page on GitHub</a>.</p>
@@ -0,0 +1,137 @@
1
+
2
+ Sortable Table Columns
3
+ ======================
4
+
5
+
6
+ Introduction
7
+ ------------
8
+
9
+ A simple yet flexible Rails gem/plugin to quickly add sortable table columns to your controller and views.
10
+
11
+
12
+ Setup (Rails 3)
13
+ ---------------
14
+
15
+ In your app's `Gemfile`, add:
16
+
17
+ gem "handles_sortable_columns"
18
+
19
+ To install the gem with RDoc/ri documentation, do a:
20
+
21
+ $ gem install handles_sortable_columns
22
+
23
+ Otherwise, do a `bundle install`.
24
+
25
+
26
+ Setup (Rails 2)
27
+ ---------------
28
+
29
+ In your app's `config/environment.rb` add:
30
+
31
+ config.gem "handles_sortable_columns"
32
+
33
+ To install the gem, do a:
34
+
35
+ $ gem sources --add http://rubygems.org
36
+ $ gem install handles_sortable_columns
37
+
38
+ , or use `rake gems:install`.
39
+
40
+
41
+ Basic Usage
42
+ -----------
43
+
44
+ Activate the feature in your controller class:
45
+
46
+ class MyController < ApplicationController
47
+ handles_sortable_columns
48
+ ...
49
+
50
+ In a view, mark up sortable columns by using the <tt>sortable_column</tt> helper:
51
+
52
+ <%= sortable_column "Product" %>
53
+ <%= sortable_column "Price" %>
54
+
55
+ In controller action, fetch and use the order clause according to current state of sortable columns:
56
+
57
+ def index
58
+ order = sortable_column_order
59
+ @records = Article.order(order) # Rails 3.
60
+ @records = Article.all(:order => order) # Rails 2.
61
+ end
62
+
63
+ That's it for basic usage. Production usage may require passing additional parameters to listed methods.
64
+
65
+
66
+ Production Usage
67
+ ----------------
68
+
69
+ Please take time to read the gem's full [RDoc documentation](http://rdoc.info/projects/dadooda/handles_sortable_columns). This README has a limited coverage.
70
+
71
+
72
+ ### Configuration ###
73
+
74
+ Change names of GET parameters used for sorting and pagination:
75
+
76
+ class MyController < ApplicationController
77
+ handles_sortable_columns do |conf|
78
+ conf.sort_param = "s"
79
+ conf.page_param = "p"
80
+ end
81
+ ...
82
+
83
+ Change CSS class of all sortable column `<a>` tags:
84
+
85
+ handles_sortable_columns do |conf|
86
+ conf.class = "SortableLink"
87
+ conf.indicator_class = {:asc => "AscSortableLink", :desc => "DescSortableLink"}
88
+ end
89
+
90
+ Change how text-based sort indicator looks like:
91
+
92
+ handles_sortable_columns do |conf|
93
+ conf.indicator_text = {:asc => "[asc]", :desc => "[desc]"}
94
+ end
95
+
96
+ Disable text-based sort indicator completely:
97
+
98
+ handles_sortable_columns do |conf|
99
+ conf.indicator_text = {}
100
+ end
101
+
102
+
103
+ ### Helper Options ###
104
+
105
+ Explicitly specify column name:
106
+
107
+ <%= sortable_column "Highest Price", :column => "max_price" %>
108
+
109
+ Specify CSS class for this particular link:
110
+
111
+ <%= sortable_column "Name", :class => "SortableLink" %>
112
+
113
+ Specify sort direction on first click:
114
+
115
+ <%= sortable_column "Created At", :direction => :asc %>
116
+
117
+
118
+ ### Fetching Sort Order ###
119
+
120
+ To fetch sort order **securely**, with **column name validation**, **default values** and **multiple sort criteria**, use the block form of `sortable_column_order`:
121
+
122
+ order = sortable_column_order do |column, direction|
123
+ case column
124
+ when "name"
125
+ "#{column} #{direction}"
126
+ when "created_at", "updated_at"
127
+ "#{column} #{direction}, name ASC"
128
+ else
129
+ "name ASC"
130
+ end
131
+ end
132
+
133
+
134
+ Feedback
135
+ --------
136
+
137
+ Send bug reports, suggestions and criticisms through [project's page on GitHub](http://github.com/dadooda/handles_sortable_columns).
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/gem_helper'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ Bundler::GemHelper.install_tasks
9
+
10
+ task :default => :build
11
+
12
+ begin
13
+ require 'rdoc/task'
14
+ rescue LoadError
15
+ require 'rdoc/rdoc'
16
+ require 'rake/rdoctask'
17
+ RDoc::Task = Rake::RDocTask
18
+ end
19
+
20
+ desc "Generate RDoc documentation"
21
+ Rake::RDocTask.new(:rdoc) do |rdoc|
22
+ rdoc.rdoc_dir = "doc"
23
+ rdoc.title = "Handles::SortableColumns"
24
+ rdoc.rdoc_files.include("lib/**/*.rb")
25
+ end
@@ -0,0 +1,5 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 1
4
+ :patch: 5
5
+ #:build: pre1
@@ -0,0 +1,41 @@
1
+
2
+ body{font:13.34px helvetica,arial,freesans,clean,sans-serif;}
3
+ body{width:920px;margin:0 auto;padding:0 15px;text-align:left;}
4
+
5
+ /* Это неважно работает, с виду погано. */
6
+ xbody{background-color:#f8f8f8;padding:.7em;}
7
+
8
+ /*
9
+ #readme div.plain,#readme div.wikistyle{background-color:#f8f8f8;padding:.7em;}
10
+ .site{width:920px;margin:0 auto;padding:0 15px;text-align:left;}
11
+ #readme{font:13.34px helvetica,arial,freesans,clean,sans-serif;}
12
+ #readme.announce{margin:1em 0;}
13
+ #readme span.name{font-size:140%;padding:.8em 0;}
14
+ #readme div.plain,#readme div.wikistyle{background-color:#f8f8f8;padding:.7em;}
15
+ #readme.announce div.plain,#readme.announce div.wikistyle{border:1px solid #e9e9e9;}
16
+ #readme.blob div.plain,#readme.blob div.wikistyle{border-top:none;}
17
+ #readme div.plain pre{font-family:'Bitstream Vera Sans Mono','Courier',monospace;font-size:85%;color:#444;}
18
+ */
19
+
20
+ h1,h2,h3,h4,h5,h6{border:0!important;}
21
+ h1{font-size:170%!important;border-top:4px solid #aaa!important;padding-top:.5em!important;margin-top:1.5em!important;}
22
+ h1:first-child{margin-top:0!important;padding-top:.25em!important;border-top:none!important;}
23
+ h2{font-size:150%!important;margin-top:1.5em!important;border-top:4px solid #e0e0e0!important;padding-top:.5em!important;}
24
+ h3{margin-top:1em!important;}
25
+ p{margin:1em 0!important;line-height:1.5em!important;}
26
+ ul{margin:1em 0 1em 2em!important;}
27
+ ol{margin:1em 0 1em 2em!important;}
28
+ ul ul,ul ol,ol ol,ol ul{margin-top:0!important;margin-bottom:0!important;}
29
+ blockquote{margin:1em 0!important;border-left:5px solid #ddd!important;padding-left:.6em!important;color:#555!important;}
30
+ dt{font-weight:bold!important;margin-left:1em!important;}
31
+ dd{margin-left:2em!important;margin-bottom:1em!important;}
32
+ table{margin:1em 0!important;}
33
+ table th{border-bottom:1px solid #bbb!important;padding:.2em 1em!important;}
34
+ table td{border-bottom:1px solid #ddd!important;padding:.2em 1em!important;}
35
+ pre{margin:1em 0!important;font-size:90%!important;background-color:#f8f8ff!important;border:1px solid #dedede!important;padding:.5em!important;line-height:1.5em!important;color:#444!important;overflow:auto!important;}
36
+ pre code{padding:0!important;font-size:100%!important;background-color:#f8f8ff!important;border:none!important;}
37
+ code{font-size:90%!important;background-color:#f8f8ff!important;color:#444!important;padding:0 .2em!important;border:1px solid #dedede!important;}
38
+ pre.console{margin:1em 0!important;font-size:90%!important;background-color:black!important;padding:.5em!important;line-height:1.5em!important;color:white!important;}
39
+ pre.console code{padding:0!important;font-size:100%!important;background-color:black!important;border:none!important;color:white!important;}
40
+ pre.console span{color:#888!important;}
41
+ pre.console span.command{color:yellow!important;}
@@ -0,0 +1,4 @@
1
+ <head>
2
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
3
+ <link href="dev/github.css" rel="stylesheet" type="text/css" />
4
+ </head>
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Rails plugin init.
2
+ require File.join(File.dirname(__FILE__), "lib/handles_sortable_columns")
@@ -0,0 +1,5 @@
1
+ module ActionController #:nodoc:
2
+ class Base #:nodoc:
3
+ include ::Handles::SortableColumns
4
+ end
5
+ end
@@ -0,0 +1,307 @@
1
+ module Handles #:nodoc:
2
+ # == Overview
3
+ #
4
+ # A sortable columns feature for your controller and views.
5
+ #
6
+ # == Basic Usage
7
+ #
8
+ # Activate the feature in your controller class:
9
+ #
10
+ # class MyController < ApplicationController
11
+ # handles_sortable_columns
12
+ # ...
13
+ #
14
+ # In a view, mark up sortable columns by using the <tt>sortable_column</tt> helper:
15
+ #
16
+ # <%= sortable_column "Product" %>
17
+ # <%= sortable_column "Price" % >
18
+ #
19
+ # In controller action, fetch and use the order clause according to current state of sortable columns:
20
+ #
21
+ # def index
22
+ # order = sortable_column_order
23
+ # @records = Article.order(order) # Rails 3.
24
+ # @records = Article.all(:order => order) # Rails 2.
25
+ # end
26
+ #
27
+ # That's it for basic usage. Production usage may require passing additional parameters to listed methods.
28
+ #
29
+ # See also:
30
+ # * MetaClassMethods#handles_sortable_columns
31
+ # * InstanceMethods#sortable_column_order
32
+ module SortableColumns
33
+ def self.included(owner) #:nodoc:
34
+ owner.extend MetaClassMethods
35
+ end
36
+
37
+ # Sortable columns configuration object. Passed to the block when you do a:
38
+ #
39
+ # handles_sortable_columns do |conf|
40
+ # ...
41
+ # end
42
+ class Config
43
+ # CSS class for link (regardless of sorted state). Default:
44
+ #
45
+ # SortableColumnLink
46
+ attr_accessor :link_class
47
+
48
+ # GET parameter name for page number. Default:
49
+ #
50
+ # page
51
+ attr_accessor :page_param
52
+
53
+ # GET parameter name for sort column and direction. Default:
54
+ #
55
+ # sort
56
+ attr_accessor :sort_param
57
+
58
+ # Default sort direction, if params[sort_param] is not given.
59
+ #
60
+ # default_sort_value
61
+ attr_accessor :default_sort_value
62
+
63
+ # Sort indicator text. If any of values are empty, indicator is not displayed. Default:
64
+ #
65
+ # {:asc => "&nbsp;&darr;&nbsp;", :desc => "&nbsp;&uarr;&nbsp;"}
66
+ attr_accessor :indicator_text
67
+
68
+ # Sort indicator class. Default:
69
+ #
70
+ # {:asc => "SortedAsc", :desc => "SortedDesc"}
71
+ attr_accessor :indicator_class
72
+
73
+ def initialize(attrs = {})
74
+ defaults = {
75
+ :link_class => "SortableColumnLink",
76
+ :indicator_class => {:asc => "SortedAsc", :desc => "SortedDesc"},
77
+ :indicator_text => {:asc => "&nbsp;&darr;&nbsp;", :desc => "&nbsp;&uarr;&nbsp;"},
78
+ :page_param => "page",
79
+ :sort_param => "sort",
80
+ :default_sort_value => nil
81
+ }
82
+
83
+ defaults.merge(attrs).each {|k, v| send("#{k}=", v)}
84
+ end
85
+
86
+ # Bracket access for convenience.
87
+ def [](key)
88
+ send(key)
89
+ end
90
+
91
+ # Bracket access for convenience.
92
+ def []=(key, value)
93
+ send("#{key}=", value)
94
+ end
95
+ end # Config
96
+
97
+ module MetaClassMethods
98
+ # Activate and optionally configure the sortable columns feature in your controller.
99
+ #
100
+ # class MyController < ApplicationController
101
+ # handles_sortable_columns
102
+ # ...
103
+ #
104
+ # With configuration:
105
+ #
106
+ # class MyController < ApplicationController
107
+ # handles_sortable_columns do |conf|
108
+ # conf.sort_param = "s"
109
+ # conf.page_param = "p"
110
+ # conf.indicator_text = {}
111
+ # ...
112
+ # end
113
+ # ...
114
+ #
115
+ # With filter options:
116
+ #
117
+ # class MyController < ApplicationController
118
+ # handles_sortable_columns(:only => [:index]) do |conf|
119
+ # ...
120
+ # end
121
+ # ...
122
+ #
123
+ # NOTE: <tt>conf</tt> is a Config object.
124
+ def handles_sortable_columns(fopts = {}, &block)
125
+ # Multiple activation protection.
126
+ if not self < InstanceMethods
127
+ include InstanceMethods
128
+ helper_method :sortable_column
129
+ end
130
+
131
+ # Process configuration at every activation.
132
+ before_filter(fopts) do |ac|
133
+ ac.instance_eval do
134
+ # NOTE: Can't `yield`, we're in a block already.
135
+ block.call(sortable_columns_config) if block
136
+ end
137
+ end
138
+ end
139
+ end # MetaClassMethods
140
+
141
+ module InstanceMethods
142
+ private
143
+
144
+ # Internal/advanced use only. Parse sortable column sort param into a Hash with predefined keys.
145
+ #
146
+ # parse_sortable_column_sort_param("name") # => {:column => "name", :direction => :asc}
147
+ # parse_sortable_column_sort_param("-name") # => {:column => "name", :direction => :desc}
148
+ # parse_sortable_column_sort_param("") # => {:column => nil, :direction => nil}
149
+ def parse_sortable_column_sort_param(sort) #:nodoc:
150
+ out = {:column => nil, :direction => nil}
151
+ if sort.to_s.strip.match /\A((?:-|))([^-]+)\z/
152
+ out[:direction] = $1.empty?? :asc : :desc
153
+ out[:column] = $2.strip
154
+ end
155
+ out
156
+ end
157
+
158
+ # Render a sortable column link.
159
+ #
160
+ # Options:
161
+ #
162
+ # * <tt>:column</tt> -- Column name. E.g. <tt>created_at</tt>.
163
+ # * <tt>:direction</tt> -- Sort direction on first click. <tt>:asc</tt> or <tt>:desc</tt>. Default is <tt>:asc</tt>.
164
+ # * <tt>:link_class</tt> -- CSS class for link, regardless of sorted state.
165
+ # * <tt>:link_style</tt> -- CSS style for link, regardless of sorted state.
166
+ #
167
+ # Examples:
168
+ #
169
+ # <%= sortable_column "Product" %>
170
+ # <%= sortable_column "Highest Price", :column => "max_price" %>
171
+ # <%= sortable_column "Name", :link_class => "SortableLink" %>
172
+ # <%= sortable_column "Created At", :direction => :asc %>
173
+ def sortable_column(title, options = {}) #:doc:
174
+ options = options.dup
175
+ o = {}
176
+ conf = {}
177
+ conf[k = :sort_param] = sortable_columns_config[k]
178
+ conf[k = :default_sort_value] = sortable_columns_config[k]
179
+ conf[k = :page_param] = sortable_columns_config[k]
180
+ conf[k = :indicator_text] = sortable_columns_config[k]
181
+ conf[k = :indicator_class] = sortable_columns_config[k]
182
+
183
+ #HELP sortable_column
184
+ o[k = :column] = options.delete(k) || sortable_column_title_to_name(title)
185
+ o[k = :direction] = options.delete(k).to_s.downcase =~ /\Adesc\z/ ? :desc : :asc
186
+ o[k = :link_class] = options.delete(k) || sortable_columns_config[k]
187
+ o[k = :link_style] = options.delete(k)
188
+ o[k = :link_style] = options.delete(k)
189
+ o[k = :route_proxy] = options.delete(k)
190
+ #HELP /sortable_column
191
+
192
+ raise "Unknown option(s): #{options.inspect}" if not options.empty?
193
+
194
+ # Parse sort param.
195
+ sort = params[conf[:sort_param]] || conf[:default_sort_value]
196
+ pp = parse_sortable_column_sort_param(sort)
197
+
198
+ css_class = []
199
+ if (s = o[:link_class]).present?
200
+ css_class << s
201
+ end
202
+
203
+ # If already sorted and indicator class defined, append it.
204
+ if pp[:column] == o[:column].to_s and (s = conf[:indicator_class][pp[:direction]]).present?
205
+ css_class << s
206
+ end
207
+
208
+ # Build link itself.
209
+ pcs = []
210
+
211
+ html_options = {}
212
+ html_options[:class] = css_class.join(" ") if css_class.present?
213
+ html_options[:style] = o[:link_style] if o[:link_style].present?
214
+
215
+ # Rails 3 / Rails 2 fork.
216
+ tpl = respond_to?(:view_context) ? view_context : @template
217
+
218
+ # Already sorted?
219
+ if pp[:column] == o[:column].to_s
220
+ if o[:route_proxy]
221
+ url = o[:route_proxy].send(:url_for, params.merge({conf[:sort_param] => [("-" if pp[:direction] == :asc), o[:column]].join, conf[:page_param] => 1}))
222
+ else
223
+ url = url_for(params.merge({conf[:sort_param] => [("-" if pp[:direction] == :asc), o[:column]].join, conf[:page_param] => 1}))
224
+ end
225
+ pcs << tpl.link_to(title, url, html_options) # Opposite sort order when clicked.
226
+
227
+ # Append indicator, if configured.
228
+ if (s = conf[:indicator_text][pp[:direction]]).present?
229
+ pcs << s
230
+ end
231
+ else
232
+ # Not sorted.
233
+ if o[:route_proxy]
234
+ url = o[:route_proxy].send(:url_for, params.merge({conf[:sort_param] => [("-" if o[:direction] != :asc), o[:column]].join, conf[:page_param] => 1}))
235
+ else
236
+ url = url_for(params.merge({conf[:sort_param] => [("-" if o[:direction] != :asc), o[:column]].join, conf[:page_param] => 1}))
237
+ end
238
+ pcs << tpl.link_to(title, url, html_options)
239
+ end
240
+
241
+ # For Rails 3 provide #html_safe.
242
+ (v = pcs.join).respond_to?(:html_safe) ? v.html_safe : v
243
+ end
244
+
245
+ # Compile SQL order clause according to current state of sortable columns.
246
+ #
247
+ # Basic (kickstart) usage:
248
+ #
249
+ # order = sortable_column_order
250
+ #
251
+ # <b>WARNING:</b> Basic usage is <b>not recommended</b> for production since it is potentially
252
+ # vulnerable to SQL injection!
253
+ #
254
+ # Production usage with multiple sort criteria, column name validation and defaults:
255
+ #
256
+ # order = sortable_column_order do |column, direction|
257
+ # case column
258
+ # when "name"
259
+ # "#{column} #{direction}"
260
+ # when "created_at", "updated_at"
261
+ # "#{column} #{direction}, name ASC"
262
+ # else
263
+ # "name ASC"
264
+ # end
265
+ # end
266
+ #
267
+ # Apply order:
268
+ #
269
+ # @records = Article.order(order) # Rails 3.
270
+ # @records = Article.all(:order => order) # Rails 2.
271
+ def sortable_column_order(&block)
272
+ conf = {}
273
+ conf[k = :sort_param] = sortable_columns_config[k]
274
+ conf[k = :default_sort_value] = sortable_columns_config[k]
275
+
276
+ # Parse sort param.
277
+ sort = params[conf[:sort_param]] || conf[:default_sort_value]
278
+ pp = parse_sortable_column_sort_param(sort)
279
+
280
+ order = if block
281
+ column, direction = pp[:column], pp[:direction]
282
+ yield(column, direction) # NOTE: Makes RDoc/ri look a little smarter.
283
+ else
284
+ # No block -- do a straight mapping.
285
+ if pp[:column]
286
+ [pp[:column], pp[:direction]].join(" ")
287
+ end
288
+ end
289
+
290
+ # Can be nil.
291
+ order
292
+ end
293
+
294
+ # Internal use only. Convert title to sortable column name.
295
+ #
296
+ # sortable_column_title_to_name("ProductName") # => "product_name"
297
+ def sortable_column_title_to_name(title) #:nodoc:
298
+ title.gsub(/(\s)(\S)/) {$2.upcase}.underscore
299
+ end
300
+
301
+ # Internal use only. Access/initialize feature's config.
302
+ def sortable_columns_config #:nodoc:
303
+ @sortable_columns_config ||= ::Handles::SortableColumns::Config.new
304
+ end
305
+ end # InstanceMethods
306
+ end # SortableColumns
307
+ end # Handles
@@ -0,0 +1,5 @@
1
+ # Rails gem init.
2
+
3
+ # NOTE: Rails 3 seems to require exact order.
4
+ require File.join(File.dirname(__FILE__), "handles/sortable_columns")
5
+ require File.join(File.dirname(__FILE__), "action_controller/base/handles_sortable_columns")
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "tvdeyen-handles_sortable_columns"
5
+ s.version = "0.1.5"
6
+ s.authors = ["Alex Fortuna", "Thomas von Deyen"]
7
+ s.summary = "Sortable Table Columns"
8
+ s.description = "Sortable Table Columns"
9
+ s.license = "MIT"
10
+ s.email = "tvdeyen@gmail.com"
11
+ s.extra_rdoc_files = [
12
+ "README.html",
13
+ "README.md"
14
+ ]
15
+ s.files = `git ls-files`.split("\n")
16
+ s.homepage = "https://github.com/tvdeyen/handles_sortable_columns"
17
+ s.require_paths = ["lib"]
18
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tvdeyen-handles_sortable_columns
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - Alex Fortuna
8
+ - Thomas von Deyen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-27 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Sortable Table Columns
15
+ email: tvdeyen@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files:
19
+ - README.html
20
+ - README.md
21
+ files:
22
+ - .gitignore
23
+ - MIT-LICENSE
24
+ - README.html
25
+ - README.md
26
+ - Rakefile
27
+ - VERSION.yml
28
+ - dev/github.css
29
+ - dev/head.html
30
+ - init.rb
31
+ - lib/action_controller/base/handles_sortable_columns.rb
32
+ - lib/handles/sortable_columns.rb
33
+ - lib/handles_sortable_columns.rb
34
+ - tvdeyen-handles_sortable_columns.gemspec
35
+ homepage: https://github.com/tvdeyen/handles_sortable_columns
36
+ licenses:
37
+ - MIT
38
+ metadata: {}
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 2.0.3
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: Sortable Table Columns
59
+ test_files: []
60
+ has_rdoc: