tabulatr2 0.9.16 → 0.9.17

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b70faeab636c745520f3c94de294232af0540e1d
4
- data.tar.gz: b3feca6e1aeabdf69b5b5ada582b2a6a91834957
3
+ metadata.gz: 28a75cdd6eebb48110ace894527bd211edb4bec0
4
+ data.tar.gz: 6d553772fe2733c6e6f129ce5f05296d0fbeb520
5
5
  SHA512:
6
- metadata.gz: 44a287bc0b2493272e229cf0646b3829a2c9f79424e8ca5a5e1717531cb56bd9349774c4b69139b6423c672dfd3f04e180687e3a9399706d6e3ce8e47cf68ab0
7
- data.tar.gz: 30052dc24ecf51e7975bd54fd5adcf75d1cbea36295bb1b100fc070fbffdda79cacd01a07defe1f91d98ae84dafa91caaeccc813cea0d538f50f98a365cf7d21
6
+ metadata.gz: 677da86fdeedcbab796ba3904e5e27e34d881ac3f8b38d954b49143dc7635c513af0a4186eb3f4f45757466b21b1c3cf1d7ecad690d54e4ecb445a4ada400101
7
+ data.tar.gz: a14ec3f70fe10b9ea241f8c608d78b39dbb7f89b57e3386a77a979c1ad13e11acfe6a7485d221b591dc65567432c5e26e0054ed5d31b25e62b3dedc924c1aec3
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 0.9.17
2
+ * If a batch action is executed without checking any rows it
3
+ will be applied to all rows in the current filter
4
+
5
+ * Add filter `enum_multiselect`
6
+
7
+ Example:
8
+ ```
9
+ column :status, filter: :enum_multiselect
10
+ ```
11
+
12
+ ## 0.9.16
13
+ Adds `paginate` as config option
14
+
1
15
  ## 0.9.15
2
16
  * Adds filter support for `enum`
3
17
  If it detects an enum it creates a dropdown filter with the possible enum
@@ -256,7 +256,14 @@ Tabulatr.prototype = {
256
256
  var form_array = $('.tabulatr_filter_form[data-table="'+ this.id +'"]')
257
257
  .find('input:visible,select:visible,input[type=hidden]').serializeArray();
258
258
  for(var i = 0; i < form_array.length; i++){
259
- hash[form_array[i].name] = form_array[i].value;
259
+ if(hash[form_array[i].name] !== undefined){
260
+ if(!Array.isArray(hash[form_array[i].name])){
261
+ hash[form_array[i].name] = [hash[form_array[i].name]];
262
+ }
263
+ hash[form_array[i].name].push(form_array[i].value);
264
+ }else{
265
+ hash[form_array[i].name] = form_array[i].value;
266
+ }
260
267
  }
261
268
  return hash;
262
269
  },
@@ -347,15 +354,21 @@ $(document).on('ready page:load', function(){
347
354
  var params = {page: 1};
348
355
  params[name] = key;
349
356
  params.tabulatr_checked = {checked_ids: jQuery.map($('#'+ tableId +' .tabulatr-checkbox:checked'), function(el){return $(el).val();}).join(',')};
350
- $('.tabulatr_mark_all[data-table='+ tableId +']').prop('indeterminate', false).prop('checked', false);
351
- $('#'+ tableId +' .tabulatr-wrench').addClass('disabled');
352
- var table_obj;
353
- for(var i = 0; i < tabulatr_tables.length; i++){
354
- if(tabulatr_tables[i].id === tableId){
355
- table_obj = tabulatr_tables[i];
357
+ var confirmation = true;
358
+ if(params.tabulatr_checked.checked_ids == ''){
359
+ confirmation = confirm(a.parents('ul').data('confirm-text'));
360
+ }
361
+ if(confirmation){
362
+ $('.tabulatr_mark_all[data-table='+ tableId +']').prop('indeterminate', false).prop('checked', false);
363
+ $('#'+ tableId +' .tabulatr-wrench').addClass('disabled');
364
+ var table_obj;
365
+ for(var i = 0; i < tabulatr_tables.length; i++){
366
+ if(tabulatr_tables[i].id === tableId){
367
+ table_obj = tabulatr_tables[i];
368
+ }
356
369
  }
370
+ table_obj.updateTable(params, true);
357
371
  }
358
- table_obj.updateTable(params, true);
359
372
  });
360
373
 
361
374
  $('form.tabulatr-fuzzy-search').submit(function(){
@@ -25,7 +25,7 @@
25
25
  a.btn.btn-default data-toggle="dropdown" href="#"
26
26
  i.icon-cog.glyphicon.glyphicon-cog.fa.fa-cog>
27
27
  i.icon-caret-down.glyphicon.glyphicon-chevron-down.fa.fa-caret-down
28
- ul.dropdown-menu role="menu" aria-labelledby="dLabel"
28
+ ul.dropdown-menu role="menu" aria-labelledby="dLabel" data-confirm-text=t('tabulatr.batch_confirm_text')
29
29
  - table_options[:batch_actions].each do |key, label|
30
30
  li
31
31
  = link_to label, '#', class: "batch-action-inputs", data: { \
@@ -66,7 +66,7 @@
66
66
  [t('tabulatr.boolean_filter.no'), "false"],
67
67
  [t('tabulatr.boolean_filter.yes'), "true"]] \
68
68
  ), class: 'form-control no-chosen')
69
- - elsif column.filter == :exact
69
+ - elsif [:exact, :integer, :decimal].member? column.filter
70
70
  input.tabulatr_filter.form-control type="text" id="#{name}_exact" data-tabulatr-attribute="#{name}" name="#{iname}"
71
71
  - elsif column.filter == :date
72
72
  select.form-control.no-chosen name="#{iname}[date][simple]" data-tabulatr-date-filter="#{formatted_name}_#{name}_filter"
@@ -94,5 +94,12 @@
94
94
  option= I18n.t('tabulatr.enum_filter.none')
95
95
  - column.klass.try(column.name.to_s.pluralize.to_sym).each do |key, value|
96
96
  option value=value = key
97
+ - elsif column.filter == :enum_multiselect
98
+ - column.klass.try(column.name.to_s.pluralize.to_sym).each do |key, value|
99
+ .row
100
+ .col-xs-2
101
+ = check_box_tag "#{iname}[]", value, true, {id: "check_box_#{key}"}
102
+ .col-xs-10
103
+ = label_tag "check_box_#{key}", key
97
104
  - else
98
105
  input.tabulatr_filter.form-control type="text" data-tabulatr-attribute="#{name}" name="#{iname}[like]"
@@ -43,7 +43,6 @@ class Tabulatr::Data
43
43
 
44
44
  @batch_actions = block if block_given?
45
45
 
46
- execute_batch_actions(batch_params(params), check_params(params))
47
46
 
48
47
  # count
49
48
  total = @relation.count
@@ -54,11 +53,11 @@ class Tabulatr::Data
54
53
  apply_sorting(sort_params params)
55
54
  join_required_tables(params)
56
55
 
56
+ execute_batch_actions(batch_params(params), check_params(params))
57
+
57
58
  pagination = compute_pagination(params[:page], params[:pagesize])
58
59
  apply_pagination(pagination.slice(:offset, :pagesize))
59
60
 
60
- # TODO: batch actions and checked ids
61
-
62
61
  # get the records
63
62
  found = apply_formats(locals: locals, controller: controller)
64
63
 
@@ -87,6 +86,7 @@ class Tabulatr::Data
87
86
  def execute_batch_actions batch_param, selected_ids
88
87
  if batch_param.present? && @batch_actions.present?
89
88
  batch_param = batch_param.keys.first.to_sym if batch_param.is_a?(Hash)
89
+ selected_ids = @relation.map(&:id) if selected_ids.empty?
90
90
  @batch_actions.yield(Invoker.new(batch_param, selected_ids))
91
91
  end
92
92
  end
@@ -115,11 +115,13 @@ class Tabulatr::Data
115
115
  end
116
116
 
117
117
  def join_required_tables(params)
118
- tt = (params[:arguments].split(",").select{|s| s[':']}.map do |s|
119
- s.split(':').first
120
- end.uniq.map(&:to_sym))
121
- tt.delete(@table_name.to_sym)
122
- @includes = @includes + tt
118
+ if params[:arguments].present?
119
+ tt = (params[:arguments].split(",").select{|s| s[':']}.map do |s|
120
+ s.split(':').first
121
+ end.uniq.map(&:to_sym))
122
+ tt.delete(@table_name.to_sym)
123
+ @includes = @includes + tt
124
+ end
123
125
  # @relation = @relation.includes(@includes.map(&:to_sym)).references(@includes.map(&:to_sym))
124
126
  @relation = @relation.eager_load(@includes.map(&:to_sym))
125
127
  # @relation = @relation.group("#{@table_name}.#{@base.primary_key}")
@@ -66,19 +66,25 @@ module Tabulatr::Data::Filtering
66
66
  end
67
67
 
68
68
  def apply_condition(n,v)
69
- if ['true', 'false'].include?(v)
70
- @relation = @relation.where("#{n.filter_sql} = ?", Tabulatr::Utility.string_to_boolean(v))
71
- elsif v.is_a?(String)
72
- apply_string_condition("#{n.filter_sql} = ?", v)
73
- elsif v.is_a?(Hash)
74
- apply_hash_condition(n, v)
75
- else
76
- raise "Wrong filter type: #{v.class}"
69
+ case n.filter
70
+ when :checkbox then apply_boolean_condition(n, v)
71
+ when :decimal then apply_string_condition("#{n.filter_sql} = ?", v.to_f)
72
+ when :integer then apply_string_condition("#{n.filter_sql} = ?", v.to_i)
73
+ when :enum then apply_string_condition("#{n.filter_sql} = ?", v.to_i)
74
+ when :enum_multiselect then apply_array_condition(n, v)
75
+ when :exact then apply_string_condition("#{n.filter_sql} = ?", v)
76
+ when :like then apply_like_condition(n, v[:like])
77
+ when :date then apply_date_condition(n, v[:date])
78
+ when :range then apply_range_condition(n, v)
79
+ else raise "Wrong filter type for #{n.name}: #{n.filter}"
77
80
  end
78
81
  end
79
82
 
83
+ def apply_boolean_condition(n, value)
84
+ @relation = @relation.where("#{n.filter_sql} = ?", Tabulatr::Utility.string_to_boolean(value))
85
+ end
86
+
80
87
  def apply_date_condition(n, cond)
81
- return unless cond.present?
82
88
  today = Date.today
83
89
  case cond[:simple]
84
90
  when 'none' then return
@@ -112,14 +118,20 @@ module Tabulatr::Data::Filtering
112
118
  @relation = @relation.where(replacement_string, value) if value.present?
113
119
  end
114
120
 
115
- def apply_hash_condition(column_name, hash)
121
+ def apply_like_condition(column_name, value)
116
122
  like ||= Tabulatr::Utility.like_statement
117
- apply_string_condition("#{column_name.filter_sql} #{like} ?", "%#{hash[:like]}%") if hash[:like].present?
118
- apply_date_condition(column_name, hash[:date])
123
+ apply_string_condition("#{column_name.filter_sql} #{like} ?", "%#{value}%") if value.present?
124
+ end
125
+
126
+ def apply_range_condition(column_name, hash)
119
127
  apply_string_condition("#{column_name.filter_sql} >= ?", "#{hash[:from]}")
120
128
  apply_string_condition("#{column_name.filter_sql} <= ?", "#{hash[:to]}")
121
129
  end
122
130
 
131
+ def apply_array_condition(column, value)
132
+ @relation = @relation.where(column.table_name => { column.name => value })
133
+ end
134
+
123
135
  private
124
136
 
125
137
  def execute_provided_search_block!(query)
@@ -180,19 +180,21 @@ class Tabulatr::Renderer::Column
180
180
  end
181
181
 
182
182
  def determine_appropriate_filter!
183
- case self.klass.columns_hash[self.name.to_s].try(:type)
184
- when :integer, :float, :decimal
183
+ typ = self.klass.columns_hash[self.name.to_s].try(:type).try(:to_sym)
184
+ case typ
185
+ when :integer
185
186
  if self.klass.respond_to?(:defined_enums) && self.klass.defined_enums.keys.include?(self.name.to_s)
186
187
  self.filter = :enum
187
188
  else
188
- self.filter = :exact
189
+ self.filter = :integer
189
190
  end
190
- when :string, :text
191
- self.filter = :like
192
- when :date, :time, :datetime, :timestamp
193
- self.filter = :date
194
- when :boolean
195
- self.filter = :checkbox
191
+ when :enum then self.filter = :enum
192
+ when :float, :decimal then self.filter = :decimal
193
+ when :string, :text then self.filter = :like
194
+ when :date, :time, :datetime, :timestamp then self.filter = :date
195
+ when :boolean then self.filter = :checkbox
196
+ when nil then self.filter = :exact
197
+ else raise "Unknown filter type for #{self.name}: »#{typ}«"
196
198
  end
197
199
  end
198
200
 
@@ -24,15 +24,15 @@
24
24
  class Tabulatr::Renderer
25
25
 
26
26
  def initialize(klass, view,
27
- filter: true, # false for no filter row at all
28
- search: true, # show fuzzy search field
29
- paginate: false, # true to show paginator
30
- pagesize: 20, # default pagesize
31
- sortable: true, # true to allow sorting (can be specified for every sortable column)
32
- batch_actions: false, # :name => value hash of batch action stuff
33
- footer_content: false, # if given, add a <%= content_for <footer_content> %> before the </table>
34
- path: '#', # where to send the AJAX-requests to
35
- order_by: nil, # default order
27
+ filter: true, # false for no filter row at all
28
+ search: true, # show fuzzy search field
29
+ paginate: Tabulatr.paginate, # true to show paginator
30
+ pagesize: 20, # default pagesize
31
+ sortable: true, # true to allow sorting (can be specified for every sortable column)
32
+ batch_actions: false, # :name => value hash of batch action stuff
33
+ footer_content: false, # if given, add a <%= content_for <footer_content> %> before the </table>
34
+ path: '#', # where to send the AJAX-requests to
35
+ order_by: nil, # default order
36
36
  html_class: '',
37
37
  pagination_position: :top,
38
38
  counter_position: :top,
@@ -22,5 +22,5 @@
22
22
  #++
23
23
 
24
24
  module Tabulatr
25
- VERSION = "0.9.16"
25
+ VERSION = "0.9.17"
26
26
  end
data/lib/tabulatr.rb CHANGED
@@ -27,8 +27,10 @@ module Tabulatr
27
27
  end
28
28
 
29
29
  mattr_accessor :spinner
30
+ mattr_accessor :paginate
30
31
 
31
- self.spinner = :standard
32
+ self.spinner = :standard
33
+ self.paginate = false
32
34
  end
33
35
 
34
36
  require 'tabulatr/engine'
@@ -64,4 +66,3 @@ end
64
66
  Dir[File.join(File.dirname(__FILE__), "tabulatr", "renderer", "*.rb")].each do |file|
65
67
  require file
66
68
  end
67
-
@@ -20,7 +20,7 @@ Dummy::Application.configure do
20
20
  # config.action_dispatch.rack_cache = true
21
21
 
22
22
  # Disable Rails's static asset server (Apache or nginx will already do this).
23
- config.serve_static_assets = false
23
+ config.serve_static_files = false
24
24
 
25
25
  # Compress JavaScripts and CSS.
26
26
  config.assets.js_compressor = :uglifier
@@ -13,7 +13,7 @@ Dummy::Application.configure do
13
13
  config.eager_load = false
14
14
 
15
15
  # Configure static asset server for tests with Cache-Control for performance.
16
- config.serve_static_assets = true
16
+ config.serve_static_files = true
17
17
  config.static_cache_control = "public, max-age=3600"
18
18
 
19
19
  # Show full error reports and disable caching.
@@ -21,6 +21,7 @@ en:
21
21
  'no': No
22
22
  enum_filter:
23
23
  none: ''
24
+ batch_confirm_text: This action will be applied to all rows within the current filter
24
25
  de:
25
26
  tabulatr:
26
27
  rows_per_page: 'Ergebnisse pro Seite'
@@ -44,3 +45,4 @@ de:
44
45
  'no': Nein
45
46
  enum_filter:
46
47
  none: ''
48
+ batch_confirm_text: Diese Aktion wird auf allen Datensätzen im aktuallen Filter ausgeführt
@@ -294,6 +294,18 @@ feature "Tabulatr" do
294
294
  end
295
295
  expect(page).to have_css(".tabulatr_table tbody tr", count: 1)
296
296
  end
297
+
298
+ scenario 'executes the action for all items if nothing selected' do
299
+ product1 = Product.create!(:title => names[0], :active => true, :price => 10.0)
300
+ product2 = Product.create!(:title => names[1], :active => true, :price => 10.0)
301
+ product3 = Product.create!(:title => names[2], :active => false, :price => 10.0)
302
+ visit with_batch_actions_products_path
303
+ find('.tabulatr-batch-actions-menu-wrapper a').click
304
+ within('.dropdown.open') do
305
+ click_link 'Delete'
306
+ end
307
+ expect(page).to have_css('.tabulatr_table tbody tr', count: 0)
308
+ end
297
309
  end
298
310
 
299
311
  feature "Column options", js: true do
@@ -33,6 +33,20 @@ describe Tabulatr::Data do
33
33
  expect(r[:products][:title]).to eql titles[ix]
34
34
  end
35
35
  end
36
+
37
+ it 'invokes the batch actions invoker with all ids if no row is selected' do
38
+ Product.create([{title: 'foo', price: 5, active: true}, {title: 'bar', price: 10, active: false}, {title: 'fuzz', price: 7, active: true}])
39
+
40
+ td = Tabulatr::Data.new(Product.where(active: true))
41
+ td.instance_variable_set(:@batch_actions, ->(batch_actions){
42
+ batch_actions.delete do |ids|
43
+ Product.where(id: ids).destroy_all
44
+ end
45
+ })
46
+ td.data_for_table(HashWithIndifferentAccess.new(example_params.merge(product_batch: 'delete', 'tabulatr_checked' => {'checked_ids' => ''})))
47
+ expect(Product.where(active: true).count).to be 0
48
+ expect(Product.count).to be 1
49
+ end
36
50
  end
37
51
 
38
52
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tabulatr2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.16
4
+ version: 0.9.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Horn
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-03-03 00:00:00.000000000 Z
13
+ date: 2015-04-28 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -267,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
267
267
  version: '0'
268
268
  requirements: []
269
269
  rubyforge_project:
270
- rubygems_version: 2.4.5
270
+ rubygems_version: 2.4.6
271
271
  signing_key:
272
272
  specification_version: 4
273
273
  summary: A tight DSL to build tables of ActiveRecord models with sorting, pagination,