awesome_nested_fields 0.3.2 → 0.4.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.
data/README.md CHANGED
@@ -114,6 +114,20 @@ To implement this on the basic example, do something like:
114
114
 
115
115
  And yeah, you need to mark it with the class `empty` or any other selector configured via javascript.
116
116
 
117
+ #### render_template
118
+
119
+ When `nested_fields_for` is called, it also includes a `<script>` tag with the html template of a new item, so the javascript code knows what to insert. But sometimes it is not possible to put the template just after the items. For example, you can be inside a table (tables cannot have script elements inside it) or have multi-level nested items (the templates would be recursively repeated). In these cases you need to render the template manually.
120
+
121
+ To do this, just set the `render_template` option to `false` and use the `nested_fields_template` helper to put the templates anywhere on the page.
122
+
123
+ <%= f.nested_fields_for :phones, render_template: false do |f| %>
124
+ <% nested field code %>
125
+ <% end %>
126
+ <!-- some lines after -->
127
+ <%= nested_fields_templates %>
128
+
129
+ Keep in mind that you can call the templates only after `nested_fields_for` and inside the DOM element you apply the `nestedFields()` javascript, so it still can find the templates.
130
+
117
131
  ### Javascript Options
118
132
 
119
133
  #### Selectors
@@ -178,6 +192,36 @@ The code above inserts a new item and does not execute the `beforeInsert` callba
178
192
  These methods can be called from the element where nested fields are applied (e.g. a form) or from any element inside it (e.g. an input or the container itself).
179
193
 
180
194
 
195
+ Multiples Nested Fields
196
+ -----------------------
197
+
198
+ It is easy to have multiple nested fields on the same page. Instead of applying `nestedFields()` on the form, put the elements (items, container, add, remove) inside a wrapper and apply nested fields to it.
199
+
200
+ <!-- ERB Code -->
201
+ <h2>Phones</h2>
202
+ <div id="phones">
203
+ <div class="container">
204
+ <%= f.nested_fields_for :phones do |f| %>
205
+ <% ... %>
206
+ <% end %>
207
+ </div>
208
+ <a href="#" class="add">add phone</a>
209
+ </div>
210
+
211
+ <h2>Addresses</h2>
212
+ <div id="addresses">
213
+ <div class="container">
214
+ <%= f.nested_fields_for :addresses do |f| %>
215
+ <% ... %>
216
+ <% end %>
217
+ </div>
218
+ <a href="#" class="add">add address</a>
219
+ </div>
220
+
221
+ // JS Code
222
+ $('#phones, #addresses').nestedFields();
223
+
224
+
181
225
  Demo
182
226
  ----
183
227
 
@@ -1,3 +1,3 @@
1
1
  module AwesomeNestedFields
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  ActionView::Helpers::FormBuilder.class_eval do
2
+
2
3
  def nested_fields_for(association, options={}, &block)
3
4
  raise ArgumentError, 'Missing block to nested_fields_for' unless block_given?
4
5
 
@@ -7,6 +8,7 @@ ActionView::Helpers::FormBuilder.class_eval do
7
8
  options[:item_template_class] ||= ['template', 'item', association.to_s.singularize].join(' ')
8
9
  options[:empty_template_class] ||= ['template', 'empty', association.to_s.singularize].join(' ')
9
10
  options[:show_empty] ||= false
11
+ options[:render_template] = options.key?(:render_template) ? options[:render_template] : true
10
12
 
11
13
  output = @template.capture { fields_for(association, &block) }
12
14
 
@@ -14,13 +16,19 @@ ActionView::Helpers::FormBuilder.class_eval do
14
16
  output.safe_concat @template.capture { yield nil }
15
17
  end
16
18
 
17
- output.safe_concat nested_fields_templates(association, options, &block)
19
+ template = render_nested_fields_template(association, options, &block)
20
+ if options[:render_template]
21
+ output.safe_concat template
22
+ else
23
+ add_nested_fields_template(association, template)
24
+ end
18
25
 
19
26
  output
20
27
  end
21
28
 
22
- private
23
- def nested_fields_templates(association, options, &block)
29
+ protected
30
+
31
+ def render_nested_fields_template(association, options, &block)
24
32
  templates = @template.content_tag(:script, type: 'text/html', class: options[:item_template_class]) do
25
33
  fields_for(association, options[:new_object], child_index: options[:new_item_index], &block)
26
34
  end
@@ -31,4 +39,21 @@ private
31
39
 
32
40
  templates
33
41
  end
42
+
43
+ def add_nested_fields_template(association, template)
44
+ # It must be a hash, so we don't get repeated templates on deeply nested models
45
+ @template.instance_variable_set(:@nested_fields_template_cache, {}) unless @template.instance_variable_get(:@nested_fields_template_cache)
46
+ @template.instance_variable_get(:@nested_fields_template_cache)[association] = template
47
+ create_nested_fields_template_helper!
48
+ end
49
+
50
+ def create_nested_fields_template_helper!
51
+ def @template.nested_fields_templates
52
+ @nested_fields_template_cache.reduce(ActiveSupport::SafeBuffer.new) do |buffer, entry|
53
+ association, template = entry
54
+ buffer.safe_concat template
55
+ end
56
+ end unless @template.respond_to?(:nested_fields_templates)
57
+ end
58
+
34
59
  end
@@ -26,26 +26,26 @@
26
26
  // PUBLIC API
27
27
  var methods = {
28
28
  init: function(options) {
29
- var $this = $(this);
30
- if($(this).data('nested-fields.options')) {
31
- console.log('Nested fields already defined for this element. If you want to redefine options, destroy it and init again.');
32
- return $this;
33
- } else if(getOptions($this)) {
34
- console.log('You cannot nest nested fields. Who would say that, uh?');
35
- return $this;
36
- }
37
-
38
- options = $.extend({}, defaultSettings, options);
39
- options.itemTemplate = $(options.itemTemplateSelector, $this);
40
- options.emptyTemplate = $(options.emptyTemplateSelector, $this);
41
- options.container = $(options.containerSelector, $this);
42
- options.add = $(options.addSelector, $this);
43
- $this.data('nested-fields.options', options);
44
-
45
- bindInsertToAdd(options);
46
- bindRemoveToItems(options);
47
-
48
- return $this;
29
+ return this.each(function() {
30
+ var $this = $(this);
31
+ if($(this).data('nested-fields.options')) {
32
+ console.log('Nested fields already defined for this element. If you want to redefine options, destroy it and init again.');
33
+ return $this;
34
+ } else if(getOptions($this)) {
35
+ console.log('You cannot nest nested fields. Who would say that, uh?');
36
+ return $this;
37
+ }
38
+
39
+ options = $.extend({}, defaultSettings, options);
40
+ options.itemTemplate = $(options.itemTemplateSelector, $this);
41
+ options.emptyTemplate = $(options.emptyTemplateSelector, $this);
42
+ options.container = $(options.containerSelector, $this);
43
+ options.add = $(options.addSelector, $this);
44
+ $this.data('nested-fields.options', options);
45
+
46
+ bindInsertToAdd(options);
47
+ bindRemoveToItems(options);
48
+ });
49
49
  },
50
50
 
51
51
  insert: function(callback, options) {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awesome_nested_fields
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-07-22 00:00:00.000000000 -03:00
12
+ date: 2011-07-23 00:00:00.000000000 -03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
17
- requirement: &2161324400 !ruby/object:Gem::Requirement
17
+ requirement: &2156407920 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 1.0.0
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *2161324400
25
+ version_requirements: *2156407920
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rails
28
- requirement: &2161323780 !ruby/object:Gem::Requirement
28
+ requirement: &2156407420 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: 3.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2161323780
36
+ version_requirements: *2156407420
37
37
  description: Awesome dynamic nested fields for Rails and jQuery
38
38
  email: lailson@guava.com.br
39
39
  executables: []