rondo_form 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +47 -9
- data/lib/generators/rondo_form/install_generator.rb +2 -2
- data/lib/generators/rondo_form/templates/nested_rondo_controller.js +41 -0
- data/lib/rondo_form/version.rb +1 -1
- data/lib/rondo_form/view_helpers.rb +18 -21
- metadata +3 -3
- data/lib/generators/rondo_form/templates/cocoon_controller.js +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3d9a9ef19130de5f6aa92adf1139711bd5faaae4ef20155579e6865f291b7d9
|
4
|
+
data.tar.gz: 791d1fff3244853568a449b8b3c7a151dec19b45d2c3e2e79dd77cdec47ad891
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e511697842f4cebf817bf61108e0556281e0702b7acd9cb6b75c0ba62d18ae7ef33b3e2665ec240a595955d0d80c77d6297bd882a7de5148552997b1020e77d5
|
7
|
+
data.tar.gz: b9d9ef124e278eef3de87275295783874535207bd4785cac54a84059f28cd350e96f6b301399a1080e3ac63ab855370983c8b3793a86daf7fdd75a1c083929c2
|
data/README.md
CHANGED
@@ -8,24 +8,62 @@ Install the gem and add to the application's Gemfile by executing:
|
|
8
8
|
|
9
9
|
$ bundle add rondo_form
|
10
10
|
|
11
|
-
|
11
|
+
Or inside the Gemfile add the following
|
12
12
|
|
13
|
-
$ gem
|
13
|
+
$ gem 'rondo_form', '~> 0.2.0'
|
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:
|
22
|
+
```
|
23
|
+
rails g scaffold Project name:string description:string
|
24
|
+
rails g model Task description:string done:boolean project:belongs_to
|
25
|
+
```
|
26
|
+
|
27
|
+
### Sample with SimpleForm
|
28
|
+
In your `projects/_form` partial:
|
29
|
+
``` erb
|
30
|
+
<%= simple_form_for(@project) do |f| %>
|
31
|
+
|
32
|
+
<div class="form-inputs">
|
33
|
+
<%= f.input :name %>
|
34
|
+
<%= f.input :description %>
|
35
|
+
</div>
|
36
|
+
|
37
|
+
<h3 class="text-xl mt-4">Tasks</h3>
|
38
|
+
<div class="my-2" data-controller="cocoon">
|
39
|
+
<%= f.simple_fields_for :tasks do |task| %>
|
40
|
+
<%= render "task_fields", f: task %>
|
41
|
+
<% end %>
|
42
|
+
<div class="links">
|
43
|
+
<%= link_to_add_association "Add Task", f, :tasks %>
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<div class="form-actions mt-4">
|
48
|
+
<%= f.button :submit %>
|
49
|
+
</div>
|
50
|
+
<% end %>
|
51
|
+
|
52
|
+
```
|
53
|
+
|
54
|
+
In your `_task_fields` partial:
|
55
|
+
``` erb
|
56
|
+
<div class="nested-fields">
|
57
|
+
<%= f.input :description %>
|
58
|
+
<%= f.input :done, as: :boolean %>
|
59
|
+
<%= link_to_remove_association "Remove Task", f %>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
```
|
63
|
+
|
64
|
+
_Note_: You must add `data-controller="cocoon"` to an element, that wraps `fields_for` and `link_to_add_association` helper.
|
21
65
|
|
22
66
|
|
23
|
-
## Development
|
24
|
-
|
25
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
26
|
-
|
27
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
28
|
-
|
29
67
|
## Contributing
|
30
68
|
|
31
69
|
Bug reports and pull requests are welcome on GitHub at https://github.com/hungle00/rondo_form.
|
@@ -5,10 +5,10 @@ module RondoForm
|
|
5
5
|
desc "This generator installs the javascript needed for rondo_form"
|
6
6
|
|
7
7
|
def copy_the_javascript
|
8
|
-
copy_file "
|
8
|
+
copy_file "nested_rondo_controller.js", "app/javascript/controllers/nested_rondo_controller.js", force: true
|
9
9
|
if (Rails.root.join("app/javascript/controllers/index.js")).exist?
|
10
10
|
append_to_file "app/javascript/controllers/index.js",
|
11
|
-
%(import
|
11
|
+
%(import NestedRondoController from "./nested_rondo_controller"\napplication.register("nested-rondo", NestedRondoController)\n)
|
12
12
|
else
|
13
13
|
say %(Couldn't find "app/javascript/controllers/index.js".), :red
|
14
14
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = ["template"]
|
5
|
+
|
6
|
+
addField(e) {
|
7
|
+
e.preventDefault();
|
8
|
+
|
9
|
+
let assoc = e.target.dataset.association;
|
10
|
+
let newField = this.buildNewAssociation(assoc);
|
11
|
+
let insertionNode = this.templateTarget.parentElement;
|
12
|
+
insertionNode.insertAdjacentHTML("beforebegin", newField);
|
13
|
+
}
|
14
|
+
|
15
|
+
removeField(e) {
|
16
|
+
e.preventDefault();
|
17
|
+
|
18
|
+
let wrapperClass = this.data.get("wrapperClass") || "nested-fields";
|
19
|
+
let wrapperField = e.target.closest("." + wrapperClass);
|
20
|
+
if(e.target.matches('.dynamic')) {
|
21
|
+
wrapperField.remove();
|
22
|
+
} else {
|
23
|
+
wrapperField.querySelector("input[name*='_destroy']").value = 1;
|
24
|
+
wrapperField.style.display = "none";
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
buildNewAssociation(assoc) {
|
29
|
+
let content = this.templateTarget.innerHTML;
|
30
|
+
let regexpBraced = new RegExp('\\[new_' + assoc + '\\]', 'g');
|
31
|
+
let newId = new Date().getTime();
|
32
|
+
let newContent = content.replace(regexpBraced, '[' + newId + ']');
|
33
|
+
|
34
|
+
if (newContent == content) {
|
35
|
+
// assoc can be singular or plural
|
36
|
+
regexpBraced = new RegExp('\\[new_' + assoc + 's\\]', 'g');
|
37
|
+
newContent = content.replace(regexpBraced, '[' + newId + ']');
|
38
|
+
}
|
39
|
+
return newContent;
|
40
|
+
}
|
41
|
+
}
|
data/lib/rondo_form/version.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module RondoForm
|
2
2
|
module ViewHelpers
|
3
|
+
|
3
4
|
# this will show a link to remove the current association. This should be placed inside the partial.
|
4
5
|
# either you give
|
5
6
|
# - *name* : the text of the link
|
@@ -18,55 +19,51 @@ module RondoForm
|
|
18
19
|
name = capture(&block)
|
19
20
|
link_to_remove_association(name, f, html_options)
|
20
21
|
else
|
21
|
-
name
|
22
|
-
|
23
|
-
html_options = args[2] || {}
|
22
|
+
name, f, html_options = *args
|
23
|
+
html_options ||= {}
|
24
24
|
|
25
25
|
is_dynamic = f.object.new_record?
|
26
26
|
html_options[:class] = [html_options[:class], "remove_fields #{is_dynamic ? 'dynamic' : 'existing'}"].compact.join(' ')
|
27
|
-
html_options[:'data-action'] = "click->
|
27
|
+
html_options[:'data-action'] = "click->nested-rondo#removeField"
|
28
28
|
f.hidden_field(:_destroy) + link_to(name, '', html_options)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
# :nodoc:
|
33
|
-
def render_association(association, f, new_object)
|
34
|
-
f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
|
35
|
-
render(association.to_s.singularize + "_fields", :f => builder, :dynamic => true)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
32
|
# shows a link that will allow to dynamically add a new associated object.
|
40
33
|
#
|
41
34
|
# - *name* : the text to show in the link
|
42
|
-
# - *f* : the form this should come in
|
35
|
+
# - *f* : the form this should come in
|
43
36
|
# - *association* : the associated objects, e.g. :tasks, this should be the name of the <tt>has_many</tt> relation.
|
44
37
|
# - *html_options*: html options to be passed to <tt>link_to</tt> (see <tt>link_to</tt>)
|
45
38
|
# - *&block*: see <tt>link_to</tt>
|
46
39
|
|
47
40
|
def link_to_add_association(*args, &block)
|
48
41
|
if block_given?
|
49
|
-
f
|
50
|
-
|
51
|
-
html_options = args[2] || {}
|
42
|
+
f, association, html_options = *args
|
43
|
+
html_options ||= {}
|
52
44
|
link_to_add_association(capture(&block), f, association, html_options)
|
53
45
|
else
|
54
|
-
name
|
55
|
-
|
56
|
-
association = args[2]
|
57
|
-
html_options = args[3] || {}
|
46
|
+
name, f, association, html_options = *args
|
47
|
+
html_options ||= {}
|
58
48
|
|
59
49
|
html_options[:class] = [html_options[:class], "add_fields"].compact.join(' ')
|
60
50
|
html_options[:'data-association'] = association.to_s.singularize
|
61
|
-
html_options[:'data-action'] = "click->
|
51
|
+
html_options[:'data-action'] = "click->nested-rondo#addField"
|
62
52
|
|
63
53
|
new_object = f.object.class.reflect_on_association(association).klass.new
|
64
54
|
model_name = new_object.class.name.underscore
|
65
|
-
hidden_div = content_tag("template", id: "#{model_name}_fields_template", data: {
|
55
|
+
hidden_div = content_tag("template", id: "#{model_name}_fields_template", data: {'nested-rondo_target': 'template'}) do
|
66
56
|
render_association(association, f, new_object)
|
67
57
|
end
|
68
58
|
end
|
69
59
|
hidden_div.html_safe + link_to(name, '', html_options )
|
70
60
|
end
|
61
|
+
|
62
|
+
# :nodoc:
|
63
|
+
def render_association(association, f, new_object)
|
64
|
+
f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
|
65
|
+
render(association.to_s.singularize + "_fields", :f => builder, :dynamic => true)
|
66
|
+
end
|
67
|
+
end
|
71
68
|
end
|
72
69
|
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.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hungle00
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-06-
|
11
|
+
date: 2023-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -78,7 +78,7 @@ files:
|
|
78
78
|
- README.md
|
79
79
|
- Rakefile
|
80
80
|
- lib/generators/rondo_form/install_generator.rb
|
81
|
-
- lib/generators/rondo_form/templates/
|
81
|
+
- lib/generators/rondo_form/templates/nested_rondo_controller.js
|
82
82
|
- lib/rondo_form.rb
|
83
83
|
- lib/rondo_form/version.rb
|
84
84
|
- lib/rondo_form/view_helpers.rb
|
@@ -1,35 +0,0 @@
|
|
1
|
-
import { Controller } from "@hotwired/stimulus"
|
2
|
-
|
3
|
-
export default class extends Controller {
|
4
|
-
static targets = ["template"]
|
5
|
-
|
6
|
-
addField(e) {
|
7
|
-
e.preventDefault()
|
8
|
-
let assoc = e.target.dataset.association
|
9
|
-
let newField = this.buildNewAssociation(assoc)
|
10
|
-
let insertionNode = this.templateTarget.parentElement
|
11
|
-
insertionNode.insertAdjacentHTML("beforebegin", newField)
|
12
|
-
}
|
13
|
-
|
14
|
-
removeField(e) {
|
15
|
-
e.preventDefault()
|
16
|
-
let closestField = e.target.closest(".nested-fields")
|
17
|
-
if(e.target.matches('.dynamic')) {
|
18
|
-
closestField.remove()
|
19
|
-
} else {
|
20
|
-
closestField.style.display = "none"
|
21
|
-
}
|
22
|
-
}
|
23
|
-
|
24
|
-
buildNewAssociation(assoc) {
|
25
|
-
let content = this.templateTarget.innerHTML;
|
26
|
-
let regexp_braced = new RegExp('\\[new_' + assoc + '\\]', 'g');
|
27
|
-
let new_id = new Date().getTime();
|
28
|
-
let new_content = content.replace(regexp_braced, '[' + new_id + ']');
|
29
|
-
if (new_content == content) {
|
30
|
-
regexp_braced = new RegExp('\\[new_' + assoc + 's\\]', 'g');
|
31
|
-
new_content = content.replace(regexp_braced, '[' + new_id + ']');
|
32
|
-
}
|
33
|
-
return new_content
|
34
|
-
}
|
35
|
-
}
|