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 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, :table_class => ["users-table", "shiny-colorful-table"] do
184
+ zable @items, class: "users-table" do
61
185
  column(:name)
62
186
  column(:email)
63
187
  column(:created_at, :title => "Join Date")
@@ -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
@@ -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
- page = (PAGE_DEFAULTS.merge(params[:page] || {})).stringify_keys
22
- scoped_object = scoped_object.paginate(:page => page['num'], :per_page => page['size']) if scoped_object.respond_to?(:paginate)
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 << param(:sort, "attr", attr[:name])
49
- params << param(:sort, "order", attr[:sort_order]) if attr[:sorted?]
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
- params = [sort_params(attr), search_params, @_extra_params.to_query.html_safe].reject(&:blank?).join("&".html_safe)
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}", -> options { order("#{table_name}.#{attr_name} #{options[:order]}") }
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
- self.send scope_for_sort_attribute(sort_params), sort_params
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, :renderer => Zable::WillPaginate::LinkWithParamsRenderer.new(self, @_extra_params))
64
+ will_paginate(@collection,
65
+ :renderer => Zable::WillPaginate::LinkWithParamsRenderer.new(self, @_extra_params)
66
+ )
65
67
  end
66
68
  end
67
69
 
@@ -10,9 +10,8 @@ module Zable
10
10
  end
11
11
 
12
12
  def url(page)
13
- page_param = @zable_view.param(:page, :num, page)
14
- all_params = [page_param, @zable_view.current_sort_params, @zable_view.search_params, @params.to_query.html_safe].reject(&:blank?).join("&".html_safe)
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.8
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-05 00:00:00.000000000 Z
13
+ date: 2013-02-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: will_paginate