nested_fields 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1 +1,32 @@
1
- jQuery is required.
1
+ = Nested Fields
2
+
3
+ nested_fields is an Engine designed for generic, dynamic nested forms which may be N>=1 levels deep.
4
+
5
+ Of what I could find, the existing solutions for dynamic nested forms in Rails are implemented with javascript rather through Controllers. It is my understanding that this is because FormBuilders cannot be passed as params to Controllers.
6
+
7
+ It does rely on some {parsing behavior}[http://guides.rubyonrails.org/form_helpers.html] within Rails which may or may not be intended for use in this manner.
8
+
9
+ == Requirements
10
+
11
+ Designed for Rails 3 applications.
12
+
13
+ jQuery is required. In the future, this requirement could be removed without much difficulty.
14
+
15
+ == Install
16
+
17
+ Add nested_fields to the Gemfile and bundle install.
18
+
19
+ == Usage
20
+
21
+ Include 'nested_fields.js' in the layout for the Add and Remove behaviors.
22
+
23
+ Use the nested_fields_for helper method.
24
+ <%= nested_fields_for form_builder, :pluralized_association_name, 'path_to/inner_partial' %>
25
+
26
+ The same type of the form builder argument (e.g. Formtastic, SimpleForm, etc.) will automatically be used for the nested fields.
27
+
28
+ The <tt>nested_fields_ready</tt> custom event is fired after a nested fieldset is (dynamically or otherwise) added.
29
+
30
+ == Credits
31
+
32
+ Inspired by Ryan Bates' nested_form[https://github.com/ryanb/nested_form] which itself is based on Tim Riley's solution.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
@@ -1,13 +1,15 @@
1
1
  class NestedFieldsController < ActionController::Base
2
2
  def add_nested_fields
3
- @parent_class = params[:parent_class].constantize
4
3
  @association = params[:association].to_sym
5
4
  @builder = params[:builder].constantize
6
- @object = @parent_class.reflect_on_association(@association).klass.new
7
5
  @index = "#{Time.now.to_i}#{Time.now.usec}"
6
+ @nested_partial = params[:nested_partial]
7
+ @parent_form = params[:parent_form]
8
+
9
+ @object = params[:parent_class].constantize.reflect_on_association(@association).klass.new
8
10
 
9
11
  respond_to do |format|
10
- format.js { render 'nested_fields/add_nested_fields' }
12
+ format.js { render :partial => 'nested_fields/add_nested_fields' }
11
13
  end
12
14
  end
13
15
  end
@@ -1,18 +1,34 @@
1
1
  module NestedFieldsHelper
2
- def nested_fields_js
3
- render 'nested_fields/js'
4
- end
2
+ def nested_fields_for(f, association, nested_partial=nil)
3
+ reflection = f.object.class.reflect_on_association(association)
4
+ is_has_one = reflection.macro == :has_one
5
+ nested_partial ||= "#{is_has_one ? association.to_s.pluralize : association}/fields"
5
6
 
6
- def nested_fields_for(f, association, nested_partial="#{association}/fields")
7
- add = add_nested_fields_path :parent_class => f.object.class, :association => association, :builder => f.class
7
+ add = add_nested_fields_path :association => association,
8
+ :builder => f.class,
9
+ :nested_partial => nested_partial,
10
+ :parent_class => f.object.class,
11
+ :parent_form => f.object_name
8
12
 
9
- render 'nested_fields/nested_fields', :add_url => add,
10
- :association => association,
11
- :f => f,
12
- :nested_partial => nested_partial
13
- end
14
13
 
15
- def link_to_remove_fields(f, text='Remove')
16
- link_to text, '#', :class => :remove_nested_fields
14
+ partial = "nested_fields/#{'singular_' if is_has_one}nested_fieldset"
15
+
16
+ locals = {:add_url => add,
17
+ :association => association,
18
+ :f => f,
19
+ :nested_partial => nested_partial}
20
+
21
+ if is_has_one
22
+ associate = f.object.send(association);
23
+
24
+ if associate.nil?
25
+ locals[:associate] = reflection.klass.new
26
+ locals[:has_zero] = true
27
+ else
28
+ locals[:associate] = associate
29
+ end
30
+ end
31
+
32
+ render partial, locals
17
33
  end
18
34
  end
@@ -0,0 +1,3 @@
1
+ <%= fields_for "#@parent_form[#{@association}_attributes][#@index]", @object, :builder => @builder do |f| %>
2
+ <%= render 'nested_fields/block', :f => f, :nested_partial => @nested_partial %>
3
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <div class="nested_fields">
2
+ <a href="#" class="remove_nested_fields">Remove</a>
3
+
4
+ <div class="nested_fields_inputs">
5
+ <%= render nested_partial, :f => f %>
6
+ <%= f.hidden_field :_destroy %>
7
+ </div>
8
+ </div>
@@ -4,13 +4,6 @@
4
4
  <a href="#" class="add_nested_fields" data-url="<%= add_url %>">Add</a>
5
5
 
6
6
  <%= f.fields_for association, :builder => f.class do |nested_f| %>
7
- <div class="nested_fields">
8
- <%= link_to_remove_fields :nested_f %>
9
-
10
- <div class="nested_fields_inputs">
11
- <%= render nested_partial, :f => nested_f %>
12
- <%= nested_f.input :_destroy, :as => :hidden %>
13
- </div>
14
- </div>
7
+ <%= render 'nested_fields/block', :f => nested_f, :nested_partial => nested_partial %>
15
8
  <% end %>
16
9
  </fieldset>
@@ -0,0 +1,16 @@
1
+ <fieldset id="<%= association %>" class="nested_fieldset">
2
+ <legend><%= association.to_s.titleize %></legend>
3
+
4
+ <%= f.fields_for association, associate, :builder => f.class do |nested_f| %>
5
+ <label class="nested_one_label">
6
+ <%= check_box_tag "has_#{association}", nil, !local_assigns[:has_zero], :class => :nested_fields_has_one %>
7
+ <%= "Has #{association.to_s.titleize}?" %>
8
+ </label>
9
+
10
+ <%= nested_f.hidden_field :_destroy, :class => :destroy_nested_one, :value => local_assigns[:has_zero] ? 'true' : 'false' %>
11
+
12
+ <%= content_tag :div, :class => :nested_one, :style => ('display:none' if local_assigns[:has_zero]) do %>
13
+ <%= render nested_partial, :f => nested_f %>
14
+ <% end %>
15
+ <% end %>
16
+ </fieldset>
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{nested_fields}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jason Murad"]
12
- s.date = %q{2010-12-15}
12
+ s.date = %q{2010-12-21}
13
13
  s.description = %q{Unobtrusive dynamic nested forms}
14
14
  s.email = %q{jason@thriess.com}
15
15
  s.extra_rdoc_files = [
@@ -24,9 +24,10 @@ Gem::Specification.new do |s|
24
24
  "VERSION",
25
25
  "app/controllers/nested_fields_controller.rb",
26
26
  "app/helpers/nested_fields_helper.rb",
27
- "app/views/nested_fields/_js.html.erb",
28
- "app/views/nested_fields/_nested_fields.html.erb",
29
- "app/views/nested_fields/add_nested_fields.html.erb",
27
+ "app/views/nested_fields/_add_nested_fields.html.erb",
28
+ "app/views/nested_fields/_block.html.erb",
29
+ "app/views/nested_fields/_nested_fieldset.html.erb",
30
+ "app/views/nested_fields/_singular_nested_fieldset.html.erb",
30
31
  "config/routes.rb",
31
32
  "lib/engine.rb",
32
33
  "lib/nested_fields.rb",
@@ -1,18 +1,30 @@
1
- $(function() {
2
- $('.add_nested_fields').live('click', function() {
3
- link = this;
4
-
5
- $.get(link.getAttribute('data-url'), function(content) {
6
- $(link).after(content);
7
- $(link).trigger('nested_fields_ready');
8
- });
9
-
10
- return false;
1
+ $(document).ready(function() {
2
+ $('.nested_fieldset').each(function(i, nf) {
3
+ $(nf).trigger('nested_fields_ready');
11
4
  });
5
+ });
12
6
 
13
- $('.remove_nested_fields').live('click', function() {
14
- $(this).closest('div.nested_fields').find('input[type=hidden]').val('1');
15
- $(this).closest('div.nested_fields').hide();
16
- return false;
7
+ $('.add_nested_fields').live('click', function() {
8
+ $.ajax({
9
+ context: this,
10
+ url: this.getAttribute('data-url'),
11
+ success: function(content) {
12
+ $(this).after(content);
13
+ $(this).trigger('nested_fields_ready');
14
+ }
17
15
  });
16
+
17
+ return false;
18
+ });
19
+
20
+ $('.remove_nested_fields').live('click', function() {
21
+ $(this).closest('div.nested_fields').find('input[type=hidden]').val('1');
22
+ $(this).closest('div.nested_fields').hide();
23
+ return false;
24
+ });
25
+
26
+ $('.nested_fields_has_one').live('change', function() {
27
+ var hidden_field = $(this).closest('.nested_fieldset').find('.destroy_nested_one');
28
+ $(hidden_field).val($(hidden_field).val() == 'true' ? 'false' : 'true');
29
+ $(this).closest('.nested_fieldset').find('.nested_one').toggle();
18
30
  });
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 1
9
- version: 0.1.1
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jason Murad
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-15 00:00:00 -05:00
17
+ date: 2010-12-21 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -90,9 +90,10 @@ files:
90
90
  - VERSION
91
91
  - app/controllers/nested_fields_controller.rb
92
92
  - app/helpers/nested_fields_helper.rb
93
- - app/views/nested_fields/_js.html.erb
94
- - app/views/nested_fields/_nested_fields.html.erb
95
- - app/views/nested_fields/add_nested_fields.html.erb
93
+ - app/views/nested_fields/_add_nested_fields.html.erb
94
+ - app/views/nested_fields/_block.html.erb
95
+ - app/views/nested_fields/_nested_fieldset.html.erb
96
+ - app/views/nested_fields/_singular_nested_fieldset.html.erb
96
97
  - config/routes.rb
97
98
  - lib/engine.rb
98
99
  - lib/nested_fields.rb
@@ -114,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
114
115
  requirements:
115
116
  - - ">="
116
117
  - !ruby/object:Gem::Version
117
- hash: 3137776754752327024
118
+ hash: -1304071014241017198
118
119
  segments:
119
120
  - 0
120
121
  version: "0"
@@ -1 +0,0 @@
1
- <%= javascript_include_tag 'nested_fields' %>
@@ -1,11 +0,0 @@
1
- <%= fields_for "#{@parent_class.name.underscore}[#{@association}_attributes]",
2
- @object, :builder => @builder, :index => @index do |f| %>
3
- <div class="nested_fields">
4
- <%= link_to_remove_fields :nested_f %>
5
-
6
- <div class="nested_fields_inputs">
7
- <%= render "#{@association}/fields", :f => f %>
8
- <%= f.input :_destroy, :as => :hidden %>
9
- </div>
10
- </div>
11
- <% end %>