vanilla_nested 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 42bb398c9c058f38333cb4c3af17957fb5477da3
4
+ data.tar.gz: bae3d4d29d855c18f9f676e7a3aeed0b58b67e5b
5
+ SHA512:
6
+ metadata.gz: 8a45642b3b74560d5cbfa90178f37c9eac5daf890ed2e0f25915e57b2bccdc5f4006d3106d04dfac2370e95d3d5ca9c444b8c50266a105698aa4a8901484b535
7
+ data.tar.gz: 5a476ebc770c15df32a6bd3579534acf7f3d7f4bed4f54ba9d278c63d2af6d679a373e0b0feccb33a8361428cec62cd36dbaeb81d4fa7a91204b08a375e50755
@@ -0,0 +1,100 @@
1
+ (function(){
2
+ window.addVanillaNestedFields = function(event) {
3
+ event.preventDefault();
4
+ const element = event.target;
5
+ const data = element.dataset;
6
+ const newHtml = data.html.replace(/_idx_placeholder_/g, Date.now());
7
+ const container = document.querySelector(data.containerSelector);
8
+
9
+ let inserted;
10
+ switch (data.methodForInsert) {
11
+ case ('append'):
12
+ container.insertAdjacentHTML('beforeend', newHtml);
13
+ inserted = container.lastElementChild;
14
+ break;
15
+ case ('prepend'):
16
+ container.insertAdjacentHTML('afterbegin', newHtml);
17
+ inserted = container.firstElementChild;
18
+ break;
19
+ }
20
+ _dispatchEvent(container, 'vanilla-nested:fields-added', element, {added: inserted})
21
+ }
22
+
23
+ window.removeVanillaNestedFields = function(event) {
24
+ event.preventDefault();
25
+ const element = event.target;
26
+ const data = element.dataset;
27
+ let wrapper = element.parentElement;
28
+ if (sel = data.fieldsWrapperSelector) wrapper = element.closest(sel);
29
+
30
+ if (data.undoTimeout) {
31
+ hideFieldsWithUndo(wrapper, element);
32
+ _dispatchEvent(wrapper, 'vanilla-nested:fields-hidden', element);
33
+ } else {
34
+ hideWrapper(wrapper);
35
+ unhideFields(wrapper);
36
+ _dispatchEvent(wrapper, 'vanilla-nested:fields-removed', element);
37
+ }
38
+ wrapper.querySelector('[name$="[_destroy]"]').value = '1';
39
+ }
40
+
41
+ function hideWrapper(wrapper) {
42
+ wrapper.style.display = 'none';
43
+ }
44
+
45
+ function unhideFields(wrapper) {
46
+ [...wrapper.children].forEach(child => child.style.display = 'initial');
47
+ }
48
+
49
+ function hideFieldsWithUndo(wrapper, element) {
50
+ [...wrapper.children].forEach(child => child.style.display = 'none');
51
+
52
+ // add the 'undo' link with it's callback
53
+ const undoLink = _createUndoWithElementsData(element.dataset);
54
+ wrapper.appendChild(undoLink);
55
+
56
+ const _onUndoClicked = function(e) {
57
+ e.preventDefault();
58
+ clearTimeout(timer);
59
+ unhideFields(wrapper);
60
+ wrapper.querySelector('[name$="[_destroy]"]').value = '0';
61
+ _dispatchEvent(wrapper, 'vanilla-nested:fields-hidden-undo', undoLink);
62
+ undoLink.remove();
63
+ }
64
+
65
+ undoLink.addEventListener('click', _onUndoClicked);
66
+
67
+ // start the timer
68
+ const _onTimerCompleted = function() {
69
+ hideWrapper(wrapper);
70
+ unhideFields(wrapper);
71
+ _dispatchEvent(wrapper, 'vanilla-nested:fields-removed', undoLink);
72
+ undoLink.remove();
73
+ }
74
+
75
+ let ms = element.dataset.undoTimeout;
76
+ let timer = setTimeout(_onTimerCompleted, ms);
77
+ }
78
+
79
+
80
+
81
+ function _dispatchEvent(element, eventName, triggeredBy, details) {
82
+ if (!details) details = {};
83
+ details.triggeredBy = triggeredBy;
84
+
85
+ let event = new CustomEvent(eventName, {bubbles: true, detail: details})
86
+ element.dispatchEvent(event);
87
+ }
88
+
89
+ function _createUndoWithElementsData(data) {
90
+ const undo = document.createElement('A');
91
+
92
+ undo.classList.add('vanilla-nested-undo');
93
+ if (classes = data.undoLinkClasses)
94
+ undo.classList.add(...classes.split(' '));
95
+
96
+ undo.innerText = data.undoText;
97
+
98
+ return undo;
99
+ }
100
+ })()
@@ -0,0 +1,11 @@
1
+ require 'vanilla_nested/view_helpers'
2
+
3
+ module VanillaNested
4
+ class Engine < ::Rails::Engine
5
+ initializer "vanilla_nested.initialize" do |app|
6
+ ActiveSupport.on_load :action_view do
7
+ ActionView::Base.send :include, VanillaNested::ViewHelpers
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,30 @@
1
+ module VanillaNested
2
+ 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)
4
+ association_class = form.object.class.reflections[association.to_s].klass
5
+ object = association_class.new
6
+
7
+ partial_name = partial ? partial : "#{association_class.name.downcase}_fields"
8
+
9
+ 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}
12
+ end
13
+ end
14
+
15
+ methodForInsert = [:append, :prepend].include?(insert_method.to_sym) ? insert_method : :append
16
+
17
+ 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}"
20
+ end
21
+ end
22
+
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: '')
24
+ capture do
25
+ 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})
27
+ end
28
+ end
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vanilla_nested
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ariel Juodziukynas <arieljuod@gmail.com>
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-04-10 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: arieljuod@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - app/assets/javascripts/vanilla_nested.js
20
+ - lib/vanilla_nested.rb
21
+ - lib/vanilla_nested/view_helpers.rb
22
+ homepage: https://github.com/arielj/vanilla-nested
23
+ licenses:
24
+ - GPL-3.0
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.6.14.1
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Dynamic nested forms using vanilla javascript
46
+ test_files: []