nested_form 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ 0.1.1 (April 23, 2011)
2
+
3
+ * Support HTML options and block in add/remove link - issue #31
4
+
5
+ * Added new RegEx to generate new objects IDs correctly - issue #26 and issue #30
6
+
1
7
  0.1.0 (March 26, 2011)
2
8
 
3
9
  * Prefix new records with "new_" so there's no possible conflict with existing records - issue #21
data/README.rdoc CHANGED
@@ -4,6 +4,8 @@ This is a Rails gem for conveniently manage multiple nested models in a single f
4
4
 
5
5
  This gem only works with Rails 3. See the {rails2 branch}[https://github.com/ryanb/nested_form/tree/rails2] for a plugin to work in Rails 2.
6
6
 
7
+ An example project showing how this works is available in the {complex-nested-forms/nested_form branch}[https://github.com/ryanb/complex-form-examples/tree/nested_form].
8
+
7
9
 
8
10
  == Setup
9
11
 
@@ -22,7 +24,11 @@ Running the generator will add a file at <tt>public/javascripts/nested_form.js</
22
24
 
23
25
  == Usage
24
26
 
25
- Use the +nested_form_for+ helper method to enable the nesting.
27
+ Imagine you have a <tt>Project</tt> model that <tt>has_many :tasks</tt>. To be able to use this gem, you'll need to add <tt>accepts_nested_attributes_for :tasks</tt> to your Project model. If you don't have the <tt>accepts_nested_attributes_for :tasks</tt> you'll get a Missing Block Error.
28
+
29
+ This will create a <tt>tasks_attributes=</tt> method, so you may need to add it to the <tt>attr_accessible</tt> array. (<tt>attr_accessible :tasks_attributes</tt>)
30
+
31
+ Then use the +nested_form_for+ helper method to enable the nesting.
26
32
 
27
33
  <%= nested_form_for @project do |f| %>
28
34
 
@@ -41,16 +47,18 @@ It is often desirable to move the nested fields into a partial to keep things or
41
47
 
42
48
  <%= f.fields_for :tasks %>
43
49
 
44
- In this case it will look for a partial called "task_fields" and pass the form builder as an f variable to it.
50
+ In this case it will look for a partial called "task_fields" and pass the form builder as an +f+ variable to it.
45
51
 
46
52
 
47
53
  == Events
48
54
 
49
- If you are using jQuery, <tt>nested:fieldAdded<tt> and <tt>nested:fieldRemoved</tt> events are triggered on the +form+ element after adding and removing fields.
55
+ If you are using jQuery, <tt>nested:fieldAdded</tt> and <tt>nested:fieldRemoved</tt> events are triggered on the +form+ element after adding and removing fields.
50
56
 
51
57
 
52
58
  == Special Thanks
53
59
 
60
+ First of all, thanks ro Ryan Bates for this gem. Awesome work.
61
+
54
62
  This gem was originally based on the solution by Tim Riley in his {complex-form-examples fork}[https://github.com/timriley/complex-form-examples/tree/unobtrusive-jquery-deep-fix2].
55
63
 
56
64
  Thank you Andrew Manshin for the Rails 3 transition, {Andrea Singh}[https://github.com/madebydna] for converting to a gem and {Peter Giacomo Lombardo}[https://github.com/pglombardo] for Prototype support.
@@ -18,10 +18,13 @@ jQuery(function($) {
18
18
 
19
19
  for(i = 0; i < parent_names.length; i++) {
20
20
  if(parent_ids[i]) {
21
+ content = content.replace(
22
+ new RegExp('(_' + parent_names[i] + ')_.+?_', 'g'),
23
+ '$1_' + parent_ids[i] + '_');
24
+
21
25
  content = content.replace(
22
26
  new RegExp('(\\[' + parent_names[i] + '\\])\\[.+?\\]', 'g'),
23
- '$1[' + parent_ids[i] + ']'
24
- )
27
+ '$1[' + parent_ids[i] + ']');
25
28
  }
26
29
  }
27
30
  }
@@ -17,12 +17,15 @@ document.observe('click', function(e, el) {
17
17
  var parent_ids = context.match(/(new_)?[0-9]+/g) || [];
18
18
 
19
19
  for(i = 0; i < parent_names.length; i++) {
20
- if(parent_ids[i]) {
21
- content = content.replace(
22
- new RegExp('(\\[' + parent_names[i] + '\\])\\[.+?\\]', 'g'),
23
- '$1[' + parent_ids[i] + ']'
24
- )
25
- }
20
+ if(parent_ids[i]) {
21
+ content = content.replace(
22
+ new RegExp('(_' + parent_names[i] + ')_.+?_', 'g'),
23
+ '$1_' + parent_ids[i] + '_');
24
+
25
+ content = content.replace(
26
+ new RegExp('(\\[' + parent_names[i] + '\\])\\[.+?\\]', 'g'),
27
+ '$1[' + parent_ids[i] + ']');
28
+ }
26
29
  }
27
30
  }
28
31
 
@@ -1,6 +1,23 @@
1
1
  module NestedForm
2
2
  class Builder < ::ActionView::Helpers::FormBuilder
3
- def link_to_add(name, association)
3
+ # Adds a link to insert a new associated records. The first argument is the name of the link, the second is the name of the association.
4
+ #
5
+ # f.link_to_add("Add Task", :tasks)
6
+ #
7
+ # You can pass HTML options in a hash at the end and a block for the content.
8
+ #
9
+ # <%= f.link_to_add(:tasks, :class => "add_task", :href => new_task_path) do %>
10
+ # Add Task
11
+ # <% end %>
12
+ #
13
+ # See the README for more details on where to call this method.
14
+ def link_to_add(*args, &block)
15
+ options = args.extract_options!.symbolize_keys
16
+ association = args.pop
17
+ options[:class] = [options[:class], "add_nested_fields"].compact.join(" ")
18
+ options["data-association"] = association
19
+ args << (options.delete(:href) || "javascript:void(0)")
20
+ args << options
4
21
  @fields ||= {}
5
22
  @template.after_nested_form(association) do
6
23
  model_object = object.class.reflect_on_association(association).klass.new
@@ -9,11 +26,26 @@ module NestedForm
9
26
  output.safe_concat('</div>')
10
27
  output
11
28
  end
12
- @template.link_to(name, "javascript:void(0)", :class => "add_nested_fields", "data-association" => association)
29
+ @template.link_to(*args, &block)
13
30
  end
14
31
 
15
- def link_to_remove(name)
16
- hidden_field(:_destroy) + @template.link_to(name, "javascript:void(0)", :class => "remove_nested_fields")
32
+ # Adds a link to remove the associated record. The first argment is the name of the link.
33
+ #
34
+ # f.link_to_remove("Remove Task")
35
+ #
36
+ # You can pass HTML options in a hash at the end and a block for the content.
37
+ #
38
+ # <%= f.link_to_remove(:class => "remove_task", :href => "#") do %>
39
+ # Remove Task
40
+ # <% end %>
41
+ #
42
+ # See the README for more details on where to call this method.
43
+ def link_to_remove(*args, &block)
44
+ options = args.extract_options!.symbolize_keys
45
+ options[:class] = [options[:class], "remove_nested_fields"].compact.join(" ")
46
+ args << (options.delete(:href) || "javascript:void(0)")
47
+ args << options
48
+ hidden_field(:_destroy) + @template.link_to(*args, &block)
17
49
  end
18
50
 
19
51
  def fields_for_with_nested_attributes(association_name, args, block)
@@ -14,7 +14,7 @@ module NestedForm
14
14
  @associations ||= []
15
15
  @after_nested_form_callbacks ||= []
16
16
  unless @associations.include?(association)
17
- @associations << association
17
+ @associations << association
18
18
  @after_nested_form_callbacks << block
19
19
  end
20
20
  end
@@ -9,12 +9,16 @@ describe NestedForm::Builder do
9
9
  @builder = NestedForm::Builder.new(:item, @project, @template, {}, proc {})
10
10
  end
11
11
 
12
- it "should have an add link" do
12
+ it "has an add link which behaves similar to a Rails link_to" do
13
13
  @builder.link_to_add("Add", :tasks).should == '<a href="javascript:void(0)" class="add_nested_fields" data-association="tasks">Add</a>'
14
+ @builder.link_to_add("Add", :tasks, :class => "foo", :href => "url").should == '<a href="url" class="foo add_nested_fields" data-association="tasks">Add</a>'
15
+ @builder.link_to_add(:tasks) { "Add" }.should == '<a href="javascript:void(0)" class="add_nested_fields" data-association="tasks">Add</a>'
14
16
  end
15
17
 
16
- it "should have a remove link" do
18
+ it "has a remove link which behaves similar to a Rails link_to" do
17
19
  @builder.link_to_remove("Remove").should == '<input id="item__destroy" name="item[_destroy]" type="hidden" value="false" /><a href="javascript:void(0)" class="remove_nested_fields">Remove</a>'
20
+ @builder.link_to_remove("Remove", :class => "foo", :href => "url").should == '<input id="item__destroy" name="item[_destroy]" type="hidden" value="false" /><a href="url" class="foo remove_nested_fields">Remove</a>'
21
+ @builder.link_to_remove { "Remove" }.should == '<input id="item__destroy" name="item[_destroy]" type="hidden" value="false" /><a href="javascript:void(0)" class="remove_nested_fields">Remove</a>'
18
22
  end
19
23
 
20
24
  it "should wrap nested fields each in a div with class" do
@@ -31,6 +35,6 @@ describe NestedForm::Builder do
31
35
  @builder.fields_for(:tasks) { "Task" }
32
36
  @builder.link_to_add("Add", :tasks)
33
37
  output.should == '<div id="tasks_fields_blueprint" style="display: none"><div class="fields">Task</div></div>'
34
- end
38
+ end
35
39
  end
36
40
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: nested_form
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.0
5
+ version: 0.1.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ryan Bates
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2011-03-26 00:00:00 -07:00
14
+ date: 2011-04-23 00:00:00 -07:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency