cool_nested_forms 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|