nested_form 0.1.0 → 0.1.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/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