awesome_nested_fields 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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: []