nested_form 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/CHANGELOG.rdoc +9 -0
  2. data/Gemfile +11 -0
  3. data/README.rdoc +23 -23
  4. data/Rakefile +23 -8
  5. data/lib/nested_form/builder_mixin.rb +1 -1
  6. data/spec/dummy/app/assets/javascripts/jquery_nested_form.js +33 -1
  7. data/spec/dummy/config/initializers/session_store.rb +1 -1
  8. data/spec/dummy/config/initializers/wrap_parameters.rb +1 -1
  9. data/spec/dummy/db/migrate/20110710143903_initial_tables.rb +5 -5
  10. data/spec/dummy/db/schema.rb +1 -0
  11. data/spec/dummy/db/test.sqlite3 +0 -0
  12. data/spec/dummy/log/test.log +58 -0
  13. data/spec/dummy/tmp/cache/assets/C99/4D0/sprockets%2F5e30a6b911437f1428dc32c3ae182123 +0 -0
  14. data/spec/dummy/tmp/cache/assets/C99/7D0/sprockets%2F79513e6956e0ee8624976e041fd5636d +0 -0
  15. data/spec/dummy/tmp/cache/assets/CAA/C90/sprockets%2F1e6c8ee1258009385ccf5b84015424b3 +0 -0
  16. data/spec/dummy/tmp/cache/assets/CDB/8A0/sprockets%2Faed2a2575c376263c26e93b56b57051d +0 -0
  17. data/spec/dummy/tmp/cache/assets/D79/BC0/sprockets%2F85a1db977361cc5130fcefb4637ff67e +0 -0
  18. data/spec/dummy/tmp/cache/assets/D87/1F0/sprockets%2F61c9ceafb877fb740c67416ff6f782a9 +0 -0
  19. data/spec/dummy/tmp/cache/assets/DAD/4F0/sprockets%2F765acd1bf68dc90f7d3e61da78b1e659 +0 -0
  20. data/spec/dummy/tmp/cache/assets/E03/3F0/sprockets%2F82b37ae9eccec44c1ef44cfdd07d8534 +0 -0
  21. data/spec/dummy/tmp/cache/assets/E0A/CA0/sprockets%2F7fe72ac1c0db1a7e8e7f59cf25e8a39e +0 -0
  22. data/spec/dummy/tmp/cache/assets/E54/400/sprockets%2Fd0cbc16cc37efcf9dc41f242b5dbbf81 +0 -0
  23. data/spec/dummy/tmp/cache/assets/EB7/AB0/sprockets%2F801d29a5debdbfbfb4eef14d70d9bcdb +0 -0
  24. data/spec/dummy/tmp/cache/assets/F48/5E0/sprockets%2F26cd6ffcffbebbe2fd6cd1a8f0c2debc +0 -0
  25. data/spec/form_spec.rb +9 -7
  26. data/vendor/assets/javascripts/jquery_nested_form.js +103 -0
  27. data/vendor/assets/javascripts/prototype_nested_form.js +51 -0
  28. metadata +66 -9
  29. data/spec/dummy/db/development.sqlite3 +0 -0
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,12 @@
1
+ 0.2.1 (June 4, 2012)
2
+
3
+ * Added Travis integration (thanks fxposter)
4
+
5
+ * Make the "context" selector stricter, to work with deeply-nested forms. (thanks groe and nickhoffman)
6
+
7
+ * Include vendor folder in the gem for Rails 3.1 asset support (thanks dmarkow)
8
+
9
+
1
10
  0.2.0 (February 7, 2012)
2
11
 
3
12
  * Integration tests (thanks fxposter) - issue #58
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ gem 'activerecord-jdbcsqlite3-adapter', :platforms => :jruby
6
+ gem 'sqlite3', :platforms => :ruby
7
+ gem 'simple_form'
8
+ gem 'formtastic'
9
+ gem 'rake'
10
+ gem 'capybara'
11
+ gem 'rails', '~> 3.2.0'
data/README.rdoc CHANGED
@@ -1,5 +1,7 @@
1
1
  = Nested Form
2
2
 
3
+ {<img src="https://secure.travis-ci.org/ryanb/nested_form.png?branch=master" alt="Build Status" />}[http://travis-ci.org/ryanb/nested_form]
4
+
3
5
  This is a Rails gem for conveniently manage multiple nested models in a single form. It does so in an unobtrusive way through jQuery or Prototype.
4
6
 
5
7
  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.
@@ -7,40 +9,24 @@ This gem only works with Rails 3. See the {rails2 branch}[https://github.com/rya
7
9
  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
10
 
9
11
 
10
- == Changes in this repo
11
-
12
- === Enhanced jQuery javascript template
13
-
14
- Now you can override default behavior of inserting new subforms into your form (jQuery-only feature, sorry). For example:
15
-
16
- window.nestedFormEvents.insertFields = function(content, assoc, link) {
17
- return $(link).closest('form').find(assoc + '_fields').append($(content));
18
- }
19
-
20
- === Rails 3.1 support (with asset pipeline)
12
+ == Setup
21
13
 
22
- There's a small fix for Rails 3.1 form handling.
23
- Also support of Rails 3.1 led me to huge refactor of specs setup (now using Helper specs from rspec-rails instead of custom implementation spec context).
14
+ Add it to your Gemfile then run +bundle+ to install it.
24
15
 
25
- Formtastic is supported only with Rails 3.0, Rails 3.1 integration is not available now.
16
+ gem "nested_form"
26
17
 
27
- Asset pipeline is supported. So you can use
18
+ And then add it to the Asset Pipeline in the appication.js file:
28
19
 
29
20
  //= require jquery_nested_form
30
- // or
31
- //= require prototype_nested_form
32
-
33
- == Setup
34
21
 
35
- Add it to your Gemfile then run +bundle+ to install it.
36
22
 
37
- gem "nested_form"
23
+ === Non Asset Pipeline Setup
38
24
 
39
- Next run the generator to create the JavaScript file. This will automatically detect if you are using jQuery or Prototype.
25
+ If you do not use the asset pipeline, run this generator to create the JavaScript file.
40
26
 
41
27
  rails g nested_form:install
42
28
 
43
- Running the generator will add a file at <tt>public/javascripts/nested_form.js</tt> which should be included after the jQuery or Prototype framework.
29
+ You can then include the generated JavaScript in your layout.
44
30
 
45
31
  <%= javascript_include_tag :defaults, "nested_form" %>
46
32
 
@@ -83,6 +69,20 @@ In this case it will look for a partial called "task_fields" and pass the form b
83
69
  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.
84
70
 
85
71
 
72
+ == Enhanced jQuery JavaScript template
73
+
74
+ You can override default behavior of inserting new subforms into your form. For example:
75
+
76
+ window.nestedFormEvents.insertFields = function(content, assoc, link) {
77
+ return $(link).closest('form').find(assoc + '_fields').append($(content));
78
+ }
79
+
80
+
81
+ == Project Status
82
+
83
+ Unfortunately I have not had time to actively work on this project recently. If you find a critical issue where it does not work as documented please {ping me on Twitter}[http://twitter.com/rbates] and I'll take a look.
84
+
85
+
86
86
  == Special Thanks
87
87
 
88
88
  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].
data/Rakefile CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'rubygems'
2
- # require 'appraisal'
3
2
  require 'rake'
4
3
 
5
4
  begin
@@ -13,17 +12,33 @@ rescue LoadError
13
12
  end
14
13
 
15
14
  task :default => :spec
15
+
16
+ namespace :db do
17
+ task :migrate do
18
+ system 'cd spec/dummy && rake db:migrate RAILS_ENV=test && rake db:migrate RAILS_ENV=development'
19
+ end
20
+ end
21
+
16
22
  namespace :spec do
17
23
  task :install do
18
- puts `bundle install --gemfile=gemfiles/Gemfile.rails3_0`
19
- puts `bundle install --gemfile=gemfiles/Gemfile.rails3_1`
24
+ system 'bundle install'
25
+ system 'bundle install --gemfile=gemfiles/Gemfile.rails3_0'
26
+ system 'bundle install --gemfile=gemfiles/Gemfile.rails3_1'
20
27
  end
21
-
22
- task :all do
28
+
29
+ task :rails3_1 do
30
+ ENV['BUNDLE_GEMFILE'] = File.expand_path('../gemfiles/Gemfile.rails3_1', __FILE__)
31
+ Rake::Task["spec"].execute
32
+ end
33
+
34
+ task :rails3_0 do
23
35
  ENV['BUNDLE_GEMFILE'] = File.expand_path('../gemfiles/Gemfile.rails3_0', __FILE__)
24
36
  Rake::Task["spec"].execute
25
-
26
- ENV['BUNDLE_GEMFILE'] = File.expand_path('../gemfiles/Gemfile.rails3_1', __FILE__)
37
+ end
38
+
39
+ task :all do
27
40
  Rake::Task["spec"].execute
41
+ Rake::Task["spec:rails3_1"].execute
42
+ Rake::Task["spec:rails3_0"].execute
28
43
  end
29
- end
44
+ end
@@ -45,7 +45,7 @@ module NestedForm
45
45
  options[:class] = [options[:class], "remove_nested_fields"].compact.join(" ")
46
46
  args << (options.delete(:href) || "javascript:void(0)")
47
47
  args << options
48
- hidden_field(:_destroy) + @template.link_to(*args, &block)
48
+ (hidden_field(:_destroy) << @template.link_to(*args, &block)).html_safe
49
49
  end
50
50
 
51
51
  def fields_for_with_nested_attributes(association_name, *args)
@@ -13,7 +13,8 @@ jQuery(function($) {
13
13
 
14
14
  // Make the context correct by replacing new_<parents> with the generated ID
15
15
  // of each of the parent objects
16
- var context = ($(link).closest('.fields').find('input:first').attr('name') || '').replace(new RegExp('\[[a-z]+\]$'), '');
16
+ var context = ($(link).closest('.fields').closestChild('input:first').attr('name') || '').replace(new RegExp('\[[a-z]+\]$'), '');
17
+
17
18
 
18
19
  // context will be something like this for a brand new form:
19
20
  // project[tasks_attributes][new_1255929127459][assignments_attributes][new_1255929128105]
@@ -69,3 +70,34 @@ jQuery(function($) {
69
70
  $('form a.add_nested_fields').live('click', nestedFormEvents.addFields);
70
71
  $('form a.remove_nested_fields').live('click', nestedFormEvents.removeFields);
71
72
  });
73
+
74
+
75
+ // http://plugins.jquery.com/project/closestChild
76
+ /*
77
+ * Copyright 2011, Tobias Lindig
78
+ *
79
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
80
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
81
+ *
82
+ */
83
+ (function($) {
84
+ $.fn.closestChild = function(selector) {
85
+ // breadth first search for the first matched node
86
+ if (selector && selector != '') {
87
+ var queue = [];
88
+ queue.push(this);
89
+ while(queue.length > 0) {
90
+ var node = queue.shift();
91
+ var children = node.children();
92
+ for(var i = 0; i < children.length; ++i) {
93
+ var child = $(children[i]);
94
+ if (child.is(selector)) {
95
+ return child; //well, we found one
96
+ }
97
+ queue.push(child);
98
+ }
99
+ }
100
+ }
101
+ return $();//nothing found
102
+ };
103
+ })(jQuery);
@@ -1,6 +1,6 @@
1
1
  # Be sure to restart your server when you modify this file.
2
2
 
3
- Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
3
+ Dummy::Application.config.session_store :cookie_store, :key => '_dummy_session'
4
4
 
5
5
  # Use the database for sessions instead of the cookie-based default,
6
6
  # which shouldn't be used to store highly confidential information
@@ -4,7 +4,7 @@
4
4
  # is enabled by default.
5
5
 
6
6
  # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7
- ActionController::Base.wrap_parameters format: [:json] if ActionController::Base.respond_to?(:wrap_parameters)
7
+ ActionController::Base.wrap_parameters :format => [:json] if ActionController::Base.respond_to?(:wrap_parameters)
8
8
 
9
9
  # Disable root element in JSON by default.
10
10
  if defined?(ActiveRecord)
@@ -1,21 +1,21 @@
1
1
  class InitialTables < ActiveRecord::Migration
2
- def up
3
- create_table :projects, :force => true do |t|
2
+ def self.up
3
+ create_table :projects do |t|
4
4
  t.string :name
5
5
  end
6
6
 
7
- create_table :tasks, :force => true do |t|
7
+ create_table :tasks do |t|
8
8
  t.integer :project_id
9
9
  t.string :name
10
10
  end
11
11
 
12
- create_table :milestones, :force => true do |t|
12
+ create_table :milestones do |t|
13
13
  t.integer :task_id
14
14
  t.string :name
15
15
  end
16
16
  end
17
17
 
18
- def down
18
+ def self.down
19
19
  drop_table :projects
20
20
  drop_table :tasks
21
21
  drop_table :milestones
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  # This file is auto-generated from the current state of the database. Instead
2
3
  # of editing this file, please use the migrations feature of Active Record to
3
4
  # incrementally modify your database, and then regenerate this schema definition.
Binary file
@@ -0,0 +1,58 @@
1
+ Connecting to database specified by database.yml
2
+
3
+
4
+ Started GET "/projects/new" for 127.0.0.1 at 2012-06-04 11:03:17 -0700
5
+ Processing by ProjectsController#new as HTML
6
+ Completed 500 Internal Server Error in 1ms
7
+ Connecting to database specified by database.yml
8
+  (0.1ms) select sqlite_version(*)
9
+  (1.8ms) CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
10
+  (0.0ms) PRAGMA index_list("schema_migrations")
11
+  (1.7ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
12
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" 
13
+ Migrating to InitialTables (20110710143903)
14
+  (0.0ms) begin transaction
15
+  (0.2ms) CREATE TABLE "projects" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255)) 
16
+  (0.1ms) CREATE TABLE "tasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "project_id" integer, "name" varchar(255))
17
+  (0.1ms) CREATE TABLE "milestones" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "task_id" integer, "name" varchar(255)) 
18
+  (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20110710143903')
19
+  (2.3ms) commit transaction
20
+  (0.2ms) select sqlite_version(*)
21
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" 
22
+  (0.0ms) PRAGMA index_list("milestones")
23
+  (0.0ms) PRAGMA index_list("projects")
24
+  (0.0ms) PRAGMA index_list("tasks")
25
+ Connecting to database specified by database.yml
26
+
27
+
28
+ Started GET "/projects/new" for 127.0.0.1 at 2012-06-04 11:08:28 -0700
29
+ Processing by ProjectsController#new as HTML
30
+ Rendered projects/new.html.erb within layouts/application (199.1ms)
31
+ Completed 200 OK in 908ms (Views: 904.8ms | ActiveRecord: 0.4ms)
32
+
33
+
34
+ Started GET "/assets/jquery.js" for 127.0.0.1 at 2012-06-04 11:08:29 -0700
35
+ Compiled jquery.js (21ms) (pid 52505)
36
+ Served asset /jquery.js - 200 OK (417ms)
37
+
38
+
39
+ Started GET "/assets/jquery_nested_form.js" for 127.0.0.1 at 2012-06-04 11:08:30 -0700
40
+ Compiled jquery_nested_form.js (0ms) (pid 52505)
41
+ Served asset /jquery_nested_form.js - 200 OK (25ms)
42
+
43
+
44
+ Started GET "/projects/new?type=prototype" for 127.0.0.1 at 2012-06-04 11:08:30 -0700
45
+ Processing by ProjectsController#new as HTML
46
+ Parameters: {"type"=>"prototype"}
47
+ Rendered projects/new.html.erb within layouts/application (2.1ms)
48
+ Completed 200 OK in 3ms (Views: 2.6ms | ActiveRecord: 0.0ms)
49
+
50
+
51
+ Started GET "/assets/prototype.js" for 127.0.0.1 at 2012-06-04 11:08:31 -0700
52
+ Compiled prototype.js (1ms) (pid 52505)
53
+ Served asset /prototype.js - 200 OK (413ms)
54
+
55
+
56
+ Started GET "/assets/prototype_nested_form.js" for 127.0.0.1 at 2012-06-04 11:08:31 -0700
57
+ Compiled prototype_nested_form.js (0ms) (pid 52505)
58
+ Served asset /prototype_nested_form.js - 200 OK (72ms)
data/spec/form_spec.rb CHANGED
@@ -2,30 +2,32 @@ require 'spec_helper'
2
2
 
3
3
  describe 'NestedForm' do
4
4
  include Capybara::DSL
5
-
5
+
6
6
  def check_form
7
7
  page.should have_no_css('form .fields input[id$=name]')
8
8
  click_link 'Add new task'
9
9
  page.should have_css('form .fields input[id$=name]', :count => 1)
10
10
  find('form .fields input[id$=name]').should be_visible
11
11
  find('form .fields input[id$=_destroy]').value.should == 'false'
12
-
12
+
13
13
  click_link 'Remove'
14
14
  find('form .fields input[id$=_destroy]').value.should == '1'
15
15
  find('form .fields input[id$=name]').should_not be_visible
16
-
16
+
17
17
  click_link 'Add new task'
18
18
  click_link 'Add new task'
19
19
  fields = all('form .fields')
20
20
  fields.select { |field| field.visible? }.count.should == 2
21
21
  fields.reject { |field| field.visible? }.count.should == 1
22
22
  end
23
-
24
- it 'should work with jQuery and Prototype', :js => true do
23
+
24
+ it 'should work with jQuery', :js => true do
25
25
  visit '/projects/new'
26
26
  check_form
27
-
27
+ end
28
+
29
+ it 'should work with Prototype', :js => true do
28
30
  visit '/projects/new?type=prototype'
29
31
  check_form
30
32
  end
31
- end
33
+ end
@@ -0,0 +1,103 @@
1
+ jQuery(function($) {
2
+ window.NestedFormEvents = function() {
3
+ this.addFields = $.proxy(this.addFields, this);
4
+ this.removeFields = $.proxy(this.removeFields, this);
5
+ };
6
+
7
+ NestedFormEvents.prototype = {
8
+ addFields: function(e) {
9
+ // Setup
10
+ var link = e.currentTarget;
11
+ var assoc = $(link).attr('data-association'); // Name of child
12
+ var content = $('#' + assoc + '_fields_blueprint').html(); // Fields template
13
+
14
+ // Make the context correct by replacing new_<parents> with the generated ID
15
+ // of each of the parent objects
16
+ var context = ($(link).closest('.fields').closestChild('input:first').attr('name') || '').replace(new RegExp('\[[a-z]+\]$'), '');
17
+
18
+
19
+ // context will be something like this for a brand new form:
20
+ // project[tasks_attributes][new_1255929127459][assignments_attributes][new_1255929128105]
21
+ // or for an edit form:
22
+ // project[tasks_attributes][0][assignments_attributes][1]
23
+ if (context) {
24
+ var parentNames = context.match(/[a-z_]+_attributes/g) || [];
25
+ var parentIds = context.match(/(new_)?[0-9]+/g) || [];
26
+
27
+ for(var i = 0; i < parentNames.length; i++) {
28
+ if(parentIds[i]) {
29
+ content = content.replace(
30
+ new RegExp('(_' + parentNames[i] + ')_.+?_', 'g'),
31
+ '$1_' + parentIds[i] + '_');
32
+
33
+ content = content.replace(
34
+ new RegExp('(\\[' + parentNames[i] + '\\])\\[.+?\\]', 'g'),
35
+ '$1[' + parentIds[i] + ']');
36
+ }
37
+ }
38
+ }
39
+
40
+ // Make a unique ID for the new child
41
+ var regexp = new RegExp('new_' + assoc, 'g');
42
+ var new_id = new Date().getTime();
43
+ content = content.replace(regexp, "new_" + new_id);
44
+
45
+ var field = this.insertFields(content, assoc, link);
46
+ $(link).closest("form")
47
+ .trigger({ type: 'nested:fieldAdded', field: field })
48
+ .trigger({ type: 'nested:fieldAdded:' + assoc, field: field });
49
+ return false;
50
+ },
51
+ insertFields: function(content, assoc, link) {
52
+ return $(content).insertBefore(link);
53
+ },
54
+ removeFields: function(e) {
55
+ var link = e.currentTarget;
56
+ var hiddenField = $(link).prev('input[type=hidden]');
57
+ hiddenField.val('1');
58
+ // if (hiddenField) {
59
+ // $(link).v
60
+ // hiddenField.value = '1';
61
+ // }
62
+ var field = $(link).closest('.fields');
63
+ field.hide();
64
+ $(link).closest("form").trigger({ type: 'nested:fieldRemoved', field: field });
65
+ return false;
66
+ }
67
+ };
68
+
69
+ window.nestedFormEvents = new NestedFormEvents();
70
+ $('form a.add_nested_fields').live('click', nestedFormEvents.addFields);
71
+ $('form a.remove_nested_fields').live('click', nestedFormEvents.removeFields);
72
+ });
73
+
74
+
75
+ // http://plugins.jquery.com/project/closestChild
76
+ /*
77
+ * Copyright 2011, Tobias Lindig
78
+ *
79
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
80
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
81
+ *
82
+ */
83
+ (function($) {
84
+ $.fn.closestChild = function(selector) {
85
+ // breadth first search for the first matched node
86
+ if (selector && selector != '') {
87
+ var queue = [];
88
+ queue.push(this);
89
+ while(queue.length > 0) {
90
+ var node = queue.shift();
91
+ var children = node.children();
92
+ for(var i = 0; i < children.length; ++i) {
93
+ var child = $(children[i]);
94
+ if (child.is(selector)) {
95
+ return child; //well, we found one
96
+ }
97
+ queue.push(child);
98
+ }
99
+ }
100
+ }
101
+ return $();//nothing found
102
+ };
103
+ })(jQuery);
@@ -0,0 +1,51 @@
1
+ document.observe('click', function(e, el) {
2
+ if (el = e.findElement('form a.add_nested_fields')) {
3
+ // Setup
4
+ var assoc = el.readAttribute('data-association'); // Name of child
5
+ var content = $(assoc + '_fields_blueprint').innerHTML; // Fields template
6
+
7
+ // Make the context correct by replacing new_<parents> with the generated ID
8
+ // of each of the parent objects
9
+ var context = (el.getOffsetParent('.fields').firstDescendant().readAttribute('name') || '').replace(new RegExp('\[[a-z]+\]$'), '');
10
+
11
+ // context will be something like this for a brand new form:
12
+ // project[tasks_attributes][new_1255929127459][assignments_attributes][new_1255929128105]
13
+ // or for an edit form:
14
+ // project[tasks_attributes][0][assignments_attributes][1]
15
+ if(context) {
16
+ var parent_names = context.match(/[a-z_]+_attributes/g) || [];
17
+ var parent_ids = context.match(/(new_)?[0-9]+/g) || [];
18
+
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
+ content = content.replace(
26
+ new RegExp('(\\[' + parent_names[i] + '\\])\\[.+?\\]', 'g'),
27
+ '$1[' + parent_ids[i] + ']');
28
+ }
29
+ }
30
+ }
31
+
32
+ // Make a unique ID for the new child
33
+ var regexp = new RegExp('new_' + assoc, 'g');
34
+ var new_id = new Date().getTime();
35
+ content = content.replace(regexp, "new_" + new_id);
36
+
37
+ el.insert({ before: content });
38
+ return false;
39
+ }
40
+ });
41
+
42
+ document.observe('click', function(e, el) {
43
+ if (el = e.findElement('form a.remove_nested_fields')) {
44
+ var hidden_field = el.previous(0);
45
+ if(hidden_field) {
46
+ hidden_field.value = '1';
47
+ }
48
+ el.ancestors()[0].hide();
49
+ return false;
50
+ }
51
+ });
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nested_form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,22 +10,59 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-02-08 00:00:00.000000000Z
13
+ date: 2012-06-04 00:00:00.000000000 Z
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: bundler
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
15
47
  - !ruby/object:Gem::Dependency
16
48
  name: rspec-rails
17
- requirement: &2152812540 !ruby/object:Gem::Requirement
49
+ requirement: !ruby/object:Gem::Requirement
18
50
  none: false
19
51
  requirements:
20
52
  - - ~>
21
53
  - !ruby/object:Gem::Version
22
- version: 2.6.0
54
+ version: '2.6'
23
55
  type: :development
24
56
  prerelease: false
25
- version_requirements: *2152812540
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: '2.6'
26
63
  - !ruby/object:Gem::Dependency
27
64
  name: mocha
28
- requirement: &2152812140 !ruby/object:Gem::Requirement
65
+ requirement: !ruby/object:Gem::Requirement
29
66
  none: false
30
67
  requirements:
31
68
  - - ! '>='
@@ -33,7 +70,12 @@ dependencies:
33
70
  version: '0'
34
71
  type: :development
35
72
  prerelease: false
36
- version_requirements: *2152812140
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
37
79
  description: Gem to conveniently handle multiple models in a single form with Rails
38
80
  3 and jQuery or Prototype.
39
81
  email: ryan@railscasts.com
@@ -80,10 +122,10 @@ files:
80
122
  - spec/dummy/config/locales/en.yml
81
123
  - spec/dummy/config/routes.rb
82
124
  - spec/dummy/config.ru
83
- - spec/dummy/db/development.sqlite3
84
125
  - spec/dummy/db/migrate/20110710143903_initial_tables.rb
85
126
  - spec/dummy/db/schema.rb
86
127
  - spec/dummy/db/test.sqlite3
128
+ - spec/dummy/log/test.log
87
129
  - spec/dummy/public/404.html
88
130
  - spec/dummy/public/422.html
89
131
  - spec/dummy/public/500.html
@@ -92,11 +134,26 @@ files:
92
134
  - spec/dummy/script/rails
93
135
  - spec/dummy/test/functional/projects_controller_test.rb
94
136
  - spec/dummy/test/unit/helpers/projects_helper_test.rb
137
+ - spec/dummy/tmp/cache/assets/C99/4D0/sprockets%2F5e30a6b911437f1428dc32c3ae182123
138
+ - spec/dummy/tmp/cache/assets/C99/7D0/sprockets%2F79513e6956e0ee8624976e041fd5636d
139
+ - spec/dummy/tmp/cache/assets/CAA/C90/sprockets%2F1e6c8ee1258009385ccf5b84015424b3
140
+ - spec/dummy/tmp/cache/assets/CDB/8A0/sprockets%2Faed2a2575c376263c26e93b56b57051d
141
+ - spec/dummy/tmp/cache/assets/D79/BC0/sprockets%2F85a1db977361cc5130fcefb4637ff67e
142
+ - spec/dummy/tmp/cache/assets/D87/1F0/sprockets%2F61c9ceafb877fb740c67416ff6f782a9
143
+ - spec/dummy/tmp/cache/assets/DAD/4F0/sprockets%2F765acd1bf68dc90f7d3e61da78b1e659
144
+ - spec/dummy/tmp/cache/assets/E03/3F0/sprockets%2F82b37ae9eccec44c1ef44cfdd07d8534
145
+ - spec/dummy/tmp/cache/assets/E0A/CA0/sprockets%2F7fe72ac1c0db1a7e8e7f59cf25e8a39e
146
+ - spec/dummy/tmp/cache/assets/E54/400/sprockets%2Fd0cbc16cc37efcf9dc41f242b5dbbf81
147
+ - spec/dummy/tmp/cache/assets/EB7/AB0/sprockets%2F801d29a5debdbfbfb4eef14d70d9bcdb
148
+ - spec/dummy/tmp/cache/assets/F48/5E0/sprockets%2F26cd6ffcffbebbe2fd6cd1a8f0c2debc
95
149
  - spec/form_spec.rb
96
150
  - spec/nested_form/builder_spec.rb
97
151
  - spec/nested_form/view_helper_spec.rb
98
152
  - spec/spec_helper.rb
153
+ - vendor/assets/javascripts/jquery_nested_form.js
154
+ - vendor/assets/javascripts/prototype_nested_form.js
99
155
  - CHANGELOG.rdoc
156
+ - Gemfile
100
157
  - LICENSE
101
158
  - Rakefile
102
159
  - README.rdoc
@@ -120,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
177
  version: 1.3.4
121
178
  requirements: []
122
179
  rubyforge_project: nested_form
123
- rubygems_version: 1.8.10
180
+ rubygems_version: 1.8.23
124
181
  signing_key:
125
182
  specification_version: 3
126
183
  summary: Gem to conveniently handle multiple models in a single form.
Binary file