cocoon 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|