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
@@ -0,0 +1,202 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::Checkboxes
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
|
4
|
+
def self.name
|
5
|
+
'Галочки'
|
6
|
+
end
|
7
|
+
|
8
|
+
# {kazakh: '1', russian: '0', english: '1'} -> ['kazakh', 'english']
|
9
|
+
def mongoize
|
10
|
+
resulting_set = []
|
11
|
+
|
12
|
+
if value.is_a? Array
|
13
|
+
return value
|
14
|
+
elsif value.is_a?(String) || value.is_a?(Symbol)
|
15
|
+
return [value.to_s]
|
16
|
+
elsif !value.is_a?(Hash)
|
17
|
+
return []
|
18
|
+
end
|
19
|
+
|
20
|
+
value.each do |key, value|
|
21
|
+
resulting_set << key if value.to_s == '1'
|
22
|
+
end
|
23
|
+
|
24
|
+
resulting_set
|
25
|
+
end
|
26
|
+
|
27
|
+
# ['kazakh', 'english'] -> {'kazakh' => 1, 'russain' => 0, 'english' => 1}
|
28
|
+
# (такой формат нужен формам)
|
29
|
+
def self.demongoize_value(value, parameter_type_class=nil)
|
30
|
+
value.present? or return {}
|
31
|
+
|
32
|
+
valid_values = parameter_type_class.try!(:valid_values) || value.map { |x| [x, nil] }
|
33
|
+
valid_values.reduce({}) do |r, (key, _)|
|
34
|
+
r[key] = value.include?(key) ? '1' : '0'
|
35
|
+
r
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Перечислим все отмеченные элементы в строку.
|
40
|
+
# options[:block] - задает шаблон sprintf для каждого вхождения
|
41
|
+
# options[:only] - массив, оставить только эти ключи (можно передать одно, без массива)
|
42
|
+
# options[:except] - :only наоборот
|
43
|
+
# options[:glue] - используем его вместо ', ' для склейки значений
|
44
|
+
# options[:short] - по-возможности сокращать: если указаны все варианты, то вернется строка вида "выбрано все"
|
45
|
+
# - или "все, кроме xxx", если не выбран только xxx
|
46
|
+
def to_s(options = nil)
|
47
|
+
checked_keys, checked_elements = [], []
|
48
|
+
return '' if value.blank?
|
49
|
+
|
50
|
+
template = '%s'
|
51
|
+
if options
|
52
|
+
options = {block: options} unless options.is_a? Hash
|
53
|
+
template = options[:block] if options[:block]
|
54
|
+
else
|
55
|
+
options = {}
|
56
|
+
end
|
57
|
+
|
58
|
+
if value.respond_to? :each_pair
|
59
|
+
value.each_pair do |k, v|
|
60
|
+
include = v == '1' && (!options[:only] || options[:only] && options[:only] == k)
|
61
|
+
exclude = options[:except] && options[:except] == k
|
62
|
+
if include && !exclude
|
63
|
+
checked_elements << sprintf(template, valid_values[k])
|
64
|
+
checked_keys << k
|
65
|
+
end
|
66
|
+
end
|
67
|
+
elsif value.respond_to? :each
|
68
|
+
value.each do |k|
|
69
|
+
exclude = options[:except] && options[:except] == k
|
70
|
+
unless exclude
|
71
|
+
checked_elements << sprintf(template, valid_values[k])
|
72
|
+
checked_keys << k
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
glue = options[:glue] || ', '
|
78
|
+
if options[:short] && checked_keys
|
79
|
+
all_keys = valid_values.keys
|
80
|
+
unchecked_keys = all_keys - checked_keys
|
81
|
+
unchecked_num = unchecked_keys.count
|
82
|
+
|
83
|
+
param_title = cck_parameter ? " «#{cck_parameter.title}»" : ''
|
84
|
+
|
85
|
+
if unchecked_num == 0
|
86
|
+
return "Все значения#{param_title}"
|
87
|
+
elsif unchecked_num < checked_keys.count./(2).round
|
88
|
+
return "Все значения#{param_title}, кроме " + valid_values.values_at(*unchecked_keys).map { |x| sprintf(template, x) }.join(glue)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
checked_elements.join glue
|
93
|
+
end
|
94
|
+
|
95
|
+
def search(selectable, field, query)
|
96
|
+
if query.respond_to? :each_pair
|
97
|
+
keys = []
|
98
|
+
query.each_pair do |key, value|
|
99
|
+
if value.present? && value != '0'
|
100
|
+
if key == 'any'
|
101
|
+
selectable = selectable.where(field.to_sym.ne => [])
|
102
|
+
else
|
103
|
+
keys << key
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
selectable = selectable.where(field.to_sym.all => keys) if keys.any?
|
108
|
+
else
|
109
|
+
selectable = selectable.where(field.to_s => query)
|
110
|
+
end
|
111
|
+
|
112
|
+
selectable
|
113
|
+
end
|
114
|
+
|
115
|
+
# Составим строку для map-reduce, чтобы emit вызывался на каждом отмеченном значении, например, в документе хранится:
|
116
|
+
#
|
117
|
+
# cck_params.city: ['almaty', 'astana']
|
118
|
+
#
|
119
|
+
# Мы вызовем emit('almaty', 1); emit('astana', 1).
|
120
|
+
def self.emit_map_reduce(field_name)
|
121
|
+
field_name = 'this.' + field_name
|
122
|
+
return "if(#{field_name} && #{field_name} instanceof Array) {
|
123
|
+
#{field_name}.forEach(function(key) {
|
124
|
+
emit(key, 1)
|
125
|
+
})
|
126
|
+
}"
|
127
|
+
end
|
128
|
+
|
129
|
+
# options[:block] - задает шаблон sprintf для каждого чекбокса (input, label)
|
130
|
+
# options[:map] - задает преобразование (ключ-значение) текстов в подписях, например, 'длинный текст' => 'кор. ткст'
|
131
|
+
# options[:data] - задает data-атрибуты для тэга label, по ключу из valid_values (capital: {almaty: 'yes', astana: 'no'})
|
132
|
+
# options[:as] - если :select, то показать не в виде чекбоксов, а в виде выпадайки
|
133
|
+
# options[:only] - только этот ключ (ключи)
|
134
|
+
def build_form(form_builder, options)
|
135
|
+
return '' unless valid_values.is_a?(Hash) || valid_values.is_a?(Array)
|
136
|
+
|
137
|
+
if options.is_a? Hash and options[:as] == :select
|
138
|
+
return build_select_form(form_builder, options.except(:for, :as))
|
139
|
+
end
|
140
|
+
|
141
|
+
options = {block: '<div class="form_check_box_block">%s %s</div>', map: {}}.merge(options)
|
142
|
+
|
143
|
+
set_value_in_hash options
|
144
|
+
val = options[:value]
|
145
|
+
|
146
|
+
result = ''
|
147
|
+
if valid_values.is_a? Array
|
148
|
+
method = :each_with_index
|
149
|
+
elsif valid_values.is_a? Hash
|
150
|
+
method = :each_pair
|
151
|
+
end
|
152
|
+
|
153
|
+
valid_values.send(method) do |k, v|
|
154
|
+
if !options[:only] || options[:only] == k || options[:only].try(:include?, k)
|
155
|
+
result += form_builder.fields_for :value do |ff|
|
156
|
+
|
157
|
+
begin
|
158
|
+
checked = ! val.try(:[], k).to_i.zero?
|
159
|
+
rescue
|
160
|
+
checked = false
|
161
|
+
end
|
162
|
+
|
163
|
+
v = options[:map][v] || v
|
164
|
+
|
165
|
+
# required не встраиваю, иначе пока я все чекбоксы не отмечу, не могу отправить форму
|
166
|
+
data = options[:data] ? extract_data_for_key(k, options[:data]) : nil
|
167
|
+
sprintf(options[:block], ff.check_box(k.to_sym, {checked: checked}, '1', options[:for] == :search ? nil : '0'), ff.label(k.to_sym, v, data: data)).html_safe
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
result
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
def build_select_form(form_builder, options)
|
180
|
+
set_value_in_hash options
|
181
|
+
|
182
|
+
values = valid_values_enum
|
183
|
+
if options[:only]
|
184
|
+
options[:only] = [options[:only]] unless options[:only].is_a? Array
|
185
|
+
values.select! { |o| o[1].in? options[:only] }
|
186
|
+
end
|
187
|
+
|
188
|
+
if options[:except]
|
189
|
+
options[:except] = [options[:except]] unless options[:except].is_a? Array
|
190
|
+
values.reject! { |o| o[1].in? options[:except] }
|
191
|
+
end
|
192
|
+
|
193
|
+
form_builder.select :value, values, {selected: options[:value], required: options[:required], include_blank: !options[:required]}, class: 'form-control'
|
194
|
+
end
|
195
|
+
|
196
|
+
def extract_data_for_key(request_key, data)
|
197
|
+
data.reduce({}) do |r, (key, values)|
|
198
|
+
r[key] = values[request_key] if values[request_key]
|
199
|
+
r
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::Date
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
include CckForms::DateTime
|
4
|
+
|
5
|
+
def self.name
|
6
|
+
'Дата'
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_form(form_builder, options)
|
10
|
+
set_value_in_hash options
|
11
|
+
self.class.build_date_form(form_builder, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.build_date_form(form_builder, options, type = '')
|
15
|
+
val = options[:value].is_a?(Hash) ? options[:value][type] : options[:value]
|
16
|
+
val = CckForms::ParameterTypeClass::Time::date_object_from_what_stored_in_database(val)
|
17
|
+
form_element_options, form_element_html = CckForms::ParameterTypeClass::Time::default_options_for_date_time_selectors(val)
|
18
|
+
form_element_html.merge!({required: options[:required]})
|
19
|
+
('<div class="form-inline">%s</div>' % form_builder.fields_for(:value) { |datetime_builder| datetime_builder.date_select type, form_element_options, form_element_html}).html_safe
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s(options = nil)
|
23
|
+
if value.is_a? Time
|
24
|
+
the_value = {
|
25
|
+
'(1i)' => value.year,
|
26
|
+
'(2i)' => value.month,
|
27
|
+
'(3i)' => value.day,
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
the_value ||= value
|
32
|
+
|
33
|
+
"#{the_value.try(:[], '(3i)')}.#{the_value.try(:[], '(2i)')}.#{the_value.try(:[], '(1i)')}"
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::DateRange
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
|
4
|
+
def self.name
|
5
|
+
'Диапазон между двумя датами'
|
6
|
+
end
|
7
|
+
|
8
|
+
def mongoize
|
9
|
+
value_from_form = value
|
10
|
+
return nil if value_from_form.blank?
|
11
|
+
db_representation = {}
|
12
|
+
|
13
|
+
%w(from till).each do |type|
|
14
|
+
type_hash = {}
|
15
|
+
%w((1i) (2i) (3i)).each do |field|
|
16
|
+
type_hash.merge!("#{field}" => value_from_form.try(:[], "#{type + field}"))
|
17
|
+
end
|
18
|
+
db_representation[type] = CckForms::ParameterTypeClass::Time::date_object_from_what_stored_in_database(type_hash)
|
19
|
+
end
|
20
|
+
|
21
|
+
db_representation
|
22
|
+
end
|
23
|
+
|
24
|
+
def build_form(form_builder, options)
|
25
|
+
result = []
|
26
|
+
set_value_in_hash options
|
27
|
+
|
28
|
+
[:from, :till].each do |type|
|
29
|
+
result << CckForms::ParameterTypeClass::Date.build_date_form(form_builder, options, type)
|
30
|
+
end
|
31
|
+
|
32
|
+
result.join.html_safe
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
return '' unless value.present? && value.is_a?(Hash)
|
37
|
+
types = {}
|
38
|
+
[:from, :till].each { |type| types[type] = value[type].strftime('%d.%m.%Y') if value[type].is_a?(Time) }
|
39
|
+
from, till = types[:from], types[:till]
|
40
|
+
|
41
|
+
if from.blank?
|
42
|
+
"до #{till}"
|
43
|
+
elsif till.blank?
|
44
|
+
"от #{from}"
|
45
|
+
elsif from == till
|
46
|
+
from.to_s
|
47
|
+
else
|
48
|
+
[from, till].join(' - ')
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::DateTime
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
include CckForms::DateTime
|
4
|
+
|
5
|
+
def self.name
|
6
|
+
'Дата и время'
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_form(form_builder, options)
|
10
|
+
set_value_in_hash options
|
11
|
+
value = CckForms::ParameterTypeClass::Time::date_object_from_what_stored_in_database(options[:value])
|
12
|
+
form_element_options, form_element_html = CckForms::ParameterTypeClass::Time.default_options_for_date_time_selectors(value)
|
13
|
+
form_element_options.merge!({minute_step: 5})
|
14
|
+
form_element_html.merge!({required: options[:required]})
|
15
|
+
('<div class="form-inline">%s</div>' % form_builder.fields_for(:value) { |datetime_builder| datetime_builder.datetime_select '', form_element_options, form_element_html})
|
16
|
+
end
|
17
|
+
|
18
|
+
# Формирует строковое представление даты и времени. Если options :символ, это эквивалентно options[:символ] = true,
|
19
|
+
# например:
|
20
|
+
#
|
21
|
+
# date_attr.to_s :only_date
|
22
|
+
# date_attr.to_s :only_date => true # эквивалентно
|
23
|
+
#
|
24
|
+
# Ключи options:
|
25
|
+
#
|
26
|
+
# year_obligatory - вывести год, по-умолчанию, он не показывается, если равен текущему
|
27
|
+
# only_date - только дату, без времени
|
28
|
+
# rus_date - дату по-русски, типа "2 июля"
|
29
|
+
#
|
30
|
+
# По-умолчанию, вернет строку вида "01.02.2012, 12:49". Если что-то сломалось, вернет пустую строку.
|
31
|
+
def to_s(options=nil)
|
32
|
+
value = if self.value.is_a? Time
|
33
|
+
{
|
34
|
+
'(1i)' => self.value.year,
|
35
|
+
'(2i)' => self.value.month,
|
36
|
+
'(3i)' => self.value.day,
|
37
|
+
'(4i)' => self.value.hour,
|
38
|
+
'(5i)' => self.value.min,
|
39
|
+
}
|
40
|
+
else
|
41
|
+
self.value
|
42
|
+
end
|
43
|
+
|
44
|
+
return '' unless value and
|
45
|
+
value.is_a?(Hash) and
|
46
|
+
value.try(:[], '(1i)').to_i > 0 and
|
47
|
+
value.try(:[], '(2i)').to_i > 0 and
|
48
|
+
value.try(:[], '(3i)').to_i > 0
|
49
|
+
|
50
|
+
options = {options => true} if options.is_a? Symbol
|
51
|
+
options = {} unless options.is_a? Hash
|
52
|
+
|
53
|
+
now = Date::today
|
54
|
+
date = DateTime.new value.try(:[], '(1i)').to_i, value.try(:[], '(2i)').to_i, value.try(:[], '(3i)').to_i, value.try(:[], '(4i)').to_i, value.try(:[], '(5i)').to_i
|
55
|
+
date = date.in_time_zone(Rails.application.config.time_zone)
|
56
|
+
|
57
|
+
need_year = options[:year_obligatory] || now.strftime('%Y') != date.strftime('%Y')
|
58
|
+
|
59
|
+
if options[:rus_date]
|
60
|
+
date_string = Russian::strftime(date, '%e %B' + (need_year ? ' %Y' : '')) # 2 июля
|
61
|
+
else
|
62
|
+
date_string = date.strftime('%d.%m' + (need_year ? '.%Y' : ''))
|
63
|
+
end
|
64
|
+
|
65
|
+
time_string = date.strftime '%H:%M'
|
66
|
+
|
67
|
+
if options[:only_date]
|
68
|
+
return date_string
|
69
|
+
else
|
70
|
+
return "#{date_string}, #{time_string}"
|
71
|
+
end
|
72
|
+
|
73
|
+
rescue
|
74
|
+
''
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::Enum
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
|
4
|
+
def self.name
|
5
|
+
'Значение из списка'
|
6
|
+
end
|
7
|
+
|
8
|
+
def mongoize
|
9
|
+
value.presence
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s(options = nil)
|
13
|
+
return '' if value.blank?
|
14
|
+
valid_values[value].to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def search(selectable, field, query)
|
18
|
+
if query.is_a? Hash
|
19
|
+
query = query.map { |k, v| v == '1' ? k : nil }.compact
|
20
|
+
end
|
21
|
+
query = [query] unless query.is_a? Array
|
22
|
+
|
23
|
+
if query.any?
|
24
|
+
selectable.where(field.to_sym.in => query)
|
25
|
+
else
|
26
|
+
selectable
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def build_form(form_builder, options)
|
31
|
+
|
32
|
+
if options.is_a? Hash and options[:as] == 'checkboxes'
|
33
|
+
options = options.except(:for, :as)
|
34
|
+
checkboxes = CckForms::ParameterTypeClass::Checkboxes.new valid_values: self.valid_values, value: self.value
|
35
|
+
return checkboxes.build_form(form_builder, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
set_value_in_hash options
|
39
|
+
|
40
|
+
values = valid_values_enum
|
41
|
+
if options[:only]
|
42
|
+
options[:only] = [options[:only]] unless options[:only].is_a? Array
|
43
|
+
values.select! { |o| o[1].in? options[:only] }
|
44
|
+
end
|
45
|
+
|
46
|
+
if options[:except]
|
47
|
+
options[:except] = [options[:except]] unless options[:except].is_a? Array
|
48
|
+
values.reject! { |o| o[1].in? options[:except] }
|
49
|
+
end
|
50
|
+
|
51
|
+
form_builder.select :value, values, {selected: options[:value], required: options[:required], include_blank: !options[:required]}, class: 'form-control '
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::File
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
|
4
|
+
def self.name
|
5
|
+
'Файл'
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.file_type
|
9
|
+
::Neofiles::File
|
10
|
+
end
|
11
|
+
|
12
|
+
def file_type
|
13
|
+
self.class.file_type
|
14
|
+
end
|
15
|
+
|
16
|
+
# Если передан Neofiles::File, вернет его идентификатор, если строка - вернет ее, иначе - nil.
|
17
|
+
def mongoize
|
18
|
+
case value
|
19
|
+
when file_type then value.id
|
20
|
+
when ::String then value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Попытаемся получить объект Neofiles::File по его идентификатору. Если не получилось, вернем nil.
|
25
|
+
def self.demongoize_value(value, parameter_type_class=nil)
|
26
|
+
file_type.find(value) unless value.blank?
|
27
|
+
rescue Mongoid::Errors::DocumentNotFound
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# Строит форму выбора и загрузки 1 картинки.
|
32
|
+
#
|
33
|
+
# Ставит ДИВ и делает аяксовый вызов метода file_compact контроллера Neofiles::AdminController.
|
34
|
+
#
|
35
|
+
# Ключи options:
|
36
|
+
#
|
37
|
+
# value - текущее значение (идентификатор или объект Neofiles::File)
|
38
|
+
#
|
39
|
+
def build_form(form_builder, options)
|
40
|
+
set_value_in_hash options
|
41
|
+
self.class.create_load_form helper: self,
|
42
|
+
file: options[:value].presence,
|
43
|
+
input_name: form_builder.object_name + '[value]',
|
44
|
+
widget_id: form_builder_name_to_id(form_builder, '[value]'),
|
45
|
+
with_desc: options[:with_desc]
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.create_load_form(helper:, file:, input_name:, append_create: false, clean_remove: false, widget_id: nil, disabled: false, multiple: false, with_desc: false)
|
49
|
+
cont_id = 'container_' + (widget_id.presence || form_name_to_id(input_name))
|
50
|
+
|
51
|
+
# создаем временное поле, чтобы пока аяксовый ответ не вернется, мы могли все же отправить родительскую форму
|
52
|
+
# и не потерять при этом данные из поля
|
53
|
+
temp_field, remove_temp_field = '', ''
|
54
|
+
if file.present? && file.is_a?(String)
|
55
|
+
temp_id = "temp_file_field_#{file}"
|
56
|
+
temp_field = '<input id="' + temp_id + '" type="hidden" name="' + input_name + '" value="' + file + '">'
|
57
|
+
remove_temp_field = '$("#' + temp_id + '").remove();'
|
58
|
+
end
|
59
|
+
|
60
|
+
'<div id="' + cont_id + '"></div>
|
61
|
+
' + temp_field + '
|
62
|
+
|
63
|
+
<script type="text/javascript">
|
64
|
+
$(function() {
|
65
|
+
$("#' + cont_id + '").load("' + helper.neofiles_file_compact_path(id: file, input_name: input_name, widget_id: widget_id, append_create: append_create ? '1' : nil, clean_remove: clean_remove ? '1' : nil, disabled: disabled ? '1' : nil, multiple: multiple ? '1' : nil, with_desc: with_desc ? '1' : nil) + '", null, function() {
|
66
|
+
$(this).children().unwrap();
|
67
|
+
' + remove_temp_field + '
|
68
|
+
});
|
69
|
+
});
|
70
|
+
</script>'
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_s
|
74
|
+
''
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_diff_value(options = {})
|
78
|
+
"Файл: #{self.value.try! :name}"
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::Float
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
|
4
|
+
def self.name
|
5
|
+
'Дробное число'
|
6
|
+
end
|
7
|
+
|
8
|
+
def mongoize
|
9
|
+
value.to_f
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s(options = nil)
|
13
|
+
value.to_f != 0.0 ? value.to_f : ''
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_form(form_builder, options)
|
17
|
+
set_value_in_hash options
|
18
|
+
form_builder.number_field :value, {class: 'form-control input-small'}.merge(options)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::Image < CckForms::ParameterTypeClass::File
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
|
4
|
+
def self.name
|
5
|
+
'Картинка'
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.file_type
|
9
|
+
::Neofiles::Image
|
10
|
+
end
|
11
|
+
|
12
|
+
def file_type
|
13
|
+
self.class.file_type
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_diff_value(options = {})
|
17
|
+
view_context = options[:view_context]
|
18
|
+
"<img style='width: 64px; height: 64px;' src='#{view_context.neofiles_image_path(id: value, format: '64x64', crop: 1)}'>".html_safe
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
class CckForms::ParameterTypeClass::Integer
|
2
|
+
include CckForms::ParameterTypeClass::Base
|
3
|
+
|
4
|
+
def self.name
|
5
|
+
'Целое число'
|
6
|
+
end
|
7
|
+
|
8
|
+
def mongoize
|
9
|
+
value.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s(options = nil)
|
13
|
+
value.to_i != 0 ? value.to_i.to_s : ''
|
14
|
+
end
|
15
|
+
|
16
|
+
# '123' -> 123
|
17
|
+
# '100/' -> $gte: 100
|
18
|
+
# '100/150' -> $gte: 100, $lte: 150
|
19
|
+
# '/150' -> $lte: 150
|
20
|
+
#
|
21
|
+
# l: 100 -> $gte: 100
|
22
|
+
# l: 100, h: 150 -> $gte: 100, $lte: 150
|
23
|
+
# h: 150 -> $lte: 150
|
24
|
+
def search(selectable, field, query)
|
25
|
+
if query.is_a?(Hash) || query.to_s.include?('/')
|
26
|
+
low, high = query.is_a?(Hash) ? [query[:l] || query['l'], query[:h] || query['h']] : query.to_s.split('/')
|
27
|
+
|
28
|
+
if low.to_i > 0
|
29
|
+
selectable = selectable.gte(field => low.to_i)
|
30
|
+
end
|
31
|
+
|
32
|
+
if high.to_i > 0
|
33
|
+
selectable = selectable.lte(field => high.to_i)
|
34
|
+
end
|
35
|
+
|
36
|
+
selectable
|
37
|
+
else
|
38
|
+
selectable.where(field => query.to_i)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Примеры options[:values] (работает, если передано options[:as] == :select и options[:for] == :search):
|
43
|
+
#
|
44
|
+
# диапазоны: [['не больше 10', '/10'], ['11-20', '11/20'], ['21-30', '21/30'], ['свыше 30', '31/']]
|
45
|
+
# перечисление: [['один', '1'], ['два', '2'], ['три', '3']]
|
46
|
+
# комбинирование: [['один', '1'], ['два', '2'], ['три и больше', '3/']]
|
47
|
+
def build_form(form_builder, options = {})
|
48
|
+
set_value_in_hash options
|
49
|
+
|
50
|
+
default_style = {class: 'form-control input-small'}
|
51
|
+
|
52
|
+
if options[:for] == :search
|
53
|
+
res = []
|
54
|
+
as = options[:as]
|
55
|
+
only = options[:only]
|
56
|
+
options = options.except :only, :for
|
57
|
+
|
58
|
+
if as == :select
|
59
|
+
res << form_builder.select(:value, [['', '']] + options[:values], options.merge(selected: options[:value]), class: 'form-control input-small')
|
60
|
+
else
|
61
|
+
value = options[:value].is_a?(Hash) ? options[:value].symbolize_keys : {}
|
62
|
+
|
63
|
+
if !only || only == :low
|
64
|
+
res << form_builder.text_field(:l, options.merge(index: 'value', value: value[:l]).reverse_merge(default_style))
|
65
|
+
end
|
66
|
+
|
67
|
+
if !only || only == :high
|
68
|
+
res << form_builder.text_field(:h, options.merge(index: 'value', value: value[:h]).reverse_merge(default_style))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
res.join ' – '
|
73
|
+
else
|
74
|
+
form_builder.number_field :value, options.reverse_merge(default_style)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|