rondo_form 0.1.0 → 0.2.1

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
  SHA256:
3
- metadata.gz: ab7c415b1a97a538742b84ffd41f05acb28e60dc6bb5721d059670c4b69e5e91
4
- data.tar.gz: e953952e1955dd4a8194b96ea28aff09aa6e0990ce5113648f4d94f846f55335
3
+ metadata.gz: c3d9a9ef19130de5f6aa92adf1139711bd5faaae4ef20155579e6865f291b7d9
4
+ data.tar.gz: 791d1fff3244853568a449b8b3c7a151dec19b45d2c3e2e79dd77cdec47ad891
5
5
  SHA512:
6
- metadata.gz: 680cb74e9d615f9e1d3444363796a2cc8ec8d25dbc3caf2504bcee3188cb88c4001b911259cb256bb236d6bbaf6e0238edc71570fee7894996fd68ffc08cfe6b
7
- data.tar.gz: 1331fec9838d555ba6742f28aa74259644acbe7a019716a99118413eecb069fd69926f31a21db89e78a9d710e080caa2a0a62f56cd570344ff1e0194c4dbc96c
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
- If bundler is not being used to manage dependencies, install the gem by executing:
11
+ Or inside the Gemfile add the following
12
12
 
13
- $ gem install rondo_form
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 "cocoon_controller.js", "app/javascript/controllers/cocoon_controller.js", force: true
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 CocoonController from "./cocoon_controller"\napplication.register("cocoon", CocoonController)\n)
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
+ }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RondoForm
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.1"
5
5
  end
@@ -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 = args[0]
22
- f = args[1]
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->cocoon#removeField"
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 (the formtastic form)
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 = args[0]
50
- association = args[1]
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 = args[0]
55
- f = args[1]
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->cocoon#addField"
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: {cocoon_target: 'template'}) do
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.0
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-13 00:00:00.000000000 Z
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/cocoon_controller.js
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
- }