tabulatr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,82 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 Peter Horn, Provideal GmbH
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ # These are extensions for use from ActionController instances
25
+ module Tabulatr::Finder
26
+
27
+ require File.join(File.dirname(__FILE__), 'finder', 'find_for_active_record_table')
28
+ require File.join(File.dirname(__FILE__), 'finder', 'find_for_mongoid_table')
29
+
30
+ # compress the list of ids as good as I could imagine ;)
31
+ # uses fancy base twisting
32
+ def self.compress_id_list(list)
33
+ IdStuffer.stuff(list)
34
+ end
35
+
36
+ # inverse of compress_id_list
37
+ def self.uncompress_id_list(str)
38
+ IdStuffer.unstuff(str).map &:to_s
39
+ end
40
+
41
+ class Invoker
42
+ def initialize(batch_action, ids)
43
+ @batch_action = batch_action.to_sym
44
+ @ids = ids
45
+ end
46
+
47
+ def method_missing(name, *args, &block)
48
+ if @batch_action == name
49
+ yield(@ids, args)
50
+ end
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def self.class_to_param(klaz)
57
+ klaz.to_s.downcase.gsub("/","_")
58
+ end
59
+
60
+ def self.condition_from(n,v,c)
61
+ raise "SECURITY violation, field name is '#{n}'" unless /^[\d\w]+(\.[\d\w]+)?$/.match n
62
+ @like ||= Tabulatr.sql_options[:like]
63
+ nc = c
64
+ if v.is_a?(String)
65
+ if v.present?
66
+ nc = [c[0] << " AND (#{n} = ?) ", c[1] << v]
67
+ end
68
+ elsif v.is_a?(Hash)
69
+ if v[:like]
70
+ if v[:like].present?
71
+ nc = [c[0] << " AND (#{n} #{@like} ?) ", c[1] << "%#{v[:like]}%"]
72
+ end
73
+ else
74
+ nc = [c[0] << " AND (#{n} >= ?) ", c[1] << "#{v[:from]}"] if v[:from].present?
75
+ nc = [nc[0] << " AND (#{n} <= ?) ", nc[1] << "#{v[:to]}"] if v[:to].present?
76
+ end
77
+ else
78
+ raise "Wrong filter type: #{v.class}"
79
+ end
80
+ nc
81
+ end
82
+ end
@@ -0,0 +1,51 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 Peter Horn, Provideal GmbH
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ module Tabulatr::Formattr
25
+ ALLOWED_METHODS = [:euro, :dollar, :percent, :lamp]
26
+
27
+ def self.format(nam, val)
28
+ nam = nam.to_sym
29
+ if ALLOWED_METHODS.member?(nam)
30
+ self.send nam, val
31
+ else
32
+ "[Requested unautorized format '#{nam}' for '#{val}'.]"
33
+ end
34
+ end
35
+
36
+ def self.euro(x)
37
+ ("%.2f&thinsp;&euro;" % x).gsub(".", ",")
38
+ end
39
+
40
+ def self.dollar(x)
41
+ "$&thinsp;%.2f" % x
42
+ end
43
+
44
+ def self.percent(x)
45
+ ("%.2f&thinspace;%%" % 100.0*x).gsub(".", ",")
46
+ end
47
+
48
+ def self.lamp(x)
49
+
50
+ end
51
+ end
@@ -0,0 +1,94 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 Peter Horn, Provideal GmbH
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ class Tabulatr
25
+
26
+
27
+ # the method used to actually define the headers of the columns,
28
+ # taking the name of the attribute and a hash of options.
29
+ #
30
+ # The following options are evaluated here:
31
+ # <tt>:th_html</tt>:: a hash with html-attributes added to the <th>s created
32
+ # <tt>:header</tt>:: if present, the value will be output in the header cell,
33
+ # otherwise, the capitalized name is used
34
+ def header_column(name, opts={}, &block)
35
+ raise "Not in header mode!" if @row_mode != :header
36
+ sortparam = "#{@classname}#{@table_form_options[:sort_postfix]}"
37
+ bid = "#{@classname}#{@table_form_options[:sort_postfix]}"
38
+ opts = normalize_column_options opts
39
+ make_tag(:th, opts[:th_html]) do
40
+ concat(t(opts[:header] || name.to_s.capitalize), :escape_html)
41
+ if opts[:sortable] and @table_options[:sortable]
42
+ if @sorting and @sorting[:by].to_s == name.to_s
43
+ pname = "#{sortparam}[_resort][#{name}][#{@sorting[:direction] == 'asc' ? 'desc' : 'asc'}]"
44
+ bid = "#{bid}_#{name}_#{@sorting[:direction] == 'asc' ? 'desc' : 'asc'}"
45
+ psrc = File.join(@table_options[:image_path_prefix], @table_options[@sorting[:direction] == 'desc' ?
46
+ :sort_down_button : :sort_up_button])
47
+ make_tag(:input, :type => :hidden,
48
+ :name => "#{sortparam}[#{name}][#{@sorting[:direction]}]",
49
+ :value => "#{@sorting[:direction]}")
50
+ else
51
+ pname = "#{sortparam}[_resort][#{name}][desc]"
52
+ bid = "#{bid}_#{name}_desc"
53
+ psrc = File.join(@table_options[:image_path_prefix], @table_options[:sort_down_button_inactive])
54
+ end
55
+ make_tag(:input, :type => 'image',
56
+ :id => bid,
57
+ :src => psrc,
58
+ :name => pname)
59
+ end
60
+ end # </th>
61
+ end
62
+
63
+ # the method used to actually define the headers of the columns,
64
+ # taking the name of the attribute and a hash of options.
65
+ #
66
+ # The following options are evaluated here:
67
+ # <tt>:th_html</tt>:: a hash with html-attributes added to the <th>s created
68
+ # <tt>:header</tt>:: if present, the value will be output in the header cell,
69
+ # otherwise, the capitalized name is used
70
+ def header_association(relation, name, opts={}, &block)
71
+ raise "Not in header mode!" if @row_mode != :header
72
+ opts = normalize_column_options opts
73
+ if opts[:sortable] and @table_options[:sortable]
74
+ # change classes accordingly
75
+ end
76
+ make_tag(:th, opts[:th_html]) do
77
+ concat(t(opts[:header] || "#{relation.to_s.capitalize} #{name.to_s.capitalize}"), :escape_html)
78
+ end # </th>
79
+ end
80
+
81
+ def header_checkbox(opts={}, &block)
82
+ raise "Whatever that's for!" if block_given?
83
+ make_tag(:th, opts[:th_html]) do
84
+ concat(t(opts[:header] || ""), :escape_html)
85
+ end
86
+ end
87
+
88
+ def header_action(opts={}, &block)
89
+ make_tag(:th, opts[:th_html]) do
90
+ concat(t(opts[:header] || ""), :escape_html)
91
+ end
92
+ end
93
+
94
+ end
@@ -0,0 +1,88 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 Peter Horn, Provideal GmbH
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ class Tabulatr
25
+
26
+ #render the paginator controls, inputs etc.
27
+ def render_paginator
28
+ # get the current pagination state
29
+ pagination_name = "#{@classname}#{TABLE_FORM_OPTIONS[:pagination_postfix]}"
30
+ pparams = @records.send(FINDER_INJECT_OPTIONS[:pagination])
31
+ page = pparams[:page].to_i
32
+ pages = pparams[:pages].to_i
33
+ pagesize = pparams[:pagesize].to_i
34
+ pagesizes = pparams[:pagesizes].map &:to_i
35
+ # render the 'wrapping' div
36
+ make_tag(:div, :class => @table_options[:paginator_div_class]) do
37
+ # << Page Left
38
+ if page > 1
39
+ make_tag(:input, :type => 'image',
40
+ :src => File.join(@table_options[:image_path_prefix], @table_options[:pager_left_button]),
41
+ :class => @table_options[:page_left_class],
42
+ :id => "#{pagination_name}_page_left",
43
+ :name => "#{pagination_name}[page_left]")
44
+ else
45
+ make_tag(:img,
46
+ :src => File.join(@table_options[:image_path_prefix], @table_options[:pager_left_button_inactive]),
47
+ :class => @table_options[:page_left_class])
48
+ end # page > 1
49
+ # current page number
50
+ concat(make_tag(:input,
51
+ :type => :hidden,
52
+ :name => "#{pagination_name}[current_page]",
53
+ :value => page))
54
+ concat(make_tag(:input,
55
+ :type => :text,
56
+ :size => pages.to_s.length,
57
+ :name => "#{pagination_name}[page]",
58
+ :value => page))
59
+ concat("/#{pages}")
60
+ # >> Page Right
61
+ if page < pages
62
+ make_tag(:input, :type => 'image',
63
+ :src => File.join(@table_options[:image_path_prefix], @table_options[:pager_right_button]),
64
+ :class => @table_options[:page_right_class],
65
+ :id => "#{pagination_name}_page_right",
66
+ :name => "#{pagination_name}[page_right]")
67
+ else
68
+ make_tag(:img, :src => File.join(@table_options[:image_path_prefix], @table_options[:pager_right_button_inactive]),
69
+ :class => @table_options[:page_right_class])
70
+ end # page < pages
71
+ if pagesizes.length > 1
72
+ make_tag(:select, :name => "#{pagination_name}[pagesize]", :class => @table_options[:pagesize_select_class]) do
73
+ pagesizes.each do |n|
74
+ make_tag(:option, (n.to_i==pagesize ? {:selected => :selected} : {}).merge(:value => n)) do
75
+ concat(n.to_s)
76
+ end # </option>
77
+ end # each
78
+ end # </select>
79
+ else # just one pagesize
80
+ concat(make_tag(:input,
81
+ :type => :hidden,
82
+ :name => "#{pagination_name}[pagesize]",
83
+ :value => pagesizes.first))
84
+ end
85
+ end # </div>
86
+ end
87
+
88
+ end
@@ -0,0 +1,115 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 Peter Horn, Provideal GmbH
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ # These are extensions for use as a row builder
25
+ # In a seperate class call only for clearity
26
+
27
+ class Tabulatr
28
+
29
+ # called inside the build_table block, branches into data, header,
30
+ # or filter building methods depending on the current mode
31
+ def column(name, opts={}, &block)
32
+ #puts "column: '#{name}'"
33
+ case @row_mode
34
+ when :data then data_column(name, opts, &block)
35
+ when :header then header_column(name, opts, &block)
36
+ when :filter then filter_column(name, opts, &block)
37
+ else raise "Wrong row mode '#{@row_mode}'"
38
+ end # case
39
+ end
40
+
41
+ # called inside the build_table block, branches into data, header,
42
+ # or filter building methods depending on the current mode
43
+ def association(relation, name, opts={}, &block)
44
+ #puts "assoc: '#{relation}.#{name}'"
45
+ case @row_mode
46
+ when :data then data_association(relation, name, opts, &block)
47
+ when :header then header_association(relation, name, opts, &block)
48
+ when :filter then filter_association(relation, name, opts, &block)
49
+ else raise "Wrong row mode '#{@row_mode}'"
50
+ end # case
51
+ end
52
+
53
+ # called inside the build_table block, branches into data, header,
54
+ # or filter building methods depending on the current mode
55
+ def checkbox(opts={}, &block)
56
+ #puts "column: '#{name}'"
57
+ case @row_mode
58
+ when :data then data_checkbox(opts, &block)
59
+ when :header then header_checkbox(opts, &block)
60
+ when :filter then filter_checkbox(opts, &block)
61
+ else raise "Wrong row mode '#{@row_mode}'"
62
+ end # case
63
+ end
64
+
65
+ def action(opts={}, &block)
66
+ #puts "column: '#{name}'"
67
+ case @row_mode
68
+ when :data then data_action(opts, &block)
69
+ when :header then header_action(opts, &block)
70
+ when :filter then filter_action(opts, &block)
71
+ else raise "Wrong row mode '#{@row_mode}'"
72
+ end # case
73
+ end
74
+
75
+ private
76
+ # returns self, sets record and row_mode as required for a
77
+ # data row
78
+ def data_row_builder(record)
79
+ @record = record
80
+ @row_mode = :data
81
+ self
82
+ end
83
+
84
+ # returns self, sets record to nil and row_mode as required for a
85
+ # header row
86
+ def header_row_builder
87
+ @record = nil
88
+ @row_mode = :header
89
+ self
90
+ end
91
+
92
+ # returns self, sets record to nil and row_mode as required for a
93
+ # filter row
94
+ def filter_row_builder
95
+ @record = nil
96
+ @row_mode = :filter
97
+ self
98
+ end
99
+
100
+ # some preprocessing of the options
101
+ def normalize_column_options(opts)
102
+ opts = Tabulatr::COLUMN_OPTIONS.merge(opts)
103
+ {:width => 'width', :align => 'text-align', :valign => 'vertical-align'}.each do |key,css|
104
+ if opts[key]
105
+ [:th_html, :filter_html, :td_html].each do |set|
106
+ opts[set] ||= {}
107
+ opts[set][:style] = (opts[set][:style] ? opts[set][:style] << "; " : "") << "#{css}: #{opts[key]}"
108
+ end # each
109
+ end # if
110
+ end # each
111
+ # more to come!
112
+ opts
113
+ end
114
+ end
115
+
@@ -0,0 +1,221 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 Peter Horn, Provideal GmbH
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require 'whiny_hash'
25
+
26
+ class Tabulatr
27
+
28
+ # Hash keeping the defaults for the table options, may be overriden in the
29
+ # table_for call
30
+ TABLE_OPTIONS = WhinyHash.new({ # WhinyHash.new({
31
+ remote: false, # add data-remote="true" to form
32
+
33
+ form_class: 'tabulatr_form', # class of the overall form
34
+ table_class: 'tabulatr_table', # class for the actual data table
35
+ sortable_class: 'sortable', # class for the header of a sortable column
36
+ sorting_asc_class: 'sorting-asc', # class for the currently asc sorting column
37
+ sorting_desc_class: 'sorting-desc', # class for the currently desc sorting column
38
+ page_left_class: 'page-left', # class for the page left button
39
+ page_right_class: 'page-right', # class for the page right button
40
+ page_no_class: 'page-no', # class for the page no <input>
41
+ control_div_class_before: 'table-controls', # class of the upper div containing the paging and batch action controls
42
+ control_div_class_after: 'table-controls', # class of the lower div containing the paging and batch action controls
43
+ paginator_div_class: 'paginator', # class of the div containing the paging controls
44
+ batch_actions_div_class: 'batch-actions', # class of the div containing the batch action controls
45
+ select_controls_div_class: 'check-controls', # class of the div containing the check controls
46
+ submit_class: 'submit-table', # class of submit button
47
+ pagesize_select_class: 'pagesize_select', # class of the pagesize select element
48
+ select_all_class: 'select-btn', # class of the select all button
49
+ select_none_class: 'select-btn', # class of the select none button
50
+ select_visible_class: 'select-btn', # class of the select visible button
51
+ unselect_visible_class: 'select-btn', # class of the unselect visible button
52
+ select_filtered_class: 'select-btn', # class of the select filtered button
53
+ unselect_filtered_class: 'select-btn', # class of the unselect filteredbutton
54
+ info_text_class: 'info-text', # class of the info text div
55
+
56
+ batch_actions_label: 'Batch Action: ', # Text to show in front of the batch action select
57
+ batch_actions_type: :select, # :select or :button depending on the kind of input you want
58
+ batch_actions_class: 'batch-action-inputs', # class to apply on the batch action input elements
59
+ submit_label: 'Apply', # Text on the submit button
60
+ select_all_label: 'Select All', # Text on the select all button
61
+ select_none_label: 'Select None', # Text on the select none button
62
+ select_visible_label: 'Select visible', # Text on the select visible button
63
+ unselect_visible_label: 'Unselect visible', # Text on the unselect visible button
64
+ select_filtered_label: 'Select filtered', # Text on the select filtered button
65
+ unselect_filtered_label: 'Unselect filtered',# Text on the unselect filtered button
66
+ info_text: "Showing %1$d, total %2$d, selected %3$d, matching %4$d",
67
+
68
+ # which controls to be rendered above and below the tabel and in which order
69
+ before_table_controls: [:submit, :paginator, :batch_actions, :select_controls, :info_text],
70
+ after_table_controls: [],
71
+
72
+ # whih selecting controls to render in which order
73
+ select_controls: [:select_all, :select_none, :select_visible, :unselect_visible,
74
+ :select_filtered, :unselect_filtered],
75
+
76
+
77
+ image_path_prefix: '/images/tabulatr/',
78
+ pager_left_button: 'left.gif',
79
+ pager_left_button_inactive: 'left_off.gif',
80
+ pager_right_button: 'right.gif',
81
+ pager_right_button_inactive: 'right_off.gif',
82
+ sort_up_button: 'up.gif',
83
+ sort_up_button_inactive: 'up_off.gif',
84
+ sort_down_button: 'down.gif',
85
+ sort_down_button_inactive: 'down_off.gif',
86
+
87
+ make_form: true, # whether or not to wrap the whole table (incl. controls) in a form
88
+ table_html: false, # a hash with html attributes for the table
89
+ row_html: false, # a hash with html attributes for the normal trs
90
+ header_html: false, # a hash with html attributes for the header trs
91
+ filter_html: false, # a hash with html attributes for the filter trs
92
+ filter: true, # false for no filter row at all
93
+ paginate: true, # true to show paginator
94
+ sortable: true, # true to allow sorting (can be specified for every sortable column)
95
+ selectable: true, # true to render "select all", "select none" and the like
96
+ action: nil, # target action of the wrapping form if applicable
97
+ batch_actions: false, # name: value hash of batch action stuff
98
+ translate: false, # call t() for all 'labels' and stuff, possible values are true/:translate or :localize
99
+ row_classes: ['odd', 'even'] # class for the trs
100
+ })
101
+
102
+ # these settings are considered constant for the whole application, can not be overridden
103
+ # on a per-table basis.
104
+ # That's necessary to allow find_for_table to work properly
105
+ TABLE_FORM_OPTIONS = WhinyHash.new({
106
+ batch_action_name: 'batch_action', # name of the batch action param
107
+ sort_by_key: 'sort_by_key', # name of key which to search, format is 'id asc'
108
+ pagination_postfix: '_pagination', # name of the param w/ the pagination infos
109
+ filter_postfix: '_filter', # postfix for name of the filter in the params hash: xxx_filter
110
+ sort_postfix: '_sort', # postfix for name of the filter in the params hash: xxx_filter
111
+ checked_postfix: '_checked', # postfix for name of the checked in the params hash: xxx_filter
112
+ associations_filter: '__association', # name of the associations in the filter hash
113
+ method: 'post', # http method for that form if applicable
114
+ batch_postfix: '_batch', # postfix for name of the batch action select
115
+ checked_separator: ',' # symbol to separate the checked ids
116
+ })
117
+
118
+ # these settings are considered constant for the whole application, can not be overridden
119
+ # on a per-table basis.
120
+ # That's necessary to allow find_for_table to work properly
121
+ PAGINATE_OPTIONS = ActiveSupport::HashWithIndifferentAccess.new({
122
+ page: 1,
123
+ pagesize: 10,
124
+ pagesizes: [10, 20, 50]
125
+ })
126
+
127
+ # Hash keeping the defaults for the column options
128
+ COLUMN_OPTIONS = ActiveSupport::HashWithIndifferentAccess.new({
129
+ header: false, # a string to write into the header cell
130
+ width: false, # the width of the cell
131
+ align: false, # horizontal alignment
132
+ valign: false, # vertical alignment
133
+ wrap: true, # wraps
134
+ type: :string, # :integer, :date
135
+ td_html: false, # a hash with html attributes for the cells
136
+ th_html: false, # a hash with html attributes for the header cell
137
+ filter_html: false, # a hash with html attributes for the filter cell
138
+ filter: true, # false for no filter field,
139
+ # container for options_for_select
140
+ # String from options_from_collection_for_select or the like
141
+ # :range for range spec
142
+ # :checkbox for a 0/1 valued checkbox
143
+ checkbox_value: '1', # value if checkbox is checked
144
+ checkbox_label: '', # text behind the checkbox
145
+ filter_width: '97%', # width of the filter <input>
146
+ range_filter_symbol: '&ndash;', # put between the <inputs> of the range filter
147
+ format: false, # a sprintf-string or a proc to do special formatting
148
+ method: false, # if you want to get the column by a different method than its name
149
+ link: false, # proc or symbol to make the content a link
150
+ join_symbol: ', ', # symbol used to join the elements of 'many' associations
151
+ sortable: true # if set, sorting-stuff is added to the header cell
152
+ })
153
+
154
+ # these settings are considered constant for the whole application, can not be overridden
155
+ # on a per-table basis.
156
+ # That's necessary to allow find_for_table to work properly
157
+ FINDER_INJECT_OPTIONS = WhinyHash.new({
158
+ pagination: :__pagination,
159
+ filters: :__filters,
160
+ classname: :__classname,
161
+ sorting: :__sorting,
162
+ checked: :__checked,
163
+ store_data: :__store_data
164
+ })
165
+
166
+ # defaults for the find_for_table
167
+ FINDER_OPTIONS = WhinyHash.new({
168
+ default_order: false,
169
+ default_pagesize: false,
170
+ precondition: false,
171
+ store_data: false
172
+ })
173
+
174
+ # Stupid hack
175
+ SQL_OPTIONS = WhinyHash.new({
176
+ like: 'LIKE'
177
+ })
178
+
179
+ def self.finder_inject_options(n=nil)
180
+ FINDER_INJECT_OPTIONS.merge!(n) if n
181
+ FINDER_INJECT_OPTIONS
182
+ end
183
+
184
+ def self.finder_options(n=nil)
185
+ FINDER_OPTIONS.merge!(n) if n
186
+ FINDER_OPTIONS
187
+ end
188
+
189
+ def self.column_options(n=nil)
190
+ COLUMN_OPTIONS.merge!(n) if n
191
+ COLUMN_OPTIONS
192
+ end
193
+
194
+ def self.table_options(n=nil)
195
+ TABLE_OPTIONS.merge!(n) if n
196
+ TABLE_OPTIONS
197
+ end
198
+
199
+ def self.paginate_options(n=nil)
200
+ PAGINATE_OPTIONS.merge!(n) if n
201
+ PAGINATE_OPTIONS
202
+ end
203
+
204
+ def self.table_form_options(n=nil)
205
+ TABLE_FORM_OPTIONS.merge!(n) if n
206
+ TABLE_FORM_OPTIONS
207
+ end
208
+
209
+ def self.table_design_options(n=nil)
210
+ raise("table_design_options stopped existing. Use table_options instead.")
211
+ end
212
+ def table_design_options(n=nil) self.class.table_design_options(n) end
213
+
214
+ def self.sql_options(n=nil)
215
+ SQL_OPTIONS.merge!(n) if n
216
+ SQL_OPTIONS
217
+ end
218
+ def sql_options(n=nil) self.class.sql_options(n) end
219
+
220
+
221
+ end