datagrid 0.9.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme.markdown +6 -4
- data/VERSION +1 -1
- data/app/assets/stylesheets/datagrid.css.sass +132 -0
- data/app/views/datagrid/_form.html.erb +5 -2
- data/app/views/datagrid/_order_for.html.erb +2 -2
- data/app/views/datagrid/_table.html.erb +1 -1
- data/datagrid.gemspec +10 -3
- data/lib/datagrid.rb +1 -0
- data/lib/datagrid/column_names_attribute.rb +38 -7
- data/lib/datagrid/columns.rb +38 -4
- data/lib/datagrid/columns/column.rb +29 -1
- data/lib/datagrid/drivers/abstract_driver.rb +8 -0
- data/lib/datagrid/drivers/active_record.rb +29 -1
- data/lib/datagrid/drivers/array.rb +14 -2
- data/lib/datagrid/drivers/mongo_mapper.rb +8 -0
- data/lib/datagrid/drivers/mongoid.rb +9 -1
- data/lib/datagrid/filters.rb +24 -6
- data/lib/datagrid/filters/base_filter.rb +42 -14
- data/lib/datagrid/filters/boolean_enum_filter.rb +1 -1
- data/lib/datagrid/filters/dynamic_filter.rb +57 -0
- data/lib/datagrid/filters/enum_filter.rb +4 -21
- data/lib/datagrid/filters/select_options.rb +26 -0
- data/lib/datagrid/form_builder.rb +41 -8
- data/lib/datagrid/helper.rb +2 -1
- data/lib/datagrid/i18n.rb +0 -0
- data/lib/datagrid/locale/en.yml +28 -0
- data/lib/datagrid/ordering.rb +33 -19
- data/lib/datagrid/utils.rb +8 -9
- data/spec/datagrid/column_names_attribute_spec.rb +44 -1
- data/spec/datagrid/columns_spec.rb +16 -0
- data/spec/datagrid/filters/dynamic_filter_spec.rb +37 -0
- data/spec/datagrid/filters/integer_filter_spec.rb +18 -0
- data/spec/datagrid/filters/string_filter_spec.rb +25 -0
- data/spec/datagrid/filters_spec.rb +15 -1
- data/spec/datagrid/form_builder_spec.rb +83 -0
- data/spec/datagrid/helper_spec.rb +1 -0
- data/spec/datagrid/ordering_spec.rb +41 -1
- data/spec/datagrid/utils_spec.rb +7 -2
- metadata +11 -4
data/Readme.markdown
CHANGED
@@ -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
|
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
|
-
|
100
|
-
|
101
|
-
|
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.
|
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
|
-
|
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"
|
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"
|
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
|
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 %>
|
data/datagrid.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "datagrid"
|
8
|
-
s.version = "0.
|
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-
|
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.
|
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
|
data/lib/datagrid.rb
CHANGED
@@ -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
|
-
|
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,
|
23
|
-
|
24
|
-
|
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
|
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
|
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
|
|
data/lib/datagrid/columns.rb
CHANGED
@@ -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
|
-
#
|
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
|