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