cool_nested_forms 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f3969154fb309fdbeb6d9b33aae0bfe3383f511d
4
- data.tar.gz: 17e7eddc9d7cc5afa7ec69b5ec45bdd66aa7fa15
3
+ metadata.gz: e5c86ef0d5b6bba5a5ed6ab919a29b88fea57e8d
4
+ data.tar.gz: 65c68db81d44c1ae8d4060383ee9edc9b0fe54d8
5
5
  SHA512:
6
- metadata.gz: cbf8acbb798e52da93f002bd04fd9b1e61587a652e91403c96f1d3c6755e910e171884a7af7f616ae81caf7087faade7affc33d106d6e1314620b9546f1a28a5
7
- data.tar.gz: 154c51f82021bd7fa9beb0c7c50ee413fc277262ca4c87f342b5ecbc0d795635ea92b7dc20715864ad0d748e96f19bbd85732122b70771de435065536f8d6dff
6
+ metadata.gz: 03bc77c8616c95989925cfef00ebe501ca63d132adb92b4313115225c3341c73c8577a46b96fa0d2e2ac32cd50badae248cf851361f91394e03c86de49032f41
7
+ data.tar.gz: 966e9e3ed104dfab84f5e6b50ccdf6a6a2267262a94418409368563a5707335c2ddd2d99d2c384c879558b1a945a186b014b4af6503e28f6f4ae0879e1ef5d08
data/README.md CHANGED
@@ -1,11 +1,16 @@
1
1
  # CoolNestedForms
2
2
  [![Gem Version](https://badge.fury.io/rb/cool_nested_forms.svg)](https://badge.fury.io/rb/cool_nested_forms)
3
3
 
4
- Add Nested Forms to your Forms. Currently tested with a depth of 2.
5
- For example a Form can add an Item and this Item can add a sub Item.
6
- It can probably support longer nests but I haven't tested it yet.
4
+ Add dynamically generated forms to your model's form for any of its associations.
5
+ For example if you have a Job model that has_many Task then this gem will assist you in adding
6
+ all the JavaScript necessary to allow your users to click an "Add Task" button on your edit view,
7
+ the view will then append a new form to the DOM with all the field attributes formatted for
8
+ rails (id, name, etc) plus will add any necessary hidden fields for existing records (task.id).
7
9
 
8
- By the way, this is intended to simplify adding the javascript required to add form_field dynamically while following form builder conventions. What that means is that there is some work to be done in the form of configuring models and controllers and adding a couple of views.
10
+ There is also JS events raised when an entry is added or removed so you can hook up your code for
11
+ pre-form submission editing.
12
+
13
+ Any entries added or removed won't update the DB until the form is submitted.
9
14
 
10
15
  ## Installation
11
16
 
@@ -23,7 +28,7 @@ Or install it yourself as:
23
28
 
24
29
  $ gem install cool_nested_forms
25
30
 
26
- Then require the javascript in your app/assets/javascripts/application.js
31
+ Then require the JavaScript in your app/assets/javascripts/application.js
27
32
  ```javascript
28
33
  //= require cool_nested_forms
29
34
  ```
@@ -35,22 +40,25 @@ For this example I will use Job and Task models
35
40
 
36
41
  #### Job Model
37
42
  ```ruby
38
- class Job < ActiveRecord::Base
43
+ class Job < ApplicationRecord
39
44
  has_many :tasks, :dependent => :destroy
40
- # :name is required - User your own required field here
45
+ # we need to accepts_nested_attributes_for Task
46
+ # :name is required in this example - Use your own required field here or remove the reject_if call
47
+ # :allow_destroy => true so we can delete entries when passing the _destroy field
41
48
  accepts_nested_attributes_for :tasks, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
42
49
  end
43
50
  ```
44
51
  #### Task Model
45
52
  ```ruby
46
- class Task < ActiveRecord::Base
53
+ class Task < ApplicationRecord
47
54
  belongs_to :job
48
55
  end
49
56
  ```
50
57
  ### Preparing the Job Controller
51
58
  ```ruby
52
59
  class JobsController < ApplicationController
53
-
60
+ # include the CoolNestedFormsHelper
61
+ helper CoolNestedFormsHelper
54
62
  # other code #
55
63
 
56
64
  def job_params
@@ -60,47 +68,75 @@ class JobsController < ApplicationController
60
68
  end
61
69
  end
62
70
  ```
63
- ### The view used to generate tasks
64
- Due to laziness remove_child_button needs to be nested right under the containing div. this will be fixed in the next version.
65
- app/views/jobs/_task.html.rb
66
- ```html
67
- <div>
68
- <%= remove_child_button "Remove" %>
69
- <%= f.hidden_field :_destroy, :class => 'removable' %>
70
-
71
- <%= f.label :name %>
72
- <%= f.text_field :name %>
71
+ ### The partials used to generate the new and existing tasks
72
+ We need to provide cool_nested_forms two partials. One for existing records and one
73
+ for existing records. They will be placed under the Job's view folder. Make sure the
74
+ id field of the container is set like so: id="<%= id %>"
75
+
76
+ app/views/jobs/_task_new.html.rb
77
+ ```erb
78
+ <!-- the id is generated from the helper methods using this template so always include it like so -->
79
+ <div id="<%= id %>">
80
+ <!-- _destroy field: used for removing the record -->
81
+ <%= builder.hidden_field :_destroy, :class => 'cnf-removable' %>
82
+
83
+ <!-- data to be collected -->
84
+ <%= builder.label :name %>
85
+ <%= builder.text_field :name %>
86
+
87
+ <!-- the remove button. make sure to pass the id as target or
88
+ it will default to the parent DOM element when removing the item -->
89
+ <%= remove_entry_button "Remove", Task, {:target => id} %>
90
+ </div>
91
+ ```
92
+ app/views/jobs/_task_edit.html.rb
93
+ ```erb
94
+ <!-- the id is generated from the helper methods using this template so always include it like so -->
95
+ <div id="<%= id %>">
96
+ <!-- _destroy field: used for removing the record -->
97
+ <%= builder.hidden_field :_destroy, :class => 'cnf-removable' %>
98
+ <%= builder.hidden_field :id %> <!-- keeps the id inside this div -->
99
+
100
+ <!-- data to be edited -->
101
+ <%= builder.label :name %>
102
+ <%= builder.text_field :name %>
103
+ <!-- Note: if you not wish for your users to edit this field after it is added
104
+ you could just display the content. -->
105
+
106
+ <!-- the remove button. make sure to pass the id as target or
107
+ it will default to the parent DOM element when removing the item -->
108
+ <%= remove_entry_button "Remove", Task, {:target => id} %>
73
109
  </div>
74
110
  ```
75
111
 
76
112
  ## Adding functionality to the Job form
77
113
  app/views/jobs/_form.html.erb
78
- ```html
79
- <%= form_for(@job) do |f| %>
80
-
114
+ ```erb
115
+ <%= form_with(model: job, local: true) do |form| %>
81
116
 
82
117
  <!-- your other job fields go here -->
83
118
 
119
+ <!-- this generates a template for JavaScript. Pass the Task model class here. -->
120
+ <%= new_entry_template(form,Task) %>
84
121
 
85
- <!-- this generates a template for javascript -->
86
- <%= new_fields_template f, :tasks, {object: Tasks.new, :template => "tasks_#{f.object.id}_fields"} %>
87
- <!-- this generates a button that adds a task into <div id="tasks_<%=f.object.id%>"> -->
88
- <%= add_child_button "Add Task", :tasks, "tasks_#{f.object.id}", "tasks_#{f.object.id}", "<your-css-classes>" %>
122
+ <!-- this generates a button that adds a task into <div id="tasks">. id="tasks"
123
+ is automatically generated by the next helper by convention. Pass the Task model class here. -->
124
+ <%= new_entry_button("Add Task", Task )%>
89
125
 
90
- <div id="tasks_<%=f.object.id%>">
91
- <%= f.fields_for :tasks, @job.tasks do |builder| %>
92
- <%= render "task", :f => builder %>
93
- <% end %>
94
- </div>
126
+ <!-- generates a container with any existing tasks. provides a location for
127
+ placing new tasks. The id of the container is by default <div id="tasks">
128
+ (the association plural form). Pass the Task model class here. -->
129
+ <%= entries_container(form,Task,job.tasks) %>
95
130
 
96
131
  <%end%>
97
132
  ```
98
133
 
99
134
  ### After add/remove events
100
- If you need to perform any other javascript actions after a child is added or removed, you can add a listener to these events
135
+ If you need to perform any other javascript actions after an entry is added or
136
+ removed, you can add a listener to these events
101
137
  ```javascript
102
- coolNestedForms.childAdded
103
- coolNestedForms.childRemoved
138
+ coolNestedForms.entryAdded
139
+ coolNestedForms.entryRemoved
104
140
  ```
105
141
  Something like this
106
142
  ```javascript
@@ -1,5 +1,45 @@
1
1
  module CoolNestedFormsHelper
2
+ ## entries_container ##
3
+ # arguments
4
+ # - builder: a FormBuilder Object obtained from form_with or form_for
5
+ # - association: a model class i.e. MyTask
6
+ # - current_entries: all the current entries for the parent i.e. a Form.tasks
7
+ # - options: hash of override options
8
+ # - partial: name of the erb partial to use as a tempalte for the existing entries
9
+ # - id: ID to be used in for the container
10
+ # - plurilized: the plural version of the model name
11
+ # - singularized: the singular version of the model name
12
+ # - parent_singularized: the name of the parent record. used for generating the entry's container id
13
+ # - parent_id: the id of the parent record. used for generating the entry's container id
14
+ # - class: a string with any css class names to be used for styling
15
+ # - style: a string with any css styles
16
+ # - tag: override the returned tag
17
+ def entries_container(builder,association,current_entries, options = {})
18
+ # initialize options
19
+ options[:partial] ||= "#{association.name.underscore}_edit"
20
+ options[:id] ||= association.name.underscore.pluralize
21
+ options[:pluralized] ||= association.name.underscore.pluralize
22
+ options[:singularized] ||= association.name.underscore
23
+ options[:parent_singularized] ||= builder.object.class.name.underscore
24
+ options[:parent_id] ||= builder.object.id.to_s
25
+ options[:class] ||= ''
26
+ options[:style] ||= ''
27
+ options[:tag] ||= :div
28
+
29
+ # render all the current entries
30
+ output = builder.fields_for(options[:pluralized], current_entries) do |assoc_builder|
31
+ id = "#{options[:parent_singularized]}_#{options[:parent_id]}_#{options[:singularized]}_#{assoc_builder.object.id}"
32
+ render options[:partial], :builder => assoc_builder, :id => id
33
+ end
2
34
 
35
+ return content_tag(
36
+ options[:tag],
37
+ output.html_safe,
38
+ :style => options[:style],
39
+ :class => options[:class],
40
+ :id => options[:id]
41
+ )
42
+ end
3
43
  ## new_entry_template ##
4
44
  # arguments
5
45
  # - builder: a FormBuilder Object obtained from form_with or form_for
@@ -12,7 +52,7 @@ module CoolNestedFormsHelper
12
52
  # - children: an array with childre association options for nested association of a nested association
13
53
  def new_entry_template(builder,association, options = {})
14
54
  # initialize options
15
- options[:partial] ||= association.name.underscore
55
+ options[:partial] ||= "#{association.name.underscore}_new"
16
56
  options[:id] ||= "#{association.name.underscore}_[tempid]"
17
57
  options[:pluralized] ||= association.name.underscore.pluralize
18
58
  options[:js_template_name] ||= association.name.underscore.pluralize
@@ -1,3 +1,3 @@
1
1
  module CoolNestedForms
2
- VERSION = "2.0.1"
2
+ VERSION = "2.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cool_nested_forms
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Roque