cck_forms 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.
- checksums.yaml +7 -0
- data/LICENSE +1 -0
- data/README.md +1 -0
- data/Rakefile +40 -0
- data/lib/cck_forms/date_time.rb +58 -0
- data/lib/cck_forms/engine.rb +23 -0
- data/lib/cck_forms/form_builder_extensions.rb +18 -0
- data/lib/cck_forms/parameter_type_class/album.rb +100 -0
- data/lib/cck_forms/parameter_type_class/base.rb +275 -0
- data/lib/cck_forms/parameter_type_class/boolean.rb +24 -0
- data/lib/cck_forms/parameter_type_class/checkboxes.rb +202 -0
- data/lib/cck_forms/parameter_type_class/date.rb +35 -0
- data/lib/cck_forms/parameter_type_class/date_range.rb +53 -0
- data/lib/cck_forms/parameter_type_class/date_time.rb +76 -0
- data/lib/cck_forms/parameter_type_class/enum.rb +53 -0
- data/lib/cck_forms/parameter_type_class/file.rb +80 -0
- data/lib/cck_forms/parameter_type_class/float.rb +20 -0
- data/lib/cck_forms/parameter_type_class/image.rb +20 -0
- data/lib/cck_forms/parameter_type_class/integer.rb +77 -0
- data/lib/cck_forms/parameter_type_class/integer_range.rb +150 -0
- data/lib/cck_forms/parameter_type_class/map.rb +259 -0
- data/lib/cck_forms/parameter_type_class/phones.rb +204 -0
- data/lib/cck_forms/parameter_type_class/string.rb +13 -0
- data/lib/cck_forms/parameter_type_class/string_collection.rb +23 -0
- data/lib/cck_forms/parameter_type_class/text.rb +18 -0
- data/lib/cck_forms/parameter_type_class/time.rb +30 -0
- data/lib/cck_forms/parameter_type_class/work_hours.rb +369 -0
- data/lib/cck_forms/version.rb +3 -0
- data/lib/cck_forms.rb +4 -0
- data/vendor/assets/javascripts/cck_forms/jquery.workhours.js +399 -0
- data/vendor/assets/javascripts/cck_forms/map.js.coffee +322 -0
- metadata +116 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9bd0c788c8c8ba1cd70dc9114891a33421105bc4
|
4
|
+
data.tar.gz: 6d1a53c9d48100fc922b37a87aa47255da929554
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7af10e028591267acfaebd5d67a22027cd8a3b7a0d8769fbc212f9b30e99a166cba7e8aa699fff3510d8f92b50a16b05d74ce02bc62e29b1f5ffc8bc90a67066
|
7
|
+
data.tar.gz: ed6f2da8765459afd914fe42595068fa803b897f861e0650550e037f617d68276c58c59777f4d39045941cda21efd5e1e55947274c8dd5a8bcb012a0398f494d
|
data/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Released under the MIT License.
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
TODO
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'CckForms'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << 'lib'
|
34
|
+
t.libs << 'test'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module CckForms::DateTime
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
module DateTimeParser
|
5
|
+
def date_object_from_what_stored_in_database(value)
|
6
|
+
parsed_value = nil
|
7
|
+
if value.is_a? Hash
|
8
|
+
|
9
|
+
force_timezone = true
|
10
|
+
v = value
|
11
|
+
|
12
|
+
if v.has_key? 'hour' and v.has_key? 'month'
|
13
|
+
parsed_value = DateTime.civil(v['year'], v['year'], v['day'], v['hour'], v['minute'])
|
14
|
+
elsif v.has_key? 'hour' or v.has_key? 'month'
|
15
|
+
if v.has_key? 'hour'
|
16
|
+
parsed_value = Time.parse("#{v['hour']}:#{v['minute']}")
|
17
|
+
elsif v.has_key? 'month'
|
18
|
+
parsed_value = Date.parse("#{v['day']}.#{v['month']}.#{v['year']}")
|
19
|
+
end
|
20
|
+
else
|
21
|
+
if v.has_key? '(5i)' and v.has_key? '(1i)' # date & time
|
22
|
+
parsed_value = DateTime.parse("#{v['(3i)']}.#{v['(2i)']}.#{v['(1i)']} #{v['(4i)']}:#{v['(5i)']}")
|
23
|
+
elsif v.has_key? '(5i)' # time
|
24
|
+
parsed_value = Time.parse("#{v['(4i)']}:#{v['(5i)']}")
|
25
|
+
elsif v.has_key? '(1i)' # date
|
26
|
+
parsed_value = Date.parse("#{v['(3i)']}.#{v['(2i)']}.#{v['(1i)']}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
value = parsed_value if parsed_value
|
31
|
+
|
32
|
+
if force_timezone || value.is_a?(Time)
|
33
|
+
value = value.change offset: ActiveSupport::TimeZone.new(Rails.application.config.time_zone).formatted_offset
|
34
|
+
end
|
35
|
+
|
36
|
+
value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module ClassMethods
|
41
|
+
include DateTimeParser
|
42
|
+
|
43
|
+
def default_options_for_date_time_selectors(value)
|
44
|
+
date_in_time_zone = value.in_time_zone(Rails.application.config.time_zone) rescue nil
|
45
|
+
[{default: date_in_time_zone, include_blank: false, with_css_classes: true}, {class: 'form-control'}]
|
46
|
+
end
|
47
|
+
|
48
|
+
def demongoize_value(value, parameter_type_class=nil)
|
49
|
+
date_object_from_what_stored_in_database value
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
include DateTimeParser
|
54
|
+
|
55
|
+
def mongoize
|
56
|
+
date_object_from_what_stored_in_database value
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module CckForms
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
config.autoload_paths << File.expand_path('../..', __FILE__)
|
4
|
+
|
5
|
+
config.after_initialize do
|
6
|
+
CckForms::ParameterTypeClass::Base.load_type_classes if Rails.application.config.cck_forms.load_type_classes
|
7
|
+
ActionView::Base.send :include, CckForms::FormBuilderExtensions if Rails.application.config.cck_forms.extend_form_builder
|
8
|
+
end
|
9
|
+
|
10
|
+
config.cck_forms = ActiveSupport::OrderedOptions.new
|
11
|
+
|
12
|
+
# general
|
13
|
+
config.cck_forms.load_type_classes = true
|
14
|
+
config.cck_forms.extend_form_builder = true
|
15
|
+
|
16
|
+
# phones
|
17
|
+
config.cck_forms.phones = ActiveSupport::OrderedOptions.new
|
18
|
+
config.cck_forms.phones.min_phones_in_form = 3
|
19
|
+
config.cck_forms.phones.mobile_codes = %w{ 777 705 771 701 702 775 778 700 707 }
|
20
|
+
config.cck_forms.phones.prefix = '+7'
|
21
|
+
config.cck_forms.phones.number_parts_glue = '-'
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Примесь для расширения ActionView::Helpers::FormBuilder, чтобы работать с нашими полями:
|
2
|
+
#
|
3
|
+
# class CckEnabled
|
4
|
+
# field :logo, type: CckForms::ParameterTypeClass::Image
|
5
|
+
# end
|
6
|
+
#
|
7
|
+
# = form_for @cck_enabled do |f|
|
8
|
+
# = f.standalone_cck_field :logo
|
9
|
+
#
|
10
|
+
module CckForms::FormBuilderExtensions
|
11
|
+
ActionView::Helpers::FormBuilder.class_eval do
|
12
|
+
def standalone_cck_field(field_name, options = {})
|
13
|
+
fields_for(field_name) do |ff|
|
14
|
+
@template.raw object.send(field_name).build_form ff, options
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::Album
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
|
4
|
+
def self.name
|
5
|
+
'Альбом'
|
6
|
+
end
|
7
|
+
|
8
|
+
# Преобразует данные для Монго.
|
9
|
+
# Приводит переданный массив или хэш объектов Neofiles::Image или их идентификаторов в массив.
|
10
|
+
def mongoize
|
11
|
+
the_value = value.is_a?(Hash) ? value['value'] : value
|
12
|
+
|
13
|
+
result = []
|
14
|
+
if the_value.respond_to? :each
|
15
|
+
the_value.each do |image|
|
16
|
+
image = image[1] if the_value.respond_to? :each_value
|
17
|
+
result.push(image.is_a?(::Neofiles::Image) ? image.id : image.to_s) if image.present?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
# Преобразуем данные из Монго.
|
25
|
+
# Приводим в массив (по идее, массив идентификаторов Neofiles::Image, хотя может быть что угодно).
|
26
|
+
def self.demongoize_value(value, parameter_type_class=nil)
|
27
|
+
if value.respond_to? :each
|
28
|
+
value
|
29
|
+
else
|
30
|
+
[]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Строит форму для обновления файлов альбома.
|
35
|
+
#
|
36
|
+
# Ключи options:
|
37
|
+
#
|
38
|
+
# value - текущее значение (идентификатор или объект Neofiles::Album)
|
39
|
+
def build_form(form_builder, options)
|
40
|
+
set_value_in_hash options
|
41
|
+
|
42
|
+
options = {
|
43
|
+
|
44
|
+
}.merge options
|
45
|
+
|
46
|
+
the_value = options[:value].is_a?(Array) ? options[:value] : []
|
47
|
+
input_name_prefix = form_builder.object_name + '[value][]'
|
48
|
+
widget_id_prefix = form_builder_name_to_id form_builder, '_value_'
|
49
|
+
file_forms = []
|
50
|
+
|
51
|
+
the_value.each do |image_id|
|
52
|
+
file_forms << CckForms::ParameterTypeClass::Image.create_load_form( helper: self,
|
53
|
+
file: image_id,
|
54
|
+
input_name: input_name_prefix,
|
55
|
+
append_create: false,
|
56
|
+
clean_remove: true,
|
57
|
+
widget_id: widget_id_prefix + file_forms.length.to_s,
|
58
|
+
multiple: true,
|
59
|
+
with_desc: options[:with_desc])
|
60
|
+
end
|
61
|
+
|
62
|
+
add_file_form = CckForms::ParameterTypeClass::Image.create_load_form( helper: self,
|
63
|
+
file: nil,
|
64
|
+
input_name: input_name_prefix,
|
65
|
+
append_create: true,
|
66
|
+
clean_remove: true,
|
67
|
+
widget_id: widget_id_prefix + file_forms.length.to_s,
|
68
|
+
multiple: true,
|
69
|
+
with_desc: options[:with_desc])
|
70
|
+
|
71
|
+
id = form_builder_name_to_id form_builder, rand(1...1_000_000).to_s
|
72
|
+
|
73
|
+
<<HTML
|
74
|
+
<div class="neofiles-album-compact" id="#{id}">
|
75
|
+
#{file_forms.join}
|
76
|
+
#{add_file_form}
|
77
|
+
</div>
|
78
|
+
|
79
|
+
<script type="text/javascript">
|
80
|
+
$(function() {
|
81
|
+
$("##{id}").album();
|
82
|
+
});
|
83
|
+
</script>
|
84
|
+
HTML
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_s(options = nil)
|
88
|
+
''
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_diff_value(options = {})
|
92
|
+
view_context = options[:view_context]
|
93
|
+
images_html_list = []
|
94
|
+
value.each do |image_id|
|
95
|
+
images_html_list << "<img style='width: 64px; height: 64px;' src='#{view_context.neofiles_image_path(id: image_id, format: '64x64', crop: 1)}'>"
|
96
|
+
end
|
97
|
+
|
98
|
+
images_html_list.join.html_safe if images_html_list.any?
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,275 @@
|
|
1
|
+
# Базовая примесь для всех типов полей. Определяет всякие помогайки. Ее нужно включать методом include во все типы,
|
2
|
+
# например, String, Checkboxes и т. п.
|
3
|
+
#
|
4
|
+
# class CckForms::ParameterTypeClass::NewType
|
5
|
+
# include CckForms::ParameterTypeClass::Base
|
6
|
+
#
|
7
|
+
# def self.name
|
8
|
+
# 'Новый тип'
|
9
|
+
# end
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# CckForms::ParameterTypeClass::NewType.name # 'Новый тип', берется из CckForms::ParameterTypeClass::NewType::name
|
13
|
+
#
|
14
|
+
# Использование типов:
|
15
|
+
#
|
16
|
+
# field :cover_photo, type: CckForms::ParameterTypeClass::Image
|
17
|
+
# field :gallery, type: CckForms::ParameterTypeClass::Album
|
18
|
+
# field :description, type: CckForms::ParameterTypeClass::Text
|
19
|
+
#
|
20
|
+
# Что есть в базовом типе:
|
21
|
+
#
|
22
|
+
# 1) все помощники УРЛов вида edit_article_path, включаемые через include Rails.application.routes.url_helpers;
|
23
|
+
#
|
24
|
+
# 2) методы cck_param и value, которые возвращают текущий параметр (module CckForms::*::Parameter) и его значение;
|
25
|
+
#
|
26
|
+
# 3) методы with_cck_param(param) do ... и with_value(value) do ..., которые устанавливают соотв, значения методов
|
27
|
+
# cck_param/value на время выполнения блока (еще есть with_cck_param_and_value(param, value) do ...);
|
28
|
+
#
|
29
|
+
# 4) динамический метод (через method_missing и respond_to?) ..._with_value(value, args*), который делает то же,
|
30
|
+
# что и with_value, но для вызова 1 метода;
|
31
|
+
#
|
32
|
+
# 5) set_value_in_hash(hash), который кладет value в hash[:value];
|
33
|
+
#
|
34
|
+
# 6) помощники для получения ХТМЛ ID form(_builder)?_name_to_id;
|
35
|
+
#
|
36
|
+
# 7) методы для потребителей (типизированных объектов):
|
37
|
+
#
|
38
|
+
# self.code - код типа из имени модуля (CckForms::ParameterType::RichText -> rich_text)
|
39
|
+
# self.name - имя типа ("Cтрока")
|
40
|
+
#
|
41
|
+
module CckForms::ParameterTypeClass::Base
|
42
|
+
extend ActiveSupport::Concern
|
43
|
+
|
44
|
+
included do
|
45
|
+
# Кое-где понадобятся помогайки-пути, сразу их включим.
|
46
|
+
include Rails.application.routes.url_helpers
|
47
|
+
|
48
|
+
attr_accessor :value
|
49
|
+
attr_reader :valid_values_class_name, :cck_parameter
|
50
|
+
|
51
|
+
def initialize(options)
|
52
|
+
options = options.symbolize_keys
|
53
|
+
|
54
|
+
self.value = options[:value]
|
55
|
+
if value.is_a?(Hash) && value.has_key?('value')
|
56
|
+
self.value = self.value['value']
|
57
|
+
end
|
58
|
+
|
59
|
+
valid_values = options.delete(:valid_values).presence
|
60
|
+
valid_values_class_name = options.delete(:valid_values_class_name)
|
61
|
+
cck_parameter = options.delete(:cck_parameter)
|
62
|
+
|
63
|
+
@valid_values = valid_values
|
64
|
+
@valid_values_class_name = valid_values_class_name
|
65
|
+
@cck_parameter = cck_parameter
|
66
|
+
@extra_options = options[:extra_options] || options.dup
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
module ClassMethods
|
73
|
+
def demongoize(something_from_database)
|
74
|
+
new value: demongoize_value(something_from_database)
|
75
|
+
end
|
76
|
+
|
77
|
+
def demongoize_value(value, parameter_type_class=nil)
|
78
|
+
value
|
79
|
+
end
|
80
|
+
|
81
|
+
def mongoize(object)
|
82
|
+
case object
|
83
|
+
when self then object.mongoize
|
84
|
+
# TODO: why only these classes? does any scalar fit?
|
85
|
+
when Hash, Array, String then new(value: object).mongoize
|
86
|
+
else object
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Возвращает строку с яваскриптовым кодом для выполнения в БД кода emit операции map-reduce на поле данного типа.
|
91
|
+
# Поскольку у различных типов данные в БД хранятся по-разному, и вообще понятие "текущего значения этого типа"
|
92
|
+
# различается, мы вынуждены отдельно описывать операцию emit, там где это необходимо. Смысл в том, чтобы этот метод
|
93
|
+
# вызвал emit для каждого хранимого значения.
|
94
|
+
#
|
95
|
+
# Пример: есть поле city типа checkboxes, хранящее список городов, то-есть объекты, описываемые этим полем,
|
96
|
+
# могут быть в разных городах. Если мы хотим сделать группировочный запрос (частный случай map-reduce) в БД, чтобы,
|
97
|
+
# например, подсчитать кол-во объектов в городах, мы не можем просто сделать emit для всего поля city, поскольку
|
98
|
+
# оно содержит список городов. Мы должны вызывать emit для каждого элемента массива (т. е., для каждого идентификатора
|
99
|
+
# города). Генерацией этого кода и занимается этот метод.
|
100
|
+
#
|
101
|
+
# В частности, он используется при подсчете популярных значения различных полей (сколько объявлений, поданых
|
102
|
+
# в разные города, и т. п.)
|
103
|
+
#
|
104
|
+
# По-умолчанию, считаем, что значение, хранимое в поле "#{feild_name}" атомарно, и вызываем emit для него.
|
105
|
+
#
|
106
|
+
# Подробнее про map-reduce см. http://docs.mongodb.org/manual/applications/map-reduce/
|
107
|
+
def emit_map_reduce(feild_name)
|
108
|
+
field_name = 'this.' + feild_name
|
109
|
+
"if(#{field_name} && #{field_name} != '') emit(#{field_name}, 1)"
|
110
|
+
end
|
111
|
+
|
112
|
+
# Конвертирует имя элемента формы в ID, например facility[cck_params][1][value] -> facility_cck_params_1_value.
|
113
|
+
def form_name_to_id(name)
|
114
|
+
name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, '_').sub(/_\z/, '')
|
115
|
+
end
|
116
|
+
|
117
|
+
# Методы, которые нужны наследникам (CckForms::ParameterTypeClass::*) для отображения, сортировки и прочей настройки самих типов.
|
118
|
+
# Эти методы не нужны обычным объектам - пользователям типов.
|
119
|
+
|
120
|
+
# CckForms::ParameterTypeClass::Checkboxes -> 'checkboxes'
|
121
|
+
# CckForms::ParameterTypeClass::RichText -> 'rich_text'
|
122
|
+
def code
|
123
|
+
self.to_s.demodulize.underscore
|
124
|
+
end
|
125
|
+
|
126
|
+
# Имя типа, например, для select>option[value]
|
127
|
+
def name
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
# Загрузит все классы-наследники.
|
135
|
+
# TODO: relies on all classes to reside in this class' directory
|
136
|
+
def self.load_type_classes
|
137
|
+
return if @type_classes_loaded
|
138
|
+
|
139
|
+
path = File.dirname(__FILE__)
|
140
|
+
Dir[path + '/*.rb'].each do |filename|
|
141
|
+
require_dependency filename unless filename.ends_with? '/base.rb'
|
142
|
+
end
|
143
|
+
|
144
|
+
@type_classes_loaded = true
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
# "Нормальные" методы, которые будут доступны всем пользователям данного модуля.
|
150
|
+
|
151
|
+
# -> [[key1, value1], [key2, value2], ...]
|
152
|
+
# Нужен для построения ХТМЛ СЕЛЕКТов.
|
153
|
+
def valid_values_enum
|
154
|
+
valid_values = self.valid_values
|
155
|
+
return [] if valid_values.blank?
|
156
|
+
result = []
|
157
|
+
method_for_enumerating = valid_values.is_a?(Array) ? :each_with_index : :each_pair
|
158
|
+
valid_values.send(method_for_enumerating) do |key, value|
|
159
|
+
result.push [value, key]
|
160
|
+
end
|
161
|
+
result
|
162
|
+
end
|
163
|
+
|
164
|
+
# -> "georgian: грузинская, albanian: албанская"
|
165
|
+
# Нужен для построения ХТМЛа и строк.
|
166
|
+
def valid_values_as_string
|
167
|
+
valid_values_enum.map { |enum| "#{enum[1]}: #{enum[0]}" }.join "\n"
|
168
|
+
end
|
169
|
+
|
170
|
+
# Чтобы получать данные из форм и сохранять в БД. Использовать во вьюхах:
|
171
|
+
# = f.text_field :valid_values_as_string
|
172
|
+
def valid_values_as_string=(string)
|
173
|
+
new_valid_values = {}
|
174
|
+
string.split("\n").reject { |line| line.blank? }.each do |line|
|
175
|
+
splitted = line.split(':', 2)
|
176
|
+
new_valid_values[splitted[0].strip] = splitted[1].strip if splitted.length == 2 and splitted[0].present?
|
177
|
+
end
|
178
|
+
self.valid_values = new_valid_values
|
179
|
+
end
|
180
|
+
|
181
|
+
# Вернет класс, указанный как valid_values_class_name.
|
182
|
+
# "City" -> City
|
183
|
+
def valid_values_class
|
184
|
+
if valid_values_class_name.present?
|
185
|
+
if valid_values_class_name.is_a? Class
|
186
|
+
valid_values_class_name
|
187
|
+
else # если это не строка, то пусть будет выборошено исключение
|
188
|
+
valid_values_class_name.constantize
|
189
|
+
end
|
190
|
+
else
|
191
|
+
nil
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Существует ли valid_values_class?
|
196
|
+
def valid_values_class?
|
197
|
+
not valid_values_class.nil?
|
198
|
+
end
|
199
|
+
|
200
|
+
# Если valid_values пустой, и есть valid_values_class, запишет в valid_values все значения
|
201
|
+
# из valid_values_class. Считает, что класс похож на ActiveRecord, и значения берет из all.
|
202
|
+
def valid_values
|
203
|
+
@valid_values ||= begin
|
204
|
+
if vv_class = valid_values_class
|
205
|
+
valid_values = {}
|
206
|
+
vv_class.all.each { |valid_value_object| valid_values[valid_value_object.id] = valid_value_object.to_s }
|
207
|
+
valid_values
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Строит форму редактирования. Просто input:text со всеми переданными опциями (значение можно определить через
|
213
|
+
# options[:value]).
|
214
|
+
def build_form(form_builder, options)
|
215
|
+
set_value_in_hash options
|
216
|
+
form_builder.text_field :value, options
|
217
|
+
end
|
218
|
+
|
219
|
+
# Вернем в виде HTML
|
220
|
+
def to_html(options = nil)
|
221
|
+
to_s options
|
222
|
+
end
|
223
|
+
|
224
|
+
# Чтобы принимать аргумент options
|
225
|
+
def to_s(options = nil)
|
226
|
+
value.to_s
|
227
|
+
end
|
228
|
+
|
229
|
+
# Отображение для страниц "было-стало" в админках и пр. (например, тип "карта" можнет вернуть ХТМЛ картинки-миниатюры).
|
230
|
+
def to_diff_value(options = nil)
|
231
|
+
to_html options
|
232
|
+
end
|
233
|
+
|
234
|
+
# Формируем поисковый запрос для монго на основе запроса (типа мини-DSL язык запроса, свой для каждого типа).
|
235
|
+
def search(selectable, field, query)
|
236
|
+
selectable.where(field => query.to_s)
|
237
|
+
end
|
238
|
+
|
239
|
+
# Нужен для Rails.application.routes.url_helpers
|
240
|
+
def default_url_options
|
241
|
+
{}
|
242
|
+
end
|
243
|
+
|
244
|
+
# Реализация перобразования в/из Монго по умолчанию: берем то, что в value
|
245
|
+
def mongoize
|
246
|
+
value
|
247
|
+
end
|
248
|
+
|
249
|
+
def demongoize_value
|
250
|
+
self.class.demongoize_value value, self
|
251
|
+
end
|
252
|
+
|
253
|
+
def demongoize_value!
|
254
|
+
self.value = demongoize_value
|
255
|
+
end
|
256
|
+
|
257
|
+
|
258
|
+
|
259
|
+
private
|
260
|
+
|
261
|
+
# options[:value] = value
|
262
|
+
def set_value_in_hash(options)
|
263
|
+
options[:value] = value unless options.has_key? :value
|
264
|
+
end
|
265
|
+
|
266
|
+
# См. ClassMethod.form_name_to_id
|
267
|
+
def form_name_to_id(name)
|
268
|
+
self.class.form_name_to_id name
|
269
|
+
end
|
270
|
+
|
271
|
+
# Конвертирует имя элемента формы из FormBuilder, см. form_name_to_id.
|
272
|
+
def form_builder_name_to_id(form_builder, suffix = '')
|
273
|
+
form_name_to_id([form_builder.options[:namespace], form_builder.object_name].compact.join('_') + suffix)
|
274
|
+
end
|
275
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::Boolean
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
|
4
|
+
def self.name
|
5
|
+
'Галочка (да/нет)'
|
6
|
+
end
|
7
|
+
|
8
|
+
def value?
|
9
|
+
value.present? && value != '0'
|
10
|
+
end
|
11
|
+
|
12
|
+
def mongoize
|
13
|
+
value?
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s(options = nil)
|
17
|
+
value? ? 'да' : 'нет'
|
18
|
+
end
|
19
|
+
|
20
|
+
def build_form(form_builder, options)
|
21
|
+
set_value_in_hash options
|
22
|
+
form_builder.check_box :value, options.merge(value: 1, checked: value?)
|
23
|
+
end
|
24
|
+
end
|