padrino-helpers 0.12.0 → 0.12.1
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 +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
|