rondo_form 0.2.5 → 1.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f953e44cde6292d12ee7bd3042659c45de36770dfd6f81a4590452f309faa45
4
- data.tar.gz: 5462a299afe097966aefbf5588ac8079dd35655e9cbd0389ddce5ef4d8978ba3
3
+ metadata.gz: bc37cc28bcea758383fa57af673206440f3d71413763fbc3bea157de11686787
4
+ data.tar.gz: 8d7e14c2d455fd0397aed863fc050bb70293a5045810c6ea4fbd16297faad9ef
5
5
  SHA512:
6
- metadata.gz: 8df5386a9afa39d992f3914e5f9ef7358aa2ca8fe41573e7ad56f7d87701f3c1c4d1202315d88fa1c581acf398148aa36c871f7b8c8855c54e17e040277e2175
7
- data.tar.gz: 45e36511f96135582e1041153c3431600376943291138000023d0bd0de0965b7b0c0c024c679eb95f8e7d421504f66303ee4d324d6b1fe1f7d8ad6d2ebac9b3d
6
+ metadata.gz: 84788ef35f96668f52aefcbd5bc9428bd655b23fb172c5e21fc46d93af5a8393d531e1afc56e22c6ae038bf8b8ca89def4c9b0e652fcfde8027da68a8317f0e7
7
+ data.tar.gz: f2729cc3cda456f0a12ab1536cfed97c6c44ed53e6bef1bd7e1a052bd045c08a03c13ba4fb89399f36cd53050c1ad8e0fff50833ee35f5652416ebb758928006
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # 1.0.0
2
+ ## Breaking Changes
3
+ - Add `render_options` as parameter to `link_to_add_association` [#10](https://github.com/hungle00/rondo_form/pull/10)
4
+ - Rename `partial_name` to `partial` to match Rails helper [#10](https://github.com/hungle00/rondo_form/pull/10)
5
+
6
+ ## All Changes
7
+ - Add documentation of the view helpers to the README [#10](https://github.com/hungle00/rondo_form/pull/10)
data/README.md CHANGED
@@ -10,22 +10,76 @@ Install the gem and add to the application's Gemfile by executing:
10
10
 
11
11
  Or inside the Gemfile add the following
12
12
 
13
- $ gem 'rondo_form', '~> 0.2.5'
13
+ $ gem 'rondo_form', '~> 0.2.6'
14
14
 
15
15
  Run the installation task:
16
16
 
17
- $ rails g rondo_form:install
17
+ $ rails g rondo_form:install
18
18
 
19
19
  ## Usage
20
20
 
21
- For example, we have `Project` model, which has `has_many` relationship with `Task` model:
21
+ For example, you have `Project` model, which has `has_many` relationship with `Task` model:
22
+
22
23
  ```
23
24
  rails g scaffold Project name:string description:string
24
25
  rails g model Task description:string done:boolean project:belongs_to
25
26
  ```
26
27
 
28
+ You need to add `accepts_nested_attributes_for` to `Project` model:
29
+
30
+ ```
31
+ class Project < ApplicationRecord
32
+ has_many :tasks, dependent: :destroy
33
+ accepts_nested_attributes_for :tasks, reject_if: :all_blank, allow_destroy: true
34
+ end
35
+ ```
36
+
37
+ ## View helpers
38
+
39
+ ### `link_to_add_association(name, form_builder, render_options, html_options, &block)`
40
+
41
+ ### Signatures
42
+ ```ruby
43
+ link_to_add_association(name, form_builder, render_options, html_options)
44
+ # Link text is passed in as name
45
+
46
+ link_to_add_association(form_builder, render_options, html_options, &block)
47
+ # Link text is passed in as a block
48
+ ```
49
+
50
+ ### Options
51
+ - `render_options: hash containing options for Rails' render helper` - This is passed to the Rails `render` helper to
52
+ provide the options that are desired when rendering your association fields. If no special requirements are needed,
53
+ can be passed as `nil` or and empty hash `{}`.
54
+
55
+ - `html_options: hash containing options for Rails' link_to helper` - This is passed to the Rails `link_to` helper to
56
+ provide the options that are desired when rendering your association fields. If no special requirements are needed,
57
+ can be passed as `nil` or and empty hash `{}`.
58
+
59
+ ### `link_to_remove_association(name, form_builder, html_options, &block)`
60
+
61
+ ### Signatures
62
+ ```ruby
63
+ link_to_remove_association(name, form_builder, html_options)
64
+ # Link text is passed in as name
65
+
66
+ link_to_remove_association(form_builder, html_options, &block)
67
+ # Link text is passed in as a block
68
+ ```
69
+
70
+ ### Options
71
+
72
+ - `html_options: hash containing options for Rails' link_to helper` - This is passed to the Rails `link_to` helper to
73
+ provide the options that are desired when rendering your association fields. If no special requirements are needed,
74
+ can be passed as `nil` or and empty hash `{}`.
75
+
27
76
  ### Sample with SimpleForm
77
+
78
+ The RondoForm gem adds two helper functions: `link_to_add_association` and `link_to_remove_association`.
79
+ The example below illustrates the way to use it.
80
+
28
81
  In your `projects/_form` partial:
82
+
29
83
  ``` erb
30
84
  <%= simple_form_for(@project) do |f| %>
31
85
 
@@ -50,23 +104,38 @@ In your `projects/_form` partial:
50
104
  <%= f.button :submit %>
51
105
  </div>
52
106
  <% end %>
53
-
54
107
  ```
55
108
 
56
109
  In your `_task_fields` partial:
110
+
57
111
  ``` erb
58
112
  <div class="task-field">
59
113
  <%= f.input :description %>
60
114
  <%= f.input :done, as: :boolean %>
61
115
  <%= link_to_remove_association "Remove Task", f %>
62
116
  </div>
117
+ ```
63
118
 
119
+ ### Controller
120
+
121
+ Using projects example, in your controller ProjectsController, your params method should look like:
122
+ ``` ruby
123
+ def project_params
124
+ params.require(:project).permit(:name, :description, tasks_attributes: [:description, :done, :_destroy, :id])
125
+ end
64
126
  ```
65
127
 
128
+ params `:_destroy` allow to delete tasks and `:id` allow to update tasks on update action
129
+
130
+
66
131
  _Convention_:
132
+
67
133
  - For convention, I named Stimulus controller `nested-rondo`. But you can change the name of Javascript file and the value of `data-controller` to match your purpose.
68
134
  - `data-nested-rondo-target="fieldContain"` must be added to an element that wraps all nested fields, the new field will be appended to this element.
69
135
  - `data-nested-rondo-field-class-value` is used to detect the element that needs to be removed. Its value must match the class name of an element that wraps the partial. If you do not declare it, it will default remove the closest parent element.
136
+ - The partial added when clicking `link_to_add_association` is named for the association name with the `_fields` suffix. In this example, the partial is named `task_fields`. You can change the partial name by passing the `partial_name` option to `link_to_add_association`.
137
+
138
+ View details implement for this sample at [rondo_form_demo_turbo_8](https://github.com/hungle00/turbo_8_demos/tree/rondo_form)
70
139
 
71
140
  ## Contributing
72
141
 
@@ -14,7 +14,7 @@ export default class extends Controller {
14
14
  removeField(e) {
15
15
  e.preventDefault();
16
16
  const wrapperField = this.hasFieldClassValue ? e.target.closest("." + this.fieldClassValue) : e.target.parentNode;
17
-
17
+
18
18
  if(e.target.matches('.dynamic')) {
19
19
  wrapperField.remove();
20
20
  } else {
@@ -23,17 +23,23 @@ export default class extends Controller {
23
23
  }
24
24
  }
25
25
 
26
- buildNewAssociation(element) {
27
- const assoc = element.target.dataset.association;
28
- const assocs = element.target.dataset.associations;
26
+ buildNewAssociation(event) {
27
+ let element = event.target;
28
+ while (element) {
29
+ if (element.hasAttribute('data-association') || element.hasAttribute('data-associations'))
30
+ break
31
+ element = element.parentElement;
32
+ }
33
+ const assoc = element.dataset.association;
34
+ const assocs = element.dataset.associations;
29
35
  const content = this.templateTarget.innerHTML;
30
-
36
+
31
37
  let regexpBraced = new RegExp('\\[new_' + assoc + '\\](.*?\\s)', 'g');
32
38
  let newId = new Date().getTime();
33
39
  let newContent = content.replace(regexpBraced, '[' + newId + ']$1');
34
40
 
35
41
  if (newContent == content) {
36
- // assoc can be singular or plural
42
+ // assoc can be singular or plural
37
43
  regexpBraced = new RegExp('\\[new_' + assocs + '\\](.*?\\s)', 'g');
38
44
  newContent = content.replace(regexpBraced, '[' + newId + ']$1');
39
45
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RondoForm
4
- VERSION = "0.2.5"
4
+ VERSION = "1.0.0"
5
5
  end
@@ -11,7 +11,7 @@ module RondoForm
11
11
  # - *f* : the form this link should be placed in
12
12
  # - *html_options*: html options to be passed to link_to (see <tt>link_to</tt>)
13
13
  # - *&block*: the output of the block will be show in the link, see <tt>link_to</tt>
14
-
14
+
15
15
  def link_to_remove_association(*args, &block)
16
16
  if block_given?
17
17
  f = args.first
@@ -31,19 +31,24 @@ module RondoForm
31
31
 
32
32
  # shows a link that will allow to dynamically add a new associated object.
33
33
  #
34
- # - *name* : the text to show in the link
35
- # - *f* : the form this should come in
36
- # - *association* : the associated objects, e.g. :tasks, this should be the name of the <tt>has_many</tt> relation.
37
- # - *html_options*: html options to be passed to <tt>link_to</tt> (see <tt>link_to</tt>)
38
- # - *&block*: see <tt>link_to</tt>
34
+ # - *name* : the text to show in the link
35
+ # - *f* : the form this should come in
36
+ # - *association* : the associated objects, e.g. :tasks, this should be the name of the <tt>has_many</tt> relation.
37
+ # - *render_options*: options to be passed to <tt>render</tt>
38
+ # - partial: 'file_name'
39
+ # - locals: { hash_of: 'local variables for rendered partial' }
40
+ # - *html_options*: html options to be passed to <tt>link_to</tt> (see <tt>link_to</tt>)
41
+ # - *&block*: see <tt>link_to</tt>
39
42
 
40
43
  def link_to_add_association(*args, &block)
41
44
  if block_given?
42
- f, association, html_options = *args
45
+ f, association, render_options, html_options = *args
46
+ render_options ||= {}
43
47
  html_options ||= {}
44
- link_to_add_association(capture(&block), f, association, html_options)
48
+ link_to_add_association(capture(&block), f, association, render_options, html_options)
45
49
  else
46
- name, f, association, html_options = *args
50
+ name, f, association, render_options, html_options = *args
51
+ render_options ||= {}
47
52
  html_options ||= {}
48
53
 
49
54
  html_options[:class] = [html_options[:class], "add_fields"].compact.join(' ')
@@ -54,16 +59,19 @@ module RondoForm
54
59
  new_object = f.object.class.reflect_on_association(association).klass.new
55
60
  model_name = new_object.class.name.underscore
56
61
  hidden_div = content_tag("template", id: "#{model_name}_fields_template", data: {'nested-rondo_target': 'template'}) do
57
- render_association(association, f, new_object)
62
+ render_association(association, f, new_object, render_options)
58
63
  end
59
64
  hidden_div.html_safe + link_to(name, '', html_options )
60
65
  end
61
66
  end
62
67
 
63
68
  # :nodoc:
64
- def render_association(association, f, new_object)
69
+ def render_association(association, f, new_object, render_options)
70
+ locals = render_options.delete(:locals) || {}
71
+ render_options[:partial] = "#{association.to_s.singularize}_fields" unless render_options[:partial]
65
72
  f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
66
- render(association.to_s.singularize + "_fields", :f => builder, :dynamic => true)
73
+ locals.store(:f, builder)
74
+ render(render_options[:partial], locals)
67
75
  end
68
76
  end
69
77
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rondo_form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hungle00
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-20 00:00:00.000000000 Z
11
+ date: 2024-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -72,6 +72,7 @@ extensions: []
72
72
  extra_rdoc_files: []
73
73
  files:
74
74
  - ".rspec"
75
+ - CHANGELOG.md
75
76
  - Gemfile
76
77
  - Gemfile.lock
77
78
  - LICENSE.txt
@@ -104,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
105
  - !ruby/object:Gem::Version
105
106
  version: '0'
106
107
  requirements: []
107
- rubygems_version: 3.4.10
108
+ rubygems_version: 3.5.16
108
109
  signing_key:
109
110
  specification_version: 4
110
111
  summary: Cocoon, but with Stimulus JS