tabulatr 0.0.1

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,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