nested_form 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +12 -0
- data/README.rdoc +30 -2
- data/Rakefile +23 -4
- data/lib/generators/nested_form/install_generator.rb +1 -1
- data/lib/nested_form/{builder.rb → builder_mixin.rb} +4 -4
- data/lib/nested_form/builders.rb +23 -0
- data/lib/nested_form/engine.rb +14 -0
- data/lib/nested_form/view_helper.rb +25 -9
- data/lib/nested_form.rb +1 -2
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +5 -0
- data/spec/dummy/app/assets/javascripts/jquery.js +8981 -0
- data/spec/dummy/app/assets/javascripts/jquery_nested_form.js +71 -0
- data/spec/dummy/app/assets/javascripts/projects.js +2 -0
- data/spec/dummy/app/assets/javascripts/prototype.js +6082 -0
- data/{lib/generators/nested_form/templates → spec/dummy/app/assets/javascripts}/prototype_nested_form.js +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/assets/stylesheets/projects.css +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/projects_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/helpers/projects_helper.rb +2 -0
- data/spec/dummy/app/models/milestone.rb +3 -0
- data/spec/dummy/app/models/project.rb +4 -0
- data/spec/dummy/app/models/task.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +11 -0
- data/spec/dummy/app/views/projects/new.html.erb +14 -0
- data/spec/dummy/config/application.rb +42 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +27 -0
- data/spec/dummy/config/environments/production.rb +54 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +59 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20110710143903_initial_tables.rb +23 -0
- data/spec/dummy/db/schema.rb +29 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/test/functional/projects_controller_test.rb +7 -0
- data/spec/dummy/test/unit/helpers/projects_helper_test.rb +4 -0
- data/spec/form_spec.rb +31 -0
- data/spec/nested_form/builder_spec.rb +33 -31
- data/spec/nested_form/view_helper_spec.rb +26 -12
- data/spec/spec_helper.rb +9 -48
- metadata +84 -59
- data/Gemfile +0 -3
- data/lib/generators/nested_form/templates/jquery_nested_form.js +0 -51
@@ -1,40 +1,42 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
describe
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
[NestedForm::Builder, NestedForm::SimpleBuilder, defined?(NestedForm::FormtasticBuilder) ? NestedForm::FormtasticBuilder : nil].compact.each do |builder|
|
4
|
+
describe builder do
|
5
|
+
describe "with no options" do
|
6
|
+
before(:each) do
|
7
|
+
@project = Project.new
|
8
|
+
@template = ActionView::Base.new
|
9
|
+
@template.output_buffer = ""
|
10
|
+
@builder = builder.new(:item, @project, @template, {}, proc {})
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
it "has an add link which behaves similar to a Rails link_to" do
|
14
|
+
@builder.link_to_add("Add", :tasks).should == '<a href="javascript:void(0)" class="add_nested_fields" data-association="tasks">Add</a>'
|
15
|
+
@builder.link_to_add("Add", :tasks, :class => "foo", :href => "url").should == '<a href="url" class="foo add_nested_fields" data-association="tasks">Add</a>'
|
16
|
+
@builder.link_to_add(:tasks) { "Add" }.should == '<a href="javascript:void(0)" class="add_nested_fields" data-association="tasks">Add</a>'
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
it "has a remove link which behaves similar to a Rails link_to" do
|
20
|
+
@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>'
|
21
|
+
@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>'
|
22
|
+
@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>'
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
it "should wrap nested fields each in a div with class" do
|
26
|
+
2.times { @project.tasks.build }
|
27
|
+
@builder.fields_for(:tasks) do
|
28
|
+
"Task"
|
29
|
+
end.should == '<div class="fields">Task</div><div class="fields">Task</div>'
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
it "should add task fields to hidden div after form" do
|
33
|
+
pending
|
34
|
+
output = ""
|
35
|
+
mock(@template).after_nested_form(:tasks) { |arg, block| output << block.call }
|
36
|
+
@builder.fields_for(:tasks) { "Task" }
|
37
|
+
@builder.link_to_add("Add", :tasks)
|
38
|
+
output.should == '<div id="tasks_fields_blueprint" style="display: none"><div class="fields">Task</div></div>'
|
39
|
+
end
|
38
40
|
end
|
39
41
|
end
|
40
42
|
end
|
@@ -1,33 +1,47 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe NestedForm::ViewHelper do
|
4
|
+
include RSpec::Rails::HelperExampleGroup
|
5
|
+
|
4
6
|
before(:each) do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@template.stubs(:projects_path).returns("")
|
9
|
-
@template.stubs(:protect_against_forgery?).returns(false)
|
7
|
+
_routes.draw do
|
8
|
+
resources :projects
|
9
|
+
end
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should pass nested form builder to form_for along with other options" do
|
13
13
|
pending
|
14
|
-
mock.proxy(
|
14
|
+
mock.proxy(_view).form_for(:first, :as => :second, :other => :arg, :builder => NestedForm::Builder) do |form_html|
|
15
15
|
form_html
|
16
16
|
end
|
17
|
-
|
17
|
+
_view.nested_form_for(:first, :as => :second, :other => :arg) {"form"}
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should pass instance of NestedForm::Builder to nested_form_for block" do
|
21
|
-
|
21
|
+
_view.nested_form_for(Project.new) do |f|
|
22
22
|
f.should be_instance_of(NestedForm::Builder)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
it "should pass instance of NestedForm::SimpleBuilder to simple_nested_form_for block" do
|
27
|
+
_view.simple_nested_form_for(Project.new) do |f|
|
28
|
+
f.should be_instance_of(NestedForm::SimpleBuilder)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
if defined?(NestedForm::FormtasticBuilder)
|
33
|
+
it "should pass instance of NestedForm::FormtasticBuilder to semantic_nested_form_for block" do
|
34
|
+
_view.semantic_nested_form_for(Project.new) do |f|
|
35
|
+
f.should be_instance_of(NestedForm::FormtasticBuilder)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
26
40
|
it "should append content to end of nested form" do
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
41
|
+
_view.after_nested_form(:tasks) { _view.concat("123") }
|
42
|
+
_view.after_nested_form(:milestones) { _view.concat("456") }
|
43
|
+
_view.nested_form_for(Project.new) {}
|
44
|
+
_view.output_buffer.should include("123456")
|
31
45
|
end
|
32
46
|
end
|
33
47
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,55 +1,16 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Configure Rails Environment
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
3
|
|
4
|
-
require "
|
5
|
-
require
|
6
|
-
|
7
|
-
Bundler.require(:default)
|
8
|
-
|
9
|
-
# require 'active_model'
|
10
|
-
# require 'active_record'
|
11
|
-
# require 'action_controller'
|
12
|
-
# require 'action_view'
|
13
|
-
# require 'action_view/template'
|
14
|
-
# require "active_support/all"
|
15
|
-
|
16
|
-
# require 'nested_form/view_helper'
|
17
|
-
# require 'nested_form/builder'
|
4
|
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
5
|
+
require 'rspec/rails'
|
6
|
+
require 'capybara/rspec'
|
18
7
|
|
8
|
+
Capybara.javascript_driver = :selenium
|
19
9
|
RSpec.configure do |config|
|
20
10
|
config.mock_with :mocha
|
21
11
|
end
|
22
12
|
|
23
|
-
|
24
|
-
def self.columns() @columns ||= []; end
|
25
|
-
|
26
|
-
def self.column(name, sql_type = nil, default = nil, null = true)
|
27
|
-
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.quoted_table_name
|
31
|
-
name.pluralize.underscore
|
32
|
-
end
|
33
|
-
|
34
|
-
def quoted_id
|
35
|
-
"0"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
class Project < TablelessModel
|
40
|
-
column :name, :string
|
41
|
-
has_many :tasks
|
42
|
-
accepts_nested_attributes_for :tasks
|
43
|
-
end
|
44
|
-
|
45
|
-
class Task < TablelessModel
|
46
|
-
column :project_id, :integer
|
47
|
-
column :name, :string
|
48
|
-
belongs_to :project
|
49
|
-
end
|
13
|
+
Rails.backtrace_cleaner.remove_silencers!
|
50
14
|
|
51
|
-
|
52
|
-
|
53
|
-
column :name, :string
|
54
|
-
belongs_to :task
|
55
|
-
end
|
15
|
+
# Load support files
|
16
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
metadata
CHANGED
@@ -1,102 +1,127 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: nested_form
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.1.1
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Ryan Bates
|
9
9
|
- Andrea Singh
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
name: rspec
|
19
|
-
prerelease: false
|
20
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
13
|
+
date: 2012-02-08 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec-rails
|
17
|
+
requirement: &2152812540 !ruby/object:Gem::Requirement
|
21
18
|
none: false
|
22
|
-
requirements:
|
19
|
+
requirements:
|
23
20
|
- - ~>
|
24
|
-
- !ruby/object:Gem::Version
|
25
|
-
version: 2.
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.6.0
|
26
23
|
type: :development
|
27
|
-
version_requirements: *id001
|
28
|
-
- !ruby/object:Gem::Dependency
|
29
|
-
name: mocha
|
30
24
|
prerelease: false
|
31
|
-
|
25
|
+
version_requirements: *2152812540
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: mocha
|
28
|
+
requirement: &2152812140 !ruby/object:Gem::Requirement
|
32
29
|
none: false
|
33
|
-
requirements:
|
34
|
-
- -
|
35
|
-
- !ruby/object:Gem::Version
|
36
|
-
version:
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
37
34
|
type: :development
|
38
|
-
version_requirements: *id002
|
39
|
-
- !ruby/object:Gem::Dependency
|
40
|
-
name: rails
|
41
35
|
prerelease: false
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
- - ~>
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 3.0.0
|
48
|
-
type: :development
|
49
|
-
version_requirements: *id003
|
50
|
-
description: Gem to conveniently handle multiple models in a single form with Rails 3 and jQuery or Prototype.
|
36
|
+
version_requirements: *2152812140
|
37
|
+
description: Gem to conveniently handle multiple models in a single form with Rails
|
38
|
+
3 and jQuery or Prototype.
|
51
39
|
email: ryan@railscasts.com
|
52
40
|
executables: []
|
53
|
-
|
54
41
|
extensions: []
|
55
|
-
|
56
42
|
extra_rdoc_files: []
|
57
|
-
|
58
|
-
files:
|
43
|
+
files:
|
59
44
|
- lib/generators/nested_form/install_generator.rb
|
60
|
-
- lib/
|
61
|
-
- lib/
|
62
|
-
- lib/nested_form/
|
45
|
+
- lib/nested_form/builder_mixin.rb
|
46
|
+
- lib/nested_form/builders.rb
|
47
|
+
- lib/nested_form/engine.rb
|
63
48
|
- lib/nested_form/view_helper.rb
|
64
49
|
- lib/nested_form.rb
|
50
|
+
- spec/dummy/app/assets/javascripts/application.js
|
51
|
+
- spec/dummy/app/assets/javascripts/jquery.js
|
52
|
+
- spec/dummy/app/assets/javascripts/jquery_nested_form.js
|
53
|
+
- spec/dummy/app/assets/javascripts/projects.js
|
54
|
+
- spec/dummy/app/assets/javascripts/prototype.js
|
55
|
+
- spec/dummy/app/assets/javascripts/prototype_nested_form.js
|
56
|
+
- spec/dummy/app/assets/stylesheets/application.css
|
57
|
+
- spec/dummy/app/assets/stylesheets/projects.css
|
58
|
+
- spec/dummy/app/controllers/application_controller.rb
|
59
|
+
- spec/dummy/app/controllers/projects_controller.rb
|
60
|
+
- spec/dummy/app/helpers/application_helper.rb
|
61
|
+
- spec/dummy/app/helpers/projects_helper.rb
|
62
|
+
- spec/dummy/app/models/milestone.rb
|
63
|
+
- spec/dummy/app/models/project.rb
|
64
|
+
- spec/dummy/app/models/task.rb
|
65
|
+
- spec/dummy/app/views/layouts/application.html.erb
|
66
|
+
- spec/dummy/app/views/projects/new.html.erb
|
67
|
+
- spec/dummy/config/application.rb
|
68
|
+
- spec/dummy/config/boot.rb
|
69
|
+
- spec/dummy/config/database.yml
|
70
|
+
- spec/dummy/config/environment.rb
|
71
|
+
- spec/dummy/config/environments/development.rb
|
72
|
+
- spec/dummy/config/environments/production.rb
|
73
|
+
- spec/dummy/config/environments/test.rb
|
74
|
+
- spec/dummy/config/initializers/backtrace_silencers.rb
|
75
|
+
- spec/dummy/config/initializers/inflections.rb
|
76
|
+
- spec/dummy/config/initializers/mime_types.rb
|
77
|
+
- spec/dummy/config/initializers/secret_token.rb
|
78
|
+
- spec/dummy/config/initializers/session_store.rb
|
79
|
+
- spec/dummy/config/initializers/wrap_parameters.rb
|
80
|
+
- spec/dummy/config/locales/en.yml
|
81
|
+
- spec/dummy/config/routes.rb
|
82
|
+
- spec/dummy/config.ru
|
83
|
+
- spec/dummy/db/development.sqlite3
|
84
|
+
- spec/dummy/db/migrate/20110710143903_initial_tables.rb
|
85
|
+
- spec/dummy/db/schema.rb
|
86
|
+
- spec/dummy/db/test.sqlite3
|
87
|
+
- spec/dummy/public/404.html
|
88
|
+
- spec/dummy/public/422.html
|
89
|
+
- spec/dummy/public/500.html
|
90
|
+
- spec/dummy/public/favicon.ico
|
91
|
+
- spec/dummy/Rakefile
|
92
|
+
- spec/dummy/script/rails
|
93
|
+
- spec/dummy/test/functional/projects_controller_test.rb
|
94
|
+
- spec/dummy/test/unit/helpers/projects_helper_test.rb
|
95
|
+
- spec/form_spec.rb
|
65
96
|
- spec/nested_form/builder_spec.rb
|
66
97
|
- spec/nested_form/view_helper_spec.rb
|
67
98
|
- spec/spec_helper.rb
|
68
99
|
- CHANGELOG.rdoc
|
69
|
-
- Gemfile
|
70
100
|
- LICENSE
|
71
101
|
- Rakefile
|
72
102
|
- README.rdoc
|
73
|
-
has_rdoc: true
|
74
103
|
homepage: http://github.com/ryanb/nested_form
|
75
104
|
licenses: []
|
76
|
-
|
77
105
|
post_install_message:
|
78
106
|
rdoc_options: []
|
79
|
-
|
80
|
-
require_paths:
|
107
|
+
require_paths:
|
81
108
|
- lib
|
82
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
110
|
none: false
|
84
|
-
requirements:
|
85
|
-
- -
|
86
|
-
- !ruby/object:Gem::Version
|
87
|
-
version:
|
88
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
116
|
none: false
|
90
|
-
requirements:
|
91
|
-
- -
|
92
|
-
- !ruby/object:Gem::Version
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
93
120
|
version: 1.3.4
|
94
121
|
requirements: []
|
95
|
-
|
96
122
|
rubyforge_project: nested_form
|
97
|
-
rubygems_version: 1.
|
123
|
+
rubygems_version: 1.8.10
|
98
124
|
signing_key:
|
99
125
|
specification_version: 3
|
100
126
|
summary: Gem to conveniently handle multiple models in a single form.
|
101
127
|
test_files: []
|
102
|
-
|
data/Gemfile
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
jQuery(function($) {
|
2
|
-
$('form a.add_nested_fields').live('click', function() {
|
3
|
-
// Setup
|
4
|
-
var assoc = $(this).attr('data-association'); // Name of child
|
5
|
-
var content = $('#' + assoc + '_fields_blueprint').html(); // 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 = ($(this).closest('.fields').find('input:first').attr('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
|
-
$(this).before(content);
|
38
|
-
$(this).closest("form").trigger('nested:fieldAdded');
|
39
|
-
return false;
|
40
|
-
});
|
41
|
-
|
42
|
-
$('form a.remove_nested_fields').live('click', function() {
|
43
|
-
var hidden_field = $(this).prev('input[type=hidden]')[0];
|
44
|
-
if(hidden_field) {
|
45
|
-
hidden_field.value = '1';
|
46
|
-
}
|
47
|
-
$(this).closest('.fields').hide();
|
48
|
-
$(this).closest("form").trigger('nested:fieldRemoved');
|
49
|
-
return false;
|
50
|
-
});
|
51
|
-
});
|