kono_utils 0.15.5
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +442 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/kono_utils/utilities.coffee +456 -0
- data/app/assets/stylesheets/kono_utils/utils.css.scss +43 -0
- data/app/controllers/kono_utils/change_log_controller.rb +6 -0
- data/app/input/bs_aceeditor_input.rb +53 -0
- data/app/input/bs_autocomplete_input.rb +60 -0
- data/app/input/bs_datepicker_input.rb +16 -0
- data/app/input/bs_datetimepicker_input.rb +80 -0
- data/app/input/bs_file_download_input.rb +35 -0
- data/app/input/bs_image_input.rb +35 -0
- data/app/input/bs_label_with_container_input.rb +22 -0
- data/app/input/bs_location_picker_input.rb +95 -0
- data/app/input/bs_readonly_input.rb +52 -0
- data/app/input/bs_timepicker_input.rb +14 -0
- data/app/policies/kono_utils/base_editing_policy_concern.rb +27 -0
- data/app/views/kono_utils/base_editing/_edit.html.erb +3 -0
- data/app/views/kono_utils/base_editing/_edit_page_side_title_header.html.erb +3 -0
- data/app/views/kono_utils/base_editing/_edit_page_title_header.html.erb +3 -0
- data/app/views/kono_utils/base_editing/_form.html.erb +15 -0
- data/app/views/kono_utils/base_editing/_index_buttons.html.erb +2 -0
- data/app/views/kono_utils/base_editing/_index_page_side_title_header.html.erb +3 -0
- data/app/views/kono_utils/base_editing/_index_page_title_header.html.erb +3 -0
- data/app/views/kono_utils/base_editing/_index_tfoot.html.erb +0 -0
- data/app/views/kono_utils/base_editing/_new.html.erb +3 -0
- data/app/views/kono_utils/base_editing/_new_page_side_title_header.html.erb +3 -0
- data/app/views/kono_utils/base_editing/_new_page_title_header.html.erb +3 -0
- data/app/views/kono_utils/base_editing/_search_form.html.erb +1 -0
- data/app/views/kono_utils/base_editing/application/_edit_page_side_title_header.html.erb +1 -0
- data/app/views/kono_utils/base_editing/application/_edit_page_title_header.html.erb +1 -0
- data/app/views/kono_utils/base_editing/application/_index_page_side_title_header.html.erb +1 -0
- data/app/views/kono_utils/base_editing/application/_index_page_title_header.html.erb +1 -0
- data/app/views/kono_utils/base_editing/application/_new_page_side_title_header.html.erb +1 -0
- data/app/views/kono_utils/base_editing/application/_new_page_title_header.html.erb +1 -0
- data/app/views/kono_utils/base_editing/application/edit.html.erb +1 -0
- data/app/views/kono_utils/base_editing/application/new.html.erb +1 -0
- data/app/views/kono_utils/base_editing/edit.html.erb +1 -0
- data/app/views/kono_utils/base_editing/index.html.erb +36 -0
- data/app/views/kono_utils/base_editing/new.html.erb +1 -0
- data/app/views/kono_utils/change_log/index.html.erb +3 -0
- data/config/initializers/mysql.rb +12 -0
- data/config/initializers/time.rb +12 -0
- data/config/locales/it.yml +18 -0
- data/lib/generators/kono_utils/install/install_generator.rb +24 -0
- data/lib/generators/templates/initializer.rb +3 -0
- data/lib/kono_utils.rb +41 -0
- data/lib/kono_utils/application_helper.rb +625 -0
- data/lib/kono_utils/base_editing_helper.rb +194 -0
- data/lib/kono_utils/base_search.rb +173 -0
- data/lib/kono_utils/concerns.rb +10 -0
- data/lib/kono_utils/concerns/active_record_translation.rb +47 -0
- data/lib/kono_utils/concerns/base_editing.rb +195 -0
- data/lib/kono_utils/concerns/base_modals.rb +97 -0
- data/lib/kono_utils/concerns/success_message.rb +25 -0
- data/lib/kono_utils/encoder.rb +55 -0
- data/lib/kono_utils/engine.rb +13 -0
- data/lib/kono_utils/fiscal_code.rb +47 -0
- data/lib/kono_utils/params_hash_array.rb +37 -0
- data/lib/kono_utils/percentage.rb +60 -0
- data/lib/kono_utils/search_attribute.rb +57 -0
- data/lib/kono_utils/tmp_file.rb +81 -0
- data/lib/kono_utils/version.rb +3 -0
- data/lib/kono_utils/virtual_model.rb +22 -0
- data/lib/tasks/kono_utils_tasks.rake +4 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +32 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +56 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/lib/kono_utils/fiscal_code_spec.rb +56 -0
- data/spec/rails_helper.rb +53 -0
- data/spec/spec_helper.rb +92 -0
- data/vendor/assets/javascripts/EventEmitter.js +473 -0
- metadata +425 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
class BsReadonlyInput < Formtastic::Inputs::StringInput
|
|
2
|
+
include FormtasticBootstrap::Inputs::Base
|
|
3
|
+
include FormtasticBootstrap::Inputs::Base::Collections
|
|
4
|
+
include ActionView::Helpers::TagHelper
|
|
5
|
+
include ActionView::Context
|
|
6
|
+
include FontAwesome::Rails::IconHelper
|
|
7
|
+
include ActionView::Helpers::JavaScriptHelper
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
##
|
|
11
|
+
# Nel caso di collection si può definire con
|
|
12
|
+
# :show_hidden => [true] per stampare il campo hidden o meno con il vero valore
|
|
13
|
+
# :display_field come options quale campo usare per stampare
|
|
14
|
+
# :value_renderer => Proc da aggiungere, a cui passiamo
|
|
15
|
+
# campo, valore , se passato nulla viene
|
|
16
|
+
# renderizzato standard un p contenente il valore
|
|
17
|
+
#
|
|
18
|
+
def to_html
|
|
19
|
+
|
|
20
|
+
field_name = method
|
|
21
|
+
show_value = object.send(method)
|
|
22
|
+
if show_value.is_a?(ActiveRecord::Base) and !options[:display_field].blank?
|
|
23
|
+
#vuol dire che siamo in una collection
|
|
24
|
+
show_value = show_value.send(options[:display_field])
|
|
25
|
+
field_name = input_name
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if !options[:value_renderer].is_a?(Proc)
|
|
29
|
+
options[:value_renderer]=Proc.new { |field, value|
|
|
30
|
+
buff = ActiveSupport::SafeBuffer.new
|
|
31
|
+
buff<<content_tag(:p, value, class: 'form-control-static', id: "#{field.form_control_input_html_options[:id]}_container")
|
|
32
|
+
buff
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
bootstrap_wrapping do
|
|
38
|
+
content_tag(:div, class: 'input-group date') do
|
|
39
|
+
|
|
40
|
+
buff = ActiveSupport::SafeBuffer.new
|
|
41
|
+
|
|
42
|
+
buff<< options[:value_renderer].call(self, show_value)
|
|
43
|
+
|
|
44
|
+
buff<< builder.hidden_field(field_name, form_control_input_html_options)
|
|
45
|
+
|
|
46
|
+
buff
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class BsTimepickerInput < BsDatetimepickerInput
|
|
2
|
+
|
|
3
|
+
def icon
|
|
4
|
+
fa_icon("clock-o".to_sym)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def default_javascript_options
|
|
8
|
+
{
|
|
9
|
+
server_format: 'YYYY-MM-DD HH:mm:ss UTC',
|
|
10
|
+
server_match: '/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} UTC$/',
|
|
11
|
+
format: 'HH:mm'
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'active_support/concern'
|
|
2
|
+
module KonoUtils
|
|
3
|
+
|
|
4
|
+
module BaseEditingPolicyConcern
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
def permitted_attributes
|
|
9
|
+
# [:descrizione]
|
|
10
|
+
record.class.column_names.collect { |s| s.to_sym } - [:id, :created_at, :updated_at]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
if defined? ::Application::Scope
|
|
15
|
+
class Scope < ::Application::Scope
|
|
16
|
+
def resolve
|
|
17
|
+
scope
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# module ClassMethods
|
|
23
|
+
|
|
24
|
+
# end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<%= semantic_form_for(*semantic_form_attributes(@object)) do |f| %>
|
|
2
|
+
|
|
3
|
+
<div class="row">
|
|
4
|
+
<% form_attributes(@object).each do |field| %>
|
|
5
|
+
|
|
6
|
+
<div class="<%= cell_column_class(field) %>">
|
|
7
|
+
<%= editing_form_print_field(f, field) %>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<% end %>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<%= form_submit f %>
|
|
14
|
+
|
|
15
|
+
<% end %>
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= search_form @search, {:reset_path => polymorphic_path(base_class)} %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'base_editing/edit_page_side_title_header' %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'base_editing/edit_page_title_header' %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'base_editing/index_page_side_title_header' %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'base_editing/index_page_title_header' %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'base_editing/new_page_title_header' %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'base_editing/new_page_title_header' %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'base_editing/edit' %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'base_editing/new' %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'base_editing/edit' %>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<%= render 'index_page_title_header' %>
|
|
2
|
+
<%= render 'index_page_side_title_header' %>
|
|
3
|
+
|
|
4
|
+
<%= render 'search_form' unless @search.nil? %>
|
|
5
|
+
|
|
6
|
+
<table class="table table-bordered table-hover">
|
|
7
|
+
<thead>
|
|
8
|
+
<tr>
|
|
9
|
+
<% table_columns.each do |t| %>
|
|
10
|
+
<%= index_column_builder(t, :th) do %>
|
|
11
|
+
<%= index_print_column_head(t) %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<% end %>
|
|
14
|
+
<th class="index-col-btn"></th>
|
|
15
|
+
</tr>
|
|
16
|
+
</thead>
|
|
17
|
+
|
|
18
|
+
<tbody>
|
|
19
|
+
<% @objects.each do |r| %>
|
|
20
|
+
<tr>
|
|
21
|
+
<% table_columns.each do |t| %>
|
|
22
|
+
<%= index_column_builder(t, :td, record: r) do %>
|
|
23
|
+
<%= index_print_column(r, t) %>
|
|
24
|
+
<% end %>
|
|
25
|
+
<% end %>
|
|
26
|
+
<th class="index-col-btn">
|
|
27
|
+
<%= render 'index_buttons', record: r %>
|
|
28
|
+
</th>
|
|
29
|
+
</tr>
|
|
30
|
+
<% end %>
|
|
31
|
+
</tbody>
|
|
32
|
+
<%= render 'index_tfoot' %>
|
|
33
|
+
</table>
|
|
34
|
+
|
|
35
|
+
<%= will_paginate_bst(@objects) %>
|
|
36
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render 'base_editing/new' %>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Creates DATETIME(6) column types by default which support microseconds.
|
|
2
|
+
#
|
|
3
|
+
# Without it, only regular (second precise) DATETIME columns are created.
|
|
4
|
+
module ActiveRecord::ConnectionAdapters
|
|
5
|
+
if ActiveRecord::Base.connection.instance_of? Mysql2Adapter
|
|
6
|
+
version = Gem::Version.new(Mysql2::Client.info.fetch(:version))
|
|
7
|
+
min_vresion = Gem::Version.new('5.6.4')
|
|
8
|
+
if version>=min_vresion
|
|
9
|
+
AbstractMysqlAdapter::NATIVE_DATABASE_TYPES[:datetime][:limit] = 6
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# NOTE: Apparently, this initializer is not necessary with Rails 4.2.5 and up.
|
|
2
|
+
# It just works with the correct database type DATETIME(6).
|
|
3
|
+
|
|
4
|
+
# Where 6N is the number of places after the decimal (.)
|
|
5
|
+
# For less precision (eg. miliseconds), change 6N to 3N
|
|
6
|
+
if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::Mysql2Adapter
|
|
7
|
+
version = Gem::Version.new(Mysql2::Client.info.fetch(:version))
|
|
8
|
+
min_vresion = Gem::Version.new('5.6.4')
|
|
9
|
+
if version>=min_vresion
|
|
10
|
+
Time::DATE_FORMATS[:db] = '%Y-%m-%d %H:%M:%S.%6N'
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
it:
|
|
2
|
+
back: Indietro
|
|
3
|
+
new: Nuovo
|
|
4
|
+
newa: Nuova
|
|
5
|
+
edit: Modifica
|
|
6
|
+
del: Cancella
|
|
7
|
+
wait: "Wait..."
|
|
8
|
+
are_you_sure: "Confermi la cancellazione?"
|
|
9
|
+
formtastic:
|
|
10
|
+
inputs:
|
|
11
|
+
bs_file_download:
|
|
12
|
+
download: Download
|
|
13
|
+
activerecord:
|
|
14
|
+
successful:
|
|
15
|
+
messages:
|
|
16
|
+
created: "%{model} creato correttamente."
|
|
17
|
+
updated: "%{model} aggiornato correttamente."
|
|
18
|
+
destroyed: "%{model} è stato correttamente cancellato."
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
module KonoUtils
|
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
|
4
|
+
desc "Installa l'inizializzatore"
|
|
5
|
+
|
|
6
|
+
# Commandline options can be defined here using Thor-like options:
|
|
7
|
+
# class_option :my_opt, :type => :boolean, :default => false, :desc => "My Option"
|
|
8
|
+
|
|
9
|
+
# I can later access that option using:
|
|
10
|
+
# options[:my_opt]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def self.source_root
|
|
14
|
+
@source_root ||= File.expand_path('../../../templates', __FILE__)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Generator Code. Remember this is just suped-up Thor so methods are executed in order
|
|
18
|
+
def copy_files
|
|
19
|
+
copy_file 'initializer.rb', 'config/initializers/kono_utils.rb'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/kono_utils.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'kono_utils/engine' if defined?(::Rails)
|
|
2
|
+
|
|
3
|
+
module KonoUtils
|
|
4
|
+
extend ActiveSupport::Autoload
|
|
5
|
+
|
|
6
|
+
autoload :VirtualModel
|
|
7
|
+
autoload :Encoder
|
|
8
|
+
autoload :ParamsHashArray
|
|
9
|
+
autoload :Percentage
|
|
10
|
+
autoload :FiscalCode
|
|
11
|
+
autoload :TmpFile
|
|
12
|
+
autoload :ApplicationHelper
|
|
13
|
+
autoload :BaseEditingHelper
|
|
14
|
+
autoload :BaseSearch
|
|
15
|
+
autoload :Concerns
|
|
16
|
+
|
|
17
|
+
class Configuration
|
|
18
|
+
attr_accessor :google_api_key
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
attr_writer :configuration
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.configuration
|
|
26
|
+
@configuration ||= Configuration.new
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.configure
|
|
30
|
+
yield configuration
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
if defined?(::Rails)
|
|
38
|
+
if Rails.gem_version > Gem::Version.new('4.2.0')
|
|
39
|
+
require 'kono_utils/concerns/active_record_translation'
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
module KonoUtils
|
|
2
|
+
module ApplicationHelper
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def will_paginate_bst(collection)
|
|
6
|
+
will_paginate collection, renderer: BootstrapPagination::Rails
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def namespace_content(&block)
|
|
11
|
+
content_tag :div, class: "#{(controller.class.name.split("::") + [action_name]).join(" ")}" do
|
|
12
|
+
yield
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def true_false_label(val)
|
|
18
|
+
|
|
19
|
+
if val
|
|
20
|
+
icon =fa_icon(:check)
|
|
21
|
+
classe='success'
|
|
22
|
+
else
|
|
23
|
+
classe='danger'
|
|
24
|
+
icon =fa_icon(:times)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
content_tag(:span, icon, class: "label label-#{classe}")
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# Genera una modal da riutilizzare per far aspettare determinate operazioni al client
|
|
34
|
+
def bootstrap_please_wait
|
|
35
|
+
content_tag(:div,
|
|
36
|
+
class: 'modal fade',
|
|
37
|
+
id: 'processing_wait',
|
|
38
|
+
tabindex: "-1",
|
|
39
|
+
role: "dialog",
|
|
40
|
+
"aria-hidden".to_sym => "true") do
|
|
41
|
+
content_tag :div, class: 'modal-dialog modal-sm' do
|
|
42
|
+
content_tag :div, class: 'modal-content' do
|
|
43
|
+
|
|
44
|
+
buff = ActiveSupport::SafeBuffer.new
|
|
45
|
+
|
|
46
|
+
buff << content_tag(:div, class: 'modal-header') do
|
|
47
|
+
content_tag(:h4, "Processing...", class: "modal-title")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
buff << content_tag(:div, class: 'modal-body') do
|
|
51
|
+
content_tag :div, class: "progress" do
|
|
52
|
+
content_tag :div, ' ', class: "progress-bar progress-bar-striped active", role: "progressbar", style: "width: 100%"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
buff
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
##
|
|
64
|
+
# Genera la form di ricerca
|
|
65
|
+
# * *Args* :
|
|
66
|
+
# - search_model -> KonoUtils::BaseSearch
|
|
67
|
+
# - args -> Hash with configurations:
|
|
68
|
+
# - attributes -> array of symbols for the search, if empty used from search_model
|
|
69
|
+
# - reset_path -> path per cui resettare la ricerca, nil
|
|
70
|
+
# - form_opts -> opzioni da aggiungere per la form
|
|
71
|
+
# - buttons_editor -> Proc chiamata, con il passaggio dell'oggetto della form e
|
|
72
|
+
# del ActiveSupport::SafeBuffer con all'interno dei bottoni
|
|
73
|
+
# come parametro, deve ritornare
|
|
74
|
+
# un ActiveSupport::SafeBuffer a sua volta
|
|
75
|
+
# * *Returns* :
|
|
76
|
+
# -
|
|
77
|
+
#
|
|
78
|
+
def search_form(search_model, args={})
|
|
79
|
+
|
|
80
|
+
args = {
|
|
81
|
+
:attributes => [],
|
|
82
|
+
:reset_path => nil,
|
|
83
|
+
:form_opts => {},
|
|
84
|
+
:field_option => {:wrapper_html => {:class => "col-xs-12 col-sm-6 col-md-4 col-lg-3"}},
|
|
85
|
+
:buttons_editor => Proc.new { |form_obj, sb| sb }
|
|
86
|
+
}.merge(args)
|
|
87
|
+
|
|
88
|
+
reset_path = args[:reset_path]
|
|
89
|
+
|
|
90
|
+
field_option = args[:field_option]
|
|
91
|
+
|
|
92
|
+
base_search_form_wrapper(search_model, {:attributes => args[:attributes], :form_opts => args[:form_opts]}) do |f|
|
|
93
|
+
content_tag :div, class: "panel panel-default search_panel" do
|
|
94
|
+
|
|
95
|
+
buffer = ActiveSupport::SafeBuffer.new
|
|
96
|
+
|
|
97
|
+
buffer<< content_tag(:div, class: 'panel-heading') do
|
|
98
|
+
content_tag :h3, class: "panel-title collapse_search" do
|
|
99
|
+
header = ActiveSupport::SafeBuffer.new
|
|
100
|
+
|
|
101
|
+
header<< content_tag(:span, t(:search))
|
|
102
|
+
|
|
103
|
+
header<<content_tag(:div, fa_icon("search") + content_tag(:span, nil, class: 'caret'), class: 'pull-right icon-search')
|
|
104
|
+
|
|
105
|
+
header
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
buffer<< content_tag(:div, class: "collapsible_panel #{(search_model.data_loaded? ? 'uncollapsed' : '')}") do
|
|
110
|
+
fb_collapse = ActiveSupport::SafeBuffer.new
|
|
111
|
+
|
|
112
|
+
fb_collapse << content_tag(:div, class: "panel-body") do
|
|
113
|
+
f.fields_builder(:field_options => field_option)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
fb_collapse << content_tag(:div, class: 'panel-footer text-right') do
|
|
118
|
+
form_buffer = ActiveSupport::SafeBuffer.new
|
|
119
|
+
|
|
120
|
+
form_buffer<< button_tag(t(:search), type: "submit", class: "btn btn-primary")
|
|
121
|
+
|
|
122
|
+
if search_model.data_loaded? and !reset_path.nil?
|
|
123
|
+
form_buffer<< link_to(content_tag(:span, nil, class: 'glyphicon glyphicon-remove'), reset_path, class: 'btn btn-info')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
args[:buttons_editor].call(f, form_buffer)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
fb_collapse
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
buffer
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
class BaseSearchFormWrapper < Struct.new(:formtastic_form, :attributes, :current_user)
|
|
140
|
+
|
|
141
|
+
def fields_builder(cfgs={field_options: {}})
|
|
142
|
+
form_buffer = ActiveSupport::SafeBuffer.new
|
|
143
|
+
|
|
144
|
+
self.attributes.each do |field|
|
|
145
|
+
|
|
146
|
+
form_options = field.form_options
|
|
147
|
+
if form_options.is_a?(Proc)
|
|
148
|
+
form_options = form_options.call(current_user, self.formtastic_form)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
form_buffer << self.formtastic_form.input(field.field, cfgs[:field_options].merge(form_options))
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
form_buffer
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
##
|
|
159
|
+
# Utility interna che si occupa della logica minima per generare la il form di ricerca
|
|
160
|
+
def base_search_form_wrapper(search_model, args={:attributes => [], :form_opts => {}})
|
|
161
|
+
attributes = args[:attributes] || {}
|
|
162
|
+
form_opts = args[:form_opts] || {}
|
|
163
|
+
if attributes.length==0
|
|
164
|
+
attributes = search_model.search_attributes
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
form_opts = {method: :get, :html => {autocomplete: 'off'}}.merge(form_opts)
|
|
168
|
+
|
|
169
|
+
semantic_form_for search_model, form_opts do |f|
|
|
170
|
+
yield BaseSearchFormWrapper.new(f, attributes, @current_user)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def title_mod(model)
|
|
176
|
+
"#{t(:edit)} #{model.mn}"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def title_new(model)
|
|
180
|
+
"#{t(:new)} #{model.mn}"
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def title_newa(model)
|
|
184
|
+
"#{t(:newa)} #{model.mn}"
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def title_del(model)
|
|
188
|
+
"#{t(:del)} #{model.mn}"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
##
|
|
193
|
+
# Genera l'hash da passare come collection alle selectbox, esegue anche la traduzione con locale
|
|
194
|
+
#
|
|
195
|
+
# <%= f.input :usage, :as => :select,
|
|
196
|
+
# :collection => enum_collection(Logo, :usage), :input_html => {:include_blank => true} %>
|
|
197
|
+
#
|
|
198
|
+
# * *Args* :
|
|
199
|
+
# - model -> ActiveRecord model contenente l'enum
|
|
200
|
+
# - attribute -> Symbol che identifica l'attributo dell'enum
|
|
201
|
+
# - variant -> se c'è la variante questa viene inserite _#{variant} dopo il nome del valore
|
|
202
|
+
# * *Returns* :
|
|
203
|
+
# - Hash
|
|
204
|
+
#
|
|
205
|
+
def enum_collection(model, attribute, variant=nil)
|
|
206
|
+
|
|
207
|
+
model.send(attribute.to_s.pluralize(2).to_sym).collect { |key, val|
|
|
208
|
+
[enum_translation(model, attribute, key, variant), key]
|
|
209
|
+
}.to_h
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
##
|
|
214
|
+
# Si occupa di tradurre un determinato valore di un enum
|
|
215
|
+
# - model -> ActiveRecord model contenente l'enum
|
|
216
|
+
# - attribute -> Symbol che identifica l'attributo dell'enum
|
|
217
|
+
# - variant -> se c'è la variante questa viene inserite _#{variant} dopo il nome del valore
|
|
218
|
+
#
|
|
219
|
+
# * *Returns* :
|
|
220
|
+
# - String
|
|
221
|
+
#
|
|
222
|
+
def enum_translation(model, attribute, value, variant=nil)
|
|
223
|
+
ApplicationHelper.enum_translation(model, attribute, value, variant)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
##
|
|
228
|
+
# Le traduzioni dentro al locale devono essere fatte in questo modo:
|
|
229
|
+
# it:
|
|
230
|
+
# activerecord:
|
|
231
|
+
# attributes:
|
|
232
|
+
# estimate_before/value:
|
|
233
|
+
# na: NA
|
|
234
|
+
# very_insufficient: 1
|
|
235
|
+
# insufficient: 2
|
|
236
|
+
# sufficient: 3
|
|
237
|
+
# excellent: 4
|
|
238
|
+
#
|
|
239
|
+
# dove in questo caso estimate_before è il modello e value è il nome del campo enum
|
|
240
|
+
#
|
|
241
|
+
def self.enum_translation(model, attribute, value, variant=nil)
|
|
242
|
+
return '' if value.nil?
|
|
243
|
+
variant = "_#{variant}" unless variant.nil?
|
|
244
|
+
model.human_attribute_name("#{attribute}.#{value}#{variant}")
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
##
|
|
249
|
+
# Helper per generare una modal con all'interno un form
|
|
250
|
+
# Utilizzare passando un block il quale riceve come parametro la form di formtastic
|
|
251
|
+
# possibile passare anche una proc in buttons_proc per scrivere in modo differente i bottoni nella modal,
|
|
252
|
+
# alla proc viene passato il solito form di formtastic e il bottone standard di chiusura
|
|
253
|
+
#
|
|
254
|
+
def modal_form_generator(args = {})
|
|
255
|
+
|
|
256
|
+
args = {
|
|
257
|
+
id: 'modal',
|
|
258
|
+
class: '',
|
|
259
|
+
title: 'Titolo',
|
|
260
|
+
form_cfgs: [],
|
|
261
|
+
buttons_proc: Proc.new do |f, default_close_btn|
|
|
262
|
+
default_close_btn +
|
|
263
|
+
f.action(:submit, button_html: {class: 'btn btn-primary'}, :label => :save_and_close)
|
|
264
|
+
end
|
|
265
|
+
}.merge(args)
|
|
266
|
+
|
|
267
|
+
raise 'Passare le configurazioni per la form' if args[:form_cfgs]==[]
|
|
268
|
+
|
|
269
|
+
default_close_btn = content_tag(:button, 'Chiudi', type: 'button', class: 'btn btn-default', data: {dismiss: "modal"})
|
|
270
|
+
|
|
271
|
+
content_tag(:div,
|
|
272
|
+
class: "modal fade kono_modal_form",
|
|
273
|
+
id: args[:id],
|
|
274
|
+
tabindex: "-1",
|
|
275
|
+
role: "dialog",
|
|
276
|
+
"aria-hidden".to_sym => "true") do
|
|
277
|
+
content_tag :div, class: 'modal-dialog' do
|
|
278
|
+
semantic_form_for(*args[:form_cfgs]) do |f|
|
|
279
|
+
content_tag :div, class: 'modal-content' do
|
|
280
|
+
|
|
281
|
+
buff = ActiveSupport::SafeBuffer.new
|
|
282
|
+
|
|
283
|
+
buff << content_tag(:div, class: 'modal-header') do
|
|
284
|
+
content_tag(:button, raw("×"), type: "button", class: "close", data: {dismiss: 'modal'}, "aria-hidden".to_sym => "true") +
|
|
285
|
+
content_tag(:h4, args[:title], class: "modal-title")
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
buff << content_tag(:div, class: 'modal-body') do
|
|
289
|
+
yield f
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
buff << content_tag(:div, class: 'modal-footer') do
|
|
293
|
+
args[:buttons_proc].call(f, default_close_btn)
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
buff
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
##
|
|
306
|
+
# Genera il bottone per editazione con una modal del contenuto,
|
|
307
|
+
# gli viene passato un block contenente la modal da lanciare per l'editazione,
|
|
308
|
+
# solitamente generata con modal_form_generator.
|
|
309
|
+
# come parametri viene passato l'id del target che si aspetta di richiamare
|
|
310
|
+
#
|
|
311
|
+
# ES:
|
|
312
|
+
# modal_edit_button do |id|
|
|
313
|
+
# render 'tikal_core/people/person_contacts/modal_form', :contact => contact, :id => id %>
|
|
314
|
+
# end
|
|
315
|
+
#
|
|
316
|
+
# Attributes:
|
|
317
|
+
# align: left|rigth
|
|
318
|
+
# updatable_content: elemento da rimpiazzare con il partial restituito
|
|
319
|
+
# class: classi aggiuntive per selezionare meglio il bottone
|
|
320
|
+
# btn_class: classi aggiuntive del bottone
|
|
321
|
+
# bnt_icon: Symbol che identifica che icona utilizzare per il bottone
|
|
322
|
+
#
|
|
323
|
+
#
|
|
324
|
+
def modal_edit_button(*args, &block)
|
|
325
|
+
|
|
326
|
+
options = {
|
|
327
|
+
align: 'left',
|
|
328
|
+
updatable_content: '',
|
|
329
|
+
class: '',
|
|
330
|
+
btn_class: '',
|
|
331
|
+
bnt_icon: :edit
|
|
332
|
+
}.merge(args.extract_options!)
|
|
333
|
+
|
|
334
|
+
id = "#{SecureRandom.hex}"
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
content_tag :div, class: "kono_edit_button align-#{options[:align]} #{options[:class]}", :data => {updatable_content: options[:updatable_content]} do
|
|
338
|
+
buffer = ActiveSupport::SafeBuffer.new
|
|
339
|
+
|
|
340
|
+
buffer << button_tag(data: {toggle: 'modal', target: "##{id}"}, class: "btn btn-default btn-xs #{options[:btn_class]}") { fa_icon(options[:bnt_icon]) }
|
|
341
|
+
|
|
342
|
+
buffer << capture do
|
|
343
|
+
block.call(id)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
buffer
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
##
|
|
352
|
+
# Genera il bottone per la cancellazione di un elemento
|
|
353
|
+
#
|
|
354
|
+
# modal_delete_button(path, [options])
|
|
355
|
+
# path -> resource to delete
|
|
356
|
+
# options:
|
|
357
|
+
# * confirm : Text to display in modal
|
|
358
|
+
# * align : left|right
|
|
359
|
+
# * callback_remove : id dell'elemento da rimuove una volta avuto successo il javascript di cancellazione
|
|
360
|
+
# * bnt_icon : Symbol che identifica che icona utilizzare per il bottone
|
|
361
|
+
def modal_delete_button(*args)
|
|
362
|
+
options = {
|
|
363
|
+
confirm: 'Sicuri di voler eliminare il record? L\'azione non è annullabile.',
|
|
364
|
+
align: 'left',
|
|
365
|
+
callback_remove: nil,
|
|
366
|
+
bnt_icon: :times
|
|
367
|
+
}.merge(args.extract_options!)
|
|
368
|
+
path = args[0]
|
|
369
|
+
|
|
370
|
+
id = "#{SecureRandom.hex}"
|
|
371
|
+
|
|
372
|
+
content_tag :div, class: "tk_delete_button align-#{options[:align]}" do
|
|
373
|
+
|
|
374
|
+
buffer = ActiveSupport::SafeBuffer.new
|
|
375
|
+
|
|
376
|
+
buffer<<button_tag(data: {toggle: 'modal', target: "##{id}"}, class: 'btn btn-danger btn-xs') { fa_icon(options[:bnt_icon]) }
|
|
377
|
+
|
|
378
|
+
buffer<< content_tag(:div,
|
|
379
|
+
class: 'modal fade',
|
|
380
|
+
id: id,
|
|
381
|
+
tabindex: "-1",
|
|
382
|
+
role: "dialog",
|
|
383
|
+
"aria-hidden".to_sym => "true") do
|
|
384
|
+
form_tag(path, method: :delete, data: {callback_remove: options[:callback_remove]}) do
|
|
385
|
+
content_tag :div, class: 'modal-dialog' do
|
|
386
|
+
content_tag :div, class: 'modal-content' do
|
|
387
|
+
|
|
388
|
+
buff = ActiveSupport::SafeBuffer.new
|
|
389
|
+
|
|
390
|
+
buff << content_tag(:div, class: 'modal-header') do
|
|
391
|
+
tmp_buff = ActiveSupport::SafeBuffer.new
|
|
392
|
+
tmp_buff<<button_tag(fa_icon(:times), type: "button", class: "close", data: {dismiss: "modal"}, "aria-hidden".to_sym => true)
|
|
393
|
+
tmp_buff<<content_tag(:h4, "Attenzione", class: "modal-title")
|
|
394
|
+
tmp_buff
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
buff << content_tag(:div, options[:confirm], class: 'modal-body text-danger')
|
|
398
|
+
|
|
399
|
+
buff << content_tag(:div, class: 'modal-footer') do
|
|
400
|
+
button_tag('Annulla', type: "button", class: "btn btn-default", data: {dismiss: "modal"})+
|
|
401
|
+
button_tag('Conferma', type: 'submit', class: "btn btn-danger")
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
buff
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
buffer << content_tag(:script, raw("$('##{id} form').kono_delete_button();"), :type => 'text/javascript')
|
|
412
|
+
|
|
413
|
+
buffer
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
##
|
|
418
|
+
# Colleziona i mesi per la select box
|
|
419
|
+
def month_collection
|
|
420
|
+
(1..12).collect { |m| [t('date.month_names')[m].capitalize, m] }
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
##
|
|
425
|
+
# Genera una collection degli anni per la select box
|
|
426
|
+
# parte da -8 a +1
|
|
427
|
+
#
|
|
428
|
+
def year_collection(start=-8, last=1)
|
|
429
|
+
((Time.now.year+start)..(Time.now.year+last)).to_a.reverse
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
module_function :year_collection
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
##
|
|
436
|
+
# Si occupa di generare la visualizzazione dell'exception passata, con informazioni
|
|
437
|
+
# aggiuntive se utente è super admin
|
|
438
|
+
# * *Args* :
|
|
439
|
+
# - exception -> Exception
|
|
440
|
+
def bs_rescue_printer(exception)
|
|
441
|
+
bff = ActiveSupport::SafeBuffer.new
|
|
442
|
+
|
|
443
|
+
bff<< content_tag(:div, class: "alert alert-warning") do
|
|
444
|
+
button_tag(raw("×"), data: {dismiss: "alert", hidden: "true"}, class: 'close') +
|
|
445
|
+
content_tag(:strong, 'Errore') +
|
|
446
|
+
" Attenzione, il codice eseguito non è valido, contattare l'amministratore."
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
if @current_user.is_super_admin?
|
|
450
|
+
|
|
451
|
+
bff<<content_tag(:div, class: "panel panel-info") do
|
|
452
|
+
tmp = ActiveSupport::SafeBuffer.new
|
|
453
|
+
tmp<<content_tag(:div, class: "panel-heading") do
|
|
454
|
+
content_tag :h3, "Messagio di Errore: #{exception.message} "
|
|
455
|
+
end
|
|
456
|
+
tmp<<content_tag(:div, class: "panel-body") do
|
|
457
|
+
content_tag :pre, exception.backtrace.join("\n")
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
tmp
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
bff
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
##
|
|
468
|
+
#
|
|
469
|
+
# * *Args* :
|
|
470
|
+
# - int -> Valore intero per definire
|
|
471
|
+
# - class -> optional classi aggiuntive
|
|
472
|
+
# * *Returns* :
|
|
473
|
+
# - content
|
|
474
|
+
#
|
|
475
|
+
def bs_spacer(space, classe='')
|
|
476
|
+
content_tag :div, nil, class: "v-spacer space-x#{space} #{classe}"
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
##
|
|
481
|
+
# Costruisce una tabella con i campi utili alla creazione di elementi multipli
|
|
482
|
+
#
|
|
483
|
+
# Attributes:
|
|
484
|
+
# form -> la form proveniente da formtastic
|
|
485
|
+
# field -> il campo referente dell'associazione
|
|
486
|
+
# fields -> elenco di campi su cui costruire le varie colonne
|
|
487
|
+
# options -> Hash di opzioni:
|
|
488
|
+
# :disable_duplication => [false] : server per disabilitare il bottone della duplicazione
|
|
489
|
+
#
|
|
490
|
+
# se gli si passa un blocco allora possiamo elaborare la costruzione dei differenti campi in modo personale
|
|
491
|
+
# al blocco viene passato la classe di formtastic della form, il campo, e un blocco contenente la proc per
|
|
492
|
+
# elaborare i campi in modo standard
|
|
493
|
+
#
|
|
494
|
+
# multiple_elements_table(form, :campo_has_many, [:label, :string_value, :number_value]) do |field, form|
|
|
495
|
+
# case field
|
|
496
|
+
# when :string_value, :number_value
|
|
497
|
+
# form.input field, label: false, input_html: {:autocomplete => 'off', class: 'toggle_value'}
|
|
498
|
+
# else
|
|
499
|
+
# form.input field, label: false, input_html: {:autocomplete => 'off'}
|
|
500
|
+
# end
|
|
501
|
+
# end
|
|
502
|
+
#
|
|
503
|
+
# Traduzioni delle colonne:
|
|
504
|
+
#
|
|
505
|
+
# modello_iniziale/campo_has_many:
|
|
506
|
+
# campo_del_has_many
|
|
507
|
+
#
|
|
508
|
+
#
|
|
509
|
+
def multiple_elements_table(*params)
|
|
510
|
+
options = params.extract_options!
|
|
511
|
+
|
|
512
|
+
options = {:disable_duplication => false}.merge(options)
|
|
513
|
+
|
|
514
|
+
form = params[0]
|
|
515
|
+
field = params[1]
|
|
516
|
+
fields = params[2]
|
|
517
|
+
|
|
518
|
+
semantic_form_nested=[field]
|
|
519
|
+
|
|
520
|
+
#inserimento logiche per scope su elenco elementi multipli
|
|
521
|
+
unless options[:scope].nil?
|
|
522
|
+
semantic_form_nested<<options[:scope]
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
content_tag :table, class: "table table-bordered" do
|
|
526
|
+
|
|
527
|
+
b = ActiveSupport::SafeBuffer.new
|
|
528
|
+
|
|
529
|
+
b<< content_tag(:thead) do
|
|
530
|
+
content_tag :tr do
|
|
531
|
+
c = ActiveSupport::SafeBuffer.new
|
|
532
|
+
|
|
533
|
+
fields.each do |f|
|
|
534
|
+
::Rails.logger.debug { form.object.class.inspect }
|
|
535
|
+
::Rails.logger.debug { field }
|
|
536
|
+
::Rails.logger.debug { f.inspect }
|
|
537
|
+
c<<content_tag(:th, form.object.class.human_attribute_name("#{field}.#{f}"),class:"multi_tab_#{f}")
|
|
538
|
+
end
|
|
539
|
+
unless options[:disable_duplication]
|
|
540
|
+
c<<content_tag(:td, nil)
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
c
|
|
544
|
+
end
|
|
545
|
+
end
|
|
546
|
+
|
|
547
|
+
b<<content_tag(:tbody) do
|
|
548
|
+
form.semantic_fields_for(*semantic_form_nested) do |measure|
|
|
549
|
+
|
|
550
|
+
default_execution = Proc.new { |field| measure.input field, :label => false }
|
|
551
|
+
|
|
552
|
+
content_tag :tr, class: "form-inline list riga_misura" do
|
|
553
|
+
|
|
554
|
+
d = ActiveSupport::SafeBuffer.new
|
|
555
|
+
|
|
556
|
+
fields.each do |f|
|
|
557
|
+
d<<content_tag(:td,class:"multi_tab_#{f}") do
|
|
558
|
+
|
|
559
|
+
if block_given?
|
|
560
|
+
yield(f, measure, default_execution)
|
|
561
|
+
else
|
|
562
|
+
default_execution.call(f)
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
unless options[:disable_duplication]
|
|
569
|
+
d << content_tag(:td) do
|
|
570
|
+
|
|
571
|
+
link_to "#", class: 'btn btn-xs btn-default add_one_more' do
|
|
572
|
+
|
|
573
|
+
h = ActiveSupport::SafeBuffer.new
|
|
574
|
+
h<< fa_icon(:plus)
|
|
575
|
+
h<< measure.input(:_destroy, as: :hidden)
|
|
576
|
+
|
|
577
|
+
h
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
end
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
d
|
|
584
|
+
end
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
b
|
|
589
|
+
end
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
##
|
|
594
|
+
# Genera un'albero con bootstrap-tree
|
|
595
|
+
# deve ricevere un array di dati da trasformare in json.
|
|
596
|
+
# per come scrivere il parametro data vedi
|
|
597
|
+
# https://github.com/jonmiles/bootstrap-treeview
|
|
598
|
+
#
|
|
599
|
+
def bs_tree(data)
|
|
600
|
+
|
|
601
|
+
id_div = SecureRandom.hex(10)
|
|
602
|
+
|
|
603
|
+
tmp = ActiveSupport::SafeBuffer.new
|
|
604
|
+
|
|
605
|
+
tmp<< content_tag(:div, nil, id: id_div, class: 'bs_tree_list')
|
|
606
|
+
|
|
607
|
+
tmp<< javascript_tag do
|
|
608
|
+
raw "$('##{id_div}').treeview({data: #{data.to_json}});"
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
##
|
|
614
|
+
# Stampa una data con il default delle date se questa non è nil
|
|
615
|
+
#
|
|
616
|
+
def print_rescue_date(date)
|
|
617
|
+
unless date.nil?
|
|
618
|
+
return l date.to_date
|
|
619
|
+
end
|
|
620
|
+
''
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
end
|
|
625
|
+
end
|