tabulatr 0.0.5 → 0.1.0
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.
- data/Changelog.textile +18 -0
- data/Gemfile.lock +9 -9
- data/README.textile +18 -14
- data/assets/company_logos.png +0 -0
- data/lib/tabulatr/tabulatr/finder/find_for_active_record_table.rb +72 -29
- data/lib/tabulatr/tabulatr/settings.rb +23 -16
- data/lib/tabulatr/tabulatr.rb +6 -1
- data/lib/tabulatr/version.rb +1 -1
- data/spec/dummy_app/app/controllers/products_controller.rb +4 -0
- data/spec/dummy_app/app/views/products/index_stateful.html.erb +6 -0
- data/spec/dummy_app/config/routes.rb +1 -0
- data/spec/requests/tabulatrs_spec.rb +53 -0
- data/tabulatr.gemspec +3 -4
- metadata +29 -6
data/Changelog.textile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
h1. Changelog for tabulatr
|
2
|
+
|
3
|
+
h2. v0.0.5 (2011-03-28)
|
4
|
+
|
5
|
+
* new column option :map (defaults to true) to disable automatic mapping on the enries of the association as in
|
6
|
+
|
7
|
+
<pre>
|
8
|
+
<%= table_for @products do |t|
|
9
|
+
...
|
10
|
+
t.association :tags, :title # mapped to all tags
|
11
|
+
t.association :tags, :count, :map => false # called on the list-of-tags
|
12
|
+
end %>
|
13
|
+
</pre>
|
14
|
+
|
15
|
+
|
16
|
+
h2. v0.0.4 (2011-03-27)
|
17
|
+
|
18
|
+
* fixed the path to paging/sorting images installed by generator. Thanks to <a href="https://github.com/sdsykes" target="_blank">sdsykes</a>!
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tabulatr (0.0
|
4
|
+
tabulatr (0.1.0)
|
5
5
|
id_stuffer (>= 0.0.1)
|
6
6
|
rails (~> 3.0)
|
7
7
|
whiny_hash (>= 0.0.2)
|
@@ -48,9 +48,9 @@ GEM
|
|
48
48
|
rack-test (>= 0.5.4)
|
49
49
|
selenium-webdriver (>= 0.0.27)
|
50
50
|
xpath (~> 0.1.3)
|
51
|
-
celerity (0.8.
|
52
|
-
childprocess (0.1.
|
53
|
-
ffi (~> 0.6
|
51
|
+
celerity (0.8.9)
|
52
|
+
childprocess (0.1.8)
|
53
|
+
ffi (~> 1.0.6)
|
54
54
|
columnize (0.3.2)
|
55
55
|
configuration (1.2.0)
|
56
56
|
culerity (0.2.15)
|
@@ -58,7 +58,7 @@ GEM
|
|
58
58
|
diff-lcs (1.1.2)
|
59
59
|
erubis (2.6.6)
|
60
60
|
abstract (>= 1.0.0)
|
61
|
-
ffi (0.
|
61
|
+
ffi (1.0.7)
|
62
62
|
rake (>= 0.8.7)
|
63
63
|
i18n (0.5.0)
|
64
64
|
id_stuffer (0.0.1)
|
@@ -77,7 +77,7 @@ GEM
|
|
77
77
|
nokogiri (1.4.4)
|
78
78
|
polyglot (0.3.1)
|
79
79
|
rack (1.2.2)
|
80
|
-
rack-mount (0.6.
|
80
|
+
rack-mount (0.6.14)
|
81
81
|
rack (>= 1.0.0)
|
82
82
|
rack-test (0.5.7)
|
83
83
|
rack (>= 1.0)
|
@@ -119,9 +119,9 @@ GEM
|
|
119
119
|
ruby_core_source (0.1.4)
|
120
120
|
archive-tar-minitar (>= 0.5.2)
|
121
121
|
rubyzip (0.9.4)
|
122
|
-
selenium-webdriver (0.1.
|
123
|
-
childprocess (
|
124
|
-
ffi (
|
122
|
+
selenium-webdriver (0.1.4)
|
123
|
+
childprocess (>= 0.1.7)
|
124
|
+
ffi (>= 1.0.7)
|
125
125
|
json_pure
|
126
126
|
rubyzip
|
127
127
|
sqlite3 (1.3.3)
|
data/README.textile
CHANGED
@@ -8,7 +8,7 @@ We found ourselves reinventing the wheel in every project we made, by using
|
|
8
8
|
|
9
9
|
* different paging mechanisms,
|
10
10
|
* different ways of implementing filtering/searching,
|
11
|
-
*
|
11
|
+
* different ways of implementing selecting and batch actions,
|
12
12
|
* different layouts.
|
13
13
|
|
14
14
|
We finally thought that whilst gems like Formtastic or SimpleForm provide a really cool, uniform, and concise way to implement forms, it's time for a table builder. During a project with Magento, we decided that their general tables are quite reasonable, and enterprise-proven -- so that's our starting point.
|
@@ -19,17 +19,17 @@ Every Tabulatr table consists of the following components:
|
|
19
19
|
|
20
20
|
* a wrapping form
|
21
21
|
* a 'Controls Container' containing the table-controls as
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
** the paginator,
|
23
|
+
** the batch_actions,
|
24
|
+
** the submit button,
|
25
|
+
** controls to manage selecting/checking/marking,
|
26
|
+
** an info_text
|
27
27
|
* The actual table consisting of
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
** A header row,
|
29
|
+
** A filter row,
|
30
|
+
** data rows,
|
31
|
+
** possibly a selecting/checking/marking column
|
32
|
+
** possibly action links/buttons
|
33
33
|
|
34
34
|
Whilst this is a strong decision, we made everything as-configurable-as-possible, there are roughly 150 options you can use to tweak almost every aspect of Tabulatr.
|
35
35
|
|
@@ -40,6 +40,7 @@ Tabulatr tries to make these common tasks as simple/transparent as possible:
|
|
40
40
|
* selecting/checking/marking
|
41
41
|
* filtering
|
42
42
|
* batch actions
|
43
|
+
* stateful index pages
|
43
44
|
|
44
45
|
h2. Example
|
45
46
|
|
@@ -60,7 +61,7 @@ In the products controllers index action we have:
|
|
60
61
|
end
|
61
62
|
</pre>
|
62
63
|
|
63
|
-
the find_for_table method is injected into ActiveRecord by Tabulatr, it retrieves all relevant data from the params hash automagically.
|
64
|
+
the <tt>find_for_table</tt> method is injected into ActiveRecord by Tabulatr, it retrieves all relevant data from the <tt>params</tt> hash automagically. If you want the the table to be stateful, i.e. remembering its sorting/filtering/selecting settings (very useful when processing a certain selection of entries), you can pass the option <tt>:stateful => session</tt> to the <tt>find_for_table</tt> call and the data will be stored. Also, a _Reset_ button will be rendered to get rid of the state.
|
64
65
|
|
65
66
|
h3. View
|
66
67
|
|
@@ -105,7 +106,9 @@ To add a select-popup with batch-actions (i.e., actions that are to be performed
|
|
105
106
|
end %>
|
106
107
|
</pre>
|
107
108
|
|
108
|
-
|
109
|
+
If you prefer individual buttons for the batch actions over a select input, give the option <tt>:batch_actions_type => :button</tt> to the <tt>table_for</tt> call.
|
110
|
+
|
111
|
+
To handle the actual batch action, we have to add a block to the <tt>find_for_table</tt> call in the controller:
|
109
112
|
|
110
113
|
<pre>
|
111
114
|
@products = Product.find_for_table(params) do |batch_actions|
|
@@ -201,6 +204,7 @@ These options are to be specified at the form_for level and change the appearanc
|
|
201
204
|
unselect_visible_label: 'Unselect visible', # Text on the unselect visible button
|
202
205
|
select_filtered_label: 'Select filtered', # Text on the select filtered button
|
203
206
|
unselect_filtered_label: 'Unselect filtered', # Text on the unselect filtered button
|
207
|
+
reset_label: 'Reset', # Text on the reset button
|
204
208
|
info_text: "Showing %1$d, total %2$d, selected %3$d, matching %4$d",
|
205
209
|
|
206
210
|
# which controls to be rendered above and below the tabel and in which order
|
@@ -313,7 +317,7 @@ We use
|
|
313
317
|
|
314
318
|
h2. Bugs
|
315
319
|
|
316
|
-
There are, definitely, roughly
|
320
|
+
There are, definitely, roughly 999 bugs in Tabulatr, although we do some testing (see <tt>spec/</tt>). So if you hunt them, please let me know using the <a href="https://github.com/provideal/tabulatr/issues">GitHub Bugtracker</a>.
|
317
321
|
|
318
322
|
h2. License
|
319
323
|
|
Binary file
|
@@ -29,8 +29,8 @@ module Tabulatr::Finder
|
|
29
29
|
# Called if SomeActveRecordSubclass::find_for_table(params) is called
|
30
30
|
#
|
31
31
|
def self.find_for_active_record_table(klaz, params, o={}, &block)
|
32
|
+
# on the first run, get the correct like db-operator, can still be ovrrridden
|
32
33
|
unless Tabulatr::SQL_OPTIONS[:like]
|
33
|
-
# get the correct like db-operator, can still be ovrrridden
|
34
34
|
case ActiveRecord::Base.connection.class.to_s
|
35
35
|
when "ActiveRecord::ConnectionAdapters::MysqlAdapter" then Tabulatr.sql_options(:like => 'LIKE')
|
36
36
|
when "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter" then Tabulatr.sql_options(:like => 'ILIKE')
|
@@ -42,25 +42,88 @@ module Tabulatr::Finder
|
|
42
42
|
Tabulatr.sql_options(:like => 'LIKE')
|
43
43
|
end
|
44
44
|
end
|
45
|
+
|
45
46
|
form_options = Tabulatr.table_form_options
|
46
|
-
cname = class_to_param(klaz)
|
47
|
-
params ||= {}
|
48
47
|
opts = Tabulatr.finder_options.merge(o)
|
48
|
+
params ||= {} # just to be sure
|
49
|
+
cname = class_to_param(klaz)
|
50
|
+
pagination_name = "#{cname}#{form_options[:pagination_postfix]}"
|
51
|
+
sort_name = "#{cname}#{form_options[:sort_postfix]}"
|
52
|
+
filter_name = "#{cname}#{form_options[:filter_postfix]}"
|
53
|
+
batch_name = "#{cname}#{form_options[:batch_postfix]}"
|
54
|
+
check_name = "#{cname}#{form_options[:checked_postfix]}"
|
55
|
+
|
56
|
+
|
49
57
|
# before we do anything else, we find whether there's something to do for batch actions
|
50
58
|
checked_param = ActiveSupport::HashWithIndifferentAccess.new({:checked_ids => '', :current_page => []}).
|
51
|
-
merge(params[
|
59
|
+
merge(params[check_name] || {})
|
52
60
|
checked_ids = uncompress_id_list(checked_param[:checked_ids])
|
53
61
|
new_ids = checked_param[:current_page]
|
54
62
|
selected_ids = checked_ids + new_ids
|
55
|
-
batch_param = params[
|
63
|
+
batch_param = params[batch_name]
|
56
64
|
if batch_param.present? and block_given?
|
57
65
|
batch_param = batch_param.keys.first.to_sym if batch_param.is_a?(Hash)
|
58
66
|
yield(Invoker.new(batch_param, selected_ids))
|
59
67
|
end
|
68
|
+
|
69
|
+
# then, we obey any "select" buttons if pushed
|
70
|
+
if checked_param[:select_all]
|
71
|
+
all = klaz.find :all, :conditions => precondition, :select => :id
|
72
|
+
selected_ids = all.map { |r| r.id.to_s }
|
73
|
+
elsif checked_param[:select_none]
|
74
|
+
selected_ids = []
|
75
|
+
elsif checked_param[:select_visible]
|
76
|
+
visible_ids = uncompress_id_list(checked_param[:visible])
|
77
|
+
selected_ids = (selected_ids + visible_ids).sort.uniq
|
78
|
+
elsif checked_param[:unselect_visible]
|
79
|
+
visible_ids = uncompress_id_list(checked_param[:visible])
|
80
|
+
selected_ids = (selected_ids - visible_ids).sort.uniq
|
81
|
+
elsif checked_param[:select_filtered]
|
82
|
+
all = klaz.find :all, :conditions => conditions, :select => :id, :include => includes
|
83
|
+
selected_ids = (selected_ids + all.map { |r| r.id.to_s }).sort.uniq
|
84
|
+
elsif checked_param[:unselect_filtered]
|
85
|
+
all = klaz.find :all, :conditions => conditions, :select => :id, :include => includes
|
86
|
+
selected_ids = (selected_ids - all.map { |r| r.id.to_s }).sort.uniq
|
87
|
+
end
|
88
|
+
|
89
|
+
# at this point, we've retrieved the filter settings, the sorting setting, the pagination settings and
|
90
|
+
# the selected_ids.
|
91
|
+
filter_param = (params[filter_name] || {})
|
92
|
+
sortparam = params[sort_name]
|
93
|
+
pops = params[pagination_name] || {}
|
94
|
+
|
95
|
+
# store the state if appropriate
|
96
|
+
if opts[:stateful]
|
97
|
+
session = opts[:stateful]
|
98
|
+
sname = "#{cname}#{form_options[:state_session_postfix]}"
|
99
|
+
raise "give the session as the :stateful parameter in find_for_table" unless session.is_a?(ActionDispatch::Session::AbstractStore::SessionHash)
|
100
|
+
session[sname] ||= {}
|
101
|
+
|
102
|
+
if params["#{cname}#{form_options[:reset_state_postfix]}"]
|
103
|
+
# clicked reset button, reset all and clear session
|
104
|
+
selected_ids = []
|
105
|
+
filter_param = {}
|
106
|
+
sortparam = nil
|
107
|
+
pops = {}
|
108
|
+
session.delete sname
|
109
|
+
elsif !pops.present? && !selected_ids.present? && !sortparam.present? && !filter_param.present?
|
110
|
+
# we're supposed to retrieve the state from the session if applicable
|
111
|
+
state = session[sname]
|
112
|
+
selected_ids = state[:selected_ids] || []
|
113
|
+
filter_param = state[:filter_param] || {}
|
114
|
+
sortparam = state[:sortparam]
|
115
|
+
pops = state[:paging_param] || {}
|
116
|
+
else
|
117
|
+
# store the current settings into the session to be stateful ;)
|
118
|
+
session[sname][:selected_ids] = selected_ids
|
119
|
+
session[sname][:filter_param] = filter_param
|
120
|
+
session[sname][:sortparam] = sortparam
|
121
|
+
session[sname][:paging_param] = pops
|
122
|
+
end
|
123
|
+
end
|
60
124
|
|
61
125
|
# firstly, get the conditions from the filters
|
62
126
|
includes = []
|
63
|
-
filter_param = (params["#{cname}#{form_options[:filter_postfix]}"] || {})
|
64
127
|
precondition = opts[:precondition] || "(1=1)"
|
65
128
|
conditions = filter_param.inject([precondition.dup, []]) do |c, t|
|
66
129
|
n, v = t
|
@@ -82,7 +145,6 @@ module Tabulatr::Finder
|
|
82
145
|
conditions = [conditions.first] + conditions.last
|
83
146
|
|
84
147
|
# secondly, find the order_by stuff
|
85
|
-
sortparam = params["#{cname}#{form_options[:sort_postfix]}"]
|
86
148
|
if sortparam
|
87
149
|
if sortparam[:_resort]
|
88
150
|
order_by = sortparam[:_resort].first.first
|
@@ -108,7 +170,6 @@ module Tabulatr::Finder
|
|
108
170
|
end
|
109
171
|
|
110
172
|
# thirdly, get the pagination data
|
111
|
-
pops = params["#{cname}#{form_options[:pagination_postfix]}"] || {}
|
112
173
|
paginate_options = Tabulatr.paginate_options.merge(opts).merge(pops)
|
113
174
|
pagesize = (pops[:pagesize] || opts[:default_pagesize] || paginate_options[:pagesize]).to_f
|
114
175
|
page = paginate_options[:page].to_i
|
@@ -118,27 +179,6 @@ module Tabulatr::Finder
|
|
118
179
|
pages = (c/pagesize).ceil
|
119
180
|
page = [1, [page, pages].min].max
|
120
181
|
|
121
|
-
# then, we obey any "select" buttons if pushed
|
122
|
-
if checked_param[:select_all]
|
123
|
-
all = klaz.find :all, :conditions => precondition, :select => :id
|
124
|
-
selected_ids = all.map { |r| r.id.to_s }
|
125
|
-
elsif checked_param[:select_none]
|
126
|
-
selected_ids = []
|
127
|
-
elsif checked_param[:select_visible]
|
128
|
-
visible_ids = uncompress_id_list(checked_param[:visible])
|
129
|
-
selected_ids = (selected_ids + visible_ids).sort.uniq
|
130
|
-
elsif checked_param[:unselect_visible]
|
131
|
-
visible_ids = uncompress_id_list(checked_param[:visible])
|
132
|
-
selected_ids = (selected_ids - visible_ids).sort.uniq
|
133
|
-
elsif checked_param[:select_filtered]
|
134
|
-
all = klaz.find :all, :conditions => conditions, :select => :id, :include => includes
|
135
|
-
selected_ids = (selected_ids + all.map { |r| r.id.to_s }).sort.uniq
|
136
|
-
elsif checked_param[:unselect_filtered]
|
137
|
-
all = klaz.find :all, :conditions => conditions, :select => :id, :include => includes
|
138
|
-
selected_ids = (selected_ids - all.map { |r| r.id.to_s }).sort.uniq
|
139
|
-
end
|
140
|
-
|
141
|
-
|
142
182
|
# Now, actually find the stuff
|
143
183
|
found = klaz.find :all, :conditions => conditions,
|
144
184
|
:limit => pagesize.to_i, :offset => ((page-1)*pagesize).to_i,
|
@@ -165,6 +205,9 @@ module Tabulatr::Finder
|
|
165
205
|
:visible => visible_ids
|
166
206
|
}
|
167
207
|
end
|
208
|
+
found.define_singleton_method(fio[:stateful]) do
|
209
|
+
(opts[:stateful] ? true : false)
|
210
|
+
end
|
168
211
|
found.define_singleton_method(fio[:store_data]) do
|
169
212
|
opts[:store_data] || {}
|
170
213
|
end
|
@@ -38,6 +38,7 @@ class Tabulatr
|
|
38
38
|
:page_left_class => 'page-left', # class for the page left button
|
39
39
|
:page_right_class => 'page-right', # class for the page right button
|
40
40
|
:page_no_class => 'page-no', # class for the page no <input>
|
41
|
+
:reset_class => 'reset', # class for the reset button
|
41
42
|
:control_div_class_before => 'table-controls', # class of the upper div containing the paging and batch action controls
|
42
43
|
:control_div_class_after => 'table-controls', # class of the lower div containing the paging and batch action controls
|
43
44
|
:paginator_div_class => 'paginator', # class of the div containing the paging controls
|
@@ -63,10 +64,11 @@ class Tabulatr
|
|
63
64
|
:unselect_visible_label => 'Unselect visible', # Text on the unselect visible button
|
64
65
|
:select_filtered_label => 'Select filtered', # Text on the select filtered button
|
65
66
|
:unselect_filtered_label => 'Unselect filtered',# Text on the unselect filtered button
|
67
|
+
:reset_label => 'Reset', # Text on the reset button
|
66
68
|
:info_text => "Showing %1$d, total %2$d, selected %3$d, matching %4$d",
|
67
69
|
|
68
70
|
# 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],
|
71
|
+
:before_table_controls => [:submit, :reset, :paginator, :batch_actions, :select_controls, :info_text],
|
70
72
|
:after_table_controls => [],
|
71
73
|
|
72
74
|
# whih selecting controls to render in which order
|
@@ -83,19 +85,20 @@ class Tabulatr
|
|
83
85
|
:sort_down_button => 'sort_arrow_down.gif',
|
84
86
|
:sort_down_button_inactive => 'sort_arrow_down_off.gif',
|
85
87
|
|
86
|
-
:make_form => true,
|
87
|
-
:table_html => false,
|
88
|
-
:row_html => false,
|
89
|
-
:header_html => false,
|
90
|
-
:filter_html => false,
|
91
|
-
:filter => true,
|
92
|
-
:paginate => true,
|
93
|
-
:sortable => true,
|
94
|
-
:selectable => true,
|
95
|
-
:
|
96
|
-
:
|
97
|
-
:
|
98
|
-
:
|
88
|
+
:make_form => true, # whether or not to wrap the whole table (incl. controls) in a form
|
89
|
+
:table_html => false, # a hash with html attributes for the table
|
90
|
+
:row_html => false, # a hash with html attributes for the normal trs
|
91
|
+
:header_html => false, # a hash with html attributes for the header trs
|
92
|
+
:filter_html => false, # a hash with html attributes for the filter trs
|
93
|
+
:filter => true, # false for no filter row at all
|
94
|
+
:paginate => true, # true to show paginator
|
95
|
+
:sortable => true, # true to allow sorting (can be specified for every sortable column)
|
96
|
+
:selectable => true, # true to render "select all", "select none" and the like
|
97
|
+
:reset => false, # true to render a reset button. Only reasonable in 'stateful' case
|
98
|
+
:action => nil, # target action of the wrapping form if applicable
|
99
|
+
:batch_actions => false, # :name => value hash of batch action stuff
|
100
|
+
:translate => false, # call t() for all 'labels' and stuff, possible values are true/:translate or :localize
|
101
|
+
:row_classes => ['odd', 'even'] # class for the trs
|
99
102
|
})
|
100
103
|
|
101
104
|
# these settings are considered constant for the whole application, can not be overridden
|
@@ -111,6 +114,8 @@ class Tabulatr
|
|
111
114
|
:associations_filter => '__association', # name of the associations in the filter hash
|
112
115
|
:method => 'post', # http method for that form if applicable
|
113
116
|
:batch_postfix => '_batch', # postfix for name of the batch action select
|
117
|
+
:state_session_postfix => '_table_state', # postfix for the state hash in the sessions
|
118
|
+
:reset_state_postfix => '_reset_state', # postfix for the name of the input to reset state
|
114
119
|
:checked_separator => ',' # symbol to separate the checked ids
|
115
120
|
})
|
116
121
|
|
@@ -160,7 +165,8 @@ class Tabulatr
|
|
160
165
|
:classname => :__classname,
|
161
166
|
:sorting => :__sorting,
|
162
167
|
:checked => :__checked,
|
163
|
-
:store_data => :__store_data
|
168
|
+
:store_data => :__store_data,
|
169
|
+
:stateful => :__stateful
|
164
170
|
})
|
165
171
|
|
166
172
|
# defaults for the find_for_table
|
@@ -168,7 +174,8 @@ class Tabulatr
|
|
168
174
|
:default_order => false,
|
169
175
|
:default_pagesize => false,
|
170
176
|
:precondition => false,
|
171
|
-
:store_data => false
|
177
|
+
:store_data => false,
|
178
|
+
:stateful => false
|
172
179
|
})
|
173
180
|
|
174
181
|
# Stupid hack
|
data/lib/tabulatr/tabulatr.rb
CHANGED
@@ -62,6 +62,7 @@ class Tabulatr
|
|
62
62
|
@sorting = @records.send(FINDER_INJECT_OPTIONS[:sorting])
|
63
63
|
@checked = @records.send(FINDER_INJECT_OPTIONS[:checked])
|
64
64
|
@store_data = @records.send(FINDER_INJECT_OPTIONS[:store_data])
|
65
|
+
@stateful = @records.send(FINDER_INJECT_OPTIONS[:stateful])
|
65
66
|
@should_translate = @table_options[:translate]
|
66
67
|
end
|
67
68
|
|
@@ -109,10 +110,14 @@ class Tabulatr
|
|
109
110
|
def render_element(element, &block)
|
110
111
|
case element
|
111
112
|
when :paginator then render_paginator if @table_options[:paginate]
|
112
|
-
when :hidden_submit then
|
113
|
+
when :hidden_submit then "IMPLEMENT ME!"
|
113
114
|
when :submit then make_tag(:input, :type => 'submit',
|
114
115
|
:class => @table_options[:submit_class],
|
115
116
|
:value => t(@table_options[:submit_label]))
|
117
|
+
when :reset then make_tag(:input, :type => 'submit',
|
118
|
+
:class => @table_options[:reset_class],
|
119
|
+
:name => "#{@classname}#{TABLE_FORM_OPTIONS[:reset_state_postfix]}",
|
120
|
+
:value => t(@table_options[:reset_label])) if @stateful
|
116
121
|
when :batch_actions then render_batch_actions if @table_options[:batch_actions]
|
117
122
|
when :select_controls then render_select_controls if @table_options[:selectable]
|
118
123
|
when :info_text
|
data/lib/tabulatr/version.rb
CHANGED
@@ -21,6 +21,10 @@ class ProductsController < ApplicationController
|
|
21
21
|
@products = Product.find_for_table(params)
|
22
22
|
end
|
23
23
|
|
24
|
+
def index_stateful
|
25
|
+
@products = Product.find_for_table(params, :stateful => session)
|
26
|
+
end
|
27
|
+
|
24
28
|
def index_select
|
25
29
|
@products = Product.find_for_table(params) do |batch_actions|
|
26
30
|
batch_actions.delete do |ids|
|
@@ -23,6 +23,8 @@ describe "Tabulatrs" do
|
|
23
23
|
FILTERS = FILTERS_WITH_LIKE = FILTERS_WITH_RANGE = tralse
|
24
24
|
# Sorting
|
25
25
|
KNOWS_HOW_TO_SORT = tralse
|
26
|
+
# Statful
|
27
|
+
SORTS_STATEFULLY = FILTERS_STATEFULLY = SELECTS_STATEFULLY = true
|
26
28
|
# selecting and batch actions
|
27
29
|
KNOWS_HOW_TO_SELECT_AND_APPLY_BATCH_ACTIONS = tralse
|
28
30
|
|
@@ -45,6 +47,7 @@ describe "Tabulatrs" do
|
|
45
47
|
].each do |n|
|
46
48
|
page.should have_button(Tabulatr::TABLE_OPTIONS[n])
|
47
49
|
end
|
50
|
+
page.should_not have_button(Tabulatr::TABLE_OPTIONS[:reset_label])
|
48
51
|
end if CONTAINS_BUTTONS
|
49
52
|
|
50
53
|
it "contains column headers" do
|
@@ -248,6 +251,56 @@ describe "Tabulatrs" do
|
|
248
251
|
end if KNOWS_HOW_TO_SORT
|
249
252
|
end
|
250
253
|
|
254
|
+
describe "statefulness" do
|
255
|
+
it "sorts statefully" do
|
256
|
+
visit index_stateful_products_path
|
257
|
+
click_button("product_sort_title_desc")
|
258
|
+
snames = names.sort
|
259
|
+
(1..10).each do |i|
|
260
|
+
page.should have_content snames[-i]
|
261
|
+
end
|
262
|
+
visit index_stateful_products_path
|
263
|
+
(1..10).each do |i|
|
264
|
+
page.should have_content snames[-i]
|
265
|
+
end
|
266
|
+
click_button("Reset")
|
267
|
+
(1..10).each do |i|
|
268
|
+
page.should have_content names[i-1]
|
269
|
+
end
|
270
|
+
end if SORTS_STATEFULLY
|
271
|
+
|
272
|
+
it "filters statefully" do
|
273
|
+
visit index_stateful_products_path
|
274
|
+
fill_in("product_filter[title]", :with => "lorem")
|
275
|
+
click_button("Apply")
|
276
|
+
visit index_stateful_products_path
|
277
|
+
page.should have_content(sprintf(Tabulatr::TABLE_OPTIONS[:info_text], 1, names.length, 0, 1))
|
278
|
+
click_button("Reset")
|
279
|
+
page.should have_content(sprintf(Tabulatr::TABLE_OPTIONS[:info_text], 10, names.length, 0, names.length))
|
280
|
+
end if FILTERS_STATEFULLY
|
281
|
+
|
282
|
+
it "selects statefully" do
|
283
|
+
visit index_stateful_products_path
|
284
|
+
n = names.length
|
285
|
+
(n/10).times do |i|
|
286
|
+
(1..3).each do |j|
|
287
|
+
check("product_checked_#{10*i+j}")
|
288
|
+
end
|
289
|
+
click_button("Apply")
|
290
|
+
tot = 3*(i+1)
|
291
|
+
page.should have_content(sprintf(Tabulatr::TABLE_OPTIONS[:info_text], 10, n, tot, n))
|
292
|
+
click_button('product_pagination_page_right')
|
293
|
+
end
|
294
|
+
visit index_stateful_products_path
|
295
|
+
tot = 3*(n/10)
|
296
|
+
page.should have_content(sprintf(Tabulatr::TABLE_OPTIONS[:info_text], names.length % 10, n, tot, n))
|
297
|
+
click_button("Reset")
|
298
|
+
page.should have_content(sprintf(Tabulatr::TABLE_OPTIONS[:info_text], 10, names.length, 0, names.length))
|
299
|
+
end if SELECTS_STATEFULLY
|
300
|
+
|
301
|
+
end
|
302
|
+
|
303
|
+
|
251
304
|
describe "Select and Batch actions" do
|
252
305
|
it "knows how to select and apply batch actions" do
|
253
306
|
visit index_select_products_path
|
data/tabulatr.gemspec
CHANGED
@@ -6,12 +6,11 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "tabulatr"
|
7
7
|
s.version = Tabulatr::VERSION.dup
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.summary = "
|
9
|
+
s.summary = "A tight DSL to build tables of ActiveRecord models with sorting, pagination, finding/filtering, selecting and batch actions."
|
10
10
|
s.email = "info@provideal.net"
|
11
11
|
s.homepage = "http://github.com/provideal/tabulatr"
|
12
|
-
s.description = "
|
13
|
-
"
|
14
|
-
"names of the columns. See the README for details."
|
12
|
+
s.description = "A tight DSL to build tables of ActiveRecord models with sorting, pagination, finding/filtering, selecting and batch actions. " +
|
13
|
+
"Tries to do for tables what formtastic and simple_form did for forms."
|
15
14
|
s.authors = ['Peter Horn', 'René Sprotte']
|
16
15
|
|
17
16
|
s.files = `git ls-files`.split("\n")
|
metadata
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tabulatr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
6
10
|
platform: ruby
|
7
11
|
authors:
|
8
12
|
- Peter Horn
|
@@ -11,7 +15,7 @@ autorequire:
|
|
11
15
|
bindir: bin
|
12
16
|
cert_chain: []
|
13
17
|
|
14
|
-
date: 2011-03-
|
18
|
+
date: 2011-03-29 00:00:00 +02:00
|
15
19
|
default_executable:
|
16
20
|
dependencies:
|
17
21
|
- !ruby/object:Gem::Dependency
|
@@ -22,6 +26,9 @@ dependencies:
|
|
22
26
|
requirements:
|
23
27
|
- - ~>
|
24
28
|
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 3
|
31
|
+
- 0
|
25
32
|
version: "3.0"
|
26
33
|
type: :runtime
|
27
34
|
version_requirements: *id001
|
@@ -33,6 +40,10 @@ dependencies:
|
|
33
40
|
requirements:
|
34
41
|
- - ">="
|
35
42
|
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
- 0
|
46
|
+
- 2
|
36
47
|
version: 0.0.2
|
37
48
|
type: :runtime
|
38
49
|
version_requirements: *id002
|
@@ -44,10 +55,14 @@ dependencies:
|
|
44
55
|
requirements:
|
45
56
|
- - ">="
|
46
57
|
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
- 0
|
61
|
+
- 1
|
47
62
|
version: 0.0.1
|
48
63
|
type: :runtime
|
49
64
|
version_requirements: *id003
|
50
|
-
description:
|
65
|
+
description: A tight DSL to build tables of ActiveRecord models with sorting, pagination, finding/filtering, selecting and batch actions. Tries to do for tables what formtastic and simple_form did for forms.
|
51
66
|
email: info@provideal.net
|
52
67
|
executables: []
|
53
68
|
|
@@ -58,11 +73,13 @@ extra_rdoc_files: []
|
|
58
73
|
files:
|
59
74
|
- .gitignore
|
60
75
|
- .rspec
|
76
|
+
- Changelog.textile
|
61
77
|
- Gemfile
|
62
78
|
- Gemfile.lock
|
63
79
|
- LICENSE
|
64
80
|
- README.textile
|
65
81
|
- Rakefile
|
82
|
+
- assets/company_logos.png
|
66
83
|
- assets/images/buttons_lite_background.png
|
67
84
|
- assets/images/pager_arrow_left.gif
|
68
85
|
- assets/images/pager_arrow_left_off.gif
|
@@ -113,6 +130,7 @@ files:
|
|
113
130
|
- spec/dummy_app/app/views/products/index_filters.html.erb
|
114
131
|
- spec/dummy_app/app/views/products/index_select.html.erb
|
115
132
|
- spec/dummy_app/app/views/products/index_simple.html.erb
|
133
|
+
- spec/dummy_app/app/views/products/index_stateful.html.erb
|
116
134
|
- spec/dummy_app/app/views/products/new.html.erb
|
117
135
|
- spec/dummy_app/app/views/products/show.html.erb
|
118
136
|
- spec/dummy_app/app/views/vendors/_form.html.erb
|
@@ -183,20 +201,24 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
183
201
|
requirements:
|
184
202
|
- - ">="
|
185
203
|
- !ruby/object:Gem::Version
|
204
|
+
segments:
|
205
|
+
- 0
|
186
206
|
version: "0"
|
187
207
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
208
|
none: false
|
189
209
|
requirements:
|
190
210
|
- - ">="
|
191
211
|
- !ruby/object:Gem::Version
|
212
|
+
segments:
|
213
|
+
- 0
|
192
214
|
version: "0"
|
193
215
|
requirements: []
|
194
216
|
|
195
217
|
rubyforge_project: tabulatr
|
196
|
-
rubygems_version: 1.
|
218
|
+
rubygems_version: 1.3.7
|
197
219
|
signing_key:
|
198
220
|
specification_version: 3
|
199
|
-
summary:
|
221
|
+
summary: A tight DSL to build tables of ActiveRecord models with sorting, pagination, finding/filtering, selecting and batch actions.
|
200
222
|
test_files:
|
201
223
|
- spec/dummy_app/.gitignore
|
202
224
|
- spec/dummy_app/app/controllers/application_controller.rb
|
@@ -215,6 +237,7 @@ test_files:
|
|
215
237
|
- spec/dummy_app/app/views/products/index_filters.html.erb
|
216
238
|
- spec/dummy_app/app/views/products/index_select.html.erb
|
217
239
|
- spec/dummy_app/app/views/products/index_simple.html.erb
|
240
|
+
- spec/dummy_app/app/views/products/index_stateful.html.erb
|
218
241
|
- spec/dummy_app/app/views/products/new.html.erb
|
219
242
|
- spec/dummy_app/app/views/products/show.html.erb
|
220
243
|
- spec/dummy_app/app/views/vendors/_form.html.erb
|