padrino-helpers 0.12.0 → 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/padrino-helpers.rb +4 -1
- data/lib/padrino-helpers/asset_tag_helpers.rb +17 -14
- data/lib/padrino-helpers/breadcrumb_helpers.rb +6 -6
- data/lib/padrino-helpers/form_builder/abstract_form_builder.rb +119 -163
- data/lib/padrino-helpers/form_builder/deprecated_builder_methods.rb +92 -0
- data/lib/padrino-helpers/form_helpers.rb +66 -347
- data/lib/padrino-helpers/form_helpers/errors.rb +138 -0
- data/lib/padrino-helpers/form_helpers/options.rb +97 -0
- data/lib/padrino-helpers/form_helpers/security.rb +70 -0
- data/lib/padrino-helpers/output_helpers.rb +1 -1
- data/lib/padrino-helpers/output_helpers/abstract_handler.rb +1 -1
- data/lib/padrino-helpers/render_helpers.rb +10 -9
- data/lib/padrino-helpers/tag_helpers.rb +2 -1
- data/lib/padrino/rendering.rb +378 -0
- data/lib/padrino/rendering/extensions/erubis.rb +74 -0
- data/lib/padrino/rendering/extensions/haml.rb +29 -0
- data/lib/padrino/rendering/extensions/slim.rb +21 -0
- data/padrino-helpers.gemspec +2 -1
- data/test/fixtures/apps/.components +6 -0
- data/test/fixtures/apps/.gitignore +7 -0
- data/test/fixtures/apps/render.rb +25 -0
- data/test/fixtures/apps/views/article/comment/show.slim +1 -0
- data/test/fixtures/apps/views/blog/post.erb +1 -0
- data/test/fixtures/apps/views/layouts/specific.erb +1 -0
- data/test/fixtures/apps/views/test/post.erb +1 -0
- data/test/fixtures/layouts/layout.erb +1 -0
- data/test/fixtures/markup_app/app.rb +0 -1
- data/test/fixtures/render_app/app.rb +25 -1
- data/test/fixtures/render_app/views/_unsafe.html.builder +2 -0
- data/test/fixtures/render_app/views/_unsafe_object.html.builder +2 -0
- data/test/fixtures/render_app/views/ruby_block_capture_erb.erb +1 -0
- data/test/fixtures/render_app/views/ruby_block_capture_haml.haml +1 -0
- data/test/fixtures/render_app/views/ruby_block_capture_slim.slim +1 -0
- data/test/helper.rb +65 -1
- data/test/test_asset_tag_helpers.rb +83 -79
- data/test/test_breadcrumb_helpers.rb +20 -20
- data/test/test_form_builder.rb +196 -196
- data/test/test_form_helpers.rb +163 -163
- data/test/test_format_helpers.rb +65 -65
- data/test/test_locale.rb +1 -1
- data/test/test_number_helpers.rb +10 -11
- data/test/test_output_helpers.rb +28 -28
- data/test/test_render_helpers.rb +89 -35
- data/test/test_rendering.rb +683 -0
- data/test/test_rendering_extensions.rb +14 -0
- data/test/test_tag_helpers.rb +23 -23
- metadata +57 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9de9c68240b6a030c87053b1f781ef7152ef5bfc
|
4
|
+
data.tar.gz: a9a5d042cd4ed7d6dd52d9977b4421c0a40389e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0d72f6b0c05eaae7fb28d4fd7c85d7d76a9e2e7a7ef719f42040b0148cdbfb19ccdd3f790ef592328ec341edaf15acf74cda7b6e24b21aa4ce25beaa2af44fa
|
7
|
+
data.tar.gz: 97eb607b9c2caf7c9242c39afa18ceac5f63e7306d46c0e01d3041e93bf3008fef4e0a7b7f03bfc5ba9624b3cb6a7bd2fc9520e63cc9a85396af7d52c621e347
|
data/lib/padrino-helpers.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'padrino-
|
1
|
+
require 'padrino-support'
|
2
2
|
require 'i18n'
|
3
3
|
require 'enumerator'
|
4
4
|
require 'active_support/time_with_zone' # next extension depends on this
|
@@ -6,6 +6,8 @@ require 'active_support/core_ext/string/conversions' # to_date
|
|
6
6
|
require 'active_support/option_merger' # with_options
|
7
7
|
require 'active_support/core_ext/object/with_options' # with_options
|
8
8
|
require 'active_support/inflector' # humanize
|
9
|
+
require 'active_support/core_ext/hash/except' # Hash#except
|
10
|
+
require 'padrino/rendering'
|
9
11
|
|
10
12
|
FileSet.glob_require('padrino-helpers/**/*.rb', __FILE__)
|
11
13
|
I18n.load_path += Dir["#{File.dirname(__FILE__)}/padrino-helpers/locale/*.yml"]
|
@@ -41,6 +43,7 @@ module Padrino
|
|
41
43
|
# end
|
42
44
|
#
|
43
45
|
def registered(app)
|
46
|
+
app.register Padrino::Rendering
|
44
47
|
app.set :default_builder, 'StandardFormBuilder'
|
45
48
|
app.helpers Padrino::Helpers::OutputHelpers
|
46
49
|
app.helpers Padrino::Helpers::TagHelpers
|
@@ -32,11 +32,11 @@ module Padrino
|
|
32
32
|
def flash_tag(*args)
|
33
33
|
options = args.extract_options!
|
34
34
|
bootstrap = options.delete(:bootstrap) if options[:bootstrap]
|
35
|
-
args.inject(
|
36
|
-
flash_text = flash[kind]
|
35
|
+
args.inject(ActiveSupport::SafeBuffer.new) do |html,kind|
|
36
|
+
flash_text = ActiveSupport::SafeBuffer.new << flash[kind]
|
37
37
|
next html if flash_text.blank?
|
38
|
-
flash_text <<
|
39
|
-
html <<
|
38
|
+
flash_text << content_tag(:button, '×'.html_safe, {:type => :button, :class => :close, :'data-dismiss' => :alert}) if bootstrap
|
39
|
+
html << content_tag(:div, flash_text, { :class => kind }.update(options))
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -230,11 +230,13 @@ module Padrino
|
|
230
230
|
#
|
231
231
|
# @api public.
|
232
232
|
def stylesheet_link_tag(*sources)
|
233
|
-
options =
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
233
|
+
options = {
|
234
|
+
:rel => 'stylesheet',
|
235
|
+
:type => 'text/css'
|
236
|
+
}.update(sources.extract_options!.symbolize_keys)
|
237
|
+
sources.flatten.inject(ActiveSupport::SafeBuffer.new) do |all,source|
|
238
|
+
all << tag(:link, { :href => asset_path(:css, source) }.update(options))
|
239
|
+
end
|
238
240
|
end
|
239
241
|
|
240
242
|
##
|
@@ -252,11 +254,12 @@ module Padrino
|
|
252
254
|
# javascript_include_tag 'application', :extjs
|
253
255
|
#
|
254
256
|
def javascript_include_tag(*sources)
|
255
|
-
options =
|
256
|
-
|
257
|
-
sources.
|
258
|
-
|
259
|
-
|
257
|
+
options = {
|
258
|
+
:type => 'text/javascript'
|
259
|
+
}.update(sources.extract_options!.symbolize_keys)
|
260
|
+
sources.flatten.inject(ActiveSupport::SafeBuffer.new) do |all,source|
|
261
|
+
all << content_tag(:script, nil, { :src => asset_path(:js, source) }.update(options))
|
262
|
+
end
|
260
263
|
end
|
261
264
|
|
262
265
|
##
|
@@ -143,7 +143,7 @@ module Padrino
|
|
143
143
|
# # </ul>
|
144
144
|
#
|
145
145
|
def breadcrumbs(breadcrumbs, bootstrap = false, active = "active", options = {})
|
146
|
-
content =
|
146
|
+
content = ActiveSupport::SafeBuffer.new
|
147
147
|
breadcrumbs.items[0..-2].each do |item|
|
148
148
|
content << render_item(item, bootstrap)
|
149
149
|
end
|
@@ -156,8 +156,8 @@ module Padrino
|
|
156
156
|
classes[1] << active if active
|
157
157
|
options[:class], last_options[:class] = classes.map { |class_name| class_name * " " }
|
158
158
|
|
159
|
-
content <<
|
160
|
-
|
159
|
+
content << content_tag(:li, last, last_options)
|
160
|
+
content_tag(:ul, content, options)
|
161
161
|
end
|
162
162
|
|
163
163
|
private
|
@@ -173,10 +173,10 @@ module Padrino
|
|
173
173
|
# @return [String] List item with breadcrumb
|
174
174
|
#
|
175
175
|
def render_item(item, bootstrap)
|
176
|
-
content =
|
176
|
+
content = ActiveSupport::SafeBuffer.new
|
177
177
|
content << link_to(item[:caption], item[:url])
|
178
|
-
content <<
|
179
|
-
|
178
|
+
content << content_tag(:span, "/", :class => "divider") if bootstrap
|
179
|
+
content_tag(:li, content, item[:options])
|
180
180
|
end
|
181
181
|
end
|
182
182
|
end
|
@@ -1,129 +1,119 @@
|
|
1
|
+
require 'padrino-helpers/form_builder/deprecated_builder_methods'
|
2
|
+
|
1
3
|
module Padrino
|
2
4
|
module Helpers
|
3
5
|
module FormBuilder
|
6
|
+
# Base class for Padrino Form Builder
|
4
7
|
class AbstractFormBuilder
|
5
8
|
attr_accessor :template, :object, :multipart
|
9
|
+
attr_reader :namespace, :is_nested, :parent_form, :nested_index, :attributes_name, :model_name
|
10
|
+
|
11
|
+
include DeprecatedBuilderMethods
|
6
12
|
|
7
13
|
def initialize(template, object, options={})
|
8
14
|
@template = template
|
9
|
-
|
10
|
-
@
|
11
|
-
|
12
|
-
|
15
|
+
fail "FormBuilder template must be initialized" unless template
|
16
|
+
@object = object.kind_of?(Symbol) ? build_object(object) : object
|
17
|
+
fail "FormBuilder object must be present. If there's no object, use a symbol instead (i.e. :user)" unless object
|
18
|
+
@options = options
|
19
|
+
@namespace = options[:namespace]
|
20
|
+
@model_name = options[:as] || @object.class.to_s.underscore.gsub(/\//, '_')
|
21
|
+
nested = options[:nested]
|
22
|
+
if @is_nested = nested && (nested_parent = nested[:parent]) && nested_parent.respond_to?(:object)
|
23
|
+
@parent_form = nested_parent
|
24
|
+
@nested_index = nested[:index]
|
25
|
+
@attributes_name = "#{nested[:association]}_attributes"
|
26
|
+
end
|
13
27
|
end
|
14
28
|
|
15
29
|
def error_messages(*params)
|
16
|
-
|
17
|
-
@template.error_messages_for(*params)
|
30
|
+
@template.error_messages_for object, *params
|
18
31
|
end
|
19
32
|
|
20
33
|
def error_message_on(field, options={})
|
21
|
-
@template.error_message_on
|
34
|
+
@template.error_message_on object, field, options
|
22
35
|
end
|
23
36
|
|
24
37
|
def label(field, options={}, &block)
|
25
|
-
options
|
26
|
-
@template.label_tag(field_id(field), options, &block)
|
38
|
+
options[:caption] ||= I18n.t("#{model_name}.attributes.#{field}", :count => 1, :default => field.to_s.humanize, :scope => :models) + ': '
|
39
|
+
@template.label_tag(field_id(field), default_options(field, options), &block)
|
27
40
|
end
|
28
41
|
|
29
42
|
def hidden_field(field, options={})
|
30
|
-
|
31
|
-
@template.hidden_field_tag field_name(field), options
|
43
|
+
@template.hidden_field_tag field_name(field), default_options(field, options)
|
32
44
|
end
|
33
45
|
|
34
46
|
def text_field(field, options={})
|
35
|
-
|
36
|
-
@template.text_field_tag field_name(field), options
|
47
|
+
@template.text_field_tag field_name(field), default_options(field, options)
|
37
48
|
end
|
38
49
|
|
39
50
|
def number_field(field, options={})
|
40
|
-
|
41
|
-
@template.number_field_tag field_name(field), options
|
51
|
+
@template.number_field_tag field_name(field), default_options(field, options)
|
42
52
|
end
|
43
53
|
|
44
54
|
def telephone_field(field, options={})
|
45
|
-
|
46
|
-
@template.telephone_field_tag field_name(field), options
|
55
|
+
@template.telephone_field_tag field_name(field), default_options(field, options)
|
47
56
|
end
|
48
57
|
alias_method :phone_field, :telephone_field
|
49
58
|
|
50
59
|
def email_field(field, options={})
|
51
|
-
|
52
|
-
@template.email_field_tag field_name(field), options
|
60
|
+
@template.email_field_tag field_name(field), default_options(field, options)
|
53
61
|
end
|
54
62
|
|
55
63
|
def search_field(field, options={})
|
56
|
-
|
57
|
-
@template.search_field_tag field_name(field), options
|
64
|
+
@template.search_field_tag field_name(field), default_options(field, options)
|
58
65
|
end
|
59
66
|
|
60
67
|
def url_field(field, options={})
|
61
|
-
|
62
|
-
@template.url_field_tag field_name(field), options
|
68
|
+
@template.url_field_tag field_name(field), default_options(field, options)
|
63
69
|
end
|
64
70
|
|
65
71
|
def text_area(field, options={})
|
66
|
-
|
67
|
-
@template.text_area_tag field_name(field), options
|
72
|
+
@template.text_area_tag field_name(field), default_options(field, options)
|
68
73
|
end
|
69
74
|
|
70
75
|
def password_field(field, options={})
|
71
|
-
|
72
|
-
@template.password_field_tag field_name(field), options
|
76
|
+
@template.password_field_tag field_name(field), default_options(field, options)
|
73
77
|
end
|
74
78
|
|
75
79
|
def select(field, options={})
|
76
|
-
|
77
|
-
options.merge!(:class => field_error(field, options))
|
78
|
-
@template.select_tag field_name(field), options
|
80
|
+
@template.select_tag field_name(field), default_options(field, options)
|
79
81
|
end
|
80
82
|
|
81
83
|
def check_box_group(field, options={})
|
82
|
-
|
83
|
-
|
84
|
-
fields = options[:fields] || [:name, :id]
|
85
|
-
selected_values = selected_values.map{ |v| (v.respond_to?(fields[0]) ? v.send(fields[1]) : v).to_s }
|
86
|
-
end
|
87
|
-
labeled_group( field, options ) do |variant|
|
88
|
-
@template.check_box_tag( field_name(field)+'[]', :value => variant[1], :id => variant[2], :checked => selected_values.include?(variant[1]) )
|
84
|
+
labeled_group(field, options) do |attributes|
|
85
|
+
@template.check_box_tag(field_name(field)+'[]', attributes)
|
89
86
|
end
|
90
87
|
end
|
91
88
|
|
92
89
|
def radio_button_group(field, options={})
|
93
|
-
|
94
|
-
|
95
|
-
selected_value = selected_value.send(fields[1]) if selected_value.respond_to?(fields[0])
|
96
|
-
labeled_group( field, options ) do |variant|
|
97
|
-
@template.radio_button_tag( field_name(field), :value => variant[1], :id => variant[2], :checked => variant[1] == selected_value.to_s )
|
90
|
+
labeled_group(field, options) do |attributes|
|
91
|
+
@template.radio_button_tag(field_name(field), attributes)
|
98
92
|
end
|
99
93
|
end
|
100
94
|
|
101
95
|
def check_box(field, options={})
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
html << @template.
|
107
|
-
html << @template.check_box_tag(field_name(field), options)
|
96
|
+
options = default_options(field, options, :value => '1')
|
97
|
+
options[:checked] = true if is_checked?(field, options)
|
98
|
+
name = field_name(field)
|
99
|
+
html = @template.hidden_field_tag(name, :value => options.delete(:uncheck_value) || '0')
|
100
|
+
html << @template.check_box_tag(name, options)
|
108
101
|
end
|
109
102
|
|
110
103
|
def radio_button(field, options={})
|
111
|
-
options
|
112
|
-
options
|
104
|
+
options = default_options(field, options)
|
105
|
+
options[:checked] = true if is_checked?(field, options)
|
106
|
+
options[:id] = field_id(field, options[:value])
|
113
107
|
@template.radio_button_tag field_name(field), options
|
114
108
|
end
|
115
109
|
|
116
110
|
def file_field(field, options={})
|
117
111
|
self.multipart = true
|
118
|
-
|
119
|
-
options.merge!(:class => field_error(field, options))
|
120
|
-
@template.file_field_tag field_name(field), options
|
112
|
+
@template.file_field_tag field_name(field), default_options(field, options).except(:value)
|
121
113
|
end
|
122
114
|
|
123
115
|
def submit(*args)
|
124
|
-
|
125
|
-
caption = args.length >= 1 ? args.shift : "Submit"
|
126
|
-
@template.submit_tag caption, options
|
116
|
+
@template.submit_tag *args
|
127
117
|
end
|
128
118
|
|
129
119
|
def image_submit(source, options={})
|
@@ -136,24 +126,16 @@ module Padrino
|
|
136
126
|
# f.fields_for :addresses, address
|
137
127
|
# f.fields_for :addresses, @addresses
|
138
128
|
# f.fields_for :addresses, address, index: i
|
139
|
-
def fields_for(child_association,
|
129
|
+
def fields_for(child_association, collection=nil, options={}, &block)
|
140
130
|
default_collection = self.object.send(child_association)
|
141
|
-
|
131
|
+
collection ||= default_collection
|
142
132
|
include_index = default_collection.respond_to?(:each)
|
143
|
-
custom_index = options.has_key?(:index)
|
144
133
|
|
145
134
|
nested_options = { :parent => self, :association => child_association }
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
elsif include_index
|
151
|
-
nested_options[:index] = index
|
152
|
-
else
|
153
|
-
nested_options[:index] = nil
|
154
|
-
end
|
155
|
-
@template.fields_for(child_instance, { :nested => nested_options }, &block)
|
156
|
-
end.join("\n").html_safe
|
135
|
+
Array(collection).each_with_index.inject(ActiveSupport::SafeBuffer.new) do |all,(child_instance,index)|
|
136
|
+
nested_options[:index] = options[:index] || (include_index ? index : nil)
|
137
|
+
all << @template.fields_for(child_instance, { :nested => nested_options }, &block) << "\n"
|
138
|
+
end
|
157
139
|
end
|
158
140
|
|
159
141
|
def csrf_token_field
|
@@ -161,43 +143,21 @@ module Padrino
|
|
161
143
|
end
|
162
144
|
|
163
145
|
protected
|
146
|
+
|
164
147
|
# Returns the known field types for a Formbuilder.
|
165
148
|
def self.field_types
|
166
149
|
[:hidden_field, :text_field, :text_area, :password_field, :file_field, :radio_button, :check_box, :select]
|
167
150
|
end
|
168
151
|
|
169
|
-
##
|
170
|
-
# Returns true if the value matches the value in the field.
|
171
|
-
# field_has_value?(:gender, 'male')
|
172
|
-
def values_matches_field?(field, value)
|
173
|
-
value.present? && (field_value(field).to_s == value.to_s || field_value(field).to_s == 'true')
|
174
|
-
end
|
175
|
-
|
176
|
-
##
|
177
|
-
# Add a :invalid css class to the field if it contain an error.
|
178
|
-
#
|
179
|
-
def field_error(field, options)
|
180
|
-
error = @object.errors[field] rescue nil
|
181
|
-
error.blank? ? options[:class] : [options[:class], :invalid].flatten.compact.join(" ")
|
182
|
-
end
|
183
|
-
|
184
|
-
##
|
185
|
-
# Returns the human name of the field. Look that use builtin I18n.
|
186
|
-
#
|
187
|
-
def field_human_name(field)
|
188
|
-
I18n.translate("#{object_model_name}.attributes.#{field}", :count => 1, :default => field.to_s.humanize, :scope => :models)
|
189
|
-
end
|
190
|
-
|
191
152
|
##
|
192
153
|
# Returns the name for the given field.
|
193
154
|
# field_name(:username) => "user[username]"
|
194
155
|
# field_name(:number) => "user[telephone_attributes][number]"
|
195
156
|
# field_name(:street) => "user[addresses_attributes][0][street]"
|
196
157
|
def field_name(field=nil)
|
197
|
-
result =
|
198
|
-
result << field_name_fragment if nested_form?
|
158
|
+
result = field_name_fragment
|
199
159
|
result << "[#{field}]" unless field.blank?
|
200
|
-
result
|
160
|
+
result
|
201
161
|
end
|
202
162
|
|
203
163
|
##
|
@@ -207,118 +167,114 @@ module Padrino
|
|
207
167
|
# field_name(:number) => "user_telephone_attributes_number"
|
208
168
|
# field_name(:street) => "user_addresses_attributes_0_street"
|
209
169
|
def field_id(field=nil, value=nil)
|
210
|
-
result =
|
211
|
-
result <<
|
212
|
-
result << field_result
|
213
|
-
result << field_id_fragment if nested_form?
|
170
|
+
result = (namespace && !is_nested) ? "#{namespace}_" : ''
|
171
|
+
result << field_id_fragment
|
214
172
|
result << "_#{field}" unless field.blank?
|
215
173
|
result << "_#{value}" unless value.blank?
|
216
|
-
result
|
174
|
+
result
|
217
175
|
end
|
218
176
|
|
219
177
|
##
|
220
178
|
# Returns the child object if it exists.
|
221
179
|
#
|
222
180
|
def nested_object_id
|
223
|
-
|
224
|
-
end
|
225
|
-
|
226
|
-
##
|
227
|
-
# Returns true if this form object is nested in a parent form.
|
228
|
-
#
|
229
|
-
def nested_form?
|
230
|
-
@options[:nested] && @options[:nested][:parent] && @options[:nested][:parent].respond_to?(:object)
|
181
|
+
is_nested && object.respond_to?(:new_record?) && !object.new_record? && object.id
|
231
182
|
end
|
232
183
|
|
233
184
|
##
|
234
185
|
# Returns the value for the object's field.
|
235
186
|
#
|
236
187
|
def field_value(field)
|
237
|
-
@object
|
188
|
+
@object.respond_to?(field) ? @object.send(field) : ''
|
238
189
|
end
|
239
190
|
|
240
191
|
##
|
241
|
-
# Returns a
|
192
|
+
# Returns a record from template instance or create a record of specified class.
|
242
193
|
#
|
243
|
-
def build_object(
|
244
|
-
|
194
|
+
def build_object(symbol)
|
195
|
+
@template.instance_variable_get("@#{symbol}") || symbol.to_s.camelize.constantize.new
|
245
196
|
end
|
246
197
|
|
247
198
|
##
|
248
|
-
#
|
199
|
+
# Builds a group of labels for radios or checkboxes.
|
249
200
|
#
|
250
|
-
def
|
251
|
-
|
252
|
-
|
201
|
+
def labeled_group(field, options={})
|
202
|
+
options = { :id => field_id(field), :selected => field_value(field) }.update(options)
|
203
|
+
options.update(error_class(field)){ |_,*values| values.compact.join(' ') }
|
204
|
+
selected_values = resolve_checked_values(field, options)
|
205
|
+
variants_for_group(options).inject(ActiveSupport::SafeBuffer.new) do |html, (caption,value)|
|
206
|
+
variant_id = "#{options[:id]}_#{value}"
|
207
|
+
attributes = { :value => value, :id => variant_id, :checked => selected_values.include?(value) }
|
208
|
+
caption = yield(attributes) << ' ' << caption
|
209
|
+
html << @template.label_tag("#{field_name(field)}[]", :for => variant_id, :caption => caption)
|
210
|
+
end
|
253
211
|
end
|
254
212
|
|
255
|
-
|
256
|
-
# Returns the class type for the given object.
|
257
|
-
#
|
258
|
-
def object_class(explicit_object)
|
259
|
-
explicit_object.is_a?(Symbol) ? explicit_object.to_s.camelize.constantize : explicit_object.class
|
260
|
-
end
|
213
|
+
private
|
261
214
|
|
262
|
-
|
263
|
-
|
264
|
-
#
|
265
|
-
def root_form?
|
266
|
-
!nested_form?
|
215
|
+
def is_checked?(field, options)
|
216
|
+
!options.has_key?(:checked) && [options[:value].to_s, 'true'].include?(field_value(field).to_s)
|
267
217
|
end
|
268
218
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
options.merge!(:class => field_error(field, options))
|
275
|
-
variants = case
|
276
|
-
when options[:options]
|
277
|
-
options[:options].map{ |caption, value| [caption.to_s, (value||caption).to_s] }
|
278
|
-
when options[:collection]
|
279
|
-
fields = options[:fields] || [:name, :id]
|
280
|
-
options[:collection].map{ |variant| [variant.send(fields.first).to_s, variant.send(fields.last).to_s] }
|
219
|
+
def variants_for_group(options)
|
220
|
+
if variants = options[:options]
|
221
|
+
variants.map{ |caption, value| [caption.to_s, (value||caption).to_s] }
|
222
|
+
elsif collection = options[:collection]
|
223
|
+
collection.map{ |variant| field_values(variant, options) }
|
281
224
|
else
|
282
225
|
[]
|
283
226
|
end
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
227
|
+
end
|
228
|
+
|
229
|
+
def resolve_checked_values(field, options)
|
230
|
+
selected_values = Array(options[:selected] || field_value(field))
|
231
|
+
if options[:collection]
|
232
|
+
_, id_method = *field_methods(options)
|
233
|
+
selected_values.map do |value|
|
234
|
+
(value.respond_to?(id_method) ? value.send(id_method) : value).to_s
|
235
|
+
end
|
236
|
+
else
|
237
|
+
selected_values
|
288
238
|
end
|
289
239
|
end
|
290
240
|
|
291
|
-
|
241
|
+
def field_methods(options)
|
242
|
+
options[:fields] || [:name, :id]
|
243
|
+
end
|
292
244
|
|
293
|
-
def
|
294
|
-
|
295
|
-
result << object_model_name if root_form?
|
296
|
-
result
|
245
|
+
def field_values(object, options)
|
246
|
+
field_methods(options).map{ |field| object.send(field).to_s }
|
297
247
|
end
|
298
248
|
|
299
249
|
def field_name_fragment
|
300
|
-
|
301
|
-
|
302
|
-
|
250
|
+
if is_nested
|
251
|
+
fragment = parent_form.field_name.dup << "[#{attributes_name}"
|
252
|
+
fragment << "][#{nested_index}" if nested_index
|
253
|
+
fragment << "]"
|
254
|
+
else
|
255
|
+
"#{model_name}"
|
256
|
+
end
|
303
257
|
end
|
304
258
|
|
305
259
|
def field_id_fragment
|
306
|
-
|
307
|
-
|
308
|
-
|
260
|
+
if is_nested
|
261
|
+
fragment = parent_form.field_id.dup << "_#{attributes_name}"
|
262
|
+
fragment << "_#{nested_index}" if nested_index
|
263
|
+
fragment
|
264
|
+
else
|
265
|
+
"#{model_name}"
|
266
|
+
end
|
309
267
|
end
|
310
268
|
|
311
|
-
def
|
312
|
-
|
313
|
-
|
314
|
-
:nested_index => @options[:nested][:index],
|
315
|
-
:attributes_name => "#{@options[:nested][:association]}_attributes"
|
316
|
-
}
|
269
|
+
def error_class(field)
|
270
|
+
error = @object.errors[field] if @object.respond_to?(:errors)
|
271
|
+
error.blank? ? {} : { :class => 'invalid' }
|
317
272
|
end
|
318
273
|
|
319
|
-
def
|
320
|
-
|
321
|
-
|
274
|
+
def default_options(field, options, defaults={})
|
275
|
+
{ :value => field_value(field),
|
276
|
+
:id => field_id(field)
|
277
|
+
}.update(defaults).update(options).update(error_class(field)){ |_,*values| values.compact.join(' ') }
|
322
278
|
end
|
323
279
|
end
|
324
280
|
end
|