formtastic 0.9.4 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +19 -2
- data/Rakefile +3 -4
- data/generators/form/form_generator.rb +9 -3
- data/lib/formtastic.rb +1042 -913
- data/lib/formtastic/i18n.rb +6 -1
- data/spec/custom_macros.rb +103 -3
- data/spec/form_helper_spec.rb +11 -1
- data/spec/i18n_spec.rb +48 -0
- data/spec/input_spec.rb +8 -8
- data/spec/inputs/boolean_input_spec.rb +34 -1
- data/spec/inputs/check_boxes_input_spec.rb +57 -1
- data/spec/inputs/date_input_spec.rb +3 -1
- data/spec/inputs/datetime_input_spec.rb +8 -8
- data/spec/inputs/radio_input_spec.rb +38 -2
- data/spec/inputs/select_input_spec.rb +124 -12
- data/spec/inputs/time_input_spec.rb +3 -1
- data/spec/inputs/time_zone_input_spec.rb +44 -1
- data/spec/inputs_spec.rb +10 -1
- data/spec/semantic_fields_for_spec.rb +3 -1
- data/spec/spec_helper.rb +13 -2
- metadata +4 -14
data/lib/formtastic/i18n.rb
CHANGED
@@ -9,7 +9,12 @@ module Formtastic
|
|
9
9
|
:create => 'Create {{model}}',
|
10
10
|
:update => 'Update {{model}}'
|
11
11
|
}.freeze
|
12
|
-
|
12
|
+
SCOPES = [
|
13
|
+
'{{model}}.{{action}}.{{attribute}}',
|
14
|
+
'{{model}}.{{attribute}}',
|
15
|
+
'{{attribute}}'
|
16
|
+
]
|
17
|
+
|
13
18
|
class << self
|
14
19
|
|
15
20
|
def translate(*args)
|
data/spec/custom_macros.rb
CHANGED
@@ -75,6 +75,7 @@ module CustomMacros
|
|
75
75
|
def it_should_use_default_text_field_size_when_method_has_no_database_column(as)
|
76
76
|
it 'should use default_text_field_size when method has no database column' do
|
77
77
|
@new_post.stub!(:column_for_attribute).and_return(nil) # Return a nil column
|
78
|
+
|
78
79
|
semantic_form_for(@new_post) do |builder|
|
79
80
|
concat(builder.input(:title, :as => as))
|
80
81
|
end
|
@@ -222,7 +223,108 @@ module CustomMacros
|
|
222
223
|
end
|
223
224
|
end
|
224
225
|
end
|
225
|
-
|
226
|
+
|
227
|
+
def it_should_select_existing_datetime_else_current(*datetime_parts)
|
228
|
+
describe "default value" do
|
229
|
+
before do
|
230
|
+
@new_post.should_receive(:publish_at=).any_number_of_times
|
231
|
+
end
|
232
|
+
|
233
|
+
describe "when attribute value is present" do
|
234
|
+
before do
|
235
|
+
@output_buffer = ''
|
236
|
+
publish_at_value = 1.year.ago + 2.month + 3.day + 4.hours + 5.minutes # No comment =)
|
237
|
+
@new_post.stub!(:publish_at).and_return(publish_at_value)
|
238
|
+
|
239
|
+
semantic_form_for(@new_post) do |builder|
|
240
|
+
concat(builder.input(:publish_at, :as => :datetime))
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should select the present value by default" do
|
245
|
+
# puts output_buffer
|
246
|
+
output_buffer.should have_tag("form li select#post_publish_at_1i option[@selected='selected'][@value='#{@new_post.publish_at.year}']") if datetime_parts.include?(:year)
|
247
|
+
output_buffer.should have_tag("form li select#post_publish_at_2i option[@selected='selected'][@value='#{@new_post.publish_at.month}']") if datetime_parts.include?(:month)
|
248
|
+
output_buffer.should have_tag("form li select#post_publish_at_3i option[@selected='selected'][@value='#{@new_post.publish_at.day}']") if datetime_parts.include?(:day)
|
249
|
+
output_buffer.should have_tag("form li select#post_publish_at_4i option[@selected='selected'][@value='#{@new_post.publish_at.strftime("%H")}']") if datetime_parts.include?(:hour)
|
250
|
+
output_buffer.should have_tag("form li select#post_publish_at_5i option[@selected='selected'][@value='#{@new_post.publish_at.strftime("%M")}']") if datetime_parts.include?(:minute)
|
251
|
+
#output_buffer.should have_tag("form li select#post_publish_at_6i option[@selected='selected'][@value='#{@new_post.publish_at.sec}']") if datetime_parts.include?(:second)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
describe "when no attribute value is present" do
|
256
|
+
before do
|
257
|
+
@output_buffer = ''
|
258
|
+
@new_post.stub!(:publish_at).and_return(nil)
|
259
|
+
@current_time = ::Time.now
|
260
|
+
|
261
|
+
semantic_form_for(@new_post) do |builder|
|
262
|
+
concat(builder.input(:publish_at, :as => :datetime))
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
it "should select the current day/time by default" do
|
267
|
+
# puts output_buffer
|
268
|
+
output_buffer.should have_tag("form li select#post_publish_at_1i option[@selected='selected'][@value='#{@current_time.year}']") if datetime_parts.include?(:year)
|
269
|
+
output_buffer.should have_tag("form li select#post_publish_at_2i option[@selected='selected'][@value='#{@current_time.month}']") if datetime_parts.include?(:month)
|
270
|
+
output_buffer.should have_tag("form li select#post_publish_at_3i option[@selected='selected'][@value='#{@current_time.day}']") if datetime_parts.include?(:day)
|
271
|
+
output_buffer.should have_tag("form li select#post_publish_at_4i option[@selected='selected'][@value='#{@current_time.strftime("%H")}']") if datetime_parts.include?(:hour)
|
272
|
+
output_buffer.should have_tag("form li select#post_publish_at_5i option[@selected='selected'][@value='#{@current_time.strftime("%M")}']") if datetime_parts.include?(:minute)
|
273
|
+
#output_buffer.should have_tag("form li select#post_publish_at_6i option[@selected='selected'][@value='#{@custom_default_time.sec}']") if datetime_parts.include?(:second)
|
274
|
+
end
|
275
|
+
|
276
|
+
# TODO: Scenario when current time is not a possible choice (because of specified date/time ranges)?
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def it_should_select_explicit_default_value_if_set(*datetime_parts)
|
282
|
+
describe 'when :selected is set' do
|
283
|
+
before do
|
284
|
+
@output_buffer = ''
|
285
|
+
end
|
286
|
+
|
287
|
+
# Note: Not possible to override default selected value for time_zone input
|
288
|
+
# without overriding Rails core helper. This Rails helper works "a bit different". =/
|
289
|
+
#
|
290
|
+
describe "no selected items" do
|
291
|
+
before do
|
292
|
+
@default_time = 2.days.ago
|
293
|
+
@new_post.stub!(:publish_at).and_return(@default_time)
|
294
|
+
|
295
|
+
semantic_form_for(@new_post) do |builder|
|
296
|
+
concat(builder.input(:publish_at, :as => :time_zone, :selected => nil))
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'should not have any selected item(s)' do
|
301
|
+
output_buffer.should_not have_tag("form li select#post_publish_at_1i option[@selected='selected']")
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
describe "single selected item" do
|
306
|
+
before do
|
307
|
+
@custom_default_time = 5.days.ago
|
308
|
+
@new_post.stub!(:publish_at).and_return(2.days.ago)
|
309
|
+
|
310
|
+
semantic_form_for(@new_post) do |builder|
|
311
|
+
concat(builder.input(:publish_at, :as => :datetime, :selected => @custom_default_time))
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
it "should select the specified value" do
|
316
|
+
output_buffer.should have_tag("form li select#post_publish_at_1i option[@selected='selected'][@value='#{@custom_default_time.year}']") if datetime_parts.include?(:year)
|
317
|
+
output_buffer.should have_tag("form li select#post_publish_at_2i option[@selected='selected'][@value='#{@custom_default_time.month}']") if datetime_parts.include?(:month)
|
318
|
+
output_buffer.should have_tag("form li select#post_publish_at_3i option[@selected='selected'][@value='#{@custom_default_time.day}']") if datetime_parts.include?(:day)
|
319
|
+
output_buffer.should have_tag("form li select#post_publish_at_4i option[@selected='selected'][@value='#{@custom_default_time.strftime("%H")}']") if datetime_parts.include?(:hour)
|
320
|
+
output_buffer.should have_tag("form li select#post_publish_at_5i option[@selected='selected'][@value='#{@custom_default_time.strftime("%M")}']") if datetime_parts.include?(:minute)
|
321
|
+
#output_buffer.should have_tag("form li select#post_publish_at_6i option[@selected='selected'][@value='#{@custom_default_time.sec}']") if datetime_parts.include?(:second)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
226
328
|
def it_should_use_the_collection_when_provided(as, countable)
|
227
329
|
describe 'when the :collection option is provided' do
|
228
330
|
|
@@ -456,6 +558,4 @@ module CustomMacros
|
|
456
558
|
end
|
457
559
|
|
458
560
|
end
|
459
|
-
|
460
|
-
|
461
561
|
end
|
data/spec/form_helper_spec.rb
CHANGED
@@ -79,7 +79,17 @@ describe 'SemanticFormHelper' do
|
|
79
79
|
builder.object_name.to_s.should == "post" # TODO: is this forced .to_s a bad assumption somewhere?
|
80
80
|
end
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
|
+
describe "with :builder option" do
|
84
|
+
it "yields an instance of the given builder" do
|
85
|
+
class MyAwesomeCustomBuilder < ::Formtastic::SemanticFormBuilder
|
86
|
+
end
|
87
|
+
semantic_form_for(:post, ::Post.new, :url => '/hello', :builder => MyAwesomeCustomBuilder) do |builder|
|
88
|
+
builder.class.should == MyAwesomeCustomBuilder
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
83
93
|
end
|
84
94
|
|
85
95
|
describe '#semantic_fields_for' do
|
data/spec/i18n_spec.rb
CHANGED
@@ -80,4 +80,52 @@ describe 'Formtastic::I18n' do
|
|
80
80
|
|
81
81
|
end
|
82
82
|
|
83
|
+
describe "I18n string lookups" do
|
84
|
+
|
85
|
+
include FormtasticSpecHelper
|
86
|
+
|
87
|
+
before do
|
88
|
+
@output_buffer = ''
|
89
|
+
mock_everything
|
90
|
+
|
91
|
+
::I18n.backend.store_translations :en, :formtastic => {
|
92
|
+
:labels => {
|
93
|
+
:title => "Hello world!",
|
94
|
+
:post => {:title => "Hello post!"},
|
95
|
+
:project => {:title => "Hello project!"}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
|
99
|
+
|
100
|
+
@new_post.stub!(:title)
|
101
|
+
@new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
|
102
|
+
end
|
103
|
+
|
104
|
+
after do
|
105
|
+
::I18n.backend.store_translations :en, :formtastic => nil
|
106
|
+
::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = false
|
107
|
+
end
|
108
|
+
|
109
|
+
it "lookup scopes should be defined" do
|
110
|
+
lambda { ::Formtastic::I18n::SCOPES }.should_not raise_error(::NameError)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should be able to translate with namespaced object" do
|
114
|
+
semantic_form_for(@new_post) do |builder|
|
115
|
+
concat(builder.input(:title))
|
116
|
+
end
|
117
|
+
output_buffer.should have_tag("form label", /Hello post!/)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should be able to translate without form-object" do
|
121
|
+
semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
122
|
+
concat(builder.input(:title))
|
123
|
+
end
|
124
|
+
output_buffer.should have_tag("form label", /Hello project!/)
|
125
|
+
end
|
126
|
+
|
127
|
+
# TODO: Add spec for namespaced models?
|
128
|
+
|
129
|
+
end
|
130
|
+
|
83
131
|
end
|
data/spec/input_spec.rb
CHANGED
@@ -400,9 +400,8 @@ describe 'SemanticFormBuilder#input' do
|
|
400
400
|
|
401
401
|
describe 'when not provided' do
|
402
402
|
describe 'when localized label is NOT provided' do
|
403
|
-
describe 'and
|
403
|
+
describe 'and label_str_method is not provided' do
|
404
404
|
it 'should default the humanized method name, passing it down to the label tag' do
|
405
|
-
::Formtastic::SemanticFormBuilder.label_str_method = :humanize
|
406
405
|
|
407
406
|
semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
408
407
|
concat(builder.input(:meta_description))
|
@@ -412,16 +411,17 @@ describe 'SemanticFormBuilder#input' do
|
|
412
411
|
end
|
413
412
|
end
|
414
413
|
|
415
|
-
describe 'and
|
416
|
-
it 'should
|
417
|
-
|
418
|
-
|
414
|
+
describe 'and label_str_method is :capitalize' do
|
415
|
+
it 'should capitalize method name, passing it down to the label tag' do
|
416
|
+
old_value = ::Formtastic::SemanticFormBuilder.label_str_method
|
417
|
+
::Formtastic::SemanticFormBuilder.label_str_method = :capitalize
|
419
418
|
|
420
|
-
semantic_form_for(
|
419
|
+
semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
421
420
|
concat(builder.input(:meta_description))
|
422
421
|
end
|
423
422
|
|
424
|
-
output_buffer.should have_tag("form li label", /#{'meta_description'.
|
423
|
+
output_buffer.should have_tag("form li label", /#{'meta_description'.capitalize}/)
|
424
|
+
::Formtastic::SemanticFormBuilder.label_str_method = old_value
|
425
425
|
end
|
426
426
|
end
|
427
427
|
end
|
@@ -56,5 +56,38 @@ describe 'boolean input' do
|
|
56
56
|
output_buffer.should have_tag('form li label input[@name="project[allow_comments]"]')
|
57
57
|
end
|
58
58
|
|
59
|
-
|
59
|
+
describe 'when :selected is set' do
|
60
|
+
before do
|
61
|
+
@output_buffer = ''
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "not selected" do
|
65
|
+
before do
|
66
|
+
@new_post.stub!(:allow_comments).and_return(true)
|
67
|
+
|
68
|
+
semantic_form_for(@new_post) do |builder|
|
69
|
+
concat(builder.input(:allow_comments, :as => :boolean, :selected => false))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should not be selected' do
|
74
|
+
output_buffer.should_not have_tag("form li label input[@type='checkbox'][@checked='checked']")
|
75
|
+
end
|
76
|
+
end
|
60
77
|
|
78
|
+
describe "selected" do
|
79
|
+
before do
|
80
|
+
@new_post.stub!(:allow_comments).and_return(false)
|
81
|
+
|
82
|
+
semantic_form_for(@new_post) do |builder|
|
83
|
+
concat(builder.input(:allow_comments, :as => :boolean, :selected => true))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should be selected' do
|
88
|
+
output_buffer.should have_tag("form li label input[@type='checkbox'][@checked='checked']")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -51,7 +51,7 @@ describe 'check_boxes input' do
|
|
51
51
|
|
52
52
|
it 'should use values as li.class when value_as_class is true' do
|
53
53
|
::Post.find(:all).each do |post|
|
54
|
-
output_buffer.should have_tag("form li fieldset ol li
|
54
|
+
output_buffer.should have_tag("form li fieldset ol li.post_#{post.id} label")
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -100,6 +100,62 @@ describe 'check_boxes input' do
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
103
|
+
|
104
|
+
describe 'when :selected is set' do
|
105
|
+
before do
|
106
|
+
@output_buffer = ''
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "no selected items" do
|
110
|
+
before do
|
111
|
+
@new_post.stub!(:author_ids).and_return(nil)
|
112
|
+
|
113
|
+
semantic_form_for(@new_post) do |builder|
|
114
|
+
concat(builder.input(:authors, :as => :check_boxes, :selected => nil))
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should not have any selected item(s)' do
|
119
|
+
output_buffer.should_not have_tag("form li fieldset ol li label input[@checked='checked']")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "single selected item" do
|
124
|
+
before do
|
125
|
+
@new_post.stub!(:author_ids).and_return(nil)
|
126
|
+
|
127
|
+
semantic_form_for(@new_post) do |builder|
|
128
|
+
concat(builder.input(:authors, :as => :check_boxes, :selected => @fred.id))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should have one item selected; the specified one" do
|
133
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']", :count => 1)
|
134
|
+
output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
|
135
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked'][@value='#{@fred.id}']")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "multiple selected items" do
|
140
|
+
before do
|
141
|
+
@new_post.stub!(:author_ids).and_return(nil)
|
142
|
+
|
143
|
+
semantic_form_for(@new_post) do |builder|
|
144
|
+
concat(builder.input(:authors, :as => :check_boxes, :selected => [@bob.id, @fred.id]))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should have multiple items selected; the specified ones" do
|
149
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']", :count => 2)
|
150
|
+
output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@bob.id}']", /bob/i)
|
151
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked'][@value='#{@bob.id}']")
|
152
|
+
output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
|
153
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked'][@value='#{@fred.id}']")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
103
159
|
end
|
104
160
|
|
105
161
|
end
|
@@ -39,5 +39,7 @@ describe 'date input' do
|
|
39
39
|
output_buffer.should have_tag('form li.date fieldset ol li select', :count => 3)
|
40
40
|
end
|
41
41
|
|
42
|
-
|
42
|
+
it_should_select_existing_datetime_else_current(:year, :month, :day)
|
43
|
+
it_should_select_explicit_default_value_if_set(:year, :month, :day)
|
43
44
|
|
45
|
+
end
|
@@ -9,6 +9,11 @@ describe 'datetime input' do
|
|
9
9
|
@output_buffer = ''
|
10
10
|
mock_everything
|
11
11
|
|
12
|
+
@new_post.should_receive(:publish_at=).any_number_of_times
|
13
|
+
@new_post.should_receive(:created_at=).any_number_of_times
|
14
|
+
@bob.should_receive(:created_at=).any_number_of_times
|
15
|
+
@new_post.should_receive(:title=).any_number_of_times # Macro stuff forces this.
|
16
|
+
|
12
17
|
semantic_form_for(@new_post) do |builder|
|
13
18
|
concat(builder.input(:publish_at, :as => :datetime))
|
14
19
|
end
|
@@ -54,15 +59,10 @@ describe 'datetime input' do
|
|
54
59
|
end
|
55
60
|
end
|
56
61
|
|
57
|
-
|
58
|
-
|
59
|
-
semantic_form_for(@new_post) do |builder|
|
60
|
-
concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
|
61
|
-
end
|
62
|
-
|
63
|
-
output_buffer.should have_tag("form li input[@type='hidden'][@value='1']")
|
64
|
-
end
|
62
|
+
it_should_select_existing_datetime_else_current(:year, :month, :day, :hour, :minute, :second)
|
63
|
+
it_should_select_explicit_default_value_if_set(:year, :month, :day, :hour, :minute, :second)
|
65
64
|
|
65
|
+
describe 'when :discard_input => true is set' do
|
66
66
|
it 'should use default attribute value when it is not nil' do
|
67
67
|
@new_post.stub!(:publish_at).and_return(Date.new(2007,12,27))
|
68
68
|
semantic_form_for(@new_post) do |builder|
|
@@ -49,7 +49,7 @@ describe 'radio input' do
|
|
49
49
|
|
50
50
|
it 'should use values as li.class when value_as_class is true' do
|
51
51
|
::Author.find(:all).each do |author|
|
52
|
-
output_buffer.should have_tag("form li fieldset ol li
|
52
|
+
output_buffer.should have_tag("form li fieldset ol li.author_#{author.id} label")
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -109,5 +109,41 @@ describe 'radio input' do
|
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
|
-
|
112
|
+
describe 'when :selected is set' do
|
113
|
+
before do
|
114
|
+
@output_buffer = ''
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "no selected items" do
|
118
|
+
before do
|
119
|
+
@new_post.stub!(:author_ids).and_return(nil)
|
120
|
+
|
121
|
+
semantic_form_for(@new_post) do |builder|
|
122
|
+
concat(builder.input(:authors, :as => :radio, :selected => nil))
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should not have any selected item(s)' do
|
127
|
+
output_buffer.should_not have_tag("form li fieldset ol li label input[@checked='checked']")
|
128
|
+
end
|
129
|
+
end
|
113
130
|
|
131
|
+
describe "single selected item" do
|
132
|
+
before do
|
133
|
+
@new_post.stub!(:author_ids).and_return(nil)
|
134
|
+
|
135
|
+
semantic_form_for(@new_post) do |builder|
|
136
|
+
concat(builder.input(:authors, :as => :radio, :selected => @fred.id))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should have one item selected; the specified one" do
|
141
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@type='radio'][@checked='checked']", :count => 1)
|
142
|
+
output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
|
143
|
+
output_buffer.should have_tag("form li fieldset ol li label input[@type='radio'][@checked='checked'][@value='#{@fred.id}']")
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|