tabulatr2 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.travis.yml +4 -0
- data/Changelog.textile +124 -0
- data/Gemfile +21 -0
- data/LICENSE +23 -0
- data/README.md +242 -0
- data/Rakefile +11 -0
- data/app/assets/images/tabulatr/buttons_lite_background.png +0 -0
- data/app/assets/images/tabulatr/pager_arrow_left.gif +0 -0
- data/app/assets/images/tabulatr/pager_arrow_left_off.gif +0 -0
- data/app/assets/images/tabulatr/pager_arrow_right.gif +0 -0
- data/app/assets/images/tabulatr/pager_arrow_right_off.gif +0 -0
- data/app/assets/images/tabulatr/sort_arrow_down.gif +0 -0
- data/app/assets/images/tabulatr/sort_arrow_down_off.gif +0 -0
- data/app/assets/images/tabulatr/sort_arrow_up.gif +0 -0
- data/app/assets/images/tabulatr/sort_arrow_up_off.gif +0 -0
- data/app/assets/javascripts/tabulatr/application.js +452 -0
- data/app/assets/javascripts/tabulatr/jquery.inview.min.js +3 -0
- data/app/assets/javascripts/tabulatr.js +1 -0
- data/app/assets/stylesheets/tabulatr/application.css +40 -0
- data/app/assets/stylesheets/tabulatr.css +4 -0
- data/init.rb +1 -0
- data/lib/generators/tabulatr/install_generator.rb +44 -0
- data/lib/generators/tabulatr/templates/tabulatr.rb +5 -0
- data/lib/generators/tabulatr/templates/tabulatr.yml +14 -0
- data/lib/initializers/action_controller.rb +13 -0
- data/lib/initializers/action_view.rb +31 -0
- data/lib/initializers/active_record.rb +48 -0
- data/lib/initializers/mark_as_localizable.rb +43 -0
- data/lib/tabulatr/engine.rb +3 -0
- data/lib/tabulatr/tabulatr/adapter/active_record.rb +84 -0
- data/lib/tabulatr/tabulatr/adapter.rb +55 -0
- data/lib/tabulatr/tabulatr/batch_actions.rb +51 -0
- data/lib/tabulatr/tabulatr/data_cell.rb +132 -0
- data/lib/tabulatr/tabulatr/dummy_record.rb +40 -0
- data/lib/tabulatr/tabulatr/empty_cell.rb +44 -0
- data/lib/tabulatr/tabulatr/filter_cell.rb +145 -0
- data/lib/tabulatr/tabulatr/filter_icon.rb +6 -0
- data/lib/tabulatr/tabulatr/finder/find_for_table.rb +187 -0
- data/lib/tabulatr/tabulatr/finder.rb +64 -0
- data/lib/tabulatr/tabulatr/formattr.rb +55 -0
- data/lib/tabulatr/tabulatr/header_cell.rb +146 -0
- data/lib/tabulatr/tabulatr/json_builder.rb +57 -0
- data/lib/tabulatr/tabulatr/paginator.rb +76 -0
- data/lib/tabulatr/tabulatr/row_builder.rb +128 -0
- data/lib/tabulatr/tabulatr/security.rb +21 -0
- data/lib/tabulatr/tabulatr/settings.rb +158 -0
- data/lib/tabulatr/tabulatr.rb +343 -0
- data/lib/tabulatr/version.rb +3 -0
- data/lib/tabulatr.rb +34 -0
- data/spec/dummy/.gitignore +18 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +16 -0
- data/spec/dummy/app/assets/stylesheets/application.css.scss +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/products_controller.rb +24 -0
- data/spec/dummy/app/controllers/tags_controller.rb +5 -0
- data/spec/dummy/app/controllers/vendors_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +9 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/product.rb +5 -0
- data/spec/dummy/app/models/tag.rb +3 -0
- data/spec/dummy/app/models/vendor.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/products/count_tags.html.erb +9 -0
- data/spec/dummy/app/views/products/one_item_per_page.html.erb +9 -0
- data/spec/dummy/app/views/products/simple_index.html.erb +9 -0
- data/spec/dummy/app/views/products/stupid_array.html.erb +20 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +23 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/tabulatr.rb +5 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/locales/tabulatr.yml +14 -0
- data/spec/dummy/config/routes.rb +13 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/20130730132101_create_vendors.rb +12 -0
- data/spec/dummy/db/migrate/20130730132321_create_products.rb +12 -0
- data/spec/dummy/db/migrate/20130730132348_create_tags.rb +14 -0
- data/spec/dummy/db/schema.rb +47 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/features/tabulatrs_spec.rb +227 -0
- data/spec/lib/tabulatr/tabulatr/finder/find_for_table_spec.rb +187 -0
- data/spec/spec_helper.rb +45 -0
- data/tabulatr.gemspec +29 -0
- metadata +258 -0
@@ -0,0 +1,43 @@
|
|
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
|
+
# This is probably a REALLY bad idea...
|
25
|
+
module MarkAsLocalizable
|
26
|
+
def l
|
27
|
+
@should_localize = true
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def should_localize?
|
32
|
+
@should_localize == true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class String
|
37
|
+
include MarkAsLocalizable
|
38
|
+
end
|
39
|
+
|
40
|
+
class Symbol
|
41
|
+
include MarkAsLocalizable
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class Tabulatr::Adapter::ActiveRecordAdapter < Tabulatr::Adapter
|
2
|
+
|
3
|
+
def initialize(klaz)
|
4
|
+
set_like_statement unless Tabulatr::SQL_OPTIONS[:like]
|
5
|
+
|
6
|
+
super klaz
|
7
|
+
end
|
8
|
+
|
9
|
+
def primary_key
|
10
|
+
@relation.primary_key.to_sym
|
11
|
+
end
|
12
|
+
|
13
|
+
def key_type
|
14
|
+
@relation.columns_hash[primary_key.to_s].type
|
15
|
+
end
|
16
|
+
|
17
|
+
def selected_ids(opts)
|
18
|
+
preconditions_scope(opts).select(:id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def table_name
|
22
|
+
@relation.table_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def table_name_for_association(assoc)
|
26
|
+
@base.reflect_on_association(assoc).table_name
|
27
|
+
end
|
28
|
+
|
29
|
+
def order_for_query(sortparam, default)
|
30
|
+
context = order(sortparam, default)
|
31
|
+
"#{context[:by]} #{context[:direction]}" if context
|
32
|
+
end
|
33
|
+
|
34
|
+
def order_for_query_new(sort_by, orientation)
|
35
|
+
"#{sort_by} #{orientation}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def includes(inc)
|
39
|
+
@relation.includes(inc)
|
40
|
+
end
|
41
|
+
|
42
|
+
def outer_joins(*args)
|
43
|
+
@relation.outer_joins(*args)
|
44
|
+
end
|
45
|
+
|
46
|
+
def select(s)
|
47
|
+
@relation.select(s)
|
48
|
+
end
|
49
|
+
|
50
|
+
def includes!(inc)
|
51
|
+
@relation = includes(includes)
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_conditions_from(n,v)
|
55
|
+
like ||= Tabulatr.sql_options[:like]
|
56
|
+
if v.is_a?(String)
|
57
|
+
@relation = @relation.where("#{n} = ?", v) unless v.blank?
|
58
|
+
elsif v.is_a?(Hash)
|
59
|
+
if v[:like].present?
|
60
|
+
@relation = @relation.where("#{n} #{like} ?", "%#{v[:like]}%")
|
61
|
+
else
|
62
|
+
@relation = @relation.where("#{n} >= ?", "#{v[:from]}") if v[:from].present?
|
63
|
+
@relation = @relation.where("#{n} <= ?", "#{v[:to]}") if v[:to].present?
|
64
|
+
end
|
65
|
+
else
|
66
|
+
raise "Wrong filter type: #{v.class}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def set_like_statement
|
72
|
+
case ActiveRecord::Base.connection.class.to_s
|
73
|
+
when "ActiveRecord::ConnectionAdapters::MysqlAdapter" then Tabulatr.sql_options(:like => 'LIKE')
|
74
|
+
when "ActiveRecord::ConnectionAdapters::Mysql2Adapter" then Tabulatr.sql_options(:like => 'LIKE')
|
75
|
+
when "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter" then Tabulatr.sql_options(:like => 'ILIKE')
|
76
|
+
when "ActiveRecord::ConnectionAdapters::SQLiteAdapter" then Tabulatr.sql_options(:like => 'LIKE')
|
77
|
+
when "ActiveRecord::ConnectionAdapters::SQLite3Adapter" then Tabulatr.sql_options(:like => 'LIKE')
|
78
|
+
else
|
79
|
+
warn("Tabulatr Warning: Don't know which LIKE operator to use for the ConnectionAdapter '#{ActiveRecord::Base.connection.class}'.\n" +
|
80
|
+
"Please specify by `Tabulatr.sql_options(:like => '<likeoperator>')`")
|
81
|
+
Tabulatr.sql_options(:like => 'LIKE')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class Tabulatr::Adapter
|
2
|
+
def initialize(klaz)
|
3
|
+
@base = klaz
|
4
|
+
@relation = klaz
|
5
|
+
end
|
6
|
+
|
7
|
+
delegate :all, :dup, :count, :limit, :to => :@relation
|
8
|
+
|
9
|
+
def to_sql
|
10
|
+
@relation.to_sql if @relation.respond_to? :to_sql
|
11
|
+
end
|
12
|
+
|
13
|
+
def class_to_param
|
14
|
+
@relation.to_s.downcase.gsub("/","_")
|
15
|
+
end
|
16
|
+
|
17
|
+
def preconditions_scope(opts)
|
18
|
+
opts[:precondition].present? ? @base.where(opts[:precondition]) : @base
|
19
|
+
end
|
20
|
+
|
21
|
+
def order(sortparam, default)
|
22
|
+
order_by, order_direction = sort_params(sortparam, default)
|
23
|
+
order_by ? { :by => order_by, :direction => order_direction } : nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def sort_params(sortparam, default)
|
27
|
+
if sortparam
|
28
|
+
if sortparam[:_resort]
|
29
|
+
order_by = sortparam[:_resort].first.first
|
30
|
+
order_direction = sortparam[:_resort].first.last.first.first
|
31
|
+
else
|
32
|
+
order_by = sortparam.first.first
|
33
|
+
order_direction = sortparam.first.last.first.first
|
34
|
+
end
|
35
|
+
raise "SECURITY violation, sort field name is '#{n}'" unless /^[\w]+$/.match order_direction
|
36
|
+
raise "SECURITY violation, sort field name is '#{n}'" unless /^[\d\w]+$/.match order_by
|
37
|
+
else
|
38
|
+
if default
|
39
|
+
l = default.split(" ")
|
40
|
+
raise(":default_order parameter should be of the form 'id asc' or 'name desc'.") if l.length == 0 or l.length > 2
|
41
|
+
|
42
|
+
order_by = l[0]
|
43
|
+
order_direction = l[1] || 'asc'
|
44
|
+
else
|
45
|
+
order_by = order_direction = nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
return order_by, order_direction
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
Dir[File.join(File.dirname(__FILE__), "adapter", "*.rb")].each do |file|
|
54
|
+
require file
|
55
|
+
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
|
+
class Tabulatr
|
25
|
+
|
26
|
+
# render the select tag or the buttons for batch actions
|
27
|
+
def render_batch_actions
|
28
|
+
iname = "#{@classname}#{TABLE_FORM_OPTIONS[:batch_postfix]}"
|
29
|
+
make_tag(:span, :class => 'dropdown') do
|
30
|
+
make_tag(:button,
|
31
|
+
:class => 'disabled btn btn-small tabulatr-wrench',
|
32
|
+
:'data-toggle' => "dropdown") do
|
33
|
+
concat("<i class='icon-wrench'></i>#{I18n.t('tabulatr.batch_actions')}
|
34
|
+
<span class='caret'></span>")
|
35
|
+
end
|
36
|
+
make_tag(:ul, class: 'dropdown-menu', role: 'menu',
|
37
|
+
:'aria-labelledby' => 'dLabel') do
|
38
|
+
@table_options[:batch_actions].each do |n,v|
|
39
|
+
make_tag(:li) do
|
40
|
+
make_tag(:a, :value => v,
|
41
|
+
:name => "#{iname}[#{n}]",
|
42
|
+
:class => "btn batch-action-inputs") do
|
43
|
+
concat(v)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,132 @@
|
|
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
|
+
# the method used to actually define the data cells of the columns,
|
27
|
+
# taking the name of the attribute and a hash of options.
|
28
|
+
#
|
29
|
+
# The following options are evaluated here:
|
30
|
+
# <tt>:td_html</tt>:: a hash with html-attributes added to the <ts>s created
|
31
|
+
# <tt>:method</tt>:: the actual method invoked on the record to retrieve the
|
32
|
+
# value for the column, or false if name is to be used.
|
33
|
+
# <tt>:fromat</tt>:: either a String by which the value is <tt>sprinf</tt>ed,
|
34
|
+
# a proc/lambda to which the value is passed or false if
|
35
|
+
# no specific formatting is desired.
|
36
|
+
def data_column(name, opts={}, &block)
|
37
|
+
raise "Not in data mode!" if @row_mode != :data
|
38
|
+
opts = normalize_column_options(name, opts)
|
39
|
+
make_tag(:td, opts[:td_html]) do
|
40
|
+
href = if opts[:link].class == Symbol || opts[:link].class == String
|
41
|
+
@view.send(opts[:link], @record)
|
42
|
+
elsif opts[:link].respond_to?(:call)
|
43
|
+
opts[:link].call(@record)
|
44
|
+
else
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
make_tag((href ? :a : nil), :href => href) do
|
48
|
+
if block_given?
|
49
|
+
concat(@view.instance_exec(@record, &block))
|
50
|
+
else
|
51
|
+
val = @record.send(opts[:method] || name)
|
52
|
+
format = opts[:format]
|
53
|
+
concat(
|
54
|
+
if format.is_a?(Proc) then @view.instance_exec(val, &format)
|
55
|
+
elsif format.is_a?(String) then h(format % val)
|
56
|
+
elsif format.is_a?(Symbol) then @view.send(format, val)
|
57
|
+
else h(val.to_s)
|
58
|
+
end)
|
59
|
+
end # block_given?
|
60
|
+
end # </a>
|
61
|
+
end # </td>
|
62
|
+
end
|
63
|
+
|
64
|
+
# the method used to actually define the data cells of the columns,
|
65
|
+
# taking the name of the attribute and a hash of options.
|
66
|
+
#
|
67
|
+
# The following options are evaluated here:
|
68
|
+
# <tt>:td_html</tt>:: a hash with html-attributes added to the <ts>s created
|
69
|
+
# <tt>:method</tt>:: the actual method invoked on the record to retrieve the
|
70
|
+
# value for the column, or false if name is to be used.
|
71
|
+
# <tt>:format</tt>:: either a String by which the value is <tt>sprinf</tt>ed,
|
72
|
+
# a proc/lambda to which the value is passed or false if
|
73
|
+
# no specific formatting is desired.
|
74
|
+
def data_association(relation, name, opts={}, &block)
|
75
|
+
raise "Not in data mode!" if @row_mode != :data
|
76
|
+
opts = normalize_column_options(name, opts)
|
77
|
+
if block_given?
|
78
|
+
return @view.instance_exec(@record, &block)
|
79
|
+
end
|
80
|
+
assoc = @record.class.reflect_on_association(relation)
|
81
|
+
make_tag(:td, opts[:td_html]) do
|
82
|
+
format = opts[:format]
|
83
|
+
ass = @record.send(relation.to_sym)
|
84
|
+
if opts[:sort_by]
|
85
|
+
# TODO: SORTING specified by opts[:sort_by]
|
86
|
+
end
|
87
|
+
concat(if (ass.is_a?(Array) || ass.respond_to?(:to_ary)) && (opts[:map] != false)
|
88
|
+
ass.map do |r|
|
89
|
+
val = h(r.send(opts[:method] || name))
|
90
|
+
if format.is_a?(Proc) then format.call(val)
|
91
|
+
elsif format.is_a?(String) then h(format % val)
|
92
|
+
elsif format.is_a?(Symbol) then @view.send(format, val)
|
93
|
+
else h(val.to_s)
|
94
|
+
end
|
95
|
+
end.join(opts[:join_symbol] || ', ')
|
96
|
+
else
|
97
|
+
return '' unless ass
|
98
|
+
#puts ass.to_s
|
99
|
+
val = h(ass.send(opts[:method] || name))
|
100
|
+
val = if format.is_a?(Proc) then @view.instance_exec(val, &format)
|
101
|
+
elsif format.is_a?(String) then h(format % val)
|
102
|
+
elsif format.is_a?(Symbol) then @view.send(format, val)
|
103
|
+
else h(val.to_s)
|
104
|
+
end
|
105
|
+
end)
|
106
|
+
end # </td>
|
107
|
+
end
|
108
|
+
|
109
|
+
def data_checkbox(opts={}, &block)
|
110
|
+
raise "Whatever that's for!" if block_given?
|
111
|
+
iname = "#{@classname}#{@table_form_options[:checked_postfix]}[current_page][]"
|
112
|
+
make_tag(:td, opts[:td_html]) do
|
113
|
+
checked = @checked[:selected].member?(@record.send(@id)) ? :checked : nil
|
114
|
+
make_tag(:input, :type => 'checkbox', :name => iname,
|
115
|
+
:id => "#{@classname}#{@table_form_options[:checked_postfix]}_#{@record.send(@id).to_s}",
|
116
|
+
:value => @record.send(@id), :checked => checked)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def data_action(opts={}, &block)
|
121
|
+
raise "Not in data mode!" if @row_mode != :data
|
122
|
+
opts = normalize_column_options(:action_column, opts)
|
123
|
+
make_tag(:td, opts[:td_html]) do
|
124
|
+
if block_given?
|
125
|
+
concat(yield(@record))
|
126
|
+
else
|
127
|
+
raise "Always give a block ino action columns"
|
128
|
+
end # block_given?
|
129
|
+
end # </td>
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Tabulatr::DummyRecord
|
2
|
+
|
3
|
+
def self.for(klaz)
|
4
|
+
c = Class.new(self)
|
5
|
+
c.instance_variable_set("@model_name", klaz.model_name)
|
6
|
+
c.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
@methods ||= []
|
11
|
+
if @methods.any?
|
12
|
+
m = @methods.join(':')
|
13
|
+
@method_names ||= []
|
14
|
+
@method_names << m
|
15
|
+
@methods.clear
|
16
|
+
"{{#{m}}}"
|
17
|
+
else
|
18
|
+
"{{id}}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing(sym, *args)
|
23
|
+
@methods ||= []
|
24
|
+
@methods << sym.to_s
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_key
|
29
|
+
["{{id}}"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def requested_methods
|
33
|
+
Array(@method_names).try(:uniq)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.model_name
|
37
|
+
@model_name
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,44 @@
|
|
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
|
+
# the method used to actually define the filters of the columns,
|
27
|
+
# taking the name of the attribute and a hash of options.
|
28
|
+
#
|
29
|
+
# The following options are evaluated here:
|
30
|
+
# <tt>:filter_html</tt>:: a hash with html-attributes added to the <ts>s created
|
31
|
+
# <tt>:filter</tt>:: may take different values:
|
32
|
+
# <tt>false</tt>:: no filter is output for this column
|
33
|
+
# a container:: the keys of the hash are used to define a <tt>select</tt>
|
34
|
+
# where the values are the <tt>value</tt> of the <tt>options</tt>.
|
35
|
+
# an Array:: the elements of that array are used to define a
|
36
|
+
# <tt>select</tt>
|
37
|
+
# a String:: a <tt>select</tt> is created with that String as options
|
38
|
+
# you can use ActionView#collection_select and the like
|
39
|
+
def empty_column(name, opts={}, &block)
|
40
|
+
raise "Not in empty mode!" if @row_mode != :empty
|
41
|
+
opts = normalize_column_options(name, opts)
|
42
|
+
make_tag(:td, opts[:filter_html])
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,145 @@
|
|
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
|
+
# the method used to actually define the filters of the columns,
|
27
|
+
# taking the name of the attribute and a hash of options.
|
28
|
+
#
|
29
|
+
# The following options are evaluated here:
|
30
|
+
# <tt>:filter_html</tt>:: a hash with html-attributes added to the <ts>s created
|
31
|
+
# <tt>:filter</tt>:: may take different values:
|
32
|
+
# <tt>false</tt>:: no filter is output for this column
|
33
|
+
# a container:: the keys of the hash are used to define a <tt>select</tt>
|
34
|
+
# where the values are the <tt>value</tt> of the <tt>options</tt>.
|
35
|
+
# an Array:: the elements of that array are used to define a
|
36
|
+
# <tt>select</tt>
|
37
|
+
# a String:: a <tt>select</tt> is created with that String as options
|
38
|
+
# you can use ActionView#collection_select and the like
|
39
|
+
def filter_column(name, opts={}, &block)
|
40
|
+
raise "Not in filter mode!" if @row_mode != :filter
|
41
|
+
opts = normalize_column_options(name, opts)
|
42
|
+
of = opts[:filter]
|
43
|
+
iname = "#{@classname}#{@table_form_options[:filter_postfix]}[#{name}]"
|
44
|
+
filter_name = "tabulatr_form_#{name}"
|
45
|
+
build_filter(of, filter_name, name, iname, opts) if filterable?(of, name.to_s)
|
46
|
+
end
|
47
|
+
|
48
|
+
# the method used to actually define the filters of the columns,
|
49
|
+
# taking the name of the attribute and a hash of options.
|
50
|
+
#
|
51
|
+
# The following options are evaluated here:
|
52
|
+
# <tt>:filter_html</tt>:: a hash with html-attributes added to the <ts>s created
|
53
|
+
# <tt>:filter</tt>:: may take different values:
|
54
|
+
# <tt>false</tt>:: no filter is output for this column
|
55
|
+
# a Hash:: the keys of the hash are used to define a <tt>select</tt>
|
56
|
+
# where the values are the <tt>value</tt> of the <tt>options</tt>.
|
57
|
+
# an Array:: the elements of that array are used to define a
|
58
|
+
# <tt>select</tt>
|
59
|
+
# a subclass of <tt>ActiveRecord::Base</tt>:: a <tt>select</tt> is created
|
60
|
+
# with all instances
|
61
|
+
def filter_association(relation, name, opts={}, &block)
|
62
|
+
raise "Not in filter mode!" if @row_mode != :filter
|
63
|
+
opts = normalize_column_options(name, opts)
|
64
|
+
|
65
|
+
of = opts[:filter]
|
66
|
+
iname = "#{@classname}#{@table_form_options[:filter_postfix]}[#{@table_form_options[:associations_filter]}][#{relation}.#{name}]"
|
67
|
+
filter_name = "tabulatr_form_#{relation}_#{name}"
|
68
|
+
build_filter(of, filter_name, name, iname, opts, relation) if filterable?(of, name.to_s, relation)
|
69
|
+
end
|
70
|
+
|
71
|
+
def filter_checkbox(opts={}, &block)
|
72
|
+
raise "Whatever that's for!" if block_given?
|
73
|
+
make_tag(:td, opts[:filter_html]) {}
|
74
|
+
end
|
75
|
+
|
76
|
+
def filter_action(opts={}, &block)
|
77
|
+
raise "Not in filter mode!" if @row_mode != :filter
|
78
|
+
opts = normalize_column_options(:action_column, opts)
|
79
|
+
make_tag(:td, opts[:filter_html]) do
|
80
|
+
concat(t(opts[:filter])) unless [true, false, nil].member?(opts[:filter])
|
81
|
+
end # </td>
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def filter_tag(of, name, iname, attr_name, opts)
|
87
|
+
if !of
|
88
|
+
""
|
89
|
+
elsif of.is_a?(Hash) or of.is_a?(Array) or of.is_a?(String)
|
90
|
+
make_tag(:select, :style => "width:#{opts[:filter_width]}",
|
91
|
+
:id => name, name: iname) do
|
92
|
+
if of.class.is_a?(String)
|
93
|
+
concat(of)
|
94
|
+
else
|
95
|
+
concat("<option></option>")
|
96
|
+
t = options_for_select(of)
|
97
|
+
concat(t.sub("value=\"\"", "value=\"\" selected=\"selected\""))
|
98
|
+
end
|
99
|
+
end # </select>
|
100
|
+
elsif opts[:filter] == :range
|
101
|
+
filter_text_tag(opts[:filter_width], "#{name}_from", iname, attr_name, 'from')
|
102
|
+
concat(t(opts[:range_filter_symbol]))
|
103
|
+
filter_text_tag(opts[:filter_width], "#{name}_to", iname, attr_name, 'to')
|
104
|
+
elsif opts[:filter] == :checkbox
|
105
|
+
checkbox_value = opts[:checkbox_value]
|
106
|
+
checkbox_label = opts[:checkbox_label]
|
107
|
+
concat(check_box_tag(iname, checkbox_value, false, {}))
|
108
|
+
concat(checkbox_label)
|
109
|
+
elsif opts[:filter] == :exact
|
110
|
+
filter_text_tag(opts[:filter_width], name, iname, attr_name, 'normal')
|
111
|
+
else
|
112
|
+
filter_text_tag(opts[:filter_width], name, iname, attr_name, 'like')
|
113
|
+
end # if
|
114
|
+
end
|
115
|
+
|
116
|
+
def filter_text_tag width, name, iname, attr_name, type=nil
|
117
|
+
name_attribute = iname
|
118
|
+
name_attribute += "[#{type}]" if type && type != 'normal'
|
119
|
+
make_tag(:input, :type => :text, :id => name,
|
120
|
+
:style => "width:#{width}",
|
121
|
+
:value => '',
|
122
|
+
:'data-type' => type,
|
123
|
+
:'data-tabulatr-attribute' => attr_name,
|
124
|
+
:class => 'tabulatr_filter',
|
125
|
+
:name => name_attribute)
|
126
|
+
end
|
127
|
+
|
128
|
+
def build_filter(of, filter_name, name, iname, opts, relation=nil)
|
129
|
+
if of
|
130
|
+
make_tag(:div, class: 'control-group') do
|
131
|
+
make_tag(:label, class: 'control-label', for: filter_name) do
|
132
|
+
concat(t(opts[:header] || readable_name_for(name, relation)), :escape_html)
|
133
|
+
end
|
134
|
+
make_tag(:div, class: 'controls') do
|
135
|
+
filter_tag(of, filter_name, iname, name, opts)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def filterable?(of, name, relation=nil)
|
142
|
+
of && (!(relation && name.to_sym == :count))
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|