vanilla_nested 1.0.0 → 1.2.5

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
- 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