cool_nested_forms 1.0.2 → 2.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 +4 -4
- data/app/assets/javascripts/cool_nested_forms.js +62 -27
- data/app/helpers/cool_nested_forms_helper.rb +101 -38
- data/cool_nested_forms.gemspec +1 -1
- data/lib/cool_nested_forms/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e0dc8dc707e61117d10794ea7ff2889d6e7bdde
|
4
|
+
data.tar.gz: 5e4cd25d4a6269fdec390efb861641d34c268ca9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 989fc6d673aeaf2830fc2afa00dfcf90904ea08592feb1365763193c80b04333acda1a1f79684aa071e4f6aec37f92bb8f988d8617150f2b443eec529c289224
|
7
|
+
data.tar.gz: d68800719b9475ba36ad6cd3857746568659bfa44f6d8295388911adcc31c0bd0f1af9b2b805f7cc6417c1ffd9deba7c4de0e8c9acd54b7fa679718cc320b915
|
@@ -1,36 +1,71 @@
|
|
1
1
|
$(function(){
|
2
|
-
$(document).
|
2
|
+
$(document).on('click', '.cnf-add-entry', function() {
|
3
|
+
// initialize options
|
3
4
|
var association = $(this).attr('data-association');
|
4
|
-
var
|
5
|
-
var
|
6
|
-
var target = $(this).attr('target');
|
7
|
-
|
8
|
-
|
9
|
-
var
|
10
|
-
var
|
11
|
-
var
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
5
|
+
var jsTemplateName = $(this).attr('data-js-template-name');
|
6
|
+
var childTemplates = $(this).attr('data-child-js-template-names').split(' ');
|
7
|
+
var target = $(this).attr('data-target');
|
8
|
+
|
9
|
+
// initialize regular expressions
|
10
|
+
var associationNewRegEx = new RegExp('new_' + association, 'g');
|
11
|
+
var tempIdRegEx = new RegExp('\\[tempid\\]', 'g');
|
12
|
+
var childTempIdRegEx = new RegExp('_tempid_', 'g');
|
13
|
+
|
14
|
+
// create a temporary id
|
15
|
+
var newId = new Date().getTime();
|
16
|
+
|
17
|
+
// select where to append the new element
|
18
|
+
var container = (target == '') ? $(this).parent() : $('#'+target);
|
19
|
+
|
20
|
+
// append the new emelent andreplace all temp_ids
|
21
|
+
container.append(window[ jsTemplateName ].replace(associationNewRegEx, newId).replace(tempIdRegEx, newId));
|
22
|
+
|
23
|
+
// parse any child templates
|
24
|
+
for(var index in childTemplates) {
|
25
|
+
|
26
|
+
childTemplate = childTemplates[index];
|
27
|
+
|
28
|
+
if(childTemplate != ""){
|
29
|
+
// get the template
|
30
|
+
body = window[childTemplate];
|
31
|
+
// generate the script tag
|
32
|
+
child_script_tag = "<script> var " + childTemplate + " = '" + body + "' </script>";
|
33
|
+
// substitute all the temp ids
|
34
|
+
child_script_tag = child_script_tag.replace(childTempIdRegEx, "_" + newId + "_")
|
35
|
+
.replace(associationNewRegEx, newId);
|
36
|
+
// append the child script tag to the target container
|
37
|
+
// this generates a new script tag associated to the element created
|
38
|
+
// before this loop
|
39
|
+
container.append(child_script_tag.replace(childTempIdRegEx, "_" + newId + "_"));
|
24
40
|
}
|
25
41
|
}
|
26
|
-
|
42
|
+
// trigger event coolNestedForms.entryAdded
|
43
|
+
$(document).trigger('coolNestedForms.entryAdded');
|
44
|
+
// false to avoid errors
|
27
45
|
return false;
|
28
46
|
});
|
29
|
-
|
30
|
-
|
31
|
-
$(this).
|
32
|
-
|
33
|
-
|
47
|
+
$(document).on('click', '.cnf-remove-entry', function() {
|
48
|
+
// get the target attribute. this is the target entry container.
|
49
|
+
var target = $(this).attr('data-target');
|
50
|
+
// initialize the container
|
51
|
+
var container = "";
|
52
|
+
// target provided?
|
53
|
+
if(target == ""){
|
54
|
+
// default to the parent container
|
55
|
+
container = $(this).parent();
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
// use the target provided
|
59
|
+
container = $('#' + target);
|
60
|
+
}
|
61
|
+
// update the hidden field that sets the record for removal
|
62
|
+
container.find('.cnf-removable')[0].value = 1;
|
63
|
+
// hide the container for user feedback
|
64
|
+
container.hide();
|
65
|
+
// trigger event coolNestedForms.entryRemoved
|
66
|
+
$(document).trigger('coolNestedForms.entryRemoved');
|
67
|
+
// false to avoid errors
|
34
68
|
return false;
|
35
69
|
});
|
70
|
+
|
36
71
|
});
|
@@ -1,45 +1,108 @@
|
|
1
1
|
module CoolNestedFormsHelper
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
3
|
+
## new_entry_template ##
|
4
|
+
# arguments
|
5
|
+
# - builder: a FormBuilder Object obtained from form_with or form_for
|
6
|
+
# - association: a model class i.e. MyTask
|
7
|
+
# - options: hash of override options
|
8
|
+
# - partial: name of the erb partial to use as a tempalte
|
9
|
+
# - id: ID to be used in for the container
|
10
|
+
# - plurilized: the plural version of the model name
|
11
|
+
# - js_template_name: name for the javascript variable generated by this method ( useful when there are multiple nested associations)
|
12
|
+
# - children: an array with childre association options for nested association of a nested association
|
13
|
+
def new_entry_template(builder,association, options = {})
|
14
|
+
# initialize options
|
15
|
+
options[:partial] ||= association.name.snakecase
|
16
|
+
options[:id] ||= "#{association.name.snakecase}_[tempid]"
|
17
|
+
options[:pluralized] ||= association.name.snakecase.pluralize
|
18
|
+
options[:js_template_name] ||= association.name.snakecase.pluralize
|
19
|
+
options[:children] ||= []
|
20
|
+
|
21
|
+
# children output
|
22
|
+
children_output = ''
|
23
|
+
# render the template using the form builder object and the association
|
24
|
+
output = builder.fields_for(options[:pluralized],association.new, :child_index => "new_#{options[:pluralized]}") do |assoc_builder|
|
25
|
+
|
26
|
+
# render each children
|
27
|
+
options[:children].each do |child|
|
28
|
+
children_output += new_entry_template(assoc_builder,child[:association],child)
|
21
29
|
end
|
22
30
|
|
23
|
-
|
24
|
-
|
25
|
-
script += child_tmpl
|
26
|
-
return script.html_safe
|
31
|
+
# render erb partial
|
32
|
+
render(:partial=>options[:partial],:locals =>{:builder => assoc_builder, :id => options[:id] })
|
27
33
|
end
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
35
|
+
# remove any new line characters
|
36
|
+
output = output.gsub( /\r?\n|\r/, ' ')
|
37
|
+
|
38
|
+
# create the script tag that will be output to the page
|
39
|
+
script_tag = "<script> var #{options[:js_template_name]} = '#{output}'; </script>"
|
40
|
+
|
41
|
+
# add children_output
|
42
|
+
script_tag += children_output
|
43
|
+
# return the output as html safe
|
44
|
+
return script_tag.html_safe
|
45
|
+
end
|
46
|
+
|
47
|
+
## new_entry_button ##
|
48
|
+
# arguments
|
49
|
+
# - name: A string to be displayed as the button text
|
50
|
+
# - association: a model class i.e. MyTask
|
51
|
+
# - target: a html tag ID where the button will be attached
|
52
|
+
# - options: hash of override options
|
53
|
+
# - plurilized: the plural version of the model name
|
54
|
+
# - js_template_name: name for the javascript variable generated by this method ( useful when there are multiple nested associations)
|
55
|
+
# - class: a string with any css class names to be used for styling
|
56
|
+
# - style: a string with any css styles
|
57
|
+
# - child_js_template_names: an array with any children js template names.
|
58
|
+
# every time a nested association that contains other nested associations is added,
|
59
|
+
# a button to add a child entry is added to the new entry
|
60
|
+
# - tag: override the returned tag
|
61
|
+
# - tag_content: override the returned tag content
|
62
|
+
def new_entry_button(name, association, options = {})
|
63
|
+
options[:pluralized] ||= association.name.snakecase.pluralize
|
64
|
+
options[:js_template_name] ||= association.name.snakecase.pluralize
|
65
|
+
options[:class] ||= ""
|
66
|
+
options[:style] ||= ""
|
67
|
+
options[:child_js_template_names] ||= ""
|
68
|
+
options[:tag] ||= :span
|
69
|
+
options[:tag_content] ||= "<span>#{name}</span>"
|
70
|
+
options[:target] ||= association.name.snakecase.pluralize
|
71
|
+
|
72
|
+
return content_tag(options[:tag],
|
73
|
+
options[:tag_content].html_safe,
|
74
|
+
:class => "cnf-add-entry #{options[:class]}",
|
75
|
+
:style => options[:style],
|
76
|
+
"data-association" => options[:pluralized],
|
77
|
+
"data-js-template-name" => options[:js_template_name],
|
78
|
+
"data-child-js-template-names" => options[:child_js_template_names],
|
79
|
+
:id => "#{options[:js_template_name]}_button",
|
80
|
+
"data-target" => options[:target])
|
81
|
+
end
|
82
|
+
|
83
|
+
## remove_entry_button
|
84
|
+
# arguments
|
85
|
+
# - name: A string to be displayed as the button text
|
86
|
+
# - target: a html tag ID that contains the element to be removed
|
87
|
+
# - options: hash of override options
|
88
|
+
# - class: a string with any css class names to be used for styling
|
89
|
+
# - style: a string with any css styles
|
90
|
+
# - tag: override the returned tag
|
91
|
+
# - tag_content: override the returned tag content
|
92
|
+
def remove_entry_button(name, association, options = {})
|
93
|
+
options[:class] ||= ''
|
94
|
+
options[:style] ||= ''
|
95
|
+
options[:tag] ||= :div
|
96
|
+
options[:tag_content] ||= "<span>#{name}</span>"
|
97
|
+
options[:target] ||= ""
|
98
|
+
|
99
|
+
return content_tag(
|
100
|
+
options[:tag],
|
101
|
+
options[:tag_content].html_safe,
|
102
|
+
:style => options[:style],
|
103
|
+
:class => "cnf-remove-entry #{options[:class]}",
|
104
|
+
"data-target" => options[:target]
|
105
|
+
)
|
106
|
+
end
|
107
|
+
|
45
108
|
end
|
data/cool_nested_forms.gemspec
CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
31
|
spec.require_paths = ["lib", "app"]
|
32
32
|
|
33
|
-
spec.add_runtime_dependency 'rails', '
|
33
|
+
spec.add_runtime_dependency 'rails', '>= 4.0'
|
34
34
|
|
35
35
|
spec.add_development_dependency "bundler"
|
36
36
|
spec.add_development_dependency "rake"
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cool_nested_forms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Roque
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|