tabulatr2 0.9.16 → 0.9.17

Sign up to get free protection for your applications and to get access to all the features.
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,