cocoon 1.0.0 → 1.0.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.
- data/README.markdown +22 -6
- data/VERSION +1 -1
- data/cocoon.gemspec +2 -2
- data/lib/cocoon/view_helpers.rb +48 -11
- data/lib/generators/cocoon/install/templates/cocoon.js +17 -2
- metadata +4 -4
data/README.markdown
CHANGED
@@ -94,13 +94,14 @@ There is an example project on github implementing it called [formtastic-cocoon-
|
|
94
94
|
|
95
95
|
### Using simple_form
|
96
96
|
|
97
|
-
|
97
|
+
This is almost identical to formtastic, instead of writing `semantic_fields_for` you write `simple_fields_for`.
|
98
|
+
|
99
|
+
There is an example project on github implementing it called [cocoon_simple_form_demo](https://github.com/nathanvda/cocoon_simple_form_demo).
|
98
100
|
|
99
|
-
I will provide a full example (and a sample project) later.
|
100
101
|
|
101
102
|
### Using standard rails forms
|
102
103
|
|
103
|
-
I provide a full example (and a sample project) later.
|
104
|
+
I will provide a full example (and a sample project) later.
|
104
105
|
|
105
106
|
## How it works
|
106
107
|
|
@@ -111,17 +112,31 @@ I define two helper functions:
|
|
111
112
|
This function will add a link to your markup that will, when clicked, dynamically add a new partial form for the given association.
|
112
113
|
This should be placed below the `semantic_fields_for`.
|
113
114
|
|
114
|
-
It takes
|
115
|
+
It takes four parameters:
|
115
116
|
|
116
117
|
- name: the text to show in the link
|
117
|
-
- f: referring to the containing
|
118
|
+
- f: referring to the containing form-object
|
118
119
|
- association: the name of the association (plural) of which a new instance needs to be added (symbol or string).
|
120
|
+
- html_options: extra html-options (see `link_to`)
|
121
|
+
There are two extra options that allow to conrol the placement of the new link-data:
|
122
|
+
- `data-association-insertion-node` : the jquery selector of the node
|
123
|
+
- `data-association-insertion-position` : insert the new data `before` or `after` the given node.
|
124
|
+
|
125
|
+
Optionally you could also leave out the name and supply a block that is captured to give the name (if you want to do something more complicated).
|
119
126
|
|
120
127
|
### link_to_remove_association
|
121
128
|
|
122
129
|
This function will add a link to your markup that will, when clicked, dynamically remove the surrounding partial form.
|
123
130
|
This should be placed inside the partial `_<association-object-singular>_fields`.
|
124
131
|
|
132
|
+
It takes three parameters:
|
133
|
+
|
134
|
+
- name: the text to show in the link
|
135
|
+
- f: referring to the containing form-object
|
136
|
+
- html_options: extra html-options (see `link_to`)
|
137
|
+
|
138
|
+
Optionally you could also leave out the name and supply a block that is captured to give the name (if you want to do something more complicated).
|
139
|
+
|
125
140
|
### Partial
|
126
141
|
|
127
142
|
The partial should be named `_<association-object_singular>_fields`, and should start with a div of class `.nested-fields`.
|
@@ -142,7 +157,8 @@ There is no limit to the amount of nesting, though.
|
|
142
157
|
|
143
158
|
## Todo
|
144
159
|
|
145
|
-
* complete the sample projects for simple_form and normal rails forms
|
160
|
+
* complete the sample projects -for simple_form- and normal rails forms
|
161
|
+
* add more sample relations: has_many :through, belongs_to, ...
|
146
162
|
* complete the test-coverage
|
147
163
|
|
148
164
|
## Copyright
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.1
|
data/cocoon.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{cocoon}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Nathan Van der Auwera"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-03-03}
|
13
13
|
s.description = %q{Unobtrusive nested forms handling, using jQuery. Use this and discover cocoon-heaven.}
|
14
14
|
s.email = %q{nathan@dixis.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/cocoon/view_helpers.rb
CHANGED
@@ -3,12 +3,31 @@ module Cocoon
|
|
3
3
|
|
4
4
|
|
5
5
|
# this will show a link to remove the current association. This should be placed inside the partial.
|
6
|
-
#
|
6
|
+
# either you give
|
7
7
|
# - *name* : the text of the link
|
8
8
|
# - *f* : the form this link should be placed in
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
# - *html_options*: html options to be passed to link_to (see <tt>link_to</tt>)
|
10
|
+
#
|
11
|
+
# or you use the form without *name* with a *&block*
|
12
|
+
# - *f* : the form this link should be placed in
|
13
|
+
# - *html_options*: html options to be passed to link_to (see <tt>link_to</tt>)
|
14
|
+
# - *&block*: the output of the block will be show in the link, see <tt>link_to</tt>
|
15
|
+
|
16
|
+
def link_to_remove_association(*args, &block)
|
17
|
+
if block_given?
|
18
|
+
f = args.first
|
19
|
+
html_options = args.second || {}
|
20
|
+
name = capture(&block)
|
21
|
+
link_to_remove_association(name, f, html_options)
|
22
|
+
else
|
23
|
+
name = args[0]
|
24
|
+
f = args[1]
|
25
|
+
html_options = args[2] || {}
|
26
|
+
|
27
|
+
is_dynamic = f.object.new_record?
|
28
|
+
html_options[:class] = [html_options[:class], "remove_fields #{is_dynamic ? 'dynamic' : 'existing'}"].compact.join(' ')
|
29
|
+
f.hidden_field(:_destroy) + link_to(name, '#', html_options)
|
30
|
+
end
|
12
31
|
end
|
13
32
|
|
14
33
|
# :nodoc:
|
@@ -23,14 +42,32 @@ module Cocoon
|
|
23
42
|
# - *name* : the text to show in the link
|
24
43
|
# - *f* : the form this should come in (the formtastic form)
|
25
44
|
# - *association* : the associated objects, e.g. :tasks, this should be the name of the <tt>has_many</tt> relation.
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
45
|
+
# - *html_options*: html options to be passed to <tt>link_to</tt> (see <tt>link_to</tt>)
|
46
|
+
# - *&block*: see <tt>link_to</tt>
|
47
|
+
|
48
|
+
def link_to_add_association(*args, &block)
|
49
|
+
if block_given?
|
50
|
+
f = args[0]
|
51
|
+
association = args[1]
|
52
|
+
html_options = args[2] || {}
|
53
|
+
link_to_add_association(capture(&block), f, association, html_options)
|
54
|
+
else
|
55
|
+
name = args[0]
|
56
|
+
f = args[1]
|
57
|
+
association = args[2]
|
58
|
+
html_options = args[3] || {}
|
59
|
+
|
60
|
+
html_options[:class] = [html_options[:class], "add_fields"].compact.join(' ')
|
61
|
+
html_options[:'data-association'] = association.to_s.singularize
|
62
|
+
|
63
|
+
new_object = f.object.class.reflect_on_association(association).klass.new
|
64
|
+
model_name = new_object.class.name.underscore
|
65
|
+
hidden_div = content_tag('div', :id => "#{model_name}_fields_template", :style => "display:none;") do
|
66
|
+
render_association(association, f, new_object)
|
67
|
+
end
|
68
|
+
|
69
|
+
hidden_div.html_safe + link_to(name, '#', html_options )
|
32
70
|
end
|
33
|
-
hidden_div.html_safe + link_to(name, '#', :class => 'add_fields', :'data-association' => association.to_s.singularize)
|
34
71
|
end
|
35
72
|
|
36
73
|
end
|
@@ -3,6 +3,8 @@ $(document).ready(function() {
|
|
3
3
|
$('.add_fields').live('click', function() {
|
4
4
|
var assoc = $(this).attr('data-association');
|
5
5
|
var content = $(this).siblings('#' + assoc + '_fields_template').html();
|
6
|
+
var insertionPosition = $(this).attr('data-association-insertion-position');
|
7
|
+
var insertionNode = $(this).attr('data-association-insertion-node');
|
6
8
|
var regexp_braced = new RegExp('\\[new_' + assoc + '\\]', 'g');
|
7
9
|
var new_id = new Date().getTime();
|
8
10
|
var new_content = content.replace(regexp_braced, '[' + new_id + ']');
|
@@ -10,7 +12,19 @@ $(document).ready(function() {
|
|
10
12
|
regexp_braced = new RegExp('\\[new_' + assoc + 's\\]', 'g');
|
11
13
|
new_content = content.replace(regexp_braced, '[' + new_id + ']');
|
12
14
|
}
|
13
|
-
|
15
|
+
if (insertionNode) {
|
16
|
+
insertionNode = $(insertionNode);
|
17
|
+
}
|
18
|
+
else {
|
19
|
+
insertionNode = $(this).parent();
|
20
|
+
}
|
21
|
+
|
22
|
+
if (insertionPosition == 'after'){
|
23
|
+
insertionNode.after(new_content);
|
24
|
+
} else {
|
25
|
+
insertionNode.before(new_content);
|
26
|
+
}
|
27
|
+
|
14
28
|
return false;
|
15
29
|
});
|
16
30
|
|
@@ -25,4 +39,5 @@ $(document).ready(function() {
|
|
25
39
|
return false;
|
26
40
|
});
|
27
41
|
|
28
|
-
});
|
42
|
+
});
|
43
|
+
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 1
|
9
|
+
version: 1.0.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Nathan Van der Auwera
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-03-03 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -101,7 +101,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
101
101
|
requirements:
|
102
102
|
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
hash:
|
104
|
+
hash: -548597357
|
105
105
|
segments:
|
106
106
|
- 0
|
107
107
|
version: "0"
|