zable 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +125 -1
- data/app/helpers/zable_helper.rb +17 -0
- data/lib/zable/active_record.rb +13 -6
- data/lib/zable/html.rb +10 -21
- data/lib/zable/sort.rb +4 -4
- data/lib/zable/view.rb +3 -1
- data/lib/zable/will_paginate.rb +2 -3
- metadata +2 -2
data/README.md
CHANGED
@@ -16,6 +16,7 @@ end
|
|
16
16
|
* **options** - (Hash)
|
17
17
|
* **:class** - (String) Html class
|
18
18
|
* **:id** - (String) Html id
|
19
|
+
* **:params** - (Hash) Additional params to be appended at the end of every header/pagination link
|
19
20
|
|
20
21
|
Within the zable block, you can use the `column` method to define the columns of your table.
|
21
22
|
|
@@ -35,6 +36,129 @@ end
|
|
35
36
|
* **:title** - (String or Proc) You can use this to designate a custom header title string, or with a proc, supply completely custom header markup.
|
36
37
|
* **:sort** - (Boolean, default: true) By default, the header title will be a link that can be used to sort its respective column. However by setting this option to false, the title will not be a link.
|
37
38
|
|
39
|
+
If you pass in a block, the content of each cell in that column will be calculated from the block; otherwise the content will be taken from the supplied attribute.
|
40
|
+
|
41
|
+
## In the controller
|
42
|
+
|
43
|
+
The zable gem provides a single `populate` method to handle sorting, searching/filtering, and pagination. Querying your objects is as simple as this:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
def index
|
47
|
+
@items = Item.populate(params)
|
48
|
+
# or
|
49
|
+
@items = current_user.items.populate(params)
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
As you can see, all me must do is pass in the request's params to the `populate` method. You can also attach the method after a chain of queries.
|
54
|
+
|
55
|
+
Below shows an example of all possible passed parameters of interest when using sorting, searching and pagination:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
params = {
|
59
|
+
sort: {
|
60
|
+
attr: "column_1", # name of the sorted attribute
|
61
|
+
order: "asc" # 'asc' or 'desc' ('asc' is default)
|
62
|
+
},
|
63
|
+
search: {
|
64
|
+
column_1: "some_search", # key is the attr being searched on, value is the search query
|
65
|
+
column_2: "some_other_search"
|
66
|
+
},
|
67
|
+
page: {
|
68
|
+
num: 1, # page number
|
69
|
+
size: 20 # items per page
|
70
|
+
}
|
71
|
+
}
|
72
|
+
```
|
73
|
+
|
74
|
+
## Sorting
|
75
|
+
|
76
|
+
You can easily sort on your models' column attributes via the `sortable` method provided on ActiveRecord.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
class Item < ActiveRecord::Base
|
80
|
+
sortable :name, :price, :created_at
|
81
|
+
end
|
82
|
+
|
83
|
+
# in the view
|
84
|
+
zable @items do
|
85
|
+
column(:name)
|
86
|
+
column(:price)
|
87
|
+
column(:created_at)
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
If you want to sort on something more complex than a column in your database, you can do so by creating a named scope:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
class Item < ActiveRecord::Base
|
95
|
+
scope :sort_category, -> asc_or_desc { includes(:category).order("category.name #{asc_or_desc}") }
|
96
|
+
end
|
97
|
+
|
98
|
+
# in the view
|
99
|
+
zable @items do
|
100
|
+
column(:category)
|
101
|
+
end
|
102
|
+
```
|
103
|
+
|
104
|
+
## Searching
|
105
|
+
|
106
|
+
Similar to sorting, zable provides a `searchable` method on ActiveRecord.
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
class Item < ActiveRecord::Base
|
110
|
+
searchable :name, :price, :created_at
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
114
|
+
This allows us to do equality-based searching on these attributes. Again, if you would like to do something more complex, create a named scope:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
class Item < ActiveRecord::Base
|
118
|
+
scope :search_category, -> value { joins(:category).where("upper(items.category) like %#{value.upcase}%") }
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
## Pagination
|
123
|
+
|
124
|
+
Optionally, you can use pagination via [will_paginate](https://github.com/mislav/will_paginate). In the view, simply set the 'paginate' option:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
zable @items, paginate: true do
|
128
|
+
...
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
As with will_paginate, page size can be set on your model:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
class Item
|
136
|
+
self.per_page = 10
|
137
|
+
end
|
138
|
+
# OR
|
139
|
+
WillPaginate.per_page = 10
|
140
|
+
```
|
141
|
+
|
142
|
+
Additionally, you can set a per_page option directly in the #populate method:
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
@items = Item.populate(params, per_page: 20)
|
146
|
+
```
|
147
|
+
|
148
|
+
Lastly, if you have a page size set in the params, this will override any of the previous per_page settings.
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
params['page']['size'] = 15 # this takes precedence over any other settings
|
152
|
+
```
|
153
|
+
|
154
|
+
This allows your users to set how many items are shown per page on the front end. To help with this, zable provides a `set_page_size_path(page_size)` helper method. In your view, you can do something like this:
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
<%= link_to "View 10 per page", set_page_size_path(10) %>
|
158
|
+
<%= link_to "View all items", set_page_size_path() %>
|
159
|
+
```
|
160
|
+
|
161
|
+
As shown above, a nil page_size can be used for showing all items on a single page.
|
38
162
|
|
39
163
|
## Example
|
40
164
|
|
@@ -57,7 +181,7 @@ end
|
|
57
181
|
index.html.erb:
|
58
182
|
```erb
|
59
183
|
<%=
|
60
|
-
zable @items, :
|
184
|
+
zable @items, class: "users-table" do
|
61
185
|
column(:name)
|
62
186
|
column(:email)
|
63
187
|
column(:created_at, :title => "Join Date")
|
data/app/helpers/zable_helper.rb
CHANGED
@@ -23,4 +23,21 @@ module ZableHelper
|
|
23
23
|
current_sort_order == :desc ? :asc : :desc
|
24
24
|
end
|
25
25
|
|
26
|
+
def set_page_size_path(page_size = nil)
|
27
|
+
page_params = if page_size
|
28
|
+
{ :page => {:size => page_size, :num => 1} }
|
29
|
+
else
|
30
|
+
{ :page => {:size => 'all'} }
|
31
|
+
end
|
32
|
+
current_path_with_params(params.slice(:sort, :search), page_params)
|
33
|
+
end
|
34
|
+
|
35
|
+
def zable_hidden_search_fields
|
36
|
+
fields = ""
|
37
|
+
fields << hidden_field_tag('sort[attr]', params[:sort][:attr]) if params[:sort] && params[:sort][:attr]
|
38
|
+
fields << hidden_field_tag('sort[order]', params[:sort][:order]) if params[:sort] && params[:sort][:order]
|
39
|
+
fields << hidden_field_tag('page[size]', params[:page][:size]) if params[:page] && params[:page][:size]
|
40
|
+
fields.html_safe
|
41
|
+
end
|
42
|
+
|
26
43
|
end
|
data/lib/zable/active_record.rb
CHANGED
@@ -3,7 +3,6 @@ module Zable
|
|
3
3
|
module ActiveRecord
|
4
4
|
|
5
5
|
module ClassMethods
|
6
|
-
PAGE_DEFAULTS = { 'num' => 1 }
|
7
6
|
|
8
7
|
def scoped_for_sort(params, scoped_object)
|
9
8
|
hash = (params[:sort] || {}).stringify_keys
|
@@ -17,16 +16,24 @@ module Zable
|
|
17
16
|
scoped_object
|
18
17
|
end
|
19
18
|
|
20
|
-
def scoped_for_paginate(params, scoped_object)
|
21
|
-
|
22
|
-
|
19
|
+
def scoped_for_paginate(params, scoped_object, options)
|
20
|
+
page_params = (params[:page] || {}).stringify_keys
|
21
|
+
if scoped_object.respond_to?(:paginate)
|
22
|
+
paginate_opts = {}
|
23
|
+
paginate_opts[:page] = page_params['num'] || 1
|
24
|
+
# params take preference over option, so that we may change page size on the frontend
|
25
|
+
page_size = page_params['size'] || options[:per_page]
|
26
|
+
page_size = 99999999 if page_size == 'all'
|
27
|
+
paginate_opts[:per_page] = page_size if page_size.present?
|
28
|
+
scoped_object = scoped_object.paginate(paginate_opts)
|
29
|
+
end
|
23
30
|
scoped_object
|
24
31
|
end
|
25
32
|
|
26
|
-
def populate(params={})
|
33
|
+
def populate(params={}, options = {})
|
27
34
|
obj = scoped_for_sort(params, self)
|
28
35
|
obj = scoped_for_search(params, obj)
|
29
|
-
scoped_for_paginate(params, obj)
|
36
|
+
scoped_for_paginate(params, obj, options)
|
30
37
|
end
|
31
38
|
|
32
39
|
module Helpers
|
data/lib/zable/html.rb
CHANGED
@@ -39,30 +39,20 @@ module Zable
|
|
39
39
|
"#{controller.request.fullpath.split("?")[0]}"
|
40
40
|
end
|
41
41
|
|
42
|
+
def current_path_with_params(*param_array)
|
43
|
+
all_params = param_array.reject(&:blank?).map {|p| p.to_query.html_safe}.join("&".html_safe)
|
44
|
+
all_params = all_params.sub("%5B", "[").sub("%5D", "]")
|
45
|
+
current_url << "?".html_safe << all_params
|
46
|
+
end
|
47
|
+
|
42
48
|
def param(param_type, param_key, attr)
|
43
49
|
"#{param_type}[#{param_key}]=#{attr}"
|
44
50
|
end
|
45
51
|
|
46
52
|
def sort_params(attr)
|
47
|
-
params = []
|
48
|
-
params
|
49
|
-
params
|
50
|
-
params.join("&".html_safe)
|
51
|
-
end
|
52
|
-
|
53
|
-
def current_sort_params
|
54
|
-
p = []
|
55
|
-
if params[:sort].present?
|
56
|
-
p << param(:sort, "attr", params[:sort][:attr])
|
57
|
-
p << param(:sort, "order", params[:sort][:order]) if params[:sort][:order].present?
|
58
|
-
end
|
59
|
-
p.join("&".html_safe)
|
60
|
-
end
|
61
|
-
|
62
|
-
def search_params
|
63
|
-
@search.to_a.collect do |param|
|
64
|
-
param(:search, param.first, param.second)
|
65
|
-
end.join("&".html_safe)
|
53
|
+
params = { :sort => {:attr => attr[:name]} }
|
54
|
+
params[:sort][:order] = attr[:sort_order] if attr[:sorted?]
|
55
|
+
params
|
66
56
|
end
|
67
57
|
|
68
58
|
def sort_arrow_image_file(attr)
|
@@ -70,8 +60,7 @@ module Zable
|
|
70
60
|
end
|
71
61
|
|
72
62
|
def header_cell_href(attr)
|
73
|
-
|
74
|
-
current_url << "?".html_safe << params
|
63
|
+
current_path_with_params(sort_params(attr), params.slice(:search), @_extra_params)
|
75
64
|
end
|
76
65
|
|
77
66
|
def header_cell_link_text(attr)
|
data/lib/zable/sort.rb
CHANGED
@@ -20,7 +20,7 @@ module Zable
|
|
20
20
|
# sortable :last_name, :created_at
|
21
21
|
def sortable(*attr_names)
|
22
22
|
attr_names.each do |attr_name|
|
23
|
-
scope "sort_#{attr_name}", ->
|
23
|
+
scope "sort_#{attr_name}", -> ordering { order("#{table_name}.#{attr_name} #{ordering}") }
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -28,7 +28,9 @@ module Zable
|
|
28
28
|
|
29
29
|
def inject_sort_scope(sort_params)
|
30
30
|
return unless sort_params
|
31
|
-
|
31
|
+
sort_params.stringify_keys!
|
32
|
+
sort_params['order'] = 'ASC' if sort_params['order'].nil? || sort_params['order'].upcase != "DESC"
|
33
|
+
self.send scope_for_sort_attribute(sort_params), sort_params['order']
|
32
34
|
end
|
33
35
|
|
34
36
|
def scope_name_for_attribute(type, attr)
|
@@ -36,8 +38,6 @@ module Zable
|
|
36
38
|
end
|
37
39
|
|
38
40
|
def scope_for_sort_attribute(sort_params)
|
39
|
-
sort_params.stringify_keys!
|
40
|
-
sort_params['order'] = 'ASC' if sort_params['order'].nil? || sort_params['order'].upcase != "DESC"
|
41
41
|
scope_name_for_attribute(:sort, sort_params['attr'])
|
42
42
|
end
|
43
43
|
end
|
data/lib/zable/view.rb
CHANGED
@@ -61,7 +61,9 @@ module Zable
|
|
61
61
|
def pagination_element
|
62
62
|
content_tag :div, :class => 'brownFilterResultsBox' do
|
63
63
|
page_entries_info(@collection, @options.slice(:entry_name)) <<
|
64
|
-
will_paginate(@collection,
|
64
|
+
will_paginate(@collection,
|
65
|
+
:renderer => Zable::WillPaginate::LinkWithParamsRenderer.new(self, @_extra_params)
|
66
|
+
)
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
data/lib/zable/will_paginate.rb
CHANGED
@@ -10,9 +10,8 @@ module Zable
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def url(page)
|
13
|
-
|
14
|
-
|
15
|
-
@zable_view.current_url << "?".html_safe << all_params
|
13
|
+
page_params = {:page => {:num => page}}
|
14
|
+
@zable_view.current_path_with_params(page_params, @zable_view.params.slice(:search, :sort), @params)
|
16
15
|
end
|
17
16
|
|
18
17
|
protected
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-02-
|
13
|
+
date: 2013-02-07 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: will_paginate
|