zable 0.0.8 → 0.0.9
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.
- 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
|