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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: af501a2bfc55ecb63e39851038dfb7d0bba6614e
4
- data.tar.gz: 594c8c6a3b576f6e836489ef47a53991e190d4b9
3
+ metadata.gz: 2e0dc8dc707e61117d10794ea7ff2889d6e7bdde
4
+ data.tar.gz: 5e4cd25d4a6269fdec390efb861641d34c268ca9
5
5
  SHA512:
6
- metadata.gz: 5508c12b75229896af14311249e770ee2303e398e30d5b4c7101dc525a506f0ead853644e51a1d8560d705c4d1f50c996f8d41758d74aeeaab2a4280a51ad3ac
7
- data.tar.gz: b2b35b327d07736004e495567c90b0fd35c7a13db4999f247b0ebdcb824f1ee3b48bf83ca3d3b9516f06a12e91ebebc1aa1849f3018d8237d9fa5c605a3cc523
6
+ metadata.gz: 989fc6d673aeaf2830fc2afa00dfcf90904ea08592feb1365763193c80b04333acda1a1f79684aa071e4f6aec37f92bb8f988d8617150f2b443eec529c289224
7
+ data.tar.gz: d68800719b9475ba36ad6cd3857746568659bfa44f6d8295388911adcc31c0bd0f1af9b2b805f7cc6417c1ffd9deba7c4de0e8c9acd54b7fa679718cc320b915
@@ -1,36 +1,71 @@
1
1
  $(function(){
2
- $(document).delegate('.add_child','click', function() {
2
+ $(document).on('click', '.cnf-add-entry', function() {
3
+ // initialize options
3
4
  var association = $(this).attr('data-association');
4
- var template = $(this).attr('data-association-template');
5
- var child_templates = $(this).attr('data-child-template').split(' ');
6
- var target = $(this).attr('target');
7
- var regexp = new RegExp('new_' + association, 'g');
8
- var regexp2 = new RegExp('\\[tempid\\]', 'g');
9
- var regexp_child_template = new RegExp('_tempid_', 'g');
10
- var regexp_parent_new_field = new RegExp('new_' + association, 'g');
11
- var new_id = new Date().getTime();
12
- var Dest = (target == '') ? $(this).parent() : $('#'+target);
13
- Dest.append(window[ template ].replace(regexp, new_id).replace(regexp2, new_id));
14
- for(var index in child_templates)
15
- {
16
- child_template = child_templates[index];
17
- if(child_template != "")
18
- {
19
- body = window[child_template];
20
- child_script_tag = "<script> var " + child_template + " = '" + body + "' </script>";
21
- child_script_tag = child_script_tag.replace(regexp_child_template, "_" + new_id + "_")
22
- .replace(regexp_parent_new_field, new_id);
23
- Dest.append(child_script_tag.replace(regexp_child_template, "_" + new_id + "_"));
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
- $(document).trigger('coolNestedForms.childAdded');
42
+ // trigger event coolNestedForms.entryAdded
43
+ $(document).trigger('coolNestedForms.entryAdded');
44
+ // false to avoid errors
27
45
  return false;
28
46
  });
29
-
30
- $(document).delegate('.remove_child','click', function() {
31
- $(this).parent().children('.removable')[0].value = 1;
32
- $(this).parent().hide();
33
- $(document).trigger('coolNestedForms.childRemoved');
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
- def new_fields_template(f,association,options={})
4
- options[:object] ||= f.object.class.reflect_on_association(association).klass.new
5
- options[:partial] ||= association.to_s.singularize
6
- options[:template] ||= association.to_s
7
- options[:child_template_options] ||= []
8
- options[:f] ||= f
9
-
10
- child_tmpl = ""
11
- tmpl = content_tag(:div,:id =>"#{options[:template]}") do
12
- tmpl = f.fields_for(association,options[:object], :child_index => "new_#{association}") do |b|
13
- if options[:child_template_options].count > 0
14
- options[:child_template_options].each do |child|
15
- child_tmpl += new_fields_template(b,child[:association],child)
16
- end
17
- child_tmpl = child_tmpl.gsub( /\r?\n|\r/, ' ')
18
- end
19
- render(:partial=>options[:partial],:locals =>{:f => b})
20
- end
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
- tmpl = tmpl.gsub( /\r?\n|\r/, ' ')
24
- script = "<script> var #{options[:template]} = '#{tmpl.to_s}'; </script>"
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
- def add_child_button(name, association,target,association_template="",classes="",child_template="")
30
- association_template = association if association_template.blank?
31
- content_tag(:span,"<span>#{name}</span>".html_safe,
32
- :class => "add_child #{classes}",
33
- :style => "",
34
- :"data-association" => association,
35
- :"data-association-template" => association_template,
36
- :"data-child-template" => child_template,
37
- :id => "#{association_template}_button",
38
- :target => target)
39
- end
40
- def remove_child_button(name, classes="", inner_html="<span>Remove</span>")
41
- content_tag(:div,inner_html.html_safe,
42
- :style => "",
43
- :class => "remove_child #{classes}")
44
- end
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
@@ -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', '~> 5.1'
33
+ spec.add_runtime_dependency 'rails', '>= 4.0'
34
34
 
35
35
  spec.add_development_dependency "bundler"
36
36
  spec.add_development_dependency "rake"
@@ -1,3 +1,3 @@
1
1
  module CoolNestedForms
2
- VERSION = "1.0.2"
2
+ VERSION = "2.0.0"
3
3
  end
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: 1.0.2
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-08 00:00:00.000000000 Z
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: '5.1'
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: '5.1'
26
+ version: '4.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement