vanilla_nested 1.0.0 → 1.2.5

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
- SHA1:
3
- metadata.gz: 42bb398c9c058f38333cb4c3af17957fb5477da3
4
- data.tar.gz: bae3d4d29d855c18f9f676e7a3aeed0b58b67e5b
2
+ SHA256:
3
+ metadata.gz: 8b6d8ed9c309bf72014920bec0254c922804f9077967492047139cb3aabc54f3
4
+ data.tar.gz: 890d67164554668f8054724329cb9bfe56884e73ab44a864ef3b8283c011cae9
5
5
  SHA512:
6
- metadata.gz: 8a45642b3b74560d5cbfa90178f37c9eac5daf890ed2e0f25915e57b2bccdc5f4006d3106d04dfac2370e95d3d5ca9c444b8c50266a105698aa4a8901484b535
7
- data.tar.gz: 5a476ebc770c15df32a6bd3579534acf7f3d7f4bed4f54ba9d278c63d2af6d679a373e0b0feccb33a8361428cec62cd36dbaeb81d4fa7a91204b08a375e50755
6
+ metadata.gz: c6df5288710235fce651f21a7d03aff41c9d7d529bbb1f0626677bdfe3bf8f670b1277fde0b942c8978a7240de1ecd0586f96d218e6c63f4a27eb63325539964
7
+ data.tar.gz: f2b7ec1060c226133354d30cb0643620bf12251657771357429f21a3069c76390085715eeb7fcc381ae4ca016ec0d6a632f0573eb1ec5f7df7bac6f1fa835296
@@ -1,10 +1,16 @@
1
1
  (function(){
2
+ // Get the html from the data attribute and insert the new fields on the container
3
+ // "event" is the click event of the link created by the rails helper
2
4
  window.addVanillaNestedFields = function(event) {
3
5
  event.preventDefault();
4
- const element = event.target;
6
+
7
+ let element = event.target;
8
+ if (!element.classList.contains('vanilla-nested-add'))
9
+ element = element.closest('.vanilla-nested-add')
10
+
5
11
  const data = element.dataset;
6
- const newHtml = data.html.replace(/_idx_placeholder_/g, Date.now());
7
12
  const container = document.querySelector(data.containerSelector);
13
+ const newHtml = data.html.replace(/_idx_placeholder_/g, Date.now());
8
14
 
9
15
  let inserted;
10
16
  switch (data.methodForInsert) {
@@ -17,12 +23,30 @@
17
23
  inserted = container.firstElementChild;
18
24
  break;
19
25
  }
26
+
20
27
  _dispatchEvent(container, 'vanilla-nested:fields-added', element, {added: inserted})
28
+
29
+ let removeLink = inserted.querySelector('.vanilla-nested-remove');
30
+ if (removeLink)
31
+ removeLink.addEventListener('click', removeVanillaNestedFields, true);
32
+
33
+ // dispatch an event if we reached the limit configured on the model
34
+ if (data.limit) {
35
+ let nestedElements = container.children.length;
36
+ if (nestedElements >= data.limit)
37
+ _dispatchEvent(container, 'vanilla-nested:fields-limit-reached', element)
38
+ }
21
39
  }
22
40
 
41
+ // Removes the fields or hides them until the undo timer times out
42
+ // "event" is the click event of the link created by the rails helper
23
43
  window.removeVanillaNestedFields = function(event) {
24
44
  event.preventDefault();
25
- const element = event.target;
45
+
46
+ let element = event.target;
47
+ if (!element.classList.contains('vanilla-nested-remove'))
48
+ element = element.closest('.vanilla-nested-remove')
49
+
26
50
  const data = element.dataset;
27
51
  let wrapper = element.parentElement;
28
52
  if (sel = data.fieldsWrapperSelector) wrapper = element.closest(sel);
@@ -38,14 +62,21 @@
38
62
  wrapper.querySelector('[name$="[_destroy]"]').value = '1';
39
63
  }
40
64
 
65
+ // Hides an element, mainly the wrapper of a group of fields
66
+ // "wrapper" is the wrapper of the link to remove fields
41
67
  function hideWrapper(wrapper) {
42
68
  wrapper.style.display = 'none';
43
69
  }
44
70
 
71
+ // Unhides the children given a fields wrapper
72
+ // "wrapper" is the wrapper of the link to remove fields
45
73
  function unhideFields(wrapper) {
46
74
  [...wrapper.children].forEach(child => child.style.display = 'initial');
47
75
  }
48
76
 
77
+ // Hides an element and adds an "undo" link to unhide it
78
+ // "wrapper" is the wrapper to hide
79
+ // "element" is the link to remove the wrapper
49
80
  function hideFieldsWithUndo(wrapper, element) {
50
81
  [...wrapper.children].forEach(child => child.style.display = 'none');
51
82
 
@@ -76,8 +107,6 @@
76
107
  let timer = setTimeout(_onTimerCompleted, ms);
77
108
  }
78
109
 
79
-
80
-
81
110
  function _dispatchEvent(element, eventName, triggeredBy, details) {
82
111
  if (!details) details = {};
83
112
  details.triggeredBy = triggeredBy;
@@ -97,4 +126,25 @@
97
126
 
98
127
  return undo;
99
128
  }
129
+
130
+ function initVanillaNested() {
131
+ document.querySelectorAll('.vanilla-nested-add').forEach(el => {
132
+ el.addEventListener('click', addVanillaNestedFields, true);
133
+ })
134
+
135
+ document.querySelectorAll('.vanilla-nested-remove').forEach(el => {
136
+ el.addEventListener('click', removeVanillaNestedFields, true);
137
+ })
138
+ }
139
+
140
+ document.addEventListener('DOMContentLoaded', function(){
141
+ initVanillaNested();
142
+ })
143
+
144
+ // Don't run turbolinks event callback for first load, we already do it with DOMContentLoaded
145
+ const notEmpty = (obj) => Object.keys(obj).length;
146
+
147
+ document.addEventListener('turbolinks:load', function(e){
148
+ if (notEmpty(e.data.timing)) initVanillaNested();
149
+ })
100
150
  })()
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'vanilla_nested/view_helpers'
2
4
 
3
5
  module VanillaNested
4
6
  class Engine < ::Rails::Engine
5
- initializer "vanilla_nested.initialize" do |app|
7
+ initializer 'vanilla_nested.initialize' do |_app|
6
8
  ActiveSupport.on_load :action_view do
7
9
  ActionView::Base.send :include, VanillaNested::ViewHelpers
8
10
  end
9
11
  end
10
12
  end
11
- end
13
+ end
@@ -1,29 +1,76 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module VanillaNested
2
4
  module ViewHelpers
3
- def link_to_add_nested(form, association, container_selector, link_text: nil, link_classes: '', insert_method: :append, partial: nil, partial_form_variable: :form)
5
+ # @param form [FormBuild] builder on a "form_for" block
6
+ # @param association [Symbol] name of the association
7
+ # @param container_selector [String] selector of the element to inser the fields
8
+ # @param link_text [String, nil] text to use for the link tag
9
+ # @param link_classes [String] space separated classes for the link tag
10
+ # @param insert_method [:append, :prepend] tells javascript if the new fields should be appended or prepended to the container
11
+ # @param partial_form_variable [String, Symbol] name of the variable that represents the form builder inside the fields partial
12
+ # @param link_content [Block] block of code for the link content
13
+ # @return [String] link tag
14
+ def link_to_add_nested(form, association, container_selector, link_text: nil, link_classes: '', insert_method: :append, partial: nil, partial_form_variable: :form, &link_content)
4
15
  association_class = form.object.class.reflections[association.to_s].klass
5
16
  object = association_class.new
6
17
 
7
- partial_name = partial ? partial : "#{association_class.name.downcase}_fields"
18
+ partial_name = partial || "#{association_class.name.underscore}_fields"
8
19
 
9
20
  html = capture do
10
- form.fields_for association, object, child_index: "_idx_placeholder_" do |ff|
11
- render partial: partial_name, locals: {partial_form_variable => ff}
21
+ form.fields_for association, object, child_index: '_idx_placeholder_' do |ff|
22
+ render partial: partial_name, locals: { partial_form_variable => ff }
12
23
  end
13
24
  end
14
25
 
15
- methodForInsert = [:append, :prepend].include?(insert_method.to_sym) ? insert_method : :append
26
+ method_for_insert = %i[append prepend].include?(insert_method.to_sym) ? insert_method : :append
16
27
 
17
28
  classes = "vanilla-nested-add #{link_classes}"
18
- link_to '#', class: classes, onclick: 'addVanillaNestedFields(event)', data: {'container-selector': container_selector, html: html, 'method-for-insert': methodForInsert} do
19
- link_text || "Add #{association_class.model_name}"
29
+ data = {
30
+ 'container-selector': container_selector,
31
+ 'html': html,
32
+ 'method-for-insert': method_for_insert
33
+ }
34
+
35
+ nested_options = form.object.class.nested_attributes_options[association.to_sym]
36
+ data['limit'] = nested_options[:limit] if nested_options[:limit]
37
+
38
+ if block_given?
39
+ link_to '#', class: classes, data: data, &link_content
40
+ else
41
+ text = link_text || "Add #{association_class.model_name}"
42
+ link_to text, '#', class: classes, data: data
20
43
  end
21
44
  end
22
45
 
23
- def link_to_remove_nested(form, link_text: 'X', fields_wrapper_selector: nil, undo_link_timeout: nil, undo_link_text: 'Undo', undo_link_classes: '')
46
+ # @param form [FormBuilder] builder on a "form_for" block
47
+ # @param link_text [String, nil] text for the link, defaults to 'X'
48
+ # @param fields_wrapper_selector [String] selector for the wrapper of the fields, must be an ancestor
49
+ # @param undo_link_timeout [Integer] time until undo timeouts
50
+ # @param undo_link_text [String] text to show as "undo"
51
+ # @param undo_link_classes [String] space separated list of classes for the "undo" link
52
+ # @param ulink_classes [String] space separated list of classes for the "x" link
53
+ # @param link_content [Block] block of code for the link content
54
+ # @return [String] hidden field and link tag
55
+ def link_to_remove_nested(form, link_text: 'X', fields_wrapper_selector: nil, undo_link_timeout: nil, undo_link_text: 'Undo', undo_link_classes: '', link_classes: '', &link_content)
56
+ data = {
57
+ 'fields-wrapper-selector': fields_wrapper_selector,
58
+ 'undo-timeout': undo_link_timeout,
59
+ 'undo-text': undo_link_text,
60
+ 'undo-link-classes': undo_link_classes
61
+ }
62
+
63
+ classes = "vanilla-nested-remove #{link_classes}"
64
+
24
65
  capture do
25
66
  concat form.hidden_field(:_destroy, value: 0)
26
- concat link_to(link_text, '#', class: 'vanilla-nested-remove', onclick: 'removeVanillaNestedFields(event)', data: {'fields-wrapper-selector': fields_wrapper_selector, 'undo-timeout': undo_link_timeout, 'undo-text': undo_link_text, 'undo-link-classes': undo_link_classes})
67
+ concat(
68
+ if block_given?
69
+ link_to('#', class: classes, data: data, &link_content)
70
+ else
71
+ link_to(link_text.html_safe, '#', class: classes, data: data)
72
+ end
73
+ )
27
74
  end
28
75
  end
29
76
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vanilla_nested
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ariel Juodziukynas <arieljuod@gmail.com>
@@ -21,7 +21,7 @@ files:
21
21
  - lib/vanilla_nested/view_helpers.rb
22
22
  homepage: https://github.com/arielj/vanilla-nested
23
23
  licenses:
24
- - GPL-3.0
24
+ - MIT
25
25
  metadata: {}
26
26
  post_install_message:
27
27
  rdoc_options: []
@@ -38,8 +38,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0'
40
40
  requirements: []
41
- rubyforge_project:
42
- rubygems_version: 2.6.14.1
41
+ rubygems_version: 3.0.9
43
42
  signing_key:
44
43
  specification_version: 4
45
44
  summary: Dynamic nested forms using vanilla javascript