sortablecolumns 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ === 0.1.0 / 2008-04-29
2
+
3
+ * Initial Release
data/Manifest.txt ADDED
@@ -0,0 +1,12 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/sortable_columns
6
+ lib/sortablecolumns.rb
7
+ lib/sortablecolumns/helpers.rb
8
+ lib/sortablecolumns/sortable_columns.rb
9
+ test/col_def_test_yaml_files/person/dude/dude_report.yml
10
+ test/col_def_test_yaml_files/person/mysorter.yml
11
+ test/col_def_test_yaml_files/person/tacosorter.yml
12
+ test/sortablecolumns_test.rb
data/README.txt ADDED
@@ -0,0 +1,202 @@
1
+ = SortableColumns
2
+
3
+ * http://rubyforge.org/projects/sortablecolumns/
4
+
5
+ == DESCRIPTION:
6
+
7
+ SortableColumns is a Rails plugin that allows easy creation of sortable HTML tables as plain HTML or as a YUI DataTable (requires YUI4Rails plugin - http://rubyforge.org/projects/yui4rails/). Table column characteristics (e.g., default sort direction, data type, CSS attributes, and methods to wrap the output in) are defined in YAML files (more options to be added later, such auto-detecting the column types, using a hash, etc.). Multiple table column definitions can be created for a single model.
8
+
9
+ An example live application can be found here: http://sortablecolumns.heroku.com/
10
+ Download the example app here: http://www.bryandonovan.com/sortable_columns_example.tar.gz
11
+
12
+ Also see: ActiveRecord::Acts::SortableColumns::ClassMethods#sortable_columns
13
+
14
+ == INSTALL:
15
+
16
+ * sudo gem install sortablecolumns
17
+ * IMPORTANT: create a directory named col_defs in your app/models directory if you want to use the default YAML directory (otherwise you can specify a path using :path_prefix).
18
+
19
+ == FEATURES/PROBLEMS:
20
+
21
+ === Features
22
+ * Simple to define column characteristics in YAML
23
+ * Can be used with regular HTML or with YUI DataTable (http://developer.yahoo.com/yui/datatable/)
24
+ * Allows definitions of arbitrary columns, so you aren't limited to the columns in your model. E.g.,
25
+ you can use custom SQL queries that return a mix of columns from different models or "virtual" columns
26
+ created in the SQL query.
27
+ * Test coverage for all current features.
28
+
29
+ === Problems
30
+ * Doesn't yet support date formats (should be easy to implement though and will hopefully happen soon)
31
+
32
+ == SYNOPSIS:
33
+ * First, create a directory to store your column definitions YAML files. The default location SortableColumns will look is app/models/col_defs.
34
+ * Create a YAML file for the configuration of your table columns.
35
+ * Call sortable_tables in your model
36
+ * Run query (get an ActiveRecord result set)
37
+ * Render table in your view
38
+
39
+ === Example Usage
40
+ Say we have a Person model (or a custom SQL query result) with the following columns/attributes:
41
+ * firstname - string, should be a link to the people/show action, TD CSS class of "left".
42
+ * lastname - string, should be wrapped in sanitize.
43
+ * age - integer, default sort direction: descending. TD CSS class: "center".
44
+ * description - string/text - should have a TD CSS class of "left", should be wrapped in auto_link, sanitize, and simple_format.
45
+ * balance - decimal/currency - precision of 2, comma for a separator, space for delimiter, British pound for unit. Default sort: descending.
46
+ * edit and detroy links, called "Edit" and "Delete" (which, of course, are not fields in the query result, but will be in the displayed table).
47
+
48
+ We're going to call this sorter "mysorter". This will be the name of the YAML file and the name passed into the sortable_columns method in the model.
49
+
50
+ In model:
51
+
52
+ class Person < ActiveRecord::Base
53
+ sortable_columns :mysorter
54
+
55
+ # method to run query with sort options
56
+ def self.find_for_mysorter(options = {})
57
+ order_by = options[:order_by]
58
+ dir = options[:dir]
59
+ query = "select * from people"
60
+ query << " order by #{order_by}" if order_by
61
+ query << " #{dir}" if dir
62
+ Person.find_by_sql(query)
63
+ end
64
+ end
65
+
66
+ YAML file:
67
+ -
68
+ firstname:
69
+ heading: First
70
+ datatype: string
71
+ link_options:
72
+ controller: people
73
+ action: show
74
+ id: obj_id
75
+ td_class: left
76
+
77
+ -
78
+ lastname:
79
+ heading: Last
80
+ datatype: string
81
+ print_options:
82
+ wrappers: sanitize
83
+ -
84
+ age:
85
+ datatype: number
86
+ sort_options:
87
+ default_dir: desc
88
+ td_class: center
89
+ -
90
+ description:
91
+ datatype: string
92
+ sortable: false
93
+ print_options:
94
+ wrappers:
95
+ - auto_link
96
+ - sanitize
97
+ - simple_format
98
+ td_class: left
99
+ -
100
+ balance:
101
+ datatype: currency
102
+ precision: 2
103
+ separator: ","
104
+ delimiter: " "
105
+ unit: £
106
+ td_class: right
107
+ -
108
+ edit:
109
+ in_resultset: false
110
+ heading: false
111
+ th_class: invisible
112
+ print_text: Edit
113
+ link_options:
114
+ controller: people
115
+ action: edit
116
+ id: obj_id
117
+ -
118
+ delete:
119
+ in_resultset: false
120
+ heading: false
121
+ th_class: invisible
122
+ print_text: Delete
123
+ link_options:
124
+ controller: people
125
+ action: destroy
126
+ id: obj_id
127
+ extras:
128
+ method: delete
129
+ confirm: Are you sure?
130
+
131
+ In the link_options, use obj_id to specify that the current object's id field should be used.
132
+
133
+ In the controller:
134
+
135
+ def index #plain HTML table
136
+ @people = Person.find_for_mysorter(options=params.dup)
137
+ respond_to do |format|
138
+ format.html
139
+ end
140
+ end
141
+
142
+ def yui #YUI DataTable
143
+ @people = Person.find_for_mysorter(options=params.dup)
144
+ @col_defs = Person.mysorter_col_defs_for_yui
145
+ @data_keys = Person.mysorter_fields_for_yui
146
+
147
+ @data_table = Yui4Rails::Widgets::DataTable.new(:table_div_id => "markup",
148
+ :col_defs => @col_defs,
149
+ :data_keys => @data_keys,
150
+ :table_id => 'yui_table')
151
+
152
+ @data_table.paginate(5)
153
+
154
+ respond_to do |format|
155
+ format.html # index.html.erb
156
+ end
157
+ end
158
+
159
+ In the view:
160
+
161
+ <%= print_table(@people, :mysorter %>
162
+ Or if you want alternating styles for table rows:
163
+ <%= print_table(@people, :mysorter, :tr => {:classes => ['even','odd']}) %>
164
+ And you can specify a table CSS class & id:
165
+ <%= print_table(@people, :mysorter, :table => {:class => 'yui-skin-sam', :id => 'yui_table'}) %>
166
+
167
+ For YUI DataTable, add the followoing after the print_table call:
168
+ <%= @data_table.render(:source => :html)%>
169
+ Also make sure the table is inside a div with the same id as specified in the controller when using the YUI DataTable.
170
+
171
+ == REQUIREMENTS:
172
+
173
+ * YUI4Rails gem if you want to use YUI datatables
174
+
175
+ == Disclaimer
176
+
177
+ This is beta-quality software. It works well according to my tests, but the API may change and other features may be added.
178
+
179
+ == LICENSE:
180
+
181
+ (The MIT License)
182
+
183
+ Copyright (c) 2008 Bryan Donovan
184
+
185
+ Permission is hereby granted, free of charge, to any person obtaining
186
+ a copy of this software and associated documentation files (the
187
+ 'Software'), to deal in the Software without restriction, including
188
+ without limitation the rights to use, copy, modify, merge, publish,
189
+ distribute, sublicense, and/or sell copies of the Software, and to
190
+ permit persons to whom the Software is furnished to do so, subject to
191
+ the following conditions:
192
+
193
+ The above copyright notice and this permission notice shall be
194
+ included in all copies or substantial portions of the Software.
195
+
196
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
197
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
198
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
199
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
200
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
201
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
202
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/sortablecolumns.rb'
6
+
7
+ Hoe.new('sortablecolumns', Sortablecolumns::VERSION) do |p|
8
+ p.name = "sortablecolumns"
9
+ p.author = "Bryan Donovan - http://www.bryandonovan.com"
10
+ p.email = "b.dondo+rubyforge@gmail.com"
11
+ p.description = "Sortable HTML tables for Rails"
12
+ p.summary = "Sortable HTML tables for Rails"
13
+ p.url = "http://rubyforge.org/projects/sortablecolumns/"
14
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
15
+ p.remote_rdoc_dir = '' # Release to root
16
+ end
17
+
18
+ rule '' do |t|
19
+ system "cd test && ruby sortablecolumns_test.rb"
20
+ end
21
+
22
+ # vim: syntax=Ruby
File without changes
@@ -0,0 +1,6 @@
1
+ module Sortablecolumns #:nodoc:
2
+ VERSION = '0.1.0'
3
+ end
4
+ Dir[File.join(File.dirname(__FILE__), "sortablecolumns/**/*.rb")].sort.each { |lib| require lib }
5
+ ActiveRecord::Base.send(:include, ActiveRecord::Acts::Sortablecolumns)
6
+ ActionView::Base.send(:include, Sortablecolumns::Helpers)
@@ -0,0 +1,167 @@
1
+ module Sortablecolumns
2
+ module Helpers
3
+
4
+ #Prints entire HTML table with content
5
+ def print_table(collection, sorter, options={})
6
+ klass = collection.first.class
7
+ txt = print_table_thead(klass, sorter)
8
+ txt << print_table_body(collection, sorter, options)
9
+ return content_tag('table', txt, options[:table])
10
+ end
11
+
12
+ #Prints a single table column (TD element) with content
13
+ def print_col(obj, sorter, col)
14
+ col = col.to_s
15
+ klass = obj.class
16
+ txt = klass.send("#{sorter}_col_text",obj,col)
17
+ wrappers = []
18
+
19
+ datatype = klass.send("#{sorter}_datatype",col) || 'string'
20
+
21
+ if datatype == 'number'
22
+ precision = klass.send("#{sorter}_precision",col)
23
+ txt = number_with_precision(txt, precision) if precision
24
+ end
25
+
26
+ if datatype == 'currency'
27
+ precision = klass.send("#{sorter}_precision",col)
28
+ unit = klass.send("#{sorter}_unit",col)
29
+ separator = klass.send("#{sorter}_separator",col)
30
+ delimiter = klass.send("#{sorter}_delimiter",col)
31
+ txt = number_to_currency(txt, :precision => precision,
32
+ :unit => unit, :separator => separator, :delimiter => delimiter)
33
+ end
34
+
35
+ do_link = klass.send("#{sorter}_link?",col)
36
+
37
+ if do_link
38
+ link_ops = klass.send("#{sorter}_link_options",col).dup
39
+ raise "link_options must be defined for #{klass}:#{col}" unless link_ops
40
+ if link_ops[:object_url]
41
+ txt = link_to(txt, send("#{klass.to_s.downcase}_url", obj))
42
+ elsif link_ops[:controller] && link_ops[:action]
43
+ if link_ops[:id] && link_ops[:id] == 'obj_id'
44
+ link_ops[:id] = obj.id
45
+ end
46
+ if link_ops[:extras]
47
+ extras = link_ops.delete(:extras)
48
+ txt = link_to(txt, link_ops, extras)
49
+ else
50
+ txt = link_to(txt, link_ops)
51
+ end
52
+ elsif link_ops[:url]
53
+ url = link_ops[:url].gsub(/:id/, obj.id.to_s)
54
+ unless url.match(/http/)
55
+ url = 'http://' + default_url_options[:host] + url
56
+ end
57
+ txt = link_to(txt, url)
58
+ end
59
+ end
60
+
61
+ print_options = klass.send("#{sorter}_print_options",col)
62
+ wrappers << print_options['wrappers'] if print_options && print_options['wrappers']
63
+
64
+ wrappers.flatten.each do |wrapper|
65
+ if wrapper.is_a? Hash
66
+ key = wrapper.keys.first
67
+ extra_args = wrapper[key]
68
+ txt = send(key, txt, extra_args)
69
+ else
70
+ txt = send(wrapper, txt)
71
+ end
72
+ end
73
+
74
+ td_class = klass.send("#{sorter}_td_class",col)
75
+
76
+ return content_tag("td", txt, :class => td_class)
77
+ end
78
+
79
+ #Prints single table row with content
80
+ def print_table_row(obj, sorter, options={})
81
+ txt = ''
82
+ klass = obj.class
83
+ cols = klass.send("#{sorter}_col_keys_in_order")
84
+ cols.each do |col|
85
+ txt << print_col(obj, sorter, col)
86
+ end
87
+ content_tag("tr", txt, options)
88
+ end
89
+
90
+ #Prints table body with content
91
+ def print_table_body(collection, sorter, options={})
92
+ txt = ""
93
+ if options[:tr] && options[:tr][:classes]
94
+ alternate = true
95
+ tr_classes = options[:tr][:classes]
96
+ end
97
+ tr_class = nil
98
+ i = 0
99
+ collection.each do |obj|
100
+ if alternate
101
+ tr_class = tr_classes[i % 2]
102
+ end
103
+ txt << print_table_row(obj, sorter, :class => tr_class)
104
+ i += 1
105
+ end
106
+ content_tag("tbody", txt)
107
+ end
108
+
109
+ #Prints single TH tag with content
110
+ def print_col_heading(klass, sorter, col, options={})
111
+ col = col.to_s
112
+ th_txt = klass.send("#{sorter}_heading", col)
113
+ th_class = klass.send("#{sorter}_th_class", col)
114
+ return content_tag("th", '', :class => th_class) unless th_txt
115
+ sortable = klass.send("#{sorter}_sortable?", col)
116
+ return content_tag("th", th_txt, :class => th_class) unless sortable
117
+ url = get_col_heading_url(klass, sorter, col)
118
+ link = link_to(th_txt, url)
119
+ return content_tag("th", link, :class => th_class)
120
+ end
121
+
122
+ #Get URL for sortable table column header (TH element)
123
+ def get_col_heading_url(klass, sorter, col)
124
+ order_by = col
125
+ default_dir = 'asc'
126
+ sort_ops = klass.send("#{sorter}_sort_options", col)
127
+ if sort_ops
128
+ order_by = sort_ops['order_by'] if sort_ops['order_by']
129
+ default_dir = sort_ops['default_dir'] if sort_ops['default_dir']
130
+ end
131
+
132
+ reg = Regexp.new(order_by.to_s)
133
+ if params[:order_by] =~ reg
134
+ dir = (params[:dir] == "asc") ? "desc" : "asc"
135
+ else
136
+ dir = default_dir
137
+ end
138
+
139
+ get_url(order_by, dir)
140
+ end
141
+
142
+ #get url for given set of params, order_by, and dir
143
+ def get_url(order_by, dir)
144
+ _params = params.dup
145
+ _params[:order_by] = order_by
146
+ _params[:dir] = dir
147
+ url_for(_params)
148
+ end
149
+
150
+ #Prints a row of TH tags with content
151
+ def print_table_heading_row(klass, sorter, options={})
152
+ cols = klass.send("#{sorter}_col_keys_in_order")
153
+ txt = ''
154
+ cols.each do |col|
155
+ txt << print_col_heading(klass, sorter, col)
156
+ end
157
+ txt
158
+ content_tag("tr", txt, options)
159
+ end
160
+
161
+ #Prints THEAD tags with content
162
+ def print_table_thead(klass, sorter)
163
+ content_tag('thead', print_table_heading_row(klass, sorter))
164
+ end
165
+
166
+ end
167
+ end
@@ -0,0 +1,254 @@
1
+ # Sortablecolumns Rails Plugin
2
+ # Lets you define column definitions for a sortable HTML table.
3
+ # Author: Bryan Donovan
4
+ # March 2008
5
+
6
+ require 'active_record'
7
+ require 'active_support'
8
+ require 'action_controller'
9
+
10
+ module ActiveRecord #:nodoc:
11
+ module Acts #:nodoc:
12
+ module Sortablecolumns
13
+ def self.included(base) # :nodoc:
14
+ base.extend(ClassMethods)
15
+ end
16
+
17
+ module ClassMethods
18
+ include ActiveSupport::CoreExtensions::Hash::Keys
19
+
20
+ # == Configuration options
21
+ #
22
+ # * <tt>sorter_name</tt> (required) - specify the name of the sorter, same name used for YAML file, method prefixes
23
+ # * <tt>subclass_name</tt> (optional) - specify the subclass name if your model inherits from another model. You must create your YAML file in a subdirectory of the same name (lowercase). E.g., app/models/person/manager_sorter.yml for a Manager model that inherits from the Person model.
24
+ # * <tt>path_prefix</tt> (optional) - path to your column definitions directory where your YAML files are stored (relative to RAILS_ROOT). If this isn't specified, Sortablecolumns looks for column definitions in /app/models/col_defs, but you must create that directory manually.
25
+ # == Examples
26
+ # class Person < ActiveRecord::Base
27
+ # sortable_columns :mysorter
28
+ # sortable_columns :othersorter, :path_prefix => '/my_column_defs'
29
+ # end
30
+
31
+ # class Manager < Person
32
+ # sortable_columns :manager_sorter, :subclass_name => 'Manager'
33
+ # end
34
+ def sortable_columns(sorter_name, options = {})
35
+ options = {:subclass_name => nil, :path_prefix => nil}.merge(options)
36
+ write_inheritable_attribute(:sorter_options, options)
37
+ class_inheritable_reader :sorter_options
38
+
39
+ self.class_eval <<-END
40
+ def self.#{sorter_name}_cols=(val)
41
+ @@#{sorter_name}_cols = val
42
+ end
43
+
44
+ def self.#{sorter_name}_cols
45
+ @@#{sorter_name}_cols
46
+ end
47
+ cattr_accessor :#{sorter_name}_cols
48
+
49
+ def self.#{sorter_name}_col_defs
50
+ @@#{sorter_name}_cols ||= #{sorter_name}_initialize_col_defs
51
+ end
52
+
53
+ def self.#{sorter_name}_col_text(obj, col)
54
+ return obj.send(col) if self.#{sorter_name}_in_resultset?(col)
55
+ return self.#{sorter_name}_print_text(col)
56
+ end
57
+
58
+ def self.#{sorter_name}_yaml_path
59
+ raise "RAILS_ROOT is not defined" unless defined?(RAILS_ROOT)
60
+ #klass_name = self.class_name.downcase
61
+ klass_name = Inflector.underscore(self.class_name)
62
+ file_name = "#{sorter_name}.yml"
63
+ if sorter_options[:subclass_name]
64
+ sub_path = File.join(klass_name, Inflector.underscore(sorter_options[:subclass_name]), file_name)
65
+ else
66
+ sub_path = File.join(klass_name, file_name)
67
+ end
68
+ if sorter_options[:path_prefix]
69
+ return File.join(RAILS_ROOT, sorter_options[:path_prefix], sub_path)
70
+ else
71
+ #defaults to col_defs subdirectory in app/models
72
+ return File.join(RAILS_ROOT, "app/models/col_defs", sub_path)
73
+ end
74
+ end
75
+
76
+ def self.#{sorter_name}_initialize_col_defs
77
+ YAML.load_file(#{sorter_name}_yaml_path)
78
+ end
79
+
80
+ def self.#{sorter_name}_col_def_hash
81
+ @@#{sorter_name}_col_def_hash ||= #{sorter_name}_initialize_col_def_hash
82
+ end
83
+
84
+ def self.#{sorter_name}_initialize_col_def_hash
85
+ col_def_hash = {}
86
+ #{sorter_name}_col_defs.each do |c|
87
+ c.keys.each do |key|
88
+ col_def_hash[key] = c[key]
89
+ end
90
+ end
91
+ col_def_hash
92
+ end
93
+
94
+ def self.#{sorter_name}_col_keys_in_order
95
+ @@#{sorter_name}_col_keys_in_order ||= #{sorter_name}_initialize_col_keys_in_order
96
+ end
97
+
98
+ def self.#{sorter_name}_initialize_col_keys_in_order
99
+ cols = []
100
+ #{sorter_name}_col_defs.each do |hsh|
101
+ hsh.each do |key, sub_hash|
102
+ cols << key
103
+ end
104
+ end
105
+ cols
106
+ end
107
+
108
+ def self.#{sorter_name}_heading(col)
109
+ return false if #{sorter_name}_col_def_hash[col]['heading'] == false
110
+ #{sorter_name}_col_def_hash[col]['heading'] || col.humanize
111
+ end
112
+
113
+ def self.#{sorter_name}_headings_in_order
114
+ @@#{sorter_name}_headings_in_order ||= #{sorter_name}_initialize_headings_in_order
115
+ end
116
+
117
+ def self.#{sorter_name}_initialize_headings_in_order
118
+ headings = []
119
+ #{sorter_name}_col_keys_in_order.each do |key|
120
+ headings << #{sorter_name}_heading(key) if #{sorter_name}_heading(key)
121
+ end
122
+ headings
123
+ end
124
+
125
+ def self.#{sorter_name}_col_def(col)
126
+ #{sorter_name}_col_def_hash[col]
127
+ end
128
+
129
+ def self.#{sorter_name}_datatype(col)
130
+ #{sorter_name}_col_def_hash[col]['datatype']
131
+ end
132
+
133
+ def self.#{sorter_name}_sort_options(col)
134
+ #{sorter_name}_col_def_hash[col]['sort_options']
135
+ end
136
+
137
+ def self.#{sorter_name}_default_sort_dir(col)
138
+ if sort_ops = #{sorter_name}_col_def_hash[col]['sort_options']
139
+ sort_ops['default_dir'] ? sort_ops['default_dir'] : 'asc'
140
+ else
141
+ 'asc'
142
+ end
143
+ end
144
+
145
+ def self.#{sorter_name}_print_options(col)
146
+ if #{sorter_name}_col_def_hash[col]
147
+ #{sorter_name}_col_def_hash[col]['print_options']
148
+ end
149
+ end
150
+
151
+ def self.#{sorter_name}_td_class(col)
152
+ #{sorter_name}_col_def_hash[col]['td_class']
153
+ end
154
+
155
+ def self.#{sorter_name}_th_class(col)
156
+ #{sorter_name}_col_def_hash[col]['th_class']
157
+ end
158
+
159
+ def self.#{sorter_name}_precision(col)
160
+ #{sorter_name}_col_def_hash[col]['precision']
161
+ end
162
+
163
+ def self.#{sorter_name}_delimiter(col)
164
+ #{sorter_name}_col_def_hash[col]['delimiter'] || ","
165
+ end
166
+
167
+ def self.#{sorter_name}_separator(col)
168
+ #{sorter_name}_col_def_hash[col]['separator'] || "."
169
+ end
170
+
171
+ def self.#{sorter_name}_unit(col)
172
+ #{sorter_name}_col_def_hash[col]['unit'] || "$"
173
+ end
174
+
175
+ def self.#{sorter_name}_print_text(col)
176
+ #{sorter_name}_col_def_hash[col]['print_text'] || ''
177
+ end
178
+
179
+ def self.#{sorter_name}_sortable?(col)
180
+ hsh = #{sorter_name}_col_def_hash[col]
181
+ return false if hsh.has_key?('sortable') && hsh['sortable'] == false
182
+ return false if hsh.has_key?('heading') && hsh['heading'] == false
183
+ return true
184
+ end
185
+
186
+ def self.#{sorter_name}_link_options(col)
187
+ link_ops = #{sorter_name}_col_def_hash[col]['link_options']
188
+ return link_ops.symbolize_keys! if link_ops
189
+ end
190
+
191
+ def self.#{sorter_name}_link?(col)
192
+ return true if #{sorter_name}_link_options(col)
193
+ return false
194
+ end
195
+
196
+ def self.#{sorter_name}_in_resultset?(col)
197
+ hsh = #{sorter_name}_col_def_hash[col]
198
+ return false if hsh.has_key?('in_resultset') && hsh['in_resultset'] == false
199
+ return true
200
+ end
201
+
202
+ def self.#{sorter_name}_col_def_for_yui(col)
203
+ label = #{sorter_name}_heading(col) ? #{sorter_name}_heading(col) : ''
204
+ sortable = #{sorter_name}_sortable?(col)
205
+ datatype = #{sorter_name}_datatype(col)
206
+ if datatype == 'number' or datatype == 'currency'
207
+ formatter = datatype
208
+ end
209
+ sort_dir = #{sorter_name}_default_sort_dir(col)
210
+ if sort_dir == 'desc'
211
+ sort_ops = {:defaultDir => "YAHOO.widget.DataTable.CLASS_DESC"}
212
+ end
213
+ yui = {:key => col, :label => label, :sortable => sortable}
214
+ yui[:sortOptions] = sort_ops if sort_ops
215
+ yui[:formatter] = formatter if formatter
216
+ yui
217
+ end
218
+
219
+ def self.#{sorter_name}_col_defs_for_yui
220
+ yui_col_defs = []
221
+ #{sorter_name}_col_keys_in_order.each do |col|
222
+ yui_col_defs << #{sorter_name}_col_def_for_yui(col)
223
+ end
224
+ yui_col_defs
225
+ end
226
+
227
+ def self.#{sorter_name}_field_def_for_yui(col)
228
+ datatype = #{sorter_name}_datatype(col)
229
+ yui_field_def = {:key => col}
230
+ if datatype == 'number'
231
+ yui_field_def[:parser] = "YAHOO.util.DataSource.parseNumber"
232
+ end
233
+ if datatype == 'currency'
234
+ yui_field_def[:parser] = "this.parseNumberFromCurrency"
235
+ end
236
+ yui_field_def
237
+ end
238
+
239
+ def self.#{sorter_name}_fields_for_yui
240
+ yui_fields = []
241
+ #{sorter_name}_col_keys_in_order.each do |col|
242
+ yui_fields << #{sorter_name}_field_def_for_yui(col)
243
+ end
244
+ yui_fields
245
+ end
246
+
247
+
248
+ END
249
+
250
+ end #sortable_columns
251
+ end #ClassMethods
252
+ end #Sortablecolumns
253
+ end #Acts
254
+ end #ActiveRecord