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 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