datagrid 0.9.3 → 1.0.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.
Files changed (39) hide show
  1. data/Readme.markdown +6 -4
  2. data/VERSION +1 -1
  3. data/app/assets/stylesheets/datagrid.css.sass +132 -0
  4. data/app/views/datagrid/_form.html.erb +5 -2
  5. data/app/views/datagrid/_order_for.html.erb +2 -2
  6. data/app/views/datagrid/_table.html.erb +1 -1
  7. data/datagrid.gemspec +10 -3
  8. data/lib/datagrid.rb +1 -0
  9. data/lib/datagrid/column_names_attribute.rb +38 -7
  10. data/lib/datagrid/columns.rb +38 -4
  11. data/lib/datagrid/columns/column.rb +29 -1
  12. data/lib/datagrid/drivers/abstract_driver.rb +8 -0
  13. data/lib/datagrid/drivers/active_record.rb +29 -1
  14. data/lib/datagrid/drivers/array.rb +14 -2
  15. data/lib/datagrid/drivers/mongo_mapper.rb +8 -0
  16. data/lib/datagrid/drivers/mongoid.rb +9 -1
  17. data/lib/datagrid/filters.rb +24 -6
  18. data/lib/datagrid/filters/base_filter.rb +42 -14
  19. data/lib/datagrid/filters/boolean_enum_filter.rb +1 -1
  20. data/lib/datagrid/filters/dynamic_filter.rb +57 -0
  21. data/lib/datagrid/filters/enum_filter.rb +4 -21
  22. data/lib/datagrid/filters/select_options.rb +26 -0
  23. data/lib/datagrid/form_builder.rb +41 -8
  24. data/lib/datagrid/helper.rb +2 -1
  25. data/lib/datagrid/i18n.rb +0 -0
  26. data/lib/datagrid/locale/en.yml +28 -0
  27. data/lib/datagrid/ordering.rb +33 -19
  28. data/lib/datagrid/utils.rb +8 -9
  29. data/spec/datagrid/column_names_attribute_spec.rb +44 -1
  30. data/spec/datagrid/columns_spec.rb +16 -0
  31. data/spec/datagrid/filters/dynamic_filter_spec.rb +37 -0
  32. data/spec/datagrid/filters/integer_filter_spec.rb +18 -0
  33. data/spec/datagrid/filters/string_filter_spec.rb +25 -0
  34. data/spec/datagrid/filters_spec.rb +15 -1
  35. data/spec/datagrid/form_builder_spec.rb +83 -0
  36. data/spec/datagrid/helper_spec.rb +1 -0
  37. data/spec/datagrid/ordering_spec.rb +41 -1
  38. data/spec/datagrid/utils_spec.rb +7 -2
  39. metadata +11 -4
@@ -93,12 +93,12 @@ In order to create a report, you need to define:
93
93
  ### Scope
94
94
 
95
95
  Default scope of objects to filter and display.
96
- In common case it is `ActiveRecord::Base` (or any other supported ORM) subclass with some generic scopes like in example above:
96
+ In common case it is `ActiveRecord::Base` (or any other supported ORM) subclass with some generic scopes like:
97
97
 
98
98
  ``` ruby
99
- scope do
100
- User.includes(:group)
101
- end
99
+ scope do
100
+ User.includes(:group)
101
+ end
102
102
  ```
103
103
 
104
104
  [More about scope](https://github.com/bogdan/datagrid/wiki/Scope)
@@ -116,11 +116,13 @@ Datagrid supports different type of filters including:
116
116
 
117
117
  * text
118
118
  * integer
119
+ * float
119
120
  * date
120
121
  * boolean
121
122
  * eboolean - the select of "yes", "no" and any
122
123
  * enum
123
124
  * string
125
+ * dynamic
124
126
 
125
127
  [More about filters](https://github.com/bogdan/datagrid/wiki/Filters)
126
128
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.3
1
+ 1.0.0
@@ -0,0 +1,132 @@
1
+ $dg-form-label: 150px
2
+
3
+ = clearfix
4
+ *zoom: 1
5
+
6
+ &:before,
7
+ &:after
8
+ display: table
9
+ content: ''
10
+
11
+ &:after
12
+ clear: both
13
+
14
+ =inline-block
15
+ display: inline-block
16
+ zoom: 1
17
+ *display: inline
18
+
19
+ table.datagrid
20
+ background-color: transparent
21
+ border-collapse: collapse
22
+ max-width: 100%
23
+
24
+ th
25
+ background-color: #eee
26
+ text-align: left
27
+
28
+ td,
29
+ th
30
+ border: 1px solid #d6d6d6
31
+ padding: 5px 10px
32
+
33
+ .order
34
+ a.asc, a.desc
35
+ text-decoration: none
36
+ font-weight: normal
37
+
38
+ &.ordered
39
+ background-color: #fff7d5
40
+
41
+ &.asc
42
+ a.asc
43
+ font-weight: bold
44
+ color: #d00
45
+
46
+ &.desc
47
+ a.desc
48
+ font-weight: bold
49
+ color: #d00
50
+ .noresults
51
+ text-align: center
52
+
53
+ .datagrid-form
54
+ background-color: #f0f0f0
55
+ border-radius: 5px
56
+ padding: 20px
57
+
58
+ .datagrid-filter
59
+ margin: 10px
60
+ +clearfix
61
+
62
+ label
63
+ width: $dg-form-label
64
+ float: left
65
+ a
66
+ float: left
67
+
68
+ &.dp-choose-date
69
+ margin-left: -22px
70
+ margin-top: 7px
71
+
72
+ input[class*='filter']
73
+ border: 2px solid #ccc
74
+ border-radius: 4px
75
+ float: left
76
+ padding: 5px 12px
77
+ width: 207px
78
+
79
+ &.from, &.to
80
+ width: 83px
81
+
82
+ select
83
+ float: left
84
+ width: 235px
85
+
86
+ &[multiple]
87
+ border: 2px solid #ccc
88
+ border-radius: 5px
89
+ height: 100px
90
+ &.dynamic_filter
91
+ &.field
92
+ width: 178px
93
+ &.operation
94
+ margin-left: 7px
95
+ width: 50px
96
+ input.dynamic_filter.value
97
+ margin: 10px 0 0 $dg-form-label
98
+ clear: both
99
+
100
+ .separator
101
+ float: left
102
+ margin: 6px 4px 0
103
+
104
+
105
+ .datagrid-actions
106
+ padding-left: $dg-form-label +10
107
+
108
+ input[type='submit']
109
+ background-color: #555
110
+ border: none
111
+ border-radius: 5px
112
+ color: white
113
+ cursor: pointer
114
+ font-size: 14px
115
+ font-weight: bold
116
+ line-height: normal
117
+ padding: 7px 15px
118
+ vertical-align: middle
119
+ +inline-block
120
+
121
+ &:hover,
122
+ &:focus
123
+ background-color: #333
124
+
125
+ &:active
126
+ background-color: #000
127
+
128
+ > a
129
+ font-size: 14px
130
+ padding: 7px 15px
131
+ vertical-align: middle
132
+ +inline-block
@@ -1,9 +1,12 @@
1
1
  <%= form_for grid, options do |f| -%>
2
2
  <% grid.filters.each do |filter| %>
3
- <div class="filter">
3
+ <div class="datagrid-filter filter">
4
4
  <%= f.datagrid_label filter %>
5
5
  <%= f.datagrid_filter filter %>
6
6
  </div>
7
7
  <% end %>
8
- <%= f.submit I18n.t("datgrid.form.submit", :default => "Search").html_safe %>
8
+ <div class="datagrid-actions">
9
+ <%= f.submit I18n.t("datagrid.form.search").html_safe, :class => "datagrid-submit" %>
10
+ <%= link_to I18n.t('datagrid.form.reset').html_safe, url_for(grid.to_param => {}), :class => "datagrid-reset" %>
11
+ </div>
9
12
  <% end -%>
@@ -1,10 +1,10 @@
1
1
  <div class="order">
2
2
  <%= link_to(
3
- I18n.t("datagrid.table.order.asc", :default => "&uarr;".html_safe).html_safe,
3
+ I18n.t("datagrid.table.order.asc").html_safe,
4
4
  url_for(grid.param_name => grid.as_query.merge(:order => column.name, :descending => false)),
5
5
  :class => "asc") %>
6
6
  <%= link_to(
7
- I18n.t("datagrid.table.order.desc", :default => "&darr;".html_safe).html_safe,
7
+ I18n.t("datagrid.table.order.desc").html_safe,
8
8
  url_for(grid.param_name => grid.as_query.merge(:order => column.name, :descending => true )),
9
9
  :class => "desc") %>
10
10
  </div>
@@ -10,7 +10,7 @@ Local variables:
10
10
  </thead>
11
11
  <tbody>
12
12
  <% if assets.empty? %>
13
- <tr><td class="noresults" colspan="100%"><%= I18n.t 'datagrid.no_results', :default => '&mdash;&mdash;'.html_safe %></td></tr>
13
+ <tr><td class="noresults" colspan="100%"><%= I18n.t('datagrid.no_results').html_safe %></td></tr>
14
14
  <% else %>
15
15
  <%= datagrid_rows(grid, assets, options) %>
16
16
  <% end %>
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "datagrid"
8
- s.version = "0.9.3"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bogdan Gusiev"]
12
- s.date = "2013-08-26"
12
+ s.date = "2013-09-19"
13
13
  s.description = "This allows you to easily build datagrid aka data tables with sortable columns and filters"
14
14
  s.email = "agresso@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  "Rakefile",
24
24
  "Readme.markdown",
25
25
  "VERSION",
26
+ "app/assets/stylesheets/datagrid.css.sass",
26
27
  "app/views/datagrid/_form.html.erb",
27
28
  "app/views/datagrid/_head.html.erb",
28
29
  "app/views/datagrid/_order_for.html.erb",
@@ -50,13 +51,17 @@ Gem::Specification.new do |s|
50
51
  "lib/datagrid/filters/composite_filters.rb",
51
52
  "lib/datagrid/filters/date_filter.rb",
52
53
  "lib/datagrid/filters/default_filter.rb",
54
+ "lib/datagrid/filters/dynamic_filter.rb",
53
55
  "lib/datagrid/filters/enum_filter.rb",
54
56
  "lib/datagrid/filters/float_filter.rb",
55
57
  "lib/datagrid/filters/integer_filter.rb",
56
58
  "lib/datagrid/filters/ranged_filter.rb",
59
+ "lib/datagrid/filters/select_options.rb",
57
60
  "lib/datagrid/filters/string_filter.rb",
58
61
  "lib/datagrid/form_builder.rb",
59
62
  "lib/datagrid/helper.rb",
63
+ "lib/datagrid/i18n.rb",
64
+ "lib/datagrid/locale/en.yml",
60
65
  "lib/datagrid/ordering.rb",
61
66
  "lib/datagrid/renderer.rb",
62
67
  "lib/datagrid/rspec.rb",
@@ -74,9 +79,11 @@ Gem::Specification.new do |s|
74
79
  "spec/datagrid/filters/boolean_enum_filter_spec.rb",
75
80
  "spec/datagrid/filters/composite_filters_spec.rb",
76
81
  "spec/datagrid/filters/date_filter_spec.rb",
82
+ "spec/datagrid/filters/dynamic_filter_spec.rb",
77
83
  "spec/datagrid/filters/enum_filter_spec.rb",
78
84
  "spec/datagrid/filters/float_filter_spec.rb",
79
85
  "spec/datagrid/filters/integer_filter_spec.rb",
86
+ "spec/datagrid/filters/string_filter_spec.rb",
80
87
  "spec/datagrid/filters_spec.rb",
81
88
  "spec/datagrid/form_builder_spec.rb",
82
89
  "spec/datagrid/helper_spec.rb",
@@ -99,7 +106,7 @@ Gem::Specification.new do |s|
99
106
  s.homepage = "http://github.com/bogdan/datagrid"
100
107
  s.licenses = ["MIT"]
101
108
  s.require_paths = ["lib"]
102
- s.rubygems_version = "1.8.24"
109
+ s.rubygems_version = "1.8.25"
103
110
  s.summary = "Ruby gem to create datagrids"
104
111
 
105
112
  if s.respond_to? :specification_version then
@@ -46,5 +46,6 @@ module Datagrid
46
46
  end
47
47
 
48
48
  require "datagrid/scaffold"
49
+ I18n.load_path << File.expand_path('../datagrid/locale/en.yml', __FILE__)
49
50
 
50
51
 
@@ -9,7 +9,7 @@ module Datagrid
9
9
  datagrid_attribute :column_names do |names|
10
10
  names = Array(names).reject(&:blank?)
11
11
  if names.reject(&:blank?).blank?
12
- columns.map(&:name)
12
+ []
13
13
  else
14
14
  names
15
15
  end
@@ -18,10 +18,12 @@ module Datagrid
18
18
 
19
19
  module ClassMethods
20
20
  # Adds a filter that acts like a column selection
21
- def column_names_filter
22
- filter(:column_names, :enum, :select => proc { |grid| grid.class.columns.map {|c| [c.header, c.name] }}, :multiple => true ) do |value|
23
- scoped
24
- end
21
+ def column_names_filter(options = {})
22
+ filter(:column_names, :enum, {
23
+ :select => :optional_columns_select,
24
+ :multiple => true,
25
+ :dummy => true
26
+ }.merge(options || {}))
25
27
  end
26
28
  end
27
29
 
@@ -32,17 +34,46 @@ module Datagrid
32
34
  super(*column_names)
33
35
  end
34
36
 
37
+ # Returns a list of columns with <tt>:mandatory => true</tt> option
38
+ # If no mandatory columns specified than all of them considered mandatory
39
+ def mandatory_columns
40
+ self.class.columns.select(&:mandatory?)
41
+ end
42
+
43
+ # Returns a list of columns without <tt>:mandatory => true</tt> option
44
+ def optional_columns
45
+ self.class.columns - mandatory_columns
46
+ end
47
+
35
48
  protected
36
49
 
37
- def selected_column_names(*args)
50
+ def optional_columns_select #:nodoc:
51
+ optional_columns.map {|c| [c.header, c.name] }
52
+ end
53
+
54
+ def selected_column_names(*args)
38
55
  if args.any?
39
56
  args.compact!
40
57
  args.map!(&:to_sym)
41
58
  args
42
59
  else
43
- column_names ? column_names.clone : []
60
+ if column_names && column_names.any?
61
+ column_names + mandatory_columns.map(&:name)
62
+ else
63
+ columns_enabled_by_default.map(&:name)
64
+ end
44
65
  end
45
66
  end
67
+
68
+ def columns_visibility_enabled?
69
+ self.class.columns.any? do |column|
70
+ column.options.key?(:mandatory)
71
+ end
72
+ end
73
+
74
+ def columns_enabled_by_default
75
+ columns_visibility_enabled? ? mandatory_columns : []
76
+ end
46
77
  end
47
78
  end
48
79
 
@@ -12,12 +12,39 @@ module Datagrid
12
12
 
13
13
  include Datagrid::Core
14
14
 
15
+ class_attribute :default_column_options
16
+ self.default_column_options = {}
17
+
15
18
  end
16
19
  base.send :include, InstanceMethods
17
20
  end # self.included
18
21
 
19
22
  module ClassMethods
20
23
 
24
+
25
+ ##
26
+ # :method: default_column_options=
27
+ #
28
+ # :call-seq: default_column_options=(options)
29
+ #
30
+ # Specifies default options for `column` method.
31
+ # They still can be overwritten at column level.
32
+ #
33
+ # # Disable default order
34
+ # self.default_column_options = { :order => false }
35
+ # # Makes entire report HTML
36
+ # self.default_column_options = { :html => true }
37
+ #
38
+
39
+ ##
40
+ # :method: default_column_options
41
+ #
42
+ # :call-seq: default_column_options
43
+ #
44
+ # Returns specified default column options hash
45
+ # See <tt>default_column_options=</tt> for more information
46
+ #
47
+
21
48
  # Returns a list of columns defined.
22
49
  # All column definistion are returned by default
23
50
  # You can limit the output with only columns you need like:
@@ -32,7 +59,7 @@ module Datagrid
32
59
  args.compact!
33
60
  args.map!(&:to_sym)
34
61
  columns_array.select do |column|
35
- (!options[:data] || column.data?) && (!options[:html] || column.html?)&& (args.empty? || args.include?(column.name))
62
+ (!options[:data] || column.data?) && (!options[:html] || column.html?) && (column.mandatory? || args.empty? || args.include?(column.name))
36
63
  end
37
64
  end
38
65
 
@@ -47,8 +74,15 @@ module Datagrid
47
74
  # Available options:
48
75
  #
49
76
  # * <tt>:html</tt> - determines if current column should be present in html table and how is it formatted
50
- # * <tt>:order</tt> - determines if this column could be sortable and how
51
- # * <tt>:order_desc</tt> - determines a descending order for given column (only in case when <tt>:order</tt> can not be easily inverted
77
+ # * <tt>:order</tt> - determines if this column could be sortable and how.
78
+ # The value of order is explicitly passed to ORM ordering method.
79
+ # Ex: <tt>"created_at, id"</tt> for ActiveRecord, <tt>[:created_at, :id]</tt> for Mongoid
80
+ # * <tt>:order_desc</tt> - determines a descending order for given column
81
+ # (only in case when <tt>:order</tt> can not be easily reversed by ORM)
82
+ # * <tt>:order_by_value</tt> - used in case it is easier to perform ordering at ruby level not on database level.
83
+ # Warning: using ruby to order large datasets is very unrecommended.
84
+ # If set to true - datagrid will use column value to order by this column
85
+ # If block is given - datagrid will use value returned from block
52
86
  # * <tt>:url</tt> - a proc with one argument, pass this option to easily convert the value into an URL
53
87
  # * <tt>:before</tt> - determines the position of this column, by adding it before the column passed here
54
88
  # * <tt>:after</tt> - determines the position of this column, by adding it after the column passed here
@@ -60,7 +94,7 @@ module Datagrid
60
94
  model.send(name)
61
95
  end
62
96
  position = Datagrid::Utils.extract_position_from_options(columns_array, options)
63
- column = Datagrid::Columns::Column.new(self, name, options, &block)
97
+ column = Datagrid::Columns::Column.new(self, name, default_column_options.merge(options), &block)
64
98
  columns_array.insert(position, column)
65
99
  end
66
100
 
@@ -58,13 +58,29 @@ class Datagrid::Columns::Column
58
58
  end
59
59
 
60
60
  def order
61
- if options.has_key?(:order)
61
+ if options.has_key?(:order) && options[:order] != true
62
62
  self.options[:order]
63
63
  else
64
64
  grid_class.driver.default_order(grid_class.scope, name)
65
65
  end
66
66
  end
67
67
 
68
+ def supports_order?
69
+ order || order_by_value?
70
+ end
71
+
72
+ def order_by_value(model, grid)
73
+ if options[:order_by_value] == true
74
+ data_value(model, grid)
75
+ else
76
+ Datagrid::Utils.apply_args(model, grid, &options[:order_by_value])
77
+ end
78
+ end
79
+
80
+ def order_by_value?
81
+ !! options[:order_by_value]
82
+ end
83
+
68
84
  def order_desc
69
85
  return nil unless order
70
86
  self.options[:order_desc]
@@ -77,6 +93,18 @@ class Datagrid::Columns::Column
77
93
  def data?
78
94
  self.data_block != nil
79
95
  end
96
+
97
+ def mandatory?
98
+ !! options[:mandatory]
99
+ end
100
+
101
+ def inspect
102
+ "#<Datagird::Columns::Column #{grid_class}##{name} #{options.inspect}>"
103
+ end
104
+
105
+ def to_s
106
+ header
107
+ end
80
108
 
81
109
  def html_value(context, asset, grid)
82
110
  if html? && html_block