simple_nested_form 0.0.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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +91 -0
- data/Rakefile +2 -0
- data/lib/generators/simple_nested_form/install_generator.rb +12 -0
- data/lib/generators/simple_nested_form/templates/simple_nested_form.js +38 -0
- data/lib/simple_nested_form/builder.rb +45 -0
- data/lib/simple_nested_form/version.rb +3 -0
- data/lib/simple_nested_form/view_helper.rb +34 -0
- data/lib/simple_nested_form.rb +5 -0
- data/simple_nested_form.gemspec +27 -0
- data/spec/simple_nested_form/builder_spec.rb +50 -0
- data/spec/simple_nested_form/view_helper_spec.rb +23 -0
- data/spec/spec_helper.rb +39 -0
- metadata +147 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
simple_nested_form (0.0.1)
|
5
|
+
simple_form (~> 1.3.1)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
abstract (1.0.0)
|
11
|
+
actionmailer (3.0.5)
|
12
|
+
actionpack (= 3.0.5)
|
13
|
+
mail (~> 2.2.15)
|
14
|
+
actionpack (3.0.5)
|
15
|
+
activemodel (= 3.0.5)
|
16
|
+
activesupport (= 3.0.5)
|
17
|
+
builder (~> 2.1.2)
|
18
|
+
erubis (~> 2.6.6)
|
19
|
+
i18n (~> 0.4)
|
20
|
+
rack (~> 1.2.1)
|
21
|
+
rack-mount (~> 0.6.13)
|
22
|
+
rack-test (~> 0.5.7)
|
23
|
+
tzinfo (~> 0.3.23)
|
24
|
+
activemodel (3.0.5)
|
25
|
+
activesupport (= 3.0.5)
|
26
|
+
builder (~> 2.1.2)
|
27
|
+
i18n (~> 0.4)
|
28
|
+
activerecord (3.0.5)
|
29
|
+
activemodel (= 3.0.5)
|
30
|
+
activesupport (= 3.0.5)
|
31
|
+
arel (~> 2.0.2)
|
32
|
+
tzinfo (~> 0.3.23)
|
33
|
+
activeresource (3.0.5)
|
34
|
+
activemodel (= 3.0.5)
|
35
|
+
activesupport (= 3.0.5)
|
36
|
+
activesupport (3.0.5)
|
37
|
+
arel (2.0.9)
|
38
|
+
builder (2.1.2)
|
39
|
+
diff-lcs (1.1.2)
|
40
|
+
erubis (2.6.6)
|
41
|
+
abstract (>= 1.0.0)
|
42
|
+
i18n (0.5.0)
|
43
|
+
mail (2.2.15)
|
44
|
+
activesupport (>= 2.3.6)
|
45
|
+
i18n (>= 0.4.0)
|
46
|
+
mime-types (~> 1.16)
|
47
|
+
treetop (~> 1.4.8)
|
48
|
+
mime-types (1.16)
|
49
|
+
nokogiri (1.4.4)
|
50
|
+
polyglot (0.3.1)
|
51
|
+
rack (1.2.1)
|
52
|
+
rack-mount (0.6.13)
|
53
|
+
rack (>= 1.0.0)
|
54
|
+
rack-test (0.5.7)
|
55
|
+
rack (>= 1.0)
|
56
|
+
rails (3.0.5)
|
57
|
+
actionmailer (= 3.0.5)
|
58
|
+
actionpack (= 3.0.5)
|
59
|
+
activerecord (= 3.0.5)
|
60
|
+
activeresource (= 3.0.5)
|
61
|
+
activesupport (= 3.0.5)
|
62
|
+
bundler (~> 1.0)
|
63
|
+
railties (= 3.0.5)
|
64
|
+
railties (3.0.5)
|
65
|
+
actionpack (= 3.0.5)
|
66
|
+
activesupport (= 3.0.5)
|
67
|
+
rake (>= 0.8.7)
|
68
|
+
thor (~> 0.14.4)
|
69
|
+
rake (0.8.7)
|
70
|
+
rspec (2.5.0)
|
71
|
+
rspec-core (~> 2.5.0)
|
72
|
+
rspec-expectations (~> 2.5.0)
|
73
|
+
rspec-mocks (~> 2.5.0)
|
74
|
+
rspec-core (2.5.1)
|
75
|
+
rspec-expectations (2.5.0)
|
76
|
+
diff-lcs (~> 1.1.2)
|
77
|
+
rspec-mocks (2.5.0)
|
78
|
+
simple_form (1.3.1)
|
79
|
+
thor (0.14.6)
|
80
|
+
treetop (1.4.9)
|
81
|
+
polyglot (>= 0.3.1)
|
82
|
+
tzinfo (0.3.24)
|
83
|
+
|
84
|
+
PLATFORMS
|
85
|
+
ruby
|
86
|
+
|
87
|
+
DEPENDENCIES
|
88
|
+
nokogiri (~> 1.4.4)
|
89
|
+
rails (~> 3.0.5)
|
90
|
+
rspec (~> 2.5.0)
|
91
|
+
simple_nested_form!
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module SimpleNestedForm
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
desc "Copy NestedSimpleForm installation files"
|
5
|
+
source_root File.expand_path("../templates", __FILE__)
|
6
|
+
|
7
|
+
def copy_javascripts
|
8
|
+
copy_file "simple_nested_form.js", "public/javascripts/simple_nested_form.js"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
jQuery(function($) {
|
2
|
+
$("form a.add_nested_fields").live("click", function() {
|
3
|
+
var association = $(this).attr("data-association");
|
4
|
+
var content = $("#" + association + "_fields_blueprint").html();
|
5
|
+
|
6
|
+
var context = ($(this).closest(".fields").find("input:first").attr("name") || "").replace(new RegExp("\[[a-z]+\]$"), "");
|
7
|
+
|
8
|
+
if (context) {
|
9
|
+
var parentNames = context.match(/[a-z_]+_attributes/g) || [];
|
10
|
+
var parentIds = context.match(/[0-9]+/g);
|
11
|
+
|
12
|
+
for(i = 0; i < parentNames.length; i++) {
|
13
|
+
if(parentIds[i]) {
|
14
|
+
content = content.replace(
|
15
|
+
new RegExp("(\\[" + parentNames[i] + "\\])\\[.+?\\]", "g"),
|
16
|
+
"$1[" + parentIds[i] + "]"
|
17
|
+
)
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
content = content.replace(new RegExp("new_" + association, "g"), new Date().getTime());
|
23
|
+
|
24
|
+
$(this).before(content);
|
25
|
+
return false;
|
26
|
+
});
|
27
|
+
|
28
|
+
$("form a.remove_nested_fields").live("click", function() {
|
29
|
+
var destroyField = $(this).prev("input[type=hidden]")[0];
|
30
|
+
|
31
|
+
if (destroyField) {
|
32
|
+
destroyField.value = "1";
|
33
|
+
}
|
34
|
+
|
35
|
+
$(this).closest(".fields").hide();
|
36
|
+
return false;
|
37
|
+
});
|
38
|
+
});
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module SimpleNestedForm
|
2
|
+
class Builder < ::SimpleForm::FormBuilder
|
3
|
+
delegate :content_tag, :link_to, :after_nested_form, :to => :@template
|
4
|
+
|
5
|
+
def link_to_add(name, association)
|
6
|
+
after_nested_form(association) do
|
7
|
+
model_object = object.class.reflect_on_association(association).klass.new
|
8
|
+
|
9
|
+
content_tag :div, :id => "#{association}_fields_blueprint", :style => "display: none" do
|
10
|
+
fields_for(association, model_object, :child_index => "new_#{association}", &nested_fields[association])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
link_to(name, "javascript:void(0)", :class => "add_nested_fields", :"data-association" => association)
|
15
|
+
end
|
16
|
+
|
17
|
+
def link_to_remove(name = "remove")
|
18
|
+
hidden_field(:_destroy) + link_to(name, "javascript:void(0)" , :class => "remove_nested_fields")
|
19
|
+
end
|
20
|
+
|
21
|
+
def fields_for(record_or_name_or_array, *args, &block)
|
22
|
+
options = args.extract_options!
|
23
|
+
options[:builder] = SimpleNestedForm::Builder
|
24
|
+
|
25
|
+
super(record_or_name_or_array, *(args << options), &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def fields_for_with_nested_attributes(association, args, block)
|
29
|
+
nested_fields[association] = block
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def fields_for_nested_model(name, association, args, block)
|
34
|
+
content_tag :div, :class => "fields" do
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def nested_fields
|
42
|
+
@nested_fields ||= {}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SimpleNestedForm
|
2
|
+
module ViewHelper
|
3
|
+
def nested_form_for(*args, &block)
|
4
|
+
options = args.extract_options!.reverse_merge(:builder => SimpleNestedForm::Builder)
|
5
|
+
|
6
|
+
simple_form_for(*(args << options), &block).tap do |output|
|
7
|
+
form_callbacks.each do |callback|
|
8
|
+
output << callback.call
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def after_nested_form(association, &block)
|
14
|
+
unless form_associations.include? association
|
15
|
+
form_associations << association
|
16
|
+
form_callbacks << block
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def form_associations
|
23
|
+
@form_associations ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
def form_callbacks
|
27
|
+
@form_callbacks ||= []
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class ActionView::Base
|
33
|
+
include SimpleNestedForm::ViewHelper
|
34
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "simple_nested_form/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "simple_nested_form"
|
7
|
+
s.version = SimpleNestedForm::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Rodrigo Navarro", "Ryan Bates"]
|
10
|
+
s.email = ["rnavarro1@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/reu/simple_nested_form"
|
12
|
+
s.summary = "Adds support for easily creeate nested forms with simple_form"
|
13
|
+
s.description = "Adds support for easily creeate nested forms with simple_form"
|
14
|
+
|
15
|
+
s.rubyforge_project = "simple_nested_form"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency "simple_form", "~> 1.3.1"
|
23
|
+
|
24
|
+
s.add_development_dependency "rspec", "~> 2.5.0"
|
25
|
+
s.add_development_dependency "nokogiri", "~> 1.4.4"
|
26
|
+
s.add_development_dependency "rails", "~> 3.0.5"
|
27
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleNestedForm::Builder do
|
4
|
+
let(:project) { Project.new }
|
5
|
+
let(:template) { ActionView::Base.new }
|
6
|
+
let(:builder) { SimpleNestedForm::Builder.new(:item, project, template, {}, proc {}) }
|
7
|
+
|
8
|
+
before { template.output_buffer = "" }
|
9
|
+
|
10
|
+
describe "fields wrapper" do
|
11
|
+
before { project.tasks.build }
|
12
|
+
subject { builder.fields_for(:tasks) { "Task"} }
|
13
|
+
|
14
|
+
it "surrounds the nested fields with a div with class fields" do
|
15
|
+
subject.should == '<div class="fields">Task</div>'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "link to add" do
|
20
|
+
subject { Nokogiri::HTML(builder.link_to_add("Add me plz", :tasks)).css("a").first }
|
21
|
+
|
22
|
+
its(:text) { should == "Add me plz" }
|
23
|
+
|
24
|
+
it "contains a class named add_nested_fields" do
|
25
|
+
subject.attr("class").should include "add_nested_fields"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "contains an attribute named data-association" do
|
29
|
+
subject.attr("data-association").should == "tasks"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "link to remove" do
|
34
|
+
let(:output) { Nokogiri::HTML(builder.link_to_remove("Remove me plz")) }
|
35
|
+
|
36
|
+
describe "the link itself" do
|
37
|
+
subject { output.css("a").first }
|
38
|
+
|
39
|
+
its(:text) { should == "Remove me plz" }
|
40
|
+
|
41
|
+
it "contains a class named remove_nested_fields" do
|
42
|
+
subject.attr("class").should include "remove_nested_fields"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "generate a destroy hidden field" do
|
47
|
+
output.css("input[type='hidden'][name*='_destroy']").should have(1).element
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe SimpleNestedForm::ViewHelper do
|
4
|
+
let(:template) { ActionView::Base.new }
|
5
|
+
|
6
|
+
before do
|
7
|
+
template.output_buffer = ""
|
8
|
+
template.stub(:projects_path).and_return("")
|
9
|
+
template.stub(:protect_against_forgery?).and_return(false)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "creates a instance of SimpleNestedForm" do
|
13
|
+
template.nested_form_for(Project.new) do |form|
|
14
|
+
form.should be_instance_of SimpleNestedForm::Builder
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "appends the nested fields after the end of the form" do
|
19
|
+
template.after_nested_form(:tasks) { template.concat "Nested task" }
|
20
|
+
template.nested_form_for(Project.new) {}
|
21
|
+
template.output_buffer.should include("Nested task")
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
require 'active_record'
|
3
|
+
require 'action_controller'
|
4
|
+
require 'action_view'
|
5
|
+
require 'action_view/template'
|
6
|
+
require 'nokogiri'
|
7
|
+
|
8
|
+
require 'simple_form'
|
9
|
+
require 'simple_nested_form'
|
10
|
+
|
11
|
+
class TablelessModel < ActiveRecord::Base
|
12
|
+
def self.columns
|
13
|
+
@columns ||= []
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.column(name, sql_type = nil, default = nil, null = true)
|
17
|
+
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.quoted_table_name
|
21
|
+
name.pluralize.underscore
|
22
|
+
end
|
23
|
+
|
24
|
+
def quoted_id
|
25
|
+
"0"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Project < TablelessModel
|
30
|
+
column :name, :string
|
31
|
+
has_many :tasks
|
32
|
+
accepts_nested_attributes_for :tasks
|
33
|
+
end
|
34
|
+
|
35
|
+
class Task < TablelessModel
|
36
|
+
column :project_id, :integer
|
37
|
+
column :name, :string
|
38
|
+
belongs_to :project
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple_nested_form
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Rodrigo Navarro
|
14
|
+
- Ryan Bates
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-03-07 00:00:00 -03:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: simple_form
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 25
|
31
|
+
segments:
|
32
|
+
- 1
|
33
|
+
- 3
|
34
|
+
- 1
|
35
|
+
version: 1.3.1
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: rspec
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 27
|
47
|
+
segments:
|
48
|
+
- 2
|
49
|
+
- 5
|
50
|
+
- 0
|
51
|
+
version: 2.5.0
|
52
|
+
type: :development
|
53
|
+
version_requirements: *id002
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: nokogiri
|
56
|
+
prerelease: false
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 15
|
63
|
+
segments:
|
64
|
+
- 1
|
65
|
+
- 4
|
66
|
+
- 4
|
67
|
+
version: 1.4.4
|
68
|
+
type: :development
|
69
|
+
version_requirements: *id003
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rails
|
72
|
+
prerelease: false
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 13
|
79
|
+
segments:
|
80
|
+
- 3
|
81
|
+
- 0
|
82
|
+
- 5
|
83
|
+
version: 3.0.5
|
84
|
+
type: :development
|
85
|
+
version_requirements: *id004
|
86
|
+
description: Adds support for easily creeate nested forms with simple_form
|
87
|
+
email:
|
88
|
+
- rnavarro1@gmail.com
|
89
|
+
executables: []
|
90
|
+
|
91
|
+
extensions: []
|
92
|
+
|
93
|
+
extra_rdoc_files: []
|
94
|
+
|
95
|
+
files:
|
96
|
+
- .gitignore
|
97
|
+
- Gemfile
|
98
|
+
- Gemfile.lock
|
99
|
+
- Rakefile
|
100
|
+
- lib/generators/simple_nested_form/install_generator.rb
|
101
|
+
- lib/generators/simple_nested_form/templates/simple_nested_form.js
|
102
|
+
- lib/simple_nested_form.rb
|
103
|
+
- lib/simple_nested_form/builder.rb
|
104
|
+
- lib/simple_nested_form/version.rb
|
105
|
+
- lib/simple_nested_form/view_helper.rb
|
106
|
+
- simple_nested_form.gemspec
|
107
|
+
- spec/simple_nested_form/builder_spec.rb
|
108
|
+
- spec/simple_nested_form/view_helper_spec.rb
|
109
|
+
- spec/spec_helper.rb
|
110
|
+
has_rdoc: true
|
111
|
+
homepage: https://github.com/reu/simple_nested_form
|
112
|
+
licenses: []
|
113
|
+
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
hash: 3
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
version: "0"
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
hash: 3
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
version: "0"
|
137
|
+
requirements: []
|
138
|
+
|
139
|
+
rubyforge_project: simple_nested_form
|
140
|
+
rubygems_version: 1.5.0
|
141
|
+
signing_key:
|
142
|
+
specification_version: 3
|
143
|
+
summary: Adds support for easily creeate nested forms with simple_form
|
144
|
+
test_files:
|
145
|
+
- spec/simple_nested_form/builder_spec.rb
|
146
|
+
- spec/simple_nested_form/view_helper_spec.rb
|
147
|
+
- spec/spec_helper.rb
|