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