active_scaffold_batch_vho 3.0.0
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/.document +5 -0
- data/LICENSE.txt +20 -0
- data/README +0 -0
- data/Rakefile +55 -0
- data/frontends/default/views/_batch_update_form.html.erb +7 -0
- data/frontends/default/views/_batch_update_form_attribute.html.erb +12 -0
- data/frontends/default/views/_batch_update_form_attribute_scope.html.erb +9 -0
- data/frontends/default/views/_batch_update_form_body.html.erb +25 -0
- data/frontends/default/views/batch_update.html.erb +5 -0
- data/frontends/default/views/on_batch_base.js.rjs +6 -0
- data/frontends/default/views/on_batch_update.js.rjs +10 -0
- data/init.rb +9 -0
- data/lib/active_scaffold/actions/batch_base.rb +118 -0
- data/lib/active_scaffold/actions/batch_destroy.rb +72 -0
- data/lib/active_scaffold/actions/batch_update.rb +320 -0
- data/lib/active_scaffold/config/batch_base.rb +11 -0
- data/lib/active_scaffold/config/batch_destroy.rb +54 -0
- data/lib/active_scaffold/config/batch_update.rb +45 -0
- data/lib/active_scaffold/helpers/calendar_date_select_update_column_helpers.rb +33 -0
- data/lib/active_scaffold/helpers/datepicker_update_column_helpers.rb +29 -0
- data/lib/active_scaffold/helpers/update_column_helpers.rb +91 -0
- data/lib/active_scaffold/helpers/view_helpers_override.rb +8 -0
- data/lib/active_scaffold_batch/config/core.rb +10 -0
- data/lib/active_scaffold_batch/version.rb +9 -0
- data/lib/active_scaffold_batch.rb +27 -0
- data/lib/active_scaffold_batch_vho.rb +2 -0
- data/uninstall.rb +1 -0
- metadata +168 -0
data/.document
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 vhochstein
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
require './lib/active_scaffold_batch/version.rb'
|
14
|
+
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "active_scaffold_batch_vho"
|
18
|
+
gem.version = ActiveScaffoldBatch::Version::STRING
|
19
|
+
gem.homepage = "http://github.com/vhochstein/active_scaffold_batch"
|
20
|
+
gem.license = "MIT"
|
21
|
+
gem.summary = %Q{Batch Processing for ActiveScaffold}
|
22
|
+
gem.description = %Q{You want to destroy/update many records at once with activescaffold?}
|
23
|
+
gem.email = "activescaffold@googlegroups.com"
|
24
|
+
gem.authors = ["Volker Hochstein"]
|
25
|
+
gem.add_runtime_dependency 'active_scaffold_vho', '~> 3.0'
|
26
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
27
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
28
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
29
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
30
|
+
end
|
31
|
+
Jeweler::RubygemsDotOrgTasks.new
|
32
|
+
|
33
|
+
require 'rake/testtask'
|
34
|
+
Rake::TestTask.new(:test) do |test|
|
35
|
+
test.libs << 'lib' << 'test'
|
36
|
+
test.pattern = 'test/**/test_*.rb'
|
37
|
+
test.verbose = true
|
38
|
+
end
|
39
|
+
|
40
|
+
require 'rcov/rcovtask'
|
41
|
+
Rcov::RcovTask.new do |test|
|
42
|
+
test.libs << 'test'
|
43
|
+
test.pattern = 'test/**/test_*.rb'
|
44
|
+
test.verbose = true
|
45
|
+
end
|
46
|
+
|
47
|
+
task :default => :test
|
48
|
+
|
49
|
+
require 'rake/rdoctask'
|
50
|
+
Rake::RDocTask.new do |rdoc|
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "active_scaffold_batch #{ActiveScaffoldBatch::Version::STRING}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<%= render :partial => "base_form", :locals => {:xhr => xhr ||= nil,
|
2
|
+
:form_action => form_action ||= :batch_update,
|
3
|
+
:method => method ||= :post,
|
4
|
+
:cancel_link => cancel_link ||= true,
|
5
|
+
:body_partial => 'batch_update_form_body',
|
6
|
+
:headline => headline ||= active_scaffold_config.batch_update.label} %>
|
7
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% scope ||= nil %>
|
2
|
+
<dl>
|
3
|
+
<dt>
|
4
|
+
<label for="<%= active_scaffold_input_options(column, scope)[:id] %>"><%= column.label %></label>
|
5
|
+
</dt>
|
6
|
+
<dd>
|
7
|
+
<%= active_scaffold_update_for column, scope %>
|
8
|
+
<% if column.description -%>
|
9
|
+
<span class="description"><%= column.description %></span>
|
10
|
+
<% end -%>
|
11
|
+
</dd>
|
12
|
+
</dl>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<% subsection_id ||= nil %>
|
2
|
+
<ol class="form" <%= "id=#{subsection_id}" unless subsection_id.nil? %> <%= 'style="display: none;"' if columns.collapsed -%>>
|
3
|
+
<li class="form-element">
|
4
|
+
<%= render :partial => 'batch_update_form_attribute_scope' -%>
|
5
|
+
</li>
|
6
|
+
<% columns.each :for => @record do |column| %>
|
7
|
+
<% next if column.plural_association? || (column.association && [:has_one].include?(column.association.macro)) %>
|
8
|
+
<% renders_as = column_renders_as(column) %>
|
9
|
+
<% if renders_as == :subsection -%>
|
10
|
+
<% subsection_id = sub_section_id(:sub_section => column.label) %>
|
11
|
+
<li class="sub-section">
|
12
|
+
<h5><%= column.label %></h5>
|
13
|
+
<%= render :partial => 'form', :locals => { :columns => column, :subsection_id => subsection_id} %>
|
14
|
+
<%= link_to_visibility_toggle(subsection_id, {:default_visible => !column.collapsed}) -%>
|
15
|
+
</li>
|
16
|
+
<% elsif column.readonly_association?
|
17
|
+
next %>
|
18
|
+
<% else
|
19
|
+
renders_as = :field if renders_as == :subform -%>
|
20
|
+
<li class="form-element <%= column.css_class unless column.css_class.nil? %>">
|
21
|
+
<%= render :partial => 'batch_update_form_attribute', :locals => { :column => column } -%>
|
22
|
+
</li>
|
23
|
+
<% end -%>
|
24
|
+
<% end -%>
|
25
|
+
</ol>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
unless @error_records.empty?
|
2
|
+
flash[:error] = @error_records.collect do |record|
|
3
|
+
active_scaffold_error_messages_for(record, :object_name => "#{record.class.model_name.human.downcase}#{record.new_record? ? '' : ": #{record.to_label}"}", :header_message => '', :message => "#{record.class.model_name.human.downcase}#{record.new_record? ? '' : ": #{record.to_label}"}", :container_tag => nil, :list_type => :br)
|
4
|
+
end.join.html_safe
|
5
|
+
end
|
6
|
+
page.call 'ActiveScaffold.replace_html', active_scaffold_content_id, render(:partial => 'list', :layout => false)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
form_selector = "#{element_form_id(:action => :batch_update)}"
|
2
|
+
|
3
|
+
if controller.send :batch_successful?
|
4
|
+
page.call 'ActiveScaffold.replace_html', active_scaffold_content_id, render(:partial => 'list', :layout => false)
|
5
|
+
page << "ActiveScaffold.find_action_link('#{form_selector}').close();"
|
6
|
+
else
|
7
|
+
page << "ActiveScaffold.find_action_link('#{form_selector}').update_flash_messages('#{escape_javascript(render(:partial => 'messages').strip)}');"
|
8
|
+
page.call 'ActiveScaffold.replace', form_selector, render(:partial => 'batch_update_form', :locals => {:xhr => true})
|
9
|
+
page.call 'ActiveScaffold.scroll_to', form_selector
|
10
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
module BatchBase
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.add_active_scaffold_path File.join(ActiveScaffold::Config::BatchBase.plugin_directory, 'frontends', 'default' , 'views')
|
6
|
+
base.helper_method :batch_scope
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def batch_action(batch_action = :batch_base)
|
12
|
+
process_action_link_action(batch_action) do
|
13
|
+
process_batch
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def process_batch
|
18
|
+
do_batch
|
19
|
+
do_search if respond_to? :do_search
|
20
|
+
do_list
|
21
|
+
end
|
22
|
+
|
23
|
+
def batch_scope
|
24
|
+
if params[:batch_scope]
|
25
|
+
@batch_scope = params[:batch_scope] if ['LISTED', 'MARKED'].include?(params[:batch_scope])
|
26
|
+
params.delete :batch_scope
|
27
|
+
end if @batch_scope.nil?
|
28
|
+
@batch_scope
|
29
|
+
end
|
30
|
+
|
31
|
+
def error_records
|
32
|
+
@error_records ||= []
|
33
|
+
end
|
34
|
+
|
35
|
+
# in case of an error we have to prepare @record object to have assigned all
|
36
|
+
# defined batch_update values, however, do not set those ones with an override
|
37
|
+
# these ones will manage on their own
|
38
|
+
def prepare_error_record
|
39
|
+
end
|
40
|
+
|
41
|
+
def batch_successful?
|
42
|
+
error_records.empty?
|
43
|
+
end
|
44
|
+
|
45
|
+
def do_batch
|
46
|
+
send("before_do_#{action_name}") if respond_to?("before_do_#{action_name}")
|
47
|
+
send("#{action_name}_#{batch_scope.downcase}") if !batch_scope.nil? && respond_to?("#{action_name}_#{batch_scope.downcase}")
|
48
|
+
prepare_error_record unless batch_successful?
|
49
|
+
end
|
50
|
+
|
51
|
+
def authorized_for_job?(record)
|
52
|
+
if record.authorized_for?(:crud_type => active_scaffold_config.send(action_name).crud_type)
|
53
|
+
true
|
54
|
+
else
|
55
|
+
record.errors.add(:base, as_(:no_authorization_for_action, :action => action_name))
|
56
|
+
error_records << record
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def batch_base_respond_to_html
|
62
|
+
if respond_to? "#{action_name}_respond_to_html"
|
63
|
+
send("#{action_name}_respond_to_html")
|
64
|
+
else
|
65
|
+
if params[:iframe]=='true' # was this an iframe post ?
|
66
|
+
responds_to_parent do
|
67
|
+
render :action => 'on_batch_base.js', :layout => false
|
68
|
+
end
|
69
|
+
else # just a regular post
|
70
|
+
if batch_successful?
|
71
|
+
flash[:info] = as_(:batch_processing_successful)
|
72
|
+
end
|
73
|
+
return_to_main
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def batch_base_respond_to_js
|
79
|
+
if respond_to? "#{action_name}_respond_to_js"
|
80
|
+
send("#{action_name}_respond_to_js")
|
81
|
+
else
|
82
|
+
render :action => "on_batch_base"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def batch_base_respond_to_xml
|
87
|
+
if respond_to? "#{action_name}_respond_to_xml"
|
88
|
+
send("#{action_name}_respond_to_xml")
|
89
|
+
else
|
90
|
+
render :xml => response_object.to_xml(:only => active_scaffold_config.send(action_name).columns.names), :content_type => Mime::XML, :status => response_status
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def batch_base_respond_to_json
|
95
|
+
if respond_to? "#{action_name}_respond_to_json"
|
96
|
+
send("#{action_name}_respond_to_json")
|
97
|
+
else
|
98
|
+
render :text => response_object.to_json(:only => active_scaffold_config.send(action_name).columns.names), :content_type => Mime::JSON, :status => response_status
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def batch_base_respond_to_yaml
|
103
|
+
if respond_to? "#{action_name}_respond_to_yaml"
|
104
|
+
send("#{action_name}_respond_to_yaml")
|
105
|
+
else
|
106
|
+
render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.send(action_name).columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def batch_base_formats
|
111
|
+
if respond_to? "#{action_name}_formats"
|
112
|
+
send("#{action_name}_formats")
|
113
|
+
else
|
114
|
+
(default_formats + active_scaffold_config.formats + active_scaffold_config.send(action_name).formats).uniq
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
module BatchDestroy
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.before_filter :batch_destroy_authorized_filter, :only => [:batch_destroy]
|
6
|
+
end
|
7
|
+
|
8
|
+
def batch_destroy
|
9
|
+
batch_action
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def batch_destroy_listed
|
15
|
+
case active_scaffold_config.batch_destroy.process_mode
|
16
|
+
when :delete then
|
17
|
+
each_record_in_scope do |record|
|
18
|
+
destroy_record(record) if authorized_for_job?(record)
|
19
|
+
end
|
20
|
+
when :delete_all then
|
21
|
+
do_search if respond_to? :do_search
|
22
|
+
active_scaffold_config.model.delete_all(all_conditions)
|
23
|
+
else
|
24
|
+
Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_destroy.process_mode} for action batch_destroy")
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def batch_destroy_marked
|
30
|
+
case active_scaffold_config.batch_destroy.process_mode
|
31
|
+
when :delete then
|
32
|
+
active_scaffold_config.model.marked.each do |record|
|
33
|
+
destroy_record(record) if authorized_for_job?(record)
|
34
|
+
end
|
35
|
+
when :delete_all then
|
36
|
+
active_scaffold_config.model.marked.delete_all
|
37
|
+
do_demark_all
|
38
|
+
else
|
39
|
+
Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_destroy.process_mode} for action batch_destroy")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy_record(record)
|
44
|
+
@successful = nil
|
45
|
+
@record = record
|
46
|
+
|
47
|
+
do_destroy
|
48
|
+
if successful?
|
49
|
+
@record.marked = false if batch_scope == 'MARKED'
|
50
|
+
else
|
51
|
+
error_records << @record
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# The default security delegates to ActiveRecordPermissions.
|
56
|
+
# You may override the method to customize.
|
57
|
+
def batch_destroy_authorized?(record = nil)
|
58
|
+
authorized_for?(:crud_type => :delete)
|
59
|
+
end
|
60
|
+
|
61
|
+
def batch_destroy_marked_ignore?(record = nil)
|
62
|
+
!active_scaffold_config.list.columns.include? :marked
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def batch_destroy_authorized_filter
|
68
|
+
link = active_scaffold_config.batch_destroy.link || active_scaffold_config.batch_destroy.class.link
|
69
|
+
raise ActiveScaffold::ActionNotAllowed unless self.send(link.first.security_method)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,320 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
module BatchUpdate
|
3
|
+
|
4
|
+
GenericOperators = [
|
5
|
+
'NO_UPDATE',
|
6
|
+
'REPLACE'
|
7
|
+
]
|
8
|
+
NumericOperators = [
|
9
|
+
'PLUS',
|
10
|
+
'MINUS',
|
11
|
+
'TIMES',
|
12
|
+
'DIVISION'
|
13
|
+
]
|
14
|
+
NumericOptions = [
|
15
|
+
'ABSOLUTE',
|
16
|
+
'PERCENT'
|
17
|
+
]
|
18
|
+
|
19
|
+
DateOperators = [
|
20
|
+
'PLUS',
|
21
|
+
'MINUS'
|
22
|
+
]
|
23
|
+
|
24
|
+
def self.included(base)
|
25
|
+
base.before_filter :batch_update_authorized_filter, :only => [:batch_edit, :batch_update]
|
26
|
+
base.verify :method => [:post, :put],
|
27
|
+
:only => :batch_update,
|
28
|
+
:redirect_to => { :action => :index }
|
29
|
+
base.helper_method :batch_update_values
|
30
|
+
end
|
31
|
+
|
32
|
+
def batch_edit
|
33
|
+
do_batch_edit
|
34
|
+
respond_to_action(:batch_edit)
|
35
|
+
end
|
36
|
+
|
37
|
+
def batch_update
|
38
|
+
batch_action
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
protected
|
43
|
+
def batch_edit_respond_to_html
|
44
|
+
if batch_successful?
|
45
|
+
render(:action => 'batch_update')
|
46
|
+
else
|
47
|
+
return_to_main
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def batch_edit_respond_to_js
|
52
|
+
render(:partial => 'batch_update_form')
|
53
|
+
end
|
54
|
+
|
55
|
+
def selected_columns
|
56
|
+
if @selected_columns.nil?
|
57
|
+
@selected_columns = []
|
58
|
+
if params[:record] && params[:record].is_a?(Hash)
|
59
|
+
params[:record].each do |key, value|
|
60
|
+
@selected_columns << key.to_sym if value[:operator] != 'NO_UPDATE'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
@selected_columns
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def batch_update_values
|
69
|
+
@batch_update_values || {}
|
70
|
+
end
|
71
|
+
|
72
|
+
def batch_update_respond_to_html
|
73
|
+
if params[:iframe]=='true' # was this an iframe post ?
|
74
|
+
responds_to_parent do
|
75
|
+
render :action => 'on_batch_update.js', :layout => false
|
76
|
+
end
|
77
|
+
else # just a regular post
|
78
|
+
if batch_successful?
|
79
|
+
flash[:info] = as_(:updated_model, :model => @record.to_label)
|
80
|
+
return_to_main
|
81
|
+
else
|
82
|
+
render(:action => 'batch_update')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def batch_update_respond_to_js
|
88
|
+
render :action => 'on_batch_update'
|
89
|
+
end
|
90
|
+
|
91
|
+
def do_batch_edit
|
92
|
+
self.successful = true
|
93
|
+
do_new
|
94
|
+
end
|
95
|
+
|
96
|
+
def before_do_batch_update
|
97
|
+
update_columns = active_scaffold_config.batch_update.columns
|
98
|
+
@batch_update_values = attribute_values_from_params(update_columns, params[:record])
|
99
|
+
end
|
100
|
+
|
101
|
+
# in case of an error we have to prepare @record object to have assigned all
|
102
|
+
# defined batch_update values, however, do not set those ones with an override
|
103
|
+
# these ones will manage on their own
|
104
|
+
def prepare_error_record
|
105
|
+
do_new
|
106
|
+
batch_update_values.each do |attribute, value|
|
107
|
+
form_ui = colunm_form_ui(value[:column])
|
108
|
+
set_record_attribute(value[:column], attribute, value[:value]) unless form_ui && override_batch_update_value?(form_ui)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def batch_update_listed
|
113
|
+
case active_scaffold_config.batch_update.process_mode
|
114
|
+
when :update then
|
115
|
+
each_record_in_scope {|record| update_record(record) if authorized_for_job?(record)}
|
116
|
+
when :update_all then
|
117
|
+
updates = updates_for_update_all
|
118
|
+
unless updates.first.empty?
|
119
|
+
do_search if respond_to? :do_search
|
120
|
+
# all_conditions might fail cause joins are not working in update_all
|
121
|
+
active_scaffold_config.model.update_all(updates, all_conditions)
|
122
|
+
end
|
123
|
+
else
|
124
|
+
Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_update.process_mode} for action batch_update")
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
def batch_update_marked
|
130
|
+
case active_scaffold_config.batch_update.process_mode
|
131
|
+
when :update then
|
132
|
+
active_scaffold_config.model.marked.each {|record| update_record(record) if authorized_for_job?(record)}
|
133
|
+
when :update_all then
|
134
|
+
updates = updates_for_update_all
|
135
|
+
unless updates.first.empty?
|
136
|
+
active_scaffold_config.model.marked.update_all(updates)
|
137
|
+
do_demark_all
|
138
|
+
end
|
139
|
+
else
|
140
|
+
Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_update.process_mode} for action batch_update")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def updates_for_update_all()
|
145
|
+
update_all = [[]]
|
146
|
+
batch_update_values.each do |attribute, value|
|
147
|
+
sql_set, value = get_update_all_attribute(value[:column], attribute, value[:value])
|
148
|
+
unless sql_set.nil?
|
149
|
+
update_all.first << sql_set
|
150
|
+
update_all << value if sql_set.include?('?')
|
151
|
+
end
|
152
|
+
end
|
153
|
+
update_all[0] = update_all.first.join(',')
|
154
|
+
update_all
|
155
|
+
end
|
156
|
+
|
157
|
+
def update_record(record)
|
158
|
+
@successful = nil
|
159
|
+
@record = record
|
160
|
+
|
161
|
+
batch_update_values.each do |attribute, value|
|
162
|
+
set_record_attribute(value[:column], attribute, value[:value])
|
163
|
+
end
|
164
|
+
|
165
|
+
update_save
|
166
|
+
if successful?
|
167
|
+
@record.marked = false if batch_scope == 'MARKED'
|
168
|
+
else
|
169
|
+
error_records << @record
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def set_record_attribute(column, attribute, value)
|
174
|
+
form_ui = colunm_form_ui(column)
|
175
|
+
if form_ui && override_batch_update_value?(form_ui)
|
176
|
+
@record.send("#{attribute}=", send(override_batch_update_value(form_ui), column, @record, value))
|
177
|
+
else
|
178
|
+
@record.send("#{attribute}=", value[:operator] == 'NULL' ? nil : value[:value])
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def colunm_form_ui(column)
|
183
|
+
form_ui = column.form_ui
|
184
|
+
form_ui = column.column.type if form_ui.nil? && column.column
|
185
|
+
end
|
186
|
+
|
187
|
+
def get_update_all_attribute(column, attribute, value)
|
188
|
+
form_ui = column.form_ui
|
189
|
+
form_ui = column.column.type if form_ui.nil? && column.column
|
190
|
+
|
191
|
+
if form_ui && override_batch_update_all_value?(form_ui)
|
192
|
+
update_value = send(override_batch_update_all_value(form_ui), column, value)
|
193
|
+
if update_value.nil?
|
194
|
+
sql_set = nil
|
195
|
+
else
|
196
|
+
sql_set = "#{attribute} = #{update_value}"
|
197
|
+
update_value = nil
|
198
|
+
end
|
199
|
+
else
|
200
|
+
sql_set = "#{attribute} = ?"
|
201
|
+
update_value = value[:operator] == 'NULL' ? nil : value[:value]
|
202
|
+
end
|
203
|
+
|
204
|
+
return sql_set, update_value
|
205
|
+
end
|
206
|
+
|
207
|
+
def attribute_values_from_params(columns, attributes)
|
208
|
+
values = {}
|
209
|
+
columns.each :for => active_scaffold_config.model.new, :crud_type => :update, :flatten => true do |column|
|
210
|
+
values[column.name] = {:column => column, :value => attributes[column.name].merge(:value => column_value_from_param_value(nil, column, attributes[column.name][:value]))} if selected_columns.include? column.name
|
211
|
+
end
|
212
|
+
values
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
# The default security delegates to ActiveRecordPermissions.
|
217
|
+
# You may override the method to customize.
|
218
|
+
def batch_update_authorized?(record = nil)
|
219
|
+
authorized_for?(:crud_type => :update)
|
220
|
+
end
|
221
|
+
|
222
|
+
def batch_update_value_for_numeric(column, record, calculation_info)
|
223
|
+
current_value = record.send(column.name)
|
224
|
+
if ActiveScaffold::Actions::BatchUpdate::GenericOperators.include?(calculation_info[:operator]) || ActiveScaffold::Actions::BatchUpdate::NumericOperators.include?(calculation_info[:operator])
|
225
|
+
operand = self.class.condition_value_for_numeric(column, calculation_info[:value])
|
226
|
+
operand = current_value / 100 * operand if calculation_info[:opt] == 'PERCENT'
|
227
|
+
case calculation_info[:operator]
|
228
|
+
when 'REPLACE' then operand
|
229
|
+
when 'NULL' then nil
|
230
|
+
when 'PLUS' then current_value.present? ? current_value + operand : nil
|
231
|
+
when 'MINUS' then current_value.present? ? current_value - operand : nil
|
232
|
+
when 'TIMES' then current_value.present? ? current_value * operand : nil
|
233
|
+
when 'DIVISION' then current_value.present? ? current_value / operand : nil
|
234
|
+
else
|
235
|
+
current_value
|
236
|
+
end
|
237
|
+
else
|
238
|
+
current_value
|
239
|
+
end
|
240
|
+
end
|
241
|
+
alias_method :batch_update_value_for_integer, :batch_update_value_for_numeric
|
242
|
+
alias_method :batch_update_value_for_decimal, :batch_update_value_for_numeric
|
243
|
+
alias_method :batch_update_value_for_float, :batch_update_value_for_numeric
|
244
|
+
|
245
|
+
def batch_update_all_value_for_numeric(column, calculation_info)
|
246
|
+
if ActiveScaffold::Actions::BatchUpdate::GenericOperators.include?(calculation_info[:operator]) || ActiveScaffold::Actions::BatchUpdate::NumericOperators.include?(calculation_info[:operator])
|
247
|
+
operand = active_scaffold_config.model.quote_value(self.class.condition_value_for_numeric(column, calculation_info[:value]))
|
248
|
+
if calculation_info[:opt] == 'PERCENT'#
|
249
|
+
operand = "#{active_scaffold_config.model.connection.quote_column_name(column.name)} / 100.0 * #{operand}"
|
250
|
+
end
|
251
|
+
case calculation_info[:operator]
|
252
|
+
when 'REPLACE' then operand
|
253
|
+
when 'NULL' then active_scaffold_config.model.quote_value(nil)
|
254
|
+
when 'PLUS' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} + #{operand}"
|
255
|
+
when 'MINUS' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} - #{operand}"
|
256
|
+
when 'TIMES' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} * #{operand}"
|
257
|
+
when 'DIVISION' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} / #{operand}"
|
258
|
+
else
|
259
|
+
nil
|
260
|
+
end
|
261
|
+
else
|
262
|
+
nil
|
263
|
+
end
|
264
|
+
end
|
265
|
+
alias_method :batch_update_all_value_for_integer, :batch_update_all_value_for_numeric
|
266
|
+
alias_method :batch_update_all_value_for_decimal, :batch_update_all_value_for_numeric
|
267
|
+
alias_method :batch_update_all_value_for_float, :batch_update_all_value_for_numeric
|
268
|
+
|
269
|
+
def batch_update_value_for_date_picker(column, record, calculation_info)
|
270
|
+
current_value = record.send(column.name)
|
271
|
+
{"number"=>"", "unit"=>"DAYS", "value"=>"November 16, 2010", "operator"=>"REPLACE"}
|
272
|
+
if ActiveScaffold::Actions::BatchUpdate::GenericOperators.include?(calculation_info[:operator]) || ActiveScaffold::Actions::BatchUpdate::DateOperators.include?(calculation_info[:operator])
|
273
|
+
operand = self.class.condition_value_for_datetime(calculation_info[:value], column.column.type == :date ? :to_date : :to_time)
|
274
|
+
case calculation_info[:operator]
|
275
|
+
when 'REPLACE' then operand
|
276
|
+
when 'NULL' then nil
|
277
|
+
when 'PLUS' then
|
278
|
+
trend_number = [calculation_info['number'].to_i, 1].max
|
279
|
+
current_value.in((trend_number).send(calculation_info['unit'].downcase.singularize.to_sym))
|
280
|
+
when 'MINUS' then
|
281
|
+
trend_number = [calculation_info['number'].to_i, 1].max
|
282
|
+
current_value.ago((trend_number).send(calculation_info['unit'].downcase.singularize.to_sym))
|
283
|
+
else
|
284
|
+
current_value
|
285
|
+
end
|
286
|
+
else
|
287
|
+
current_value
|
288
|
+
end
|
289
|
+
end
|
290
|
+
alias_method :batch_update_value_for_calendar_date_select, :batch_update_value_for_date_picker
|
291
|
+
|
292
|
+
|
293
|
+
|
294
|
+
def override_batch_update_value?(form_ui)
|
295
|
+
respond_to?(override_batch_update_value(form_ui))
|
296
|
+
end
|
297
|
+
|
298
|
+
def override_batch_update_value(form_ui)
|
299
|
+
"batch_update_value_for_#{form_ui}"
|
300
|
+
end
|
301
|
+
|
302
|
+
def override_batch_update_all_value?(form_ui)
|
303
|
+
respond_to?(override_batch_update_all_value(form_ui))
|
304
|
+
end
|
305
|
+
|
306
|
+
def override_batch_update_all_value(form_ui)
|
307
|
+
"batch_update_all_value_for_#{form_ui}"
|
308
|
+
end
|
309
|
+
|
310
|
+
private
|
311
|
+
|
312
|
+
def batch_update_authorized_filter
|
313
|
+
link = active_scaffold_config.batch_update.link || active_scaffold_config.batch_update.class.link
|
314
|
+
raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
|
315
|
+
end
|
316
|
+
def batch_edit_formats
|
317
|
+
(default_formats + active_scaffold_config.formats).uniq
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module ActiveScaffold::Config
|
2
|
+
class BatchBase < ActiveScaffold::Config::Base
|
3
|
+
def initialize(core_config)
|
4
|
+
@core = core_config
|
5
|
+
end
|
6
|
+
|
7
|
+
# configures where the plugin itself is located. there is no instance version of this.
|
8
|
+
cattr_accessor :plugin_directory
|
9
|
+
@@plugin_directory = File.expand_path(__FILE__).match(%{(^.*)/lib/active_scaffold/config/batch_base.rb})[1]
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module ActiveScaffold::Config
|
2
|
+
class BatchDestroy < ActiveScaffold::Config::Base
|
3
|
+
self.crud_type = :delete
|
4
|
+
|
5
|
+
def initialize(core_config)
|
6
|
+
@core = core_config
|
7
|
+
|
8
|
+
# start with the ActionLink defined globally
|
9
|
+
@link = self.class.link
|
10
|
+
@action_group = self.class.action_group.clone if self.class.action_group
|
11
|
+
@action_group ||= 'collection.batch.destroy'
|
12
|
+
@process_mode = self.class.process_mode
|
13
|
+
end
|
14
|
+
|
15
|
+
# global level configuration
|
16
|
+
# --------------------------
|
17
|
+
# the ActionLink for this action
|
18
|
+
def self.link
|
19
|
+
@@link
|
20
|
+
end
|
21
|
+
def self.link=(val)
|
22
|
+
@@link = val
|
23
|
+
end
|
24
|
+
@@link = [ ActiveScaffold::DataStructures::ActionLink.new('batch_destroy', :label => :listed, :type => :collection, :method => :delete, :position => false, :crud_type => :delete, :confirm => :are_you_sure_to_delete, :parameters => {:batch_scope => 'LISTED'},:security_method => :batch_destroy_authorized?),
|
25
|
+
ActiveScaffold::DataStructures::ActionLink.new('batch_destroy', :label => :marked, :type => :collection, :method => :delete, :position => false, :crud_type => :delete, :confirm => :are_you_sure_to_delete, :parameters => {:batch_scope => 'MARKED'}, :security_method => :batch_destroy_authorized?, :ignore_method => :batch_destroy_marked_ignore?)]
|
26
|
+
|
27
|
+
# configures where the plugin itself is located. there is no instance version of this.
|
28
|
+
cattr_accessor :plugin_directory
|
29
|
+
@@plugin_directory = File.expand_path(__FILE__).match(/vendor\/plugins\/([^\/]*)/)[1]
|
30
|
+
|
31
|
+
# configures how batch updates should be processed
|
32
|
+
# :delete => standard activerecord delete including validations
|
33
|
+
# :delete_all => updating in one sql call without activerecord instantiation and validation
|
34
|
+
cattr_accessor :process_mode
|
35
|
+
@@process_mode = :delete
|
36
|
+
|
37
|
+
|
38
|
+
# instance-level configuration
|
39
|
+
# ----------------------------
|
40
|
+
|
41
|
+
# see class accessor
|
42
|
+
attr_accessor :process_mode
|
43
|
+
|
44
|
+
# the ActionLink for this action
|
45
|
+
attr_accessor :link
|
46
|
+
|
47
|
+
# the label= method already exists in the Form base class
|
48
|
+
def label(model = nil)
|
49
|
+
model ||= @core.label(:count => 2)
|
50
|
+
@label ? as_(@label) : as_(:deleted_model, :model => model)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActiveScaffold::Config
|
2
|
+
class BatchUpdate < ActiveScaffold::Config::Form
|
3
|
+
self.crud_type = :update
|
4
|
+
def initialize(*args)
|
5
|
+
super
|
6
|
+
@process_mode = self.class.process_mode
|
7
|
+
@action_group ||= 'collection.batch'
|
8
|
+
end
|
9
|
+
|
10
|
+
# global level configuration
|
11
|
+
# --------------------------
|
12
|
+
# the ActionLink for this action
|
13
|
+
def self.link
|
14
|
+
@@link
|
15
|
+
end
|
16
|
+
def self.link=(val)
|
17
|
+
@@link = val
|
18
|
+
end
|
19
|
+
@@link = ActiveScaffold::DataStructures::ActionLink.new('batch_edit', :label => :edit, :type => :collection, :security_method => :batch_update_authorized?)
|
20
|
+
|
21
|
+
# configures where the plugin itself is located. there is no instance version of this.
|
22
|
+
cattr_accessor :plugin_directory
|
23
|
+
@@plugin_directory = File.expand_path(__FILE__).match(/vendor\/plugins\/([^\/]*)/)[1]
|
24
|
+
|
25
|
+
# configures how batch updates should be processed
|
26
|
+
# :update => standard activerecord update including validations
|
27
|
+
# :update_all => updating in one sql call without activerecord instantiation and validation
|
28
|
+
cattr_accessor :process_mode
|
29
|
+
@@process_mode = :update
|
30
|
+
|
31
|
+
|
32
|
+
# instance-level configuration
|
33
|
+
# ----------------------------
|
34
|
+
|
35
|
+
# see class accessor
|
36
|
+
attr_accessor :process_mode
|
37
|
+
|
38
|
+
|
39
|
+
# the label= method already exists in the Form base class
|
40
|
+
def label(model = nil)
|
41
|
+
model ||= @core.label(:count => 2)
|
42
|
+
@label ? as_(@label) : as_(:update_model, :model => model)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ActiveScaffold
|
2
|
+
module Helpers
|
3
|
+
module CalendarDateSelectUpdateColumnHelpers
|
4
|
+
def active_scaffold_update_calendar_date_select(column, options)
|
5
|
+
current_params = {:value => nil, :number => nil, :unit => nil, :operator => 'NO_UPDATE'}
|
6
|
+
current_params.merge!(batch_update_values[column.name][:value].symbolize_keys) if batch_update_values[column.name] && batch_update_values[column.name][:value]
|
7
|
+
Rails.logger.info("update_date column: #{column.name}: #{current_params[:value].inspect}, class: #{current_params[:value].class}")
|
8
|
+
Rails.logger.info("update_date column: #{column.name}: options #{options.inspect}")
|
9
|
+
current_params[:value] = nil if current_params[:value].is_a?(String)
|
10
|
+
Rails.logger.info("update_date2 column: #{column.name}: #{current_params[:value].inspect}, class: #{current_params[:value].class}")
|
11
|
+
operator_options = active_scaffold_update_generic_operators(column)
|
12
|
+
operator_options.concat(ActiveScaffold::Actions::BatchUpdate::DateOperators.collect {|comp| [as_(comp.downcase.to_sym), comp]}) if active_scaffold_config.batch_update.process_mode == :update
|
13
|
+
options = options.merge(:show => ['PLUS', 'MINUS'].exclude?(current_params[:operator]))
|
14
|
+
tags = []
|
15
|
+
tags << select_tag("[record][#{column.name}][operator]",
|
16
|
+
options_for_select(operator_options, current_params[:operator]),
|
17
|
+
:id => "#{options[:id]}_operator",
|
18
|
+
:class => "text-input as_update_date_operator")
|
19
|
+
tags << active_scaffold_search_date_bridge_calendar_control(column, options, current_params[:value], 'value')
|
20
|
+
tags << active_scaffold_update_date_bridge_trend_tag(column, current_params, options)
|
21
|
+
tags.join(" ").html_safe
|
22
|
+
end
|
23
|
+
|
24
|
+
def active_scaffold_update_date_bridge_trend_tag(column, current_params, options)
|
25
|
+
active_scaffold_date_bridge_trend_tag(column, options,
|
26
|
+
{:name_prefix => '[record]',
|
27
|
+
:number_value => current_params[:number],
|
28
|
+
:unit_value => current_params[:unit],
|
29
|
+
:show => ['PLUS','MINUS'].include?(current_params[:operator])})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ActiveScaffold
|
2
|
+
module Helpers
|
3
|
+
module DatepickerUpdateColumnHelpers
|
4
|
+
def active_scaffold_update_date_picker(column, options)
|
5
|
+
current_params = {:value => nil, :number => nil, :unit => nil, :operator => 'NO_UPDATE'}
|
6
|
+
current_params.merge!(batch_update_values[column.name][:value].symbolize_keys) if batch_update_values[column.name] && batch_update_values[column.name][:value]
|
7
|
+
operator_options = active_scaffold_update_generic_operators(column)
|
8
|
+
operator_options.concat(ActiveScaffold::Actions::BatchUpdate::DateOperators.collect {|comp| [as_(comp.downcase.to_sym), comp]}) if active_scaffold_config.batch_update.process_mode == :update
|
9
|
+
options = options.merge(:show => ['PLUS', 'MINUS'].exclude?(current_params[:operator]))
|
10
|
+
tags = []
|
11
|
+
tags << select_tag("[record][#{column.name}][operator]",
|
12
|
+
options_for_select(operator_options, current_params[:operator]),
|
13
|
+
:id => "#{options[:id]}_operator",
|
14
|
+
:class => "text-input as_update_date_operator")
|
15
|
+
tags << active_scaffold_search_date_bridge_calendar_control(column, options, current_params[:value], 'value')
|
16
|
+
tags << active_scaffold_update_date_bridge_trend_tag(column, current_params, options)
|
17
|
+
tags.join(" ").html_safe
|
18
|
+
end
|
19
|
+
|
20
|
+
def active_scaffold_update_date_bridge_trend_tag(column, current_params, options)
|
21
|
+
active_scaffold_date_bridge_trend_tag(column, options,
|
22
|
+
{:name_prefix => '[record]',
|
23
|
+
:number_value => current_params[:number],
|
24
|
+
:unit_value => current_params[:unit],
|
25
|
+
:show => ['PLUS','MINUS'].include?(current_params[:operator])})
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module ActiveScaffold
|
2
|
+
module Helpers
|
3
|
+
# Helpers that assist with the rendering of a Form Column
|
4
|
+
module UpdateColumnHelpers
|
5
|
+
# This method decides which input to use for the given column.
|
6
|
+
# It does not do any rendering. It only decides which method is responsible for rendering.
|
7
|
+
def active_scaffold_update_for(column, scope = nil, options = {})
|
8
|
+
options = active_scaffold_input_options(column, scope, options)
|
9
|
+
|
10
|
+
# first, check if the dev has created an override for this specific field for search
|
11
|
+
if override_update_field?(column)
|
12
|
+
send(override_update_field(column), @record, options)
|
13
|
+
# second, check if the dev has specified a valid form_ui for this column, using specific ui for searches
|
14
|
+
elsif column.form_ui and override_update?(column.form_ui)
|
15
|
+
send(override_update(column.form_ui), column, options)
|
16
|
+
elsif column.column and override_update?(column.column.type)
|
17
|
+
send(override_update(column.column.type), column, options)
|
18
|
+
else
|
19
|
+
active_scaffold_update_generic_operators_select(column, options)<< ' ' << active_scaffold_render_input(column, options.merge(:name => "record[#{column.name}][value]"))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def active_scaffold_update_generic_operators(column)
|
24
|
+
operators = ActiveScaffold::Actions::BatchUpdate::GenericOperators.collect {|comp| [as_(comp.downcase.to_sym), comp]}
|
25
|
+
if column.column.nil? || column.column.null
|
26
|
+
operators << [as_(:null), 'NULL']
|
27
|
+
end
|
28
|
+
operators
|
29
|
+
end
|
30
|
+
|
31
|
+
def active_scaffold_update_generic_operators_select(column, options)
|
32
|
+
current = {:operator => 'NO_UPDATE'}
|
33
|
+
current.merge!(batch_update_values[column.name][:value].symbolize_keys) if batch_update_values[column.name] && batch_update_values[column.name][:value]
|
34
|
+
select_tag("[record][#{column.name}][operator]",
|
35
|
+
options_for_select(active_scaffold_update_generic_operators(column), current[:operator]),
|
36
|
+
:id => "#{options[:id]}_operator",
|
37
|
+
:class => "as_batch_update_operator text_input")
|
38
|
+
end
|
39
|
+
|
40
|
+
def active_scaffold_update_numeric(column, options)
|
41
|
+
current = {:value => nil, :opt => 'ABSOLUTE', :operator => 'NO_UPDATE'}
|
42
|
+
current.merge!(batch_update_values[column.name][:value].symbolize_keys) if batch_update_values[column.name] && batch_update_values[column.name][:value]
|
43
|
+
operator_options = active_scaffold_update_generic_operators(column) + ActiveScaffold::Actions::BatchUpdate::NumericOperators.collect {|comp| [as_(comp.downcase.to_sym), comp]}
|
44
|
+
select_options = ActiveScaffold::Actions::BatchUpdate::NumericOptions.collect {|comp| [as_(comp.downcase.to_sym), comp]}
|
45
|
+
html = select_tag("[record][#{column.name}][operator]",
|
46
|
+
options_for_select(operator_options, current[:operator]),
|
47
|
+
:id => "#{options[:id]}_operator",
|
48
|
+
:class => "as_update_numeric_option")
|
49
|
+
html << ' ' << text_field_tag("[record][#{column.name}][value]", current[:value], active_scaffold_input_text_options)
|
50
|
+
html << ' ' << select_tag("[record][#{column.name}][opt]",
|
51
|
+
options_for_select(select_options, current[:opt]),
|
52
|
+
:id => "#{options[:id]}_opt",
|
53
|
+
:class => "as_update_numeric_option")
|
54
|
+
html
|
55
|
+
end
|
56
|
+
alias_method :active_scaffold_update_integer, :active_scaffold_update_numeric
|
57
|
+
alias_method :active_scaffold_update_decimal, :active_scaffold_update_numeric
|
58
|
+
alias_method :active_scaffold_update_float, :active_scaffold_update_numeric
|
59
|
+
|
60
|
+
def active_scaffold_update_scope_select
|
61
|
+
select_options = [[as_(:listed), 'LISTED']]
|
62
|
+
select_options << [as_(:marked), 'MARKED'] if active_scaffold_config.actions.include?(:mark)
|
63
|
+
select_tag("batch_scope",
|
64
|
+
options_for_select(select_options, batch_scope || select_options.last[1]),
|
65
|
+
:class => "text_input")
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
## Search column override signatures
|
70
|
+
##
|
71
|
+
|
72
|
+
def override_update_field?(column)
|
73
|
+
respond_to?(override_update_field(column))
|
74
|
+
end
|
75
|
+
|
76
|
+
# the naming convention for overriding form fields with helpers
|
77
|
+
def override_update_field(column)
|
78
|
+
"#{column.name}_update_column"
|
79
|
+
end
|
80
|
+
|
81
|
+
def override_update?(update_ui)
|
82
|
+
respond_to?(override_update(update_ui))
|
83
|
+
end
|
84
|
+
|
85
|
+
# the naming convention for overriding search input types with helpers
|
86
|
+
def override_update(update_ui)
|
87
|
+
"active_scaffold_update_#{update_ui}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
ActionView::Base.class_eval do
|
2
|
+
include ActiveScaffold::Helpers::UpdateColumnHelpers
|
3
|
+
if ActiveScaffold.js_framework == :jquery
|
4
|
+
include ActiveScaffold::Helpers::DatepickerUpdateColumnHelpers
|
5
|
+
elsif ActiveScaffold.js_framework == :prototype
|
6
|
+
include ActiveScaffold::Helpers::CalendarDateSelectUpdateColumnHelpers
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Need to open the AS module carefully due to Rails 2.3 lazy loading
|
2
|
+
ActiveScaffold::Config::Core.class_eval do
|
3
|
+
ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection][:batch_edit] = :get
|
4
|
+
ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection][:batch_update] = :post
|
5
|
+
#not working because routing picks show route instead
|
6
|
+
#ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection][:batch_destroy] = :get
|
7
|
+
#you may define a route for your controller before resource routes
|
8
|
+
#match 'players/batch_destroy' => 'players#batch_destroy', :via => [:get]
|
9
|
+
ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection][:batch_destroy] = :delete
|
10
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Make sure that ActiveScaffold has already been included
|
2
|
+
ActiveScaffold rescue throw "should have included ActiveScaffold plug in first. Please make sure that this overwrite plugging comes alphabetically after the ActiveScaffold plug in"
|
3
|
+
|
4
|
+
# Load our overrides
|
5
|
+
require "#{File.dirname(__FILE__)}/active_scaffold_batch/config/core.rb"
|
6
|
+
require "#{File.dirname(__FILE__)}/active_scaffold/config/batch_update.rb"
|
7
|
+
require "#{File.dirname(__FILE__)}/active_scaffold/actions/batch_update.rb"
|
8
|
+
require "#{File.dirname(__FILE__)}/active_scaffold/helpers/view_helpers_override.rb"
|
9
|
+
|
10
|
+
module ActiveScaffoldBatch
|
11
|
+
def self.root
|
12
|
+
File.dirname(__FILE__) + "/.."
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
##
|
18
|
+
## Run the install assets script, too, just to make sure
|
19
|
+
## But at least rescue the action in production
|
20
|
+
##
|
21
|
+
Rails::Application.initializer("active_scaffold_batch.install_assets") do
|
22
|
+
begin
|
23
|
+
ActiveScaffoldAssets.copy_to_public(ActiveScaffoldBatch.root)
|
24
|
+
rescue
|
25
|
+
raise $! unless Rails.env == 'production'
|
26
|
+
end
|
27
|
+
end unless defined?(ACTIVE_SCAFFOLD_BATCH_INSTALLED) && ACTIVE_SCAFFOLD_BATCH_INSTALLED == :plugin
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# see active_scaffold/uninstall.rb
|
metadata
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_scaffold_batch_vho
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 7
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 3.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Volker Hochstein
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-26 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
prerelease: false
|
23
|
+
name: shoulda
|
24
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
requirement: *id001
|
34
|
+
type: :development
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
prerelease: false
|
37
|
+
name: bundler
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 23
|
44
|
+
segments:
|
45
|
+
- 1
|
46
|
+
- 0
|
47
|
+
- 0
|
48
|
+
version: 1.0.0
|
49
|
+
requirement: *id002
|
50
|
+
type: :development
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
prerelease: false
|
53
|
+
name: jeweler
|
54
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 7
|
60
|
+
segments:
|
61
|
+
- 1
|
62
|
+
- 5
|
63
|
+
- 2
|
64
|
+
version: 1.5.2
|
65
|
+
requirement: *id003
|
66
|
+
type: :development
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
prerelease: false
|
69
|
+
name: rcov
|
70
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
requirement: *id004
|
80
|
+
type: :development
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
prerelease: false
|
83
|
+
name: active_scaffold_vho
|
84
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 7
|
90
|
+
segments:
|
91
|
+
- 3
|
92
|
+
- 0
|
93
|
+
version: "3.0"
|
94
|
+
requirement: *id005
|
95
|
+
type: :runtime
|
96
|
+
description: You want to destroy/update many records at once with activescaffold?
|
97
|
+
email: activescaffold@googlegroups.com
|
98
|
+
executables: []
|
99
|
+
|
100
|
+
extensions: []
|
101
|
+
|
102
|
+
extra_rdoc_files:
|
103
|
+
- LICENSE.txt
|
104
|
+
- README
|
105
|
+
files:
|
106
|
+
- .document
|
107
|
+
- LICENSE.txt
|
108
|
+
- README
|
109
|
+
- Rakefile
|
110
|
+
- frontends/default/views/_batch_update_form.html.erb
|
111
|
+
- frontends/default/views/_batch_update_form_attribute.html.erb
|
112
|
+
- frontends/default/views/_batch_update_form_attribute_scope.html.erb
|
113
|
+
- frontends/default/views/_batch_update_form_body.html.erb
|
114
|
+
- frontends/default/views/batch_update.html.erb
|
115
|
+
- frontends/default/views/on_batch_base.js.rjs
|
116
|
+
- frontends/default/views/on_batch_update.js.rjs
|
117
|
+
- init.rb
|
118
|
+
- lib/active_scaffold/actions/batch_base.rb
|
119
|
+
- lib/active_scaffold/actions/batch_destroy.rb
|
120
|
+
- lib/active_scaffold/actions/batch_update.rb
|
121
|
+
- lib/active_scaffold/config/batch_base.rb
|
122
|
+
- lib/active_scaffold/config/batch_destroy.rb
|
123
|
+
- lib/active_scaffold/config/batch_update.rb
|
124
|
+
- lib/active_scaffold/helpers/calendar_date_select_update_column_helpers.rb
|
125
|
+
- lib/active_scaffold/helpers/datepicker_update_column_helpers.rb
|
126
|
+
- lib/active_scaffold/helpers/update_column_helpers.rb
|
127
|
+
- lib/active_scaffold/helpers/view_helpers_override.rb
|
128
|
+
- lib/active_scaffold_batch.rb
|
129
|
+
- lib/active_scaffold_batch/config/core.rb
|
130
|
+
- lib/active_scaffold_batch/version.rb
|
131
|
+
- lib/active_scaffold_batch_vho.rb
|
132
|
+
- uninstall.rb
|
133
|
+
has_rdoc: true
|
134
|
+
homepage: http://github.com/vhochstein/active_scaffold_batch
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
none: false
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
hash: 3
|
148
|
+
segments:
|
149
|
+
- 0
|
150
|
+
version: "0"
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
none: false
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
hash: 3
|
157
|
+
segments:
|
158
|
+
- 0
|
159
|
+
version: "0"
|
160
|
+
requirements: []
|
161
|
+
|
162
|
+
rubyforge_project:
|
163
|
+
rubygems_version: 1.3.7
|
164
|
+
signing_key:
|
165
|
+
specification_version: 3
|
166
|
+
summary: Batch Processing for ActiveScaffold
|
167
|
+
test_files: []
|
168
|
+
|