diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..64424809 Binary files /dev/null and b/.DS_Store differ diff --git a/.rvmrc b/.rvmrc deleted file mode 100644 index 3f63e3a7..00000000 --- a/.rvmrc +++ /dev/null @@ -1 +0,0 @@ -rvm use 1.9.2@nested_form --create diff --git a/Gemfile b/Gemfile index f5191458..d2aa28b0 100644 --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,4 @@ gemspec :path => '.' instance_eval File.read(File.expand_path('../gemfiles/Gemfile.base', __FILE__)) gem 'rails', '~> 3.2.0' +gem 'test-unit' \ No newline at end of file diff --git a/Rakefile b/Rakefile index 93920dda..3548596d 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,13 @@ require 'rubygems' require 'rake' +module TempFixForRakeLastComment + def last_comment + last_description + end +end +Rake::Application.send :include, TempFixForRakeLastComment + begin require 'rspec/core/rake_task' desc "Run RSpec" @@ -24,11 +31,11 @@ namespace :spec do desc 'Install gems from additional gemfiles' task :install do system 'bundle install' - ENV.delete('GEM_HOME') - ENV['BUNDLE_GEMFILE'] = File.expand_path('../gemfiles/Gemfile.rails3_1', __FILE__) - system 'bundle install' - ENV['BUNDLE_GEMFILE'] = File.expand_path('../gemfiles/Gemfile.rails3_0', __FILE__) - system 'bundle install' + # ENV.delete('GEM_HOME') + # ENV['BUNDLE_GEMFILE'] = File.expand_path('../gemfiles/Gemfile.rails3_1', __FILE__) + # system 'bundle install' + # ENV['BUNDLE_GEMFILE'] = File.expand_path('../gemfiles/Gemfile.rails3_0', __FILE__) + # system 'bundle install' end desc 'Run tests with Rails 3.1.x' @@ -47,7 +54,7 @@ namespace :spec do task :all do Rake::Task["spec"].execute - Rake::Task["spec:rails3_1"].execute - Rake::Task["spec:rails3_0"].execute + # Rake::Task["spec:rails3_1"].execute + # Rake::Task["spec:rails3_0"].execute end end diff --git a/gemfiles/Gemfile.rails3_0 b/gemfiles/Gemfile.rails3_0 deleted file mode 100644 index 89368140..00000000 --- a/gemfiles/Gemfile.rails3_0 +++ /dev/null @@ -1,5 +0,0 @@ -gemspec :path => '../' -instance_eval File.read(File.expand_path('../Gemfile.base', __FILE__)) -# forcing 3.0.20 (rather than 3.0.0) fixes a bug where bundle hangs -# trying to fetch gems from github -gem "rails", "~> 3.0.20" diff --git a/gemfiles/Gemfile.rails3_1 b/gemfiles/Gemfile.rails3_2 similarity index 79% rename from gemfiles/Gemfile.rails3_1 rename to gemfiles/Gemfile.rails3_2 index 3b5f9faa..334591d8 100644 --- a/gemfiles/Gemfile.rails3_1 +++ b/gemfiles/Gemfile.rails3_2 @@ -1,3 +1,3 @@ gemspec :path => '../' instance_eval File.read(File.expand_path('../Gemfile.base', __FILE__)) -gem "rails", "~> 3.1.0" +gem "rails", "~> 3.2.0" diff --git a/spec/.DS_Store b/spec/.DS_Store new file mode 100644 index 00000000..50abe249 Binary files /dev/null and b/spec/.DS_Store differ diff --git a/spec/dummy/.DS_Store b/spec/dummy/.DS_Store new file mode 100644 index 00000000..c32d382d Binary files /dev/null and b/spec/dummy/.DS_Store differ diff --git a/spec/dummy/app/.DS_Store b/spec/dummy/app/.DS_Store new file mode 100644 index 00000000..650ce685 Binary files /dev/null and b/spec/dummy/app/.DS_Store differ diff --git a/spec/dummy/app/assets/.DS_Store b/spec/dummy/app/assets/.DS_Store new file mode 100644 index 00000000..f3027350 Binary files /dev/null and b/spec/dummy/app/assets/.DS_Store differ diff --git a/spec/dummy/app/assets/javascripts/application.js b/spec/dummy/app/assets/javascripts/application.js old mode 100644 new mode 100755 diff --git a/spec/dummy/app/assets/javascripts/jquery.js b/spec/dummy/app/assets/javascripts/jquery.js old mode 100644 new mode 100755 diff --git a/spec/dummy/app/assets/javascripts/jquery_events_test.js b/spec/dummy/app/assets/javascripts/jquery_events_test.js old mode 100644 new mode 100755 diff --git a/spec/dummy/app/assets/javascripts/projects.js b/spec/dummy/app/assets/javascripts/projects.js old mode 100644 new mode 100755 diff --git a/spec/dummy/app/assets/javascripts/prototype.js b/spec/dummy/app/assets/javascripts/prototype.js old mode 100644 new mode 100755 diff --git a/spec/dummy/app/assets/javascripts/prototype_events_test.js b/spec/dummy/app/assets/javascripts/prototype_events_test.js old mode 100644 new mode 100755 diff --git a/spec/dummy/app/views/projects/with_target_links.html.erb b/spec/dummy/app/views/projects/with_target_links.html.erb new file mode 100644 index 00000000..e9e868ab --- /dev/null +++ b/spec/dummy/app/views/projects/with_target_links.html.erb @@ -0,0 +1,17 @@ +<%= nested_form_for Project.new do |f| -%> + <%= f.text_field :name %> +
+ <%= f.fields_for :tasks do |tf| -%> + <%= tf.text_field :name %> +
+ <%= tf.fields_for :milestones do |mf| %> + <%= mf.text_field :name %> + <%= mf.link_to_remove 'Remove milestone' %> + <% end %> +
+ <%= tf.link_to_add 'Add new milestone', :milestones, data: {target: '#milestone-fields'} %> + <%= tf.link_to_remove 'Remove' %> + <% end -%> +
+ <%= f.link_to_add 'Add new task', :tasks, data: {target: '#task-fields'} %> +<% end -%> diff --git a/spec/form_spec.rb b/spec/form_spec.rb index 2701051b..89ee69d7 100644 --- a/spec/form_spec.rb +++ b/spec/form_spec.rb @@ -40,6 +40,17 @@ def check_form inputs.first[:name].should_not eq(inputs.last[:name]) end + it 'works when specify target', :js => true do + visit '/projects/with_target_links' + click_link 'Add new task' + click_link 'Remove' + click_link 'Add new task' + click_link 'Add new milestone' + + # page.should have_selector('#milestone-fields .fields', :visible => true) + find(:css, "#milestone-fields .fields").should be_visible + end + it 'generates correct name for the nested input', :js => true do visit '/projects/new?type=jquery' click_link 'Add new task' diff --git a/vendor/assets/javascripts/jquery_nested_form.js b/vendor/assets/javascripts/jquery_nested_form.js index b9225b14..4445c5e8 100644 --- a/vendor/assets/javascripts/jquery_nested_form.js +++ b/vendor/assets/javascripts/jquery_nested_form.js @@ -16,37 +16,15 @@ // of each of the parent objects var context = ($(link).closest('.fields').closestChild('input, textarea, select').eq(0).attr('name') || '').replace(/\[[a-z_]+\]$/, ''); - // If the parent has no inputs we need to strip off the last pair - var current = content.match(new RegExp('\\[([a-z_]+)\\]\\[new_' + assoc + '\\]'))[1]; - if (current) { - context = context.replace(new RegExp('\\['+current+'\\]\\[(new_)?\\d+\\]$'), ''); - } - - // context will be something like this for a brand new form: - // project[tasks_attributes][1255929127459][assignments_attributes][1255929128105] - // or for an edit form: - // project[tasks_attributes][0][assignments_attributes][1] - if (context) { - var parentNames = context.match(/[a-z_]+_attributes(?=\]\[(new_)?\d+\])/g) || []; - var parentIds = context.match(/[0-9]+/g) || []; + if (context){ + var parentNames = context.match(/[a-z_]+_attributes(?=\]\[(new_)?.+\])/g) || []; + var parentIds = context.match(/[0-9]+/g) || []; - for(var i = 0; i < parentNames.length; i++) { - if(parentIds[i]) { - content = content.replace( - new RegExp('(_' + parentNames[i] + ')_.+?_', 'g'), - '$1_' + parentIds[i] + '_'); - - content = content.replace( - new RegExp('(\\[' + parentNames[i] + '\\])\\[.+?\\]', 'g'), - '$1[' + parentIds[i] + ']'); - } - } + content = this.replaceContentFromParents(content, assoc, parentNames, parentIds) + } + else{ + content = this.replaceContentFromParents(content, assoc) } - - // Make a unique ID for the new child - var regexp = new RegExp('new_' + assoc, 'g'); - var new_id = this.newId(); - content = $.trim(content.replace(regexp, new_id)); var field = this.insertFields(content, assoc, link); // bubble up event upto document (through form) @@ -60,8 +38,12 @@ }, insertFields: function(content, assoc, link) { var target = $(link).data('target'); - if (target) { - return $(content).appendTo($(target)); + if (target) { + if($(link).closest('.fields').length > 0) { + return $(content).appendTo($(link).closest('.fields').find($(link).data('target'))); + } else { + return $(content).appendTo($(target)); + } } else { return $(content).insertBefore(link); } @@ -80,6 +62,36 @@ .trigger({ type: 'nested:fieldRemoved', field: field }) .trigger({ type: 'nested:fieldRemoved:' + assoc, field: field }); return false; + }, + replaceContentFromParents: function(content, assoc, parentNames, parentIds){ + parentNames = parentNames || []; + parentIds = parentIds || []; + + if (parentNames.length > 0 && parentNames.length == parentIds.length){ + // we need to get a name pattern and id pattern that is mapped to parent + var fullNameRegexp = ""; // regexp used to find the full name pattern in blueprint + var fullIdRegexp = ""; // regexp used to find the full id pattern in blueprint + var fullNameReplace = ""; // name part from parents, eg. [parameters_attributes][0][children_attributes][1] + var fullIdReplace = ""; // id part from parents, eg. _parameters_attributes_0_children_attributes_1 + for (var i=0; i< parentNames.length; i++){ + fullNameRegexp += "\\[" + parentNames[i] + "\\]\\[.+?\\]"; + fullNameReplace += "[" + parentNames[i] + "][" + parentIds[i] + "]"; + fullIdRegexp += "_" + parentNames[i] + "_.+?"; + fullIdReplace += "_" + parentNames[i] + "_" + parentIds[i]; + + if (i== parentNames.length -1){ + fullIdRegexp += "(?=_" + assoc + "_attributes)" + } + } + content = content.replace(new RegExp(fullNameRegexp, 'g'), fullNameReplace); + content = content.replace(new RegExp(fullIdRegexp, 'g'), fullIdReplace); + } + + // Make a unique ID for the new child + var regexp = new RegExp('new_' + assoc, 'g'); + var new_id = this.newId(); + content = $.trim(content.replace(regexp, new_id)); + return content; } };