dynamic_fieldsets 0.0.16 → 0.1.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.
Files changed (97) hide show
  1. data/.rdebugrc +3 -0
  2. data/.rspec +1 -0
  3. data/CHANGELOG +7 -0
  4. data/Gemfile +17 -8
  5. data/Gemfile.lock +77 -60
  6. data/README.rdoc +1 -1
  7. data/VERSION +1 -1
  8. data/app/controllers/dynamic_fieldsets/fields_controller.rb +5 -4
  9. data/app/helpers/dynamic_fieldsets_helper.rb +48 -131
  10. data/app/models/dynamic_fieldsets.rb +2 -0
  11. data/app/models/dynamic_fieldsets/checkbox_field.rb +29 -0
  12. data/app/models/dynamic_fieldsets/date_field.rb +37 -0
  13. data/app/models/dynamic_fieldsets/datetime_field.rb +36 -0
  14. data/app/models/dynamic_fieldsets/dependency.rb +1 -1
  15. data/app/models/dynamic_fieldsets/dependency_clause.rb +1 -1
  16. data/app/models/dynamic_fieldsets/dependency_group.rb +1 -1
  17. data/app/models/dynamic_fieldsets/field.rb +170 -42
  18. data/app/models/dynamic_fieldsets/field_default.rb +3 -3
  19. data/app/models/dynamic_fieldsets/field_html_attribute.rb +1 -1
  20. data/app/models/dynamic_fieldsets/field_option.rb +1 -1
  21. data/app/models/dynamic_fieldsets/field_record.rb +1 -1
  22. data/app/models/dynamic_fieldsets/fieldset.rb +36 -1
  23. data/app/models/dynamic_fieldsets/fieldset_associator.rb +9 -34
  24. data/app/models/dynamic_fieldsets/fieldset_child.rb +43 -24
  25. data/app/models/dynamic_fieldsets/instruction_field.rb +35 -0
  26. data/app/models/dynamic_fieldsets/multiple_select_field.rb +43 -0
  27. data/app/models/dynamic_fieldsets/radio_field.rb +27 -0
  28. data/app/models/dynamic_fieldsets/select_field.rb +16 -0
  29. data/app/models/dynamic_fieldsets/text_field.rb +14 -0
  30. data/app/models/dynamic_fieldsets/textarea_field.rb +40 -0
  31. data/app/views/dynamic_fieldsets/fields/_form.html.erb +50 -52
  32. data/app/views/dynamic_fieldsets/fields/edit.html.erb +5 -2
  33. data/app/views/dynamic_fieldsets/fields/index.html.erb +1 -1
  34. data/app/views/dynamic_fieldsets/fields/new.html.erb +3 -1
  35. data/app/views/dynamic_fieldsets/fields/show.html.erb +1 -1
  36. data/app/views/dynamic_fieldsets/fieldsets/_child.html.erb +1 -1
  37. data/app/views/dynamic_fieldsets/form_partials/_checkbox_field.html.erb +8 -0
  38. data/app/views/dynamic_fieldsets/form_partials/_date_field.html.erb +1 -0
  39. data/app/views/dynamic_fieldsets/form_partials/_datetime_field.html.erb +1 -0
  40. data/app/views/dynamic_fieldsets/form_partials/_input_footer.html.erb +1 -0
  41. data/app/views/dynamic_fieldsets/form_partials/_input_header.html.erb +7 -0
  42. data/app/views/dynamic_fieldsets/form_partials/_instruction_field.html.erb +1 -0
  43. data/app/views/dynamic_fieldsets/form_partials/_multiple_select_field.html.erb +1 -0
  44. data/app/views/dynamic_fieldsets/form_partials/_radio_field.html.erb +8 -0
  45. data/app/views/dynamic_fieldsets/form_partials/_select_field.html.erb +1 -0
  46. data/app/views/dynamic_fieldsets/form_partials/_text_field.html.erb +1 -0
  47. data/app/views/dynamic_fieldsets/form_partials/_textarea_field.html.erb +1 -0
  48. data/app/views/dynamic_fieldsets/shared/_javascript_watcher.html.erb +8 -8
  49. data/app/views/dynamic_fieldsets/show_partials/_show_incomplete.html.erb +1 -0
  50. data/app/views/dynamic_fieldsets/show_partials/_show_incomplete_footer.html.erb +2 -0
  51. data/app/views/dynamic_fieldsets/show_partials/_show_incomplete_header.html.erb +1 -0
  52. data/app/views/dynamic_fieldsets/show_partials/_show_instruction.html.erb +1 -0
  53. data/app/views/dynamic_fieldsets/show_partials/_show_multiple_answers.html.erb +13 -0
  54. data/app/views/dynamic_fieldsets/show_partials/_show_single_answer.html.erb +8 -0
  55. data/autotest/discover.rb +2 -0
  56. data/dynamic_fieldsets.gemspec +74 -20
  57. data/lib/dynamic_fieldsets/config.rb +45 -0
  58. data/lib/dynamic_fieldsets/dynamic_fieldsets_in_model.rb +38 -63
  59. data/lib/dynamic_fieldsets/field_with_field_options.rb +58 -0
  60. data/lib/dynamic_fieldsets/field_with_multiple_answers.rb +89 -0
  61. data/lib/dynamic_fieldsets/field_with_single_answer.rb +84 -0
  62. data/lib/dynamic_fieldsets/railtie.rb +6 -1
  63. data/lib/generators/dynamic_fieldsets/install_generator.rb +3 -3
  64. data/lib/generators/dynamic_fieldsets/templates/config.rb +15 -0
  65. data/lib/generators/dynamic_fieldsets/templates/migrations/install_migration.rb +1 -1
  66. data/spec/dummy/config/initializers/dynamic_fieldsets.rb +15 -0
  67. data/spec/dummy/db/migrate/20120213211033_create_dynamic_fieldsets_tables.rb +1 -1
  68. data/spec/dummy/db/schema.rb +1 -1
  69. data/spec/dummy/features/step_definitions/field_steps.rb +4 -4
  70. data/spec/dummy/features/step_definitions/fieldset_children_steps.rb +2 -2
  71. data/spec/dummy/features/step_definitions/javascript_steps.rb +7 -7
  72. data/spec/dynamic_fieldsets_helper_spec.rb +278 -312
  73. data/spec/dynamic_fieldsets_in_model_spec.rb +2 -2
  74. data/spec/field_with_field_options_spec.rb +49 -0
  75. data/spec/field_with_multiple_answers_spec.rb +50 -0
  76. data/spec/field_with_single_answer_spec.rb +51 -0
  77. data/spec/models/checkbox_field_spec.rb +19 -0
  78. data/spec/models/date_field_spec.rb +24 -0
  79. data/spec/models/datetime_field_spec.rb +24 -0
  80. data/spec/models/dependency_clause_spec.rb +7 -8
  81. data/spec/models/dependency_group_spec.rb +27 -30
  82. data/spec/models/dependency_spec.rb +8 -9
  83. data/spec/models/field_default_spec.rb +19 -14
  84. data/spec/models/field_html_attribute_spec.rb +3 -4
  85. data/spec/models/field_option_spec.rb +8 -9
  86. data/spec/models/field_record_spec.rb +8 -9
  87. data/spec/models/field_spec.rb +195 -94
  88. data/spec/models/fieldset_associator_spec.rb +39 -41
  89. data/spec/models/fieldset_child_spec.rb +99 -47
  90. data/spec/models/fieldset_spec.rb +25 -29
  91. data/spec/models/instruction_field_spec.rb +38 -0
  92. data/spec/models/multiple_select_field_spec.rb +31 -0
  93. data/spec/models/radio_field_spec.rb +21 -0
  94. data/spec/models/text_field_spec.rb +19 -0
  95. data/spec/models/textarea_field_spec.rb +39 -0
  96. data/spec/support/field_helper.rb +1 -1
  97. metadata +106 -28
@@ -1,6 +1,6 @@
1
1
  module DynamicFieldsets
2
2
  class FieldsetAssociator < ActiveRecord::Base
3
- set_table_name "dynamic_fieldsets_fieldset_associators"
3
+ self.table_name = "dynamic_fieldsets_fieldset_associators"
4
4
 
5
5
  belongs_to :fieldset
6
6
  belongs_to :fieldset_model, :polymorphic => true
@@ -41,43 +41,18 @@ module DynamicFieldsets
41
41
  end
42
42
 
43
43
  # Returns a hash of field record values
44
- # Fun nonintuitive stuff here
45
44
  #
46
- # The hash keys are field ids
47
- # The hash values are field_record values or field_records ids depending on the field type
48
- # The hash values are usually strings but sometimes arrays
49
- # If a field that expects a single value has multiple values, it will
50
- # choose one to use arbitrarily
51
- #
52
- # multiple_select: [option_ids,]
53
- # checkbox: [option_ids,]
54
- # select: option_id
55
- # radio: option_id
56
- # textfield: "value"
57
- # textarea: "value"
58
- # date: "value"
59
- # datetime: "value"
60
- # instruction: "value"
45
+ # This version returns a tree structure for nested fieldsets
46
+ # Could lead to all sorts of problems
61
47
  #
62
48
  # @return [Hash] A hash of field record values associated with field ids
63
49
  def field_values
64
- output = {}
65
- self.field_records.each do |record|
66
- fieldtype = record.fieldset_child.child.field_type
67
- child_id = record.fieldset_child.id
68
- if fieldtype == "checkbox" || fieldtype == "multiple_select"
69
- output[child_id] = [] unless output[child_id].is_a? Array
70
- # note record.id array
71
- output[child_id].push record.value.to_i
72
- elsif fieldtype == "radio" || fieldtype == "select"
73
- # note record.id
74
- output[child_id] = record.value.to_i
75
- else
76
- # note record.value
77
- output[child_id] = record.value
78
- end
79
- end
80
- return output
50
+ fieldset.get_values_using_fsa(self)
51
+ end
52
+
53
+ # given the params, passes along to the fieldset
54
+ def update_fieldset_records_with_form_information(fsa_params)
55
+ fieldset.update_field_records_with_form_information(fsa_params)
81
56
  end
82
57
 
83
58
  # Record whose field matches the name and associator matches the current associator
@@ -3,7 +3,7 @@ module DynamicFieldsets
3
3
  # FieldsetChild
4
4
  # @author Jeremiah Hemphill, John "hex" Carter
5
5
  class FieldsetChild < ActiveRecord::Base
6
- set_table_name "dynamic_fieldsets_fieldset_children"
6
+ self.table_name = "dynamic_fieldsets_fieldset_children"
7
7
 
8
8
  # Constants
9
9
 
@@ -46,16 +46,6 @@ module DynamicFieldsets
46
46
  self.order_num = self.last_order_num + 1 if self.order_num.nil?
47
47
  end
48
48
 
49
- # Methods
50
-
51
- # Returns a list of all the values in the FIELDSET_CHILD_LIST constant
52
- #
53
- # @params [None]
54
- # @returns [Array] An array of all the values stored in FIELDSET_CHILD_LIST
55
- def fieldset_child_list
56
- return FIELDSET_CHILD_LIST
57
- end
58
-
59
49
  # Sends a validation error if there are any duplicate pairings of fieldsets and fieldset children.
60
50
  #
61
51
  # @params [None]
@@ -102,19 +92,42 @@ module DynamicFieldsets
102
92
  parent_array.pop
103
93
  return false
104
94
  end
105
-
95
+
96
+ # Filters
97
+
98
+ # Scopes and Static Methods
99
+
106
100
  scope :ordered, order( 'order_num asc' )
107
-
101
+
102
+ # Methods
103
+
108
104
  # @return [ActiveRecord::Relation] Collection of FieldsetChildren that are direct descendents; ascending order.
109
105
  def children
110
106
  FieldsetChild.where( fieldset_id: self.child_id ).ordered
111
107
  end
112
-
113
- # @return [ActiveRecord::Relation] Collection of FieldsetChildren that share the same parent; ascending order.
114
- def siblings
115
- sib = FieldsetChild.where( fieldset_id: self.fieldset_id ).ordered
116
- sib.delete_if{ |child| child.id == self.id }
117
- sib
108
+
109
+ # Returns a list of all the values in the FIELDSET_CHILD_LIST constant
110
+ #
111
+ # @params [None]
112
+ # @returns [Array] An array of all the values stored in FIELDSET_CHILD_LIST
113
+ def fieldset_child_list
114
+ return FIELDSET_CHILD_LIST
115
+ end
116
+
117
+ # returns all the field record values for a single fieldset child
118
+ #
119
+ # @param [DynamicFieldsets::FieldsetAssociator] The parent fsa
120
+ # @return [Hash] A hash of field record values using the fieldset child id as they key
121
+ def get_value_using_fsa(fsa)
122
+ output = {}
123
+ if child.class == DynamicFieldsets::Fieldset
124
+ return child.get_values_using_fsa(fsa)
125
+ elsif child.class.superclass == DynamicFieldsets::Field
126
+ return child.get_values_using_fsa_and_fsc(fsa, self)
127
+ else
128
+ # I am not sure if we need to use child.superclass equals Field due to the sti
129
+ throw "there is a problem with fieldset_child.get_value_using_fsa possibly due to the single table inheritance."
130
+ end
118
131
  end
119
132
 
120
133
  # @return [Integer] The order number of the last sibling.
@@ -122,11 +135,6 @@ module DynamicFieldsets
122
135
  return 0 if siblings.empty?
123
136
  return self.siblings.last[:order_num]
124
137
  end
125
-
126
-
127
- def to_hash
128
- return { "id" => self.id, "fieldset_id" => self.fieldset_id, "child_id" => self.child_id, "child_type" => self.child_type }
129
- end
130
138
 
131
139
  # Returns the root fieldset of the child
132
140
  # Loops up the parent fieldset field until the parent is nil, then returns the child
@@ -145,5 +153,16 @@ module DynamicFieldsets
145
153
  return root_fieldset(parent_as_a_child.first.fieldset)
146
154
  end
147
155
  end
156
+
157
+ # @return [ActiveRecord::Relation] Collection of FieldsetChildren that share the same parent; ascending order.
158
+ def siblings
159
+ sib = FieldsetChild.where( fieldset_id: self.fieldset_id ).ordered
160
+ sib.delete_if{ |child| child.id == self.id }
161
+ sib
162
+ end
163
+
164
+ def to_hash
165
+ return { "id" => self.id, "fieldset_id" => self.fieldset_id, "child_id" => self.child_id, "child_type" => self.child_type }
166
+ end
148
167
  end
149
168
  end
@@ -0,0 +1,35 @@
1
+ module DynamicFieldsets
2
+ # A special field used only for instruction
3
+ # No user input is included
4
+ #
5
+ # Note that this field does not use the default header and footer partials for the fields
6
+ class InstructionField < Field
7
+ # no answers possible, need an include for this?
8
+
9
+ def show_partial
10
+ "/dynamic_fieldsets/show_partials/show_instruction"
11
+ end
12
+ # @return [Boolean] False because this field does not have the standard question: answer styling
13
+ def use_form_header_partial?
14
+ false
15
+ end
16
+
17
+ # @return [Boolean] False because this field does not have the standard question: answer styling
18
+ def use_form_footer_partial?
19
+ false
20
+ end
21
+
22
+ # @return [Hash] The label for the instruction plus the rest of the partial data
23
+ def form_partial_locals(args)
24
+ output = super
25
+ output[:label] = self.label
26
+ return output
27
+ end
28
+
29
+ # Do not update any options for the instruction
30
+ def update_field_records(fsa, fieldset_child, value)
31
+ # do nothing
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,43 @@
1
+ module DynamicFieldsets
2
+ # A select field that handles multiple selections
3
+ #
4
+ # Even though it just uses a select tag helper with multiple: true, the backend is quite different
5
+ # from the select field. It uses the multiple_answers mixin and all of the value and default
6
+ # methods return arrays instead of strings.
7
+ class MultipleSelectField < Field
8
+ acts_as_field_with_field_options
9
+ acts_as_field_with_multiple_answers
10
+
11
+ # @return [Hash] Sets multiple to true along with the standard arguments
12
+ def html_attribute_hash
13
+ super.merge!({
14
+ :multiple => true
15
+ })
16
+ end
17
+
18
+ # @return [Hash] data for the form partial
19
+ def form_partial_locals(args)
20
+ super.merge!({
21
+ :selected_ids => values_or_defaults_for_form(args[:values]),
22
+ :collection => self.options
23
+ })
24
+ end
25
+
26
+ # this returns field option ids based on the field default values
27
+ # due to funness with field options
28
+ #
29
+ # there is a good chance this is only needed due to a bug in multiple select's save default method
30
+ # We may need to take a look at this in the future. I think it could be moved to a mixin. (JH 2-28-2012)
31
+ # @return [Array] An array of field option ids that correspond to the field defaults
32
+ def collect_default_values
33
+ output = []
34
+ field_defaults.each do |default|
35
+ # find a field option with the same name as the default
36
+ # add it's id to the output
37
+ output << field_options.select { |option| option.name == default.value }.first.id
38
+ end
39
+ return output
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,27 @@
1
+ module DynamicFieldsets
2
+ # Radio buttons input
3
+ class RadioField < Field
4
+ acts_as_field_with_field_options
5
+ acts_as_field_with_single_answer
6
+
7
+ # Note that the radio buttons need special data per field option
8
+ # output[:options] contains information for each of the field options for the radio field
9
+ #
10
+ # @return [Hash] Data needed for the radio buttons partial
11
+ def form_partial_locals(args)
12
+ output = super
13
+ output[:options] = []
14
+ field_options.each do |option|
15
+ output[:options] << {
16
+ :name => "#{DynamicFieldsets.config.form_fieldset_associator_prefix}#{args[:fsa].id}[#{DynamicFieldsets.config.form_field_prefix}#{args[:fieldset_child].id}]",
17
+ :value => option.id.to_s,
18
+ :checked => value_or_default_for_form(args[:values]).eql?(option.id.to_s),
19
+ :html_attributes => html_attribute_hash,
20
+ :label => option.name,
21
+ }
22
+ end
23
+ return output
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,16 @@
1
+ module DynamicFieldsets
2
+ # Select input with one selection possible
3
+ class SelectField < Field
4
+ acts_as_field_with_field_options
5
+ acts_as_field_with_single_answer
6
+
7
+ # @return [Hash] data for the form partial
8
+ def form_partial_locals(args)
9
+ super.merge({
10
+ :selected_id => value_or_default_for_form(args[:value]).to_i,
11
+ :collection => self.options
12
+ })
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,14 @@
1
+ module DynamicFieldsets
2
+ # Text field input
3
+ class TextField < Field
4
+ acts_as_field_with_single_answer
5
+
6
+ # @return [Hash] data for the form partial
7
+ def form_partial_locals(args)
8
+ output = super
9
+ output[:attrs][:value] = value_or_default_for_form(args[:value])
10
+ return output
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,40 @@
1
+ module DynamicFieldsets
2
+ # Textarea input
3
+ #
4
+ # Note that this one is a little different than normal because the textarea does not store it's data
5
+ # in a value attribute
6
+ class TextareaField < Field
7
+ acts_as_field_with_single_answer
8
+
9
+ # @return [Integer] Default number of columns for the textarea
10
+ def default_cols
11
+ 40
12
+ end
13
+
14
+ # @return [Integer] Default number of rows for the textarea
15
+ def default_rows
16
+ 6
17
+ end
18
+
19
+ # @return [Hash] Html attributes for the textarea with default cols and rows if none are set
20
+ def html_attribute_hash
21
+ # this should get overriden by attributes the user sets
22
+ # with the call to super
23
+ output = {
24
+ :cols => default_cols,
25
+ :rows => default_rows,
26
+ }
27
+ output.merge!(super)
28
+ return output
29
+ end
30
+
31
+ # @return [Hash] Data for the form partial
32
+ def form_partial_locals(args)
33
+ output = super
34
+ output[:content] = value_or_default_for_form(args[:value])
35
+ output[:attrs][:name] = output[:name]
36
+ return output
37
+ end
38
+ end
39
+ end
40
+
@@ -1,63 +1,61 @@
1
- <%= form_for(@field) do |f| %>
2
- <% if @field.errors.any? %>
3
- <div id="error_explanation">
4
- <h2><%= pluralize(@field.errors.count, "error") %> prohibited this field from being saved:</h2>
5
-
6
- <ul>
7
- <% @field.errors.full_messages.each do |msg| %>
8
- <li><%= msg %></li>
9
- <% end %>
10
- </ul>
11
- </div>
12
- <% end %>
13
-
14
- <%= hidden_field_tag :parent, params[:parent] %>
1
+ <% if @field.errors.any? %>
2
+ <div id="error_explanation">
3
+ <h2><%= pluralize(@field.errors.count, "error") %> prohibited this field from being saved:</h2>
15
4
 
16
- <div class="field">
17
- <%= f.label :name %>: (internal)<br/>
18
- <%= f.text_field :name %>
19
- </div>
20
- <div class="field">
21
- <%= f.label :label %>: (displayed on the form)<br/>
22
- <%= f.text_field :label %>
5
+ <ul>
6
+ <% @field.errors.full_messages.each do |msg| %>
7
+ <li><%= msg %></li>
8
+ <% end %>
9
+ </ul>
23
10
  </div>
11
+ <% end %>
24
12
 
25
- <div class="field">
26
- <%= f.label :field_type %>:
27
- <%= f.select :field_type, options_for_select(DynamicFieldsets::Field.field_types, @field.field_type), :include_blank => "Choose One" %>
28
- </div>
29
- <% @field.field_options.each do |field_option| %>
30
- <%= f.fields_for :field_options, field_option do |field_option_form| %>
31
- <%= render :partial => "field_option_fields", :locals => {:f => field_option_form} %>
32
- <% end %>
33
- <% end %>
34
- <p><%= link_to_add_fields "Add Field Option", f, :field_options %></p>
13
+ <%= hidden_field_tag :parent, params[:parent] %>
35
14
 
36
- <div class="field">
37
- <%= f.label :required %>
38
- <%= f.check_box :required %>
39
- </div>
40
- <div class="field">
41
- <%= f.label :enabled %>
42
- <%= f.check_box :enabled %>
43
- </div>
15
+ <div class="field">
16
+ <%= f.label :name %>: (internal)<br/>
17
+ <%= f.text_field :name %>
18
+ </div>
19
+ <div class="field">
20
+ <%= f.label :label %>: (displayed on the form)<br/>
21
+ <%= f.text_field :label %>
22
+ </div>
44
23
 
45
- <% @field.field_defaults.each do |field_default| %>
46
- <%= f.fields_for :field_defaults, field_default do |field_default_form| %>
47
- <%= render :partial => "field_default_fields", :locals => {:f => field_default_form, :obj => field_default} %>
48
- <% end %>
24
+ <div class="field">
25
+ <%= f.label :type %>:
26
+ <%= f.select :type, options_for_select(DynamicFieldsets::Field.descendant_collection, @field.type), :include_blank => "Choose One" %>
27
+ </div>
28
+ <% @field.field_options.each do |field_option| %>
29
+ <%= f.fields_for :field_options, field_option do |field_option_form| %>
30
+ <%= render :partial => "field_option_fields", :locals => {:f => field_option_form} %>
49
31
  <% end %>
50
- <p><%= link_to_add_fields "Add Default Value", f, :field_defaults %></p>
32
+ <% end %>
33
+ <p><%= link_to_add_fields "Add Field Option", f, :field_options %></p>
51
34
 
52
- <% @field.field_html_attributes.each do |field_html_attribute| %>
53
- <%= f.fields_for :field_html_attributes, field_html_attribute do |field_html_attribute_form| %>
54
- <%= render :partial => "field_html_attribute_fields", :locals => {:f => field_html_attribute_form} %>
55
- <% end %>
35
+ <div class="field">
36
+ <%= f.label :required %>
37
+ <%= f.check_box :required %>
38
+ </div>
39
+ <div class="field">
40
+ <%= f.label :enabled %>
41
+ <%= f.check_box :enabled %>
42
+ </div>
43
+
44
+ <% @field.field_defaults.each do |field_default| %>
45
+ <%= f.fields_for :field_defaults, field_default do |field_default_form| %>
46
+ <%= render :partial => "field_default_fields", :locals => {:f => field_default_form, :obj => field_default} %>
56
47
  <% end %>
57
- <p><%= link_to_add_fields "Add Html Attribute", f, :field_html_attributes %></p>
48
+ <% end %>
49
+ <p><%= link_to_add_fields "Add Default Value", f, :field_defaults %></p>
58
50
 
59
- <div class="actions">
60
- <%= f.submit %>
61
- </div>
51
+ <% @field.field_html_attributes.each do |field_html_attribute| %>
52
+ <%= f.fields_for :field_html_attributes, field_html_attribute do |field_html_attribute_form| %>
53
+ <%= render :partial => "field_html_attribute_fields", :locals => {:f => field_html_attribute_form} %>
54
+ <% end %>
62
55
  <% end %>
56
+ <p><%= link_to_add_fields "Add Html Attribute", f, :field_html_attributes %></p>
57
+
58
+ <div class="actions">
59
+ <%= f.submit %>
60
+ </div>
63
61
  <%= render :partial => "/dynamic_fieldsets/shared/nested_model_javascript" %>