tableficate 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/README.markdown +6 -4
  2. data/app/views/tableficate/_data.html.erb +7 -1
  3. data/app/views/tableficate/_header.html.erb +2 -2
  4. data/app/views/tableficate/_table.html.erb +16 -23
  5. data/app/views/tableficate/_table_for.html.erb +9 -0
  6. data/app/views/tableficate/filters/_check_box_choice.html.erb +3 -0
  7. data/app/views/tableficate/filters/_form.html.erb +16 -0
  8. data/app/views/tableficate/filters/_radio_choice.html.erb +3 -0
  9. data/changelog.markdown +17 -0
  10. data/lib/generators/tableficate/theme/theme_generator.rb +17 -1
  11. data/lib/tableficate.rb +3 -0
  12. data/lib/tableficate/action_column.rb +2 -2
  13. data/lib/tableficate/caption.rb +29 -0
  14. data/lib/tableficate/column.rb +13 -7
  15. data/lib/tableficate/empty.rb +34 -0
  16. data/lib/tableficate/filters/base.rb +7 -5
  17. data/lib/tableficate/filters/check_box.rb +1 -1
  18. data/lib/tableficate/filters/choice.rb +2 -2
  19. data/lib/tableficate/filters/collection_base.rb +13 -0
  20. data/lib/tableficate/filters/input.rb +2 -2
  21. data/lib/tableficate/filters/input_range.rb +6 -6
  22. data/lib/tableficate/filters/radio.rb +1 -1
  23. data/lib/tableficate/filters/select.rb +1 -1
  24. data/lib/tableficate/filters/select_range.rb +4 -4
  25. data/lib/tableficate/finder.rb +70 -28
  26. data/lib/tableficate/helper.rb +44 -47
  27. data/lib/tableficate/table.rb +64 -24
  28. data/lib/tableficate/utils.rb +27 -2
  29. data/lib/tableficate/version.rb +1 -1
  30. data/spec/action_column_spec.rb +9 -1
  31. data/spec/base_spec.rb +10 -0
  32. data/spec/caption_spec.rb +33 -0
  33. data/spec/column_spec.rb +29 -0
  34. data/spec/empty_spec.rb +45 -0
  35. data/spec/filters/base_spec.rb +6 -5
  36. data/spec/filters/choice_spec.rb +5 -2
  37. data/spec/filters/collection_spec.rb +4 -4
  38. data/spec/filters/input_range_spec.rb +10 -8
  39. data/spec/filters/select_range_spec.rb +79 -0
  40. data/spec/finder_spec.rb +48 -1
  41. data/spec/generators/tableficate_theme_spec.rb +14 -0
  42. data/spec/table_spec.rb +114 -3
  43. data/spec/test_app/app/controllers/filters_controller.rb +1 -1
  44. data/spec/test_app/app/controllers/tests_controller.rb +5 -0
  45. data/spec/test_app/app/controllers/themes_controller.rb +7 -0
  46. data/spec/test_app/app/views/filters/html5_input_types.html.erb +31 -0
  47. data/spec/test_app/app/views/tableficate/custom_check_box_block/filters/_check_box_choice.html.erb +2 -0
  48. data/spec/test_app/app/views/tableficate/custom_radio_block/filters/_radio_choice.html.erb +2 -0
  49. data/spec/test_app/app/views/tests/index.html.erb +13 -0
  50. data/spec/test_app/app/views/themes/caption.html.erb +9 -0
  51. data/spec/test_app/app/views/themes/column_attrs.html.erb +7 -0
  52. data/spec/test_app/app/views/themes/column_cell_attrs.html.erb +7 -0
  53. data/spec/test_app/app/views/themes/column_cell_attrs_with_proc.html.erb +7 -0
  54. data/spec/test_app/app/views/themes/column_header_attrs.html.erb +7 -0
  55. data/spec/test_app/app/views/themes/empty_with_data.html.erb +9 -0
  56. data/spec/test_app/app/views/themes/empty_with_no_data.html.erb +9 -0
  57. data/spec/test_app/app/views/themes/no_caption.html.erb +7 -0
  58. data/spec/test_app/app/views/themes/no_column_attrs.html.erb +7 -0
  59. data/spec/test_app/config/application.rb +1 -1
  60. data/spec/test_app/config/routes.rb +2 -0
  61. data/spec/test_app/db/migrate/20111227224959_additional_columns.rb +73 -0
  62. data/spec/test_app/db/migrate/20111230203456_created_at_specific_dates.rb +11 -0
  63. data/spec/test_app/db/schema.rb +10 -3
  64. data/spec/test_app/db/test.sqlite3 +0 -0
  65. data/spec/theme/caption_spec.rb +15 -0
  66. data/spec/theme/column_spec.rb +35 -0
  67. data/spec/theme/empty_spec.rb +15 -0
  68. data/spec/utils_spec.rb +44 -4
  69. metadata +69 -58
  70. data/spec/test_app/app/views/tableficate/custom_check_box_block/_data.html.erb +0 -1
  71. data/spec/test_app/app/views/tableficate/custom_check_box_block/_header.html.erb +0 -8
  72. data/spec/test_app/app/views/tableficate/custom_check_box_block/_row.html.erb +0 -5
  73. data/spec/test_app/app/views/tableficate/custom_check_box_block/_table.html.erb +0 -36
  74. data/spec/test_app/app/views/tableficate/custom_check_box_block/filters/_check_box.html.erb +0 -7
  75. data/spec/test_app/app/views/tableficate/custom_check_box_block/filters/_input.html.erb +0 -4
  76. data/spec/test_app/app/views/tableficate/custom_check_box_block/filters/_input_range.html.erb +0 -6
  77. data/spec/test_app/app/views/tableficate/custom_check_box_block/filters/_radio.html.erb +0 -4
  78. data/spec/test_app/app/views/tableficate/custom_check_box_block/filters/_select.html.erb +0 -4
  79. data/spec/test_app/app/views/tableficate/custom_check_box_block/filters/_select_range_filter.html.erb +0 -6
  80. data/spec/test_app/app/views/tableficate/custom_radio_block/_data.html.erb +0 -1
  81. data/spec/test_app/app/views/tableficate/custom_radio_block/_header.html.erb +0 -8
  82. data/spec/test_app/app/views/tableficate/custom_radio_block/_row.html.erb +0 -5
  83. data/spec/test_app/app/views/tableficate/custom_radio_block/_table.html.erb +0 -36
  84. data/spec/test_app/app/views/tableficate/custom_radio_block/filters/_check_box.html.erb +0 -4
  85. data/spec/test_app/app/views/tableficate/custom_radio_block/filters/_input.html.erb +0 -4
  86. data/spec/test_app/app/views/tableficate/custom_radio_block/filters/_input_range.html.erb +0 -6
  87. data/spec/test_app/app/views/tableficate/custom_radio_block/filters/_radio.html.erb +0 -7
  88. data/spec/test_app/app/views/tableficate/custom_radio_block/filters/_select.html.erb +0 -4
  89. data/spec/test_app/app/views/tableficate/custom_radio_block/filters/_select_range_filter.html.erb +0 -6
  90. data/spec/test_app/public/index.html +0 -241
@@ -9,7 +9,7 @@ This project follows [Semantic Versioning](http://semver.org/).
9
9
 
10
10
  If you're using Bundler, add this to your Gemfile:
11
11
 
12
- gem 'tableficate', '~>0.2.0'
12
+ gem 'tableficate', '~>0.3.0'
13
13
 
14
14
  ## Support
15
15
 
@@ -119,7 +119,9 @@ The theme can then be applied to a table.
119
119
  ...
120
120
  <% end %>
121
121
 
122
- ## Changes Needed to Upgrade From 0.1
122
+ ## Changes Needed to Upgrade From 0.2
123
123
 
124
- 1. The filter functions used in the `table_for` call have been completely changed. They will need to be rewritten in all of your calls.
125
- 2. New filter partials have been added to accomodate the new filter types that are available. If you have custom themes they will need to be updated. This can be done by first moving "_column_header.html.erb" to "_header.html.erb", "filters/_input_field.html.erb" to "filters/_input.html.erb" and "filters/_input_field_range.html.erb" to "filters/_input_range.html.erb". Then rerun `rails generate tableficate:theme NAME`. This will not overwrite files you have altered for your new theme.
124
+ 1. HTML attributes passed to `table_for` will no longer be passed via the `:html` option. Now all unrecognized options are passed as HTML attributes. This is more consistent with the other functions.
125
+ 2. In custom templates the `options` attribute is no longer available on all objects that had it. Any options specific to the object have been turned into attributes. For example, `label_options` is now an attribute on filters and `collection` is now an attribute on select, radio and check box filters. All other options will be used as HTML attributes and can be found in the new `attrs` attribute.
126
+ 3. The `_table.html.erb` theme partial has been renamed to `_table_for.html.erb`. The `_table.html.erb` file has been repurposed for the new `tableficate_table_tag` helper. Another helper, `tableficate_filter_form_tag`, has replaced the filter form in `_table_for.html.erb`. A new partial, `filters/_form.html.erb` was created for this new helper. The `_header.html.erb` and `_data.html.erb` partials have been updated so that `th` and `td` tags can accept attributes. Running `rails generate tableficate:theme NAME` for an existing theme will provide an interactive means of updating your existing theme. Additionally, if a partial is missing it will now be retrieved from the standard theme. This means you can optionally delete any partials that you have not altered. This should make future upgrades easier.
127
+ 4. When creating custom themes the `tableficate_radio_tags` and `tableficate_check_box_tags` no longer accept blocks to format the output. Instead, they now use templates called "filters/_radio_choice.html.erb" and "filters/_check_box_choice.html.erb" respectively. All you have to do is move the block code into the new templates.
@@ -1 +1,7 @@
1
- <td><%= column.value(row) %></td>
1
+ <% attrs = column.cell_attrs.dup %>
2
+ <% attrs.each do |key, value| %>
3
+ <% attrs[key] = value.call(row) if attrs[key].is_a?(Proc) %>
4
+ <% end %>
5
+ <%= content_tag(:td, attrs) do %>
6
+ <%= column.value(row) %>
7
+ <% end %>
@@ -1,8 +1,8 @@
1
- <th>
1
+ <%= content_tag(:th, column.header_attrs) do %>
2
2
  <%= column.header %>
3
3
  <% table_params = (params[column.table.as] || {}) %>
4
4
  <% if column.show_sort? %>
5
5
  <%= link_to 'A', url_for(params.merge(column.table.as => table_params.merge({sort: column.name.to_s, dir: 'asc'}))) %><% if column.is_sorted?('asc') %>*<% end %>
6
6
  <%= link_to 'D', url_for(params.merge(column.table.as => table_params.merge({sort: column.name.to_s, dir: 'desc'}))) %><% if column.is_sorted?('desc') %>*<% end %>
7
7
  <% end %>
8
- </th>
8
+ <% end %>
@@ -1,26 +1,15 @@
1
- <% if table.filters.any? %>
2
- <%= form_tag('', method: :get, novalidate: 'novalidate') do %>
3
- <% if params[table.as] and params[table.as][:sort] %>
4
- <%= hidden_field_tag("#{table.as}[sort]", params[table.as][:sort]) %>
5
- <% end %>
6
- <% if params[table.as] and params[table.as][:dir] %>
7
- <%= hidden_field_tag("#{table.as}[dir]", params[table.as][:dir]) %>
8
- <% end %>
9
- <% table.filters.each do |filter| %>
10
- <%= tableficate_filter_tag(filter) %>
1
+ <%= content_tag(:table, table.attrs) do %>
2
+ <% if table.caption %>
3
+ <%= content_tag(:caption, table.caption.value, table.caption.attrs) %>
4
+ <% end %>
5
+ <% if table.columns.any?{|column| column.attrs.present?} %>
6
+ <% table.columns.chunk{|column| column.attrs}.each do |column_group| %>
7
+ <% span = column_group.last.length %>
8
+ <% attrs = column_group.first %>
9
+ <% attrs.merge!(span: span) if span > 1 %>
10
+ <%= tag(:col, attrs) %>
11
11
  <% end %>
12
-
13
- <%= submit_tag('Filter') %>
14
12
  <% end %>
15
- <% end %>
16
-
17
- <% if defined? ::Kaminari %>
18
- <%= paginate(table.rows, param_name: "#{table.as}_page") %>
19
- <% elsif defined? ::WillPaginate %>
20
- <%= will_paginate(table.rows, param_name: "#{table.as}_page") %>
21
- <% end %>
22
-
23
- <%= content_tag(:table, table.options[:html]) do %>
24
13
  <thead>
25
14
  <tr>
26
15
  <% table.columns.each do |column| %>
@@ -29,8 +18,12 @@
29
18
  </tr>
30
19
  </thead>
31
20
  <tbody>
32
- <% table.rows.each do |row| %>
33
- <%= tableficate_row_tag(row, table.columns) %>
21
+ <% if table.rows.size > 0 %>
22
+ <% table.rows.each do |row| %>
23
+ <%= tableficate_row_tag(row, table.columns) %>
24
+ <% end %>
25
+ <% elsif table.empty and table.empty.value.present? %>
26
+ <tr><%= content_tag(:td, table.empty.value, table.empty.attrs) %></tr>
34
27
  <% end %>
35
28
  </tbody>
36
29
  <% end %>
@@ -0,0 +1,9 @@
1
+ <%= tableficate_filter_form_tag(table) %>
2
+
3
+ <% if defined? ::Kaminari %>
4
+ <%= paginate(table.rows, param_name: "#{table.as}_page") %>
5
+ <% elsif defined? ::WillPaginate %>
6
+ <%= will_paginate(table.rows, param_name: "#{table.as}_page") %>
7
+ <% end %>
8
+
9
+ <%= tableficate_table_tag(table) %>
@@ -0,0 +1,3 @@
1
+ <%= check_box_tag("#{filter.field_name}[#{choice.value}]", choice.value, choice.checked?, choice.attrs.reverse_merge(name: "#{filter.field_name}[]")) %>
2
+ <%= label_tag("#{filter.field_name}[#{choice.value}]", choice.name) %>
3
+ <br/>
@@ -0,0 +1,16 @@
1
+ <% if table.filters.any? %>
2
+ <%= form_tag('', method: :get, novalidate: 'novalidate') do %>
3
+ <% if params[table.as] and params[table.as][:sort] %>
4
+ <%= hidden_field_tag("#{table.as}[sort]", params[table.as][:sort]) %>
5
+ <% end %>
6
+ <% if params[table.as] and params[table.as][:dir] %>
7
+ <%= hidden_field_tag("#{table.as}[dir]", params[table.as][:dir]) %>
8
+ <% end %>
9
+
10
+ <% table.filters.each do |filter| %>
11
+ <%= tableficate_filter_tag(filter) %>
12
+ <% end %>
13
+
14
+ <%= submit_tag('Filter') %>
15
+ <% end %>
16
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%= radio_button_tag(filter.field_name, choice.value, choice.checked?, choice.attrs) %>
2
+ <%= label_tag("#{filter.field_name}[#{choice.value}]", choice.name) %>
3
+ <br/>
@@ -1,3 +1,20 @@
1
+ ## 0.3.0
2
+ * tables no longer take the :html option, all non-recognized options are passed through as HTML attributes
3
+ * The `options` attribute on a variety of objects has been removed. It has been replaced with specialized functions such as `label_options` and `collection` with all unrecognized options placed into the `attrs` attribute.
4
+ * adding `tableficate_table_tag` helper
5
+ * adding `tableficate_filter_form_tag` helper
6
+ * adding support for captions
7
+ * missing theme partials will default to the standard partial
8
+ * tableficate:theme generator now takes an optional `PARTIAL` arg to specify one file
9
+ * `actions` now takes options just like `column`
10
+ * `column` now takes a `header_attrs` option to provide attributes for the `th`
11
+ * `column` now takes a `cell_attrs` option to provide attributes for every `td` in the column, a proc can be passed in place of a string for attributes to customize on a per cell basis
12
+ * `column` now places all unrecognized options into the `attrs` attribute which is used on a `col` tag
13
+ * adding `empty` to display a message when a table has no data
14
+ * input types are automatically figured out by label name and DB column type
15
+ * `tableficate_radio_tags` and `tableficate_check_box_tags` use partials now rather than block formatting
16
+ * dates and date ranges used against datetime and timestamp columns will automatically work as expected (i.e. 01/01/2011 will get everything between 00:00:00 and 23:59:59 for that day)
17
+
1
18
  ## 0.2.1
2
19
  * fix table generator to provide `scope` the proper argument and correct documentation
3
20
 
@@ -6,10 +6,26 @@ module Tableficate
6
6
 
7
7
  source_root File.expand_path("../../../../../#{VIEW_PATH}", __FILE__)
8
8
 
9
+ argument :partial, required: false
10
+
9
11
  def create_theme
10
12
  empty_directory(VIEW_PATH)
11
13
 
12
- directory('', "#{VIEW_PATH}/#{file_name}")
14
+ if partial
15
+ if partial =~ /\//
16
+ partial =~ /^(.*)\/(.*)$/
17
+ extra_dirs = $1
18
+ partial_name = $2
19
+
20
+ empty_directory("#{VIEW_PATH}/#{file_name}/#{extra_dirs}")
21
+
22
+ copy_file("#{extra_dirs}/_#{partial_name}.html.erb", "#{VIEW_PATH}/#{file_name}/#{extra_dirs}/_#{partial_name}.html.erb")
23
+ else
24
+ copy_file("_#{partial}.html.erb", "#{VIEW_PATH}/#{file_name}/_#{partial}.html.erb")
25
+ end
26
+ else
27
+ directory('', "#{VIEW_PATH}/#{file_name}")
28
+ end
13
29
  end
14
30
  end
15
31
  end
@@ -4,9 +4,12 @@ require 'tableficate/utils'
4
4
  require 'tableficate/finder'
5
5
  require 'tableficate/column'
6
6
  require 'tableficate/action_column'
7
+ require 'tableficate/caption'
8
+ require 'tableficate/empty'
7
9
  require 'tableficate/filters/collection'
8
10
  require 'tableficate/filters/choice'
9
11
  require 'tableficate/filters/base'
12
+ require 'tableficate/filters/collection_base'
10
13
  require 'tableficate/filters/input'
11
14
  require 'tableficate/filters/input_range'
12
15
  require 'tableficate/filters/select'
@@ -1,7 +1,7 @@
1
1
  module Tableficate
2
2
  class ActionColumn < Column
3
- def initialize(table, &block)
4
- super(table, '', {}, &block)
3
+ def initialize(table, options = {}, &block)
4
+ super(table, '', options, &block)
5
5
  end
6
6
 
7
7
  def show_sort?
@@ -0,0 +1,29 @@
1
+ module Tableficate
2
+ class Caption
3
+ attr_reader :attrs
4
+
5
+ def initialize(*args, &block)
6
+ if block_given?
7
+ @attrs = args.first || {}
8
+ @content = block
9
+ else
10
+ @content = args[0]
11
+ @attrs = args[1] || {}
12
+ end
13
+ end
14
+
15
+ def value
16
+ if @content.is_a?(String)
17
+ @content
18
+ else
19
+ output = @content.call
20
+ if output.is_a?(ActionView::OutputBuffer)
21
+ ''
22
+ else
23
+ output = output.html_safe if output.respond_to? :html_safe
24
+ output
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,14 +1,20 @@
1
1
  module Tableficate
2
2
  class Column
3
- attr_reader :name, :header, :table
3
+ attr_reader :name, :header, :table, :header_attrs, :cell_attrs, :attrs
4
4
 
5
5
  def initialize(table, name, options = {}, &block)
6
- @table = table
7
- @name = name
8
- @options = options
9
- @block = block
6
+ @table = table
7
+ @name = name
8
+ @block = block
10
9
 
11
- @header = @options.delete(:header) || name.to_s.titleize
10
+ @header = options.delete(:header) || name.to_s.titleize
11
+ @header_attrs = options.delete(:header_attrs) || {}
12
+
13
+ @cell_attrs = options.delete(:cell_attrs) || {}
14
+
15
+ @show_sort = options.delete(:show_sort) || false
16
+
17
+ @attrs = options
12
18
  end
13
19
 
14
20
  def value(row)
@@ -26,7 +32,7 @@ module Tableficate
26
32
  end
27
33
 
28
34
  def show_sort?
29
- !!@options[:show_sort]
35
+ @show_sort
30
36
  end
31
37
 
32
38
  def is_sorted?(dir = nil)
@@ -0,0 +1,34 @@
1
+ module Tableficate
2
+ class Empty
3
+ def initialize(table, *args, &block)
4
+ @table = table
5
+
6
+ if block_given?
7
+ @attrs = args.first || {}
8
+ @content = block
9
+ else
10
+ @content = args[0]
11
+ @attrs = args[1] || {}
12
+ end
13
+ end
14
+
15
+ def value
16
+ if @content.is_a?(String)
17
+ @content
18
+ else
19
+ output = @content.call
20
+ if output.is_a?(ActionView::OutputBuffer)
21
+ ''
22
+ else
23
+ output = output.html_safe if output.respond_to? :html_safe
24
+ output
25
+ end
26
+ end
27
+ end
28
+
29
+ def attrs
30
+ @attrs[:colspan] = @table.columns.length
31
+ @attrs
32
+ end
33
+ end
34
+ end
@@ -1,15 +1,17 @@
1
1
  module Tableficate
2
2
  module Filter
3
3
  class Base
4
- attr_reader :name, :label, :options, :template, :table, :field_name
4
+ attr_reader :name, :label, :attrs, :template, :table, :field_name, :label_options
5
5
 
6
6
  def initialize(table, name, options = {})
7
- @table = table
8
- @name = name
9
- @options = options
7
+ @table = table
8
+ @name = name
9
+
10
+ @label = options.delete(:label) || table.columns.detect{|column| column.name == @name}.try(:header) || name.to_s.titleize
11
+ @label_options = options.delete(:label_options) || {}
12
+ @attrs = options
10
13
 
11
14
  @template = 'filters/' + self.class.name.demodulize.underscore
12
- @label = @options.delete(:label) || table.columns.detect{|column| column.name == @name}.try(:header) || name.to_s.titleize
13
15
  @field_name = "#{table.as}[filter][#{@name}]"
14
16
  end
15
17
 
@@ -1,6 +1,6 @@
1
1
  module Tableficate
2
2
  module Filter
3
- class CheckBox < Base
3
+ class CheckBox < CollectionBase
4
4
  end
5
5
  end
6
6
  end
@@ -1,7 +1,7 @@
1
1
  module Tableficate
2
2
  module Filter
3
3
  class Choice
4
- attr_reader :name, :value, :options
4
+ attr_reader :name, :value, :attrs
5
5
 
6
6
  def initialize(name, value, options = {})
7
7
  @name = name
@@ -11,7 +11,7 @@ module Tableficate
11
11
  options.delete(:selected)
12
12
  options.delete(:checked)
13
13
 
14
- @options = options
14
+ @attrs = options
15
15
  end
16
16
 
17
17
  def selected?
@@ -0,0 +1,13 @@
1
+ module Tableficate
2
+ module Filter
3
+ class CollectionBase < Base
4
+ attr_reader :collection
5
+
6
+ def initialize(table, name, options = {})
7
+ @collection = options.delete(:collection) || []
8
+
9
+ super(table, name, options)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -4,8 +4,8 @@ module Tableficate
4
4
  def initialize(table, name, options = {})
5
5
  super(table, name, options)
6
6
 
7
- new_template = "filters/input_#{options[:type]}"
8
- @template = new_template if table.template.lookup_context.exists?(Tableficate::Utils::template_path(new_template, table.options[:theme]), [], true)
7
+ new_partial = "filters/input_#{@attrs[:type]}"
8
+ @template = new_partial if table.template.lookup_context.exists?(Tableficate::Utils::template_path(table.template, new_partial, table.theme), [], true)
9
9
  end
10
10
  end
11
11
  end
@@ -41,16 +41,16 @@ module Tableficate
41
41
 
42
42
  super(table, name, options)
43
43
 
44
- start_options.reverse_merge!(@options)
45
- start_options.reverse_merge!(label: self.label)
46
- stop_options.reverse_merge!(@options)
47
- stop_options.reverse_merge!(label: self.label)
44
+ start_options.reverse_merge!(@attrs)
45
+ start_options.reverse_merge!(label: self.label, label_options: self.label_options)
46
+ stop_options.reverse_merge!(@attrs)
47
+ stop_options.reverse_merge!(label: self.label, label_options: self.label_options)
48
48
 
49
49
  @start = InputStart.new(table, name, start_options)
50
50
  @stop = InputStop.new(table, name, stop_options)
51
51
 
52
- new_template = "filters/input_range_#{options[:type]}"
53
- @template = new_template if table.template.lookup_context.exists?(Tableficate::Utils::template_path(new_template, table.options[:theme]), [], true)
52
+ new_partial = "filters/input_range_#{@attrs[:type]}"
53
+ @template = new_partial if table.template.lookup_context.exists?(Tableficate::Utils::template_path(table.template, new_partial, table.theme), [], true)
54
54
  end
55
55
  end
56
56
  end
@@ -1,6 +1,6 @@
1
1
  module Tableficate
2
2
  module Filter
3
- class Radio < Base
3
+ class Radio < CollectionBase
4
4
  end
5
5
  end
6
6
  end
@@ -1,6 +1,6 @@
1
1
  module Tableficate
2
2
  module Filter
3
- class Select < Base
3
+ class Select < CollectionBase
4
4
  end
5
5
  end
6
6
  end
@@ -41,10 +41,10 @@ module Tableficate
41
41
 
42
42
  super(table, name, options)
43
43
 
44
- start_options.reverse_merge!(@options)
45
- start_options.reverse_merge!(label: self.label)
46
- stop_options.reverse_merge!(@options)
47
- stop_options.reverse_merge!(label: self.label)
44
+ start_options.reverse_merge!(@attrs)
45
+ start_options.reverse_merge!(label: self.label, label_options: self.label_options)
46
+ stop_options.reverse_merge!(@attrs)
47
+ stop_options.reverse_merge!(label: self.label, label_options: self.label_options)
48
48
 
49
49
  @start = SelectStart.new(table, name, start_options)
50
50
  @stop = SelectStop.new(table, name, stop_options)
@@ -5,42 +5,74 @@ module Tableficate
5
5
  raise Tableficate::MissingScope unless scope.new.kind_of?(ActiveRecord::Base)
6
6
 
7
7
  # filtering
8
- if params
9
- if params[:filter]
10
- params[:filter].each do |name, value|
11
- next if value.blank? or (value.is_a?(Hash) and value.all?{|key, value| value.blank?})
8
+ if params and params[:filter]
9
+ params[:filter].each do |name, value|
10
+ next if value.blank? or (value.is_a?(Hash) and value.all?{|key, value| value.blank?})
12
11
 
13
- name = name.to_sym
14
- value.strip! if value.is_a?(String)
12
+ # cleanup filter params
13
+ name = name.to_sym
14
+ if value.is_a?(Array)
15
+ value.map!{|v| prepare_value(v)}
16
+ elsif value.is_a?(Hash)
17
+ value.each do |k, v|
18
+ value[k] = prepare_value(v)
19
+ end
20
+ else
21
+ value = prepare_value(value)
22
+ end
15
23
 
16
- if @filter and @filter[name]
17
- if @filter[name].is_a?(Proc)
18
- scope = @filter[name].call(value, scope)
19
- elsif value.is_a?(String)
20
- value = "%#{value}%" if @filter[name][:match] == 'contains'
24
+ # convert dates, datetimes, and timestamps to Ruby objects and account for date filtering on datetime type columns
25
+ case Tableficate::Utils::find_column_type(scope, name)
26
+ when :date
27
+ value = value.to_date
28
+ when :datetime, :timestamp
29
+ if value.is_a?(Hash)
30
+ # if it looks like it's only dates
31
+ if value[:start].gsub(/\D/, '').length <= 8 and value[:stop].gsub(/\D/, '').length <= 8
32
+ value = {start: Time.zone.parse(value[:start]), stop: Time.zone.parse(value[:stop]).advance(hours: 23, minutes: 59, seconds: 59)}
33
+ else
34
+ value[:start] = Time.zone.parse(value[:start])
35
+ value[:stop] = Time.zone.parse(value[:stop])
36
+ end
37
+ elsif value.is_a?(String)
38
+ # if it looks like it's only a date
39
+ if value.gsub(/\D/, '').length <= 8
40
+ value = Time.zone.parse(value)
41
+ value = {start: value, stop: value.advance(hours: 23, minutes: 59, seconds: 59)}
42
+ else
43
+ value = Time.zone.parse(value)
44
+ end
45
+ end
46
+ end
21
47
 
22
- scope = scope.where(["#{get_full_column_name(@filter[name][:field])} LIKE ?", value])
23
- elsif value.is_a?(Array)
24
- full_column_name = get_full_column_name(@filter[name][:field])
48
+ # attach the filter
49
+ if @filter and @filter[name]
50
+ if @filter[name].is_a?(Proc)
51
+ scope = @filter[name].call(value, scope)
52
+ elsif value.is_a?(Array)
53
+ full_column_name = get_full_column_name(@filter[name][:field])
25
54
 
26
- if @filter[name][:match] == 'contains'
27
- scope = scope.where([
28
- Array.new(value.size, "#{full_column_name} LIKE ?").join(' OR '),
29
- *value.map{|v| "%#{v}%"}
30
- ])
31
- else
32
- scope = scope.where(["#{full_column_name} IN(?)", value])
33
- end
34
- elsif value.is_a?(Hash)
35
- scope = scope.where(["#{get_full_column_name(@filter[name][:field])} BETWEEN :start AND :stop", value])
55
+ if @filter[name][:match] == 'contains'
56
+ scope = scope.where([
57
+ Array.new(value.size, "#{full_column_name} LIKE ?").join(' OR '),
58
+ *value.map{|v| "%#{v}%"}
59
+ ])
60
+ else
61
+ scope = scope.where(["#{full_column_name} IN(?)", value])
36
62
  end
37
- elsif value.is_a?(Array)
38
- scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} IN(?)", value])
39
63
  elsif value.is_a?(Hash)
40
- scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} BETWEEN :start AND :stop", value])
64
+ scope = scope.where(["#{get_full_column_name(@filter[name][:field])} BETWEEN :start AND :stop", value])
41
65
  else
42
- scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} LIKE ?", value])
66
+ value = "%#{value}%" if @filter[name][:match] == 'contains'
67
+
68
+ scope = scope.where(["#{get_full_column_name(@filter[name][:field])} LIKE ?", value])
43
69
  end
70
+ elsif value.is_a?(Array)
71
+ scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} IN(?)", value])
72
+ elsif value.is_a?(Hash)
73
+ scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} BETWEEN :start AND :stop", value])
74
+ else
75
+ scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} LIKE ?", value])
44
76
  end
45
77
  end
46
78
  end
@@ -61,6 +93,8 @@ module Tableficate
61
93
  sorting[:dir] = ['asc', 'desc'].include?(dir) ? dir : 'asc'
62
94
  end
63
95
  scope.tableficate_add_data(:current_sort, sorting)
96
+ filters_with_field = @filter ? @filter.select{|name, options| not options.is_a?(Proc) and options and options.has_key?(:field)} : {}
97
+ scope.tableficate_add_data(:field_map, Hash[filters_with_field.map{|name, options| [name, options[:field]]}])
64
98
  scope
65
99
  end
66
100
 
@@ -75,5 +109,13 @@ module Tableficate
75
109
  end
76
110
  end
77
111
  private :get_full_column_name
112
+
113
+ def prepare_value(value)
114
+ value.strip! if value.respond_to?(:strip!)
115
+ value = true if value == 'true'
116
+ value = false if value == 'false'
117
+ value
118
+ end
119
+ private :prepare_value
78
120
  end
79
121
  end