dynamic_fieldsets 0.1.18 → 0.1.19

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.
data/CHANGELOG CHANGED
@@ -1,7 +1,16 @@
1
1
  == unreleased changes
2
2
 
3
+ == 0.1.19
4
+ * Added auto clearing for selects boxes when they're hidden by their dependency actions
5
+ * js show watcher now hides unused questions
6
+ * fixed nested dependencies hiding on form page
7
+
8
+ == 0.1.18
9
+ * Removed inter-fieldset dependencies
10
+ * made it so fieldset child associations can only be made with 'children' of the same fieldset (frontend)
11
+
3
12
  == 0.1.17
4
- * Handling for nested fieldsets dependencies and for 'parallele' fieldset dependencies
13
+ * Handling for nested fieldsets dependencies and for 'parallel' fieldset dependencies
5
14
  * Wrote a js watcher for the show page, since previous solution is limited to a single fieldset.
6
15
  * Fixed problems that came up for AND and OR dependencies during more complex testing.
7
16
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.18
1
+ 0.1.19
@@ -148,10 +148,12 @@ module DynamicFieldsetsHelper
148
148
  def javascript_renderer(fsa, form_type)
149
149
  unless fsa.id == nil
150
150
  rendered_javascript = "<script type='text/javascript'>
151
+ var current_fsa = #{fsa.id};
151
152
  if ( typeof dynamic_fieldsets_dependencies == 'undefined' ){
152
- var dynamic_fieldsets_dependencies = #{fsa.dependency_child_hash.to_json};
153
+ var dynamic_fieldsets_dependencies = {};
154
+ dynamic_fieldsets_dependencies[current_fsa] = #{fsa.dependency_child_hash.to_json};
153
155
  } else {
154
- $.extend(dynamic_fieldsets_dependencies, #{fsa.dependency_child_hash.to_json});
156
+ dynamic_fieldsets_dependencies[current_fsa] = #{fsa.dependency_child_hash.to_json};
155
157
  }</script>"
156
158
 
157
159
  if form_type == "form"
@@ -1,5 +1,5 @@
1
1
  <tr>
2
- <td><%= f.select :fieldset_child_id, options_for_select(@fieldset_child.fieldset.fieldset_children.select { |x| x.child_type == "DynamicFieldsets::Field" && x.child.type != "DynamicFieldsets::InstructionField" }.collect { |c| [c.child.name, c.id]}, obj.fieldset_child_id)%></td>
2
+ <td><%= f.select :fieldset_child_id, options_for_select(@fieldset_child.fieldset.fieldset_children.select { |x| x != @fieldset_child && x.child_type == "DynamicFieldsets::Field" && x.child.type != "DynamicFieldsets::InstructionField" }.collect { |c| [c.child.name, c.id]}, obj.fieldset_child_id)%></td>
3
3
  <td><%= f.select :relationship, DynamicFieldsets::Dependency::RELATIONSHIP_LIST %></td>
4
4
  <td><%= f.text_field :value %></td>
5
5
  <td>
@@ -1,7 +1,6 @@
1
1
  <script type='text/javascript'>
2
2
 
3
- // The only inputs we care about are visible... not hidden
4
- var all_inputs = $(":input:not(:hidden)[id^=fsa]").add("p[id^='fsa']").add("textarea[id^='fsa']");
3
+ var all_inputs = $(":input[id^=fsa-]").add("p[id^=fsa-]").add("textarea[id^=fsa-]");
5
4
 
6
5
  //Return the fieldset child id for the input
7
6
  //This uniquely associated the fieldset child with the fieldset associator
@@ -100,46 +99,45 @@ function get_field_type(field) {
100
99
  //
101
100
  // the dependency information is stored in dynamic_fieldsets_dependencies
102
101
  all_inputs.change( function() {
103
- field = $(this);
104
- var type = get_field_type(field);
105
- var fieldset_child_id = get_fieldset_child_id(field, type);
106
-
107
- var user_inputs = {};
108
- $.each(all_inputs, function(index, input){
109
- var each_type = get_field_type($(input));
110
- var each_fieldset_child_id = get_fieldset_child_id($(input), each_type);
102
+ var field = $(this);
103
+ var type = get_field_type(field);
104
+ var fieldset_child_id = get_fieldset_child_id(field, type);
105
+ var fieldset_associator_id = get_fieldset_associator_id(field);
106
+
107
+ var user_inputs = {};
108
+ $.each(all_inputs, function(index, input){
109
+ var each_type = get_field_type($(input));
110
+ var input_id = $(input).attr('id');
111
+ if (each_type == 'checkbox' || each_type == 'radio'){
112
+ user_inputs[$(input).parent().parent().attr('id')] = get_input_value($(input), each_type);
113
+ } else{
114
+ user_inputs[input_id] = get_input_value($(input), each_type);
115
+ }
116
+ });
111
117
 
112
- //checking if field is used has multiple associators to make a unique entry for each in user_inputs
113
- if (each_fieldset_child_id in dynamic_fieldsets_dependencies) {
114
- $.each(dynamic_fieldsets_dependencies[each_fieldset_child_id], function(index2, group) {
115
- var each_fsa = $(input).attr('id').split("_")[0].split('-')[1]
116
- user_inputs[each_fsa+"-"+each_fieldset_child_id] = get_input_value($(input), each_type);
117
- });
118
- }
118
+ var dependencies_by_fsa = dynamic_fieldsets_dependencies[fieldset_associator_id];
119
+ if (fieldset_child_id in dependencies_by_fsa) {
120
+ $.each(dependencies_by_fsa[fieldset_child_id], function(index, group) {
121
+ update_dependency_group_for_fieldset_child(fieldset_child_id, fieldset_associator_id, group, user_inputs);
119
122
  });
120
-
121
- if (fieldset_child_id in dynamic_fieldsets_dependencies) {
122
- $.each(dynamic_fieldsets_dependencies[fieldset_child_id], function(index, group) {
123
- var current_fsa = field.attr('id').split("_")[0].split('-')[1]
124
- update_dependency_group_for_fieldset_child(fieldset_child_id, current_fsa, group, user_inputs);
125
- });
126
- }
123
+ }
127
124
  });
128
125
 
129
126
  // checks the clauses for a dependency group and runs the action
127
+ // fieldset_child_id: field being currently evaluated
128
+ // fsa_id: fsa it corresponds to
130
129
  // group: the dependency group
131
- // user_input: the input from the form
132
- function update_dependency_group_for_fieldset_child(fieldset_child_id, current_fsa, group, user_inputs) {
130
+ // user_inputs: array of inputs from all fields on page
131
+ function update_dependency_group_for_fieldset_child(fieldset_child_id, fsa_id, group, user_inputs) {
133
132
  var action = group['action'];
134
133
  var group_fsc_id = group['fieldset_child_id'];
135
- var group_field_id = group['field_id'];
136
- group_field = '<%= DynamicFieldsets.config.form_fieldset_associator_prefix %>' + current_fsa + '_' + '<%=DynamicFieldsets.config.form_field_prefix %>' + group_fsc_id;
137
- dependency_action(all_dependency_clauses_true(fieldset_child_id, current_fsa, group, user_inputs), action, group_field);
134
+ var group_field = '<%= DynamicFieldsets.config.form_fieldset_associator_prefix %>' + fsa_id + '_' + '<%=DynamicFieldsets.config.form_field_prefix %>' + group_fsc_id;
135
+ dependency_action(all_dependency_clauses_true(fieldset_child_id, fsa_id, group, user_inputs), action, group_field);
138
136
  }
139
137
 
140
- //all dependencies clauses are ANDed
141
- //the first one that is false makes this return false
142
- //only return true if all return true
138
+ // all dependencies clauses are ANDed
139
+ // the first one that is false makes this return false
140
+ // only return true if all return true
143
141
  function all_dependency_clauses_true(fieldset_child_id, fieldset_associator, group, user_inputs) {
144
142
  for(var key in group["clause"]) {
145
143
  var clause = group["clause"][key];
@@ -150,16 +148,16 @@ function all_dependency_clauses_true(fieldset_child_id, fieldset_associator, gro
150
148
  return true;
151
149
  }
152
150
 
153
- //The dependencies are ORed together
154
- //So as soon as one returns true, return true
155
- //Only return false if all are false
156
- //It looks to see what dependencies inside the clause should actually be tested (AU 08-07-13)
157
- // If dependency doesn't match current field, it looks up the correct stored input to compare
151
+ // The dependencies are ORed together
152
+ // So as soon as one returns true, return true
153
+ // Only return false if all are false
154
+ // It looks to see what dependencies inside the clause should actually be tested (AU 08-07-13)
155
+ // If dependency doesn't match current field, it looks up the correct stored input to compare
158
156
  function at_least_one_dependency_true(clause, user_inputs, fieldset_associator) {
159
157
  for(var key in clause) {
160
158
  var dependency = clause[key];
161
159
  var fieldset_child_id = dependency["fieldset_child_id"];
162
- if( evaluate_dependency(user_inputs[fieldset_associator+"-"+fieldset_child_id], dependency["relationship"], dependency["value"]) ){
160
+ if( evaluate_dependency(user_inputs["fsa-"+fieldset_associator+"_field-"+fieldset_child_id], dependency["relationship"], dependency["value"]) ){
163
161
  return true;
164
162
  }
165
163
  }
@@ -227,11 +225,11 @@ function dependency_action(success_flag, action, group_field) {
227
225
  }
228
226
  };
229
227
 
230
- //clears fields that are being hidden
228
+ // clears fields that are being hidden
231
229
  function clear_unused_field(group_field) {
232
230
  var fields = $('[id$='+group_field+'] :input');
233
231
  fields.each( function(index, field) {
234
- type = get_field_type($(field));
232
+ var type = get_field_type($(field));
235
233
  switch(type)
236
234
  {
237
235
  case 'text':
@@ -244,15 +242,18 @@ function clear_unused_field(group_field) {
244
242
  }
245
243
  case 'select':
246
244
  case 'multi-select':
245
+ $(field).prop("selectedIndex",0);
247
246
  }
248
247
  });
249
248
  };
250
249
 
251
- //looks through dependency hash to find dependent fields that may need to be hidden (AU 08-07-13)
250
+ // looks through dependency hash to find dependent fields that may need to be hidden (AU 08-07-13)
252
251
  function nested_dependencies(success_flag, action, group_field) {
252
+ var fsa = group_field.split("_")[0].split("-")[1];
253
253
  var dependent_on = group_field.split("-").pop();
254
- for( var key in dynamic_fieldsets_dependencies ) {
255
- var child = dynamic_fieldsets_dependencies[key];
254
+ var dependencies_by_fieldset = dynamic_fieldsets_dependencies[fsa];
255
+ for( var key in dependencies_by_fieldset ) {
256
+ var child = dependencies_by_fieldset[key];
256
257
  for( var keyg in child ) {
257
258
  var group_search = child[keyg];
258
259
  for( var keyc in group_search["clause"] ) {
@@ -261,11 +262,8 @@ function nested_dependencies(success_flag, action, group_field) {
261
262
  var dependency = clause[keyd];
262
263
  //select dependent by comparing who the dependency belongs to
263
264
  if ( dependency["fieldset_child_id"] == dependent_on ) {
264
- var fsa = group_field.split("_")[0];
265
- var field = group_field.split("_")[1];
266
- var dependent_id = field.replace(dependent_on, group_search["fieldset_child_id"]);
267
- var full_dep_id = fsa+"_"+dependent_id;
268
- dependency_action(success_flag, action, [full_dep_id]);
265
+ var dependent_id = group_field.replace(dependent_on, group_search["fieldset_child_id"]);
266
+ dependency_action(success_flag, action, dependent_id);
269
267
  }
270
268
  }
271
269
  }
@@ -1,67 +1,80 @@
1
1
  <script type='text/javascript'>
2
2
 
3
3
  function hide_fields(){
4
- var all_divs = $("div :not(:hidden)[id^=fsa]").add("p[id^='fsa']");
4
+ var all_divs = $("div :not(:hidden)[id^=fsa-"+current_fsa+"]").add("p[id^='fsa-"+current_fsa+"']");
5
5
  var values = {};
6
6
  $.each(all_divs, function(index, div){
7
7
  var div_id = $(div).attr('id');
8
- var fieldset_child_id = div_id.substring(div_id.length-1);
9
- var fsa_id = div_id.split("_")[0].split("-")[1];
10
8
 
11
9
  if($(div).is("p")){
12
- values[fieldset_child_id] = div.innerHTML;
10
+ values[div_id] = div.innerHTML;
13
11
  } else {
14
- if($(div).attr('type') == 'single'){
15
- values[fieldset_child_id] = $(div).find('span').find('span').text();
12
+ if($(div).attr('type') == "single"){
13
+ values[div_id] = $(div).find('span').find('span').text();
16
14
  } else {
17
- values[fieldset_child_id] = $(div).find('li').map(function(index, li){
18
- return $(div).find('span').find('span').text();
15
+ values[div_id] = $(div).find('li').map( function(index,li){
16
+ return $(li).find('span').text();
19
17
  });
20
18
  }
21
19
  }
20
+ });
22
21
 
23
- var dependency_group = dynamic_fieldsets_dependencies[fieldset_child_id];
24
- if((typeof dependency_group) != "undefined"){
22
+ $.each(all_divs, function(index, div){
23
+ var div_id = $(div).attr('id');
24
+ var fieldset_child_id = div_id.split("_")[1].split("-")[1];
25
+ var dependency_group = dynamic_fieldsets_dependencies[current_fsa][fieldset_child_id];
26
+ if( typeof dependency_group != "undefined" ){
25
27
  $.each(dependency_group, function(index, group){
26
- var fieldset_associator_ids = group['fieldset_associators'];
27
- evaluate_dependencies(fieldset_child_id, group, values, fieldset_associator_ids);
28
- })
28
+ process_dependencies(div_id, group, values);
29
+ });
29
30
  }
30
31
  });
31
32
  }
32
33
 
33
- function evaluate_dependencies(fieldset_child_id, group, values, fieldset_associator_ids) {
34
+ // checks dependency clauses in a dependency group and determines what action to take
35
+ // current_div: the div we are currently processing
36
+ // group: the dependency group passed from dynamic_fieldsets_dependencies
37
+ // values: the values stored for each field indexed by div id attributes
38
+ function process_dependencies(current_div, group, values) {
34
39
  var action = group['action'];
35
40
  var group_fsc_id = group['fieldset_child_id'];
36
- var group_field_id = group['field_id'];
37
- var group_fields = [];
38
- $.each(fieldset_associator_ids, function(index, fsa_id) {
39
- group_fields[index] = '<%= DynamicFieldsets.config.form_fieldset_associator_prefix %>' + fsa_id + '_' + '<%=DynamicFieldsets.config.form_field_prefix %>' + group_fsc_id;
40
- });
41
- dependency_action(all_dependency_clauses_true(fieldset_child_id, group, values), action, group_fields, 0 );
41
+ var div_id = '<%= DynamicFieldsets.config.form_fieldset_associator_prefix %>' + current_fsa + '_' + '<%=DynamicFieldsets.config.form_field_prefix %>' + group_fsc_id;
42
+ var fieldset_associator_id = div_id.split("_")[0].split("-")[1];
43
+ dependency_action(current_div, all_dependency_clauses_true(fieldset_associator_id, group, values), action, div_id);
42
44
  }
43
45
 
44
- function all_dependency_clauses_true(fieldset_child_id, group, values) {
46
+ // all dependencies are in AND relations so all must be true
47
+ function all_dependency_clauses_true(fsa_id, group, values) {
45
48
  for(var key in group["clause"]) {
46
49
  var clause = group["clause"][key];
47
- if(!at_least_one_dependency_true(clause, values)) {
50
+ if(!at_least_one_dependency_true(fsa_id, clause, values)) {
48
51
  return false;
49
52
  }
50
53
  }
51
54
  return true;
52
55
  }
53
56
 
54
- function at_least_one_dependency_true(clause, values) {
57
+ // all dependencies within clause are in OR relationship,
58
+ // only one needs to be true, to return true for the clause
59
+ function at_least_one_dependency_true(fsa_id, clause, values) {
55
60
  for(var key in clause) {
56
61
  var dependency = clause[key];
57
- var fieldset_child_id = dependency["fieldset_child_id"];
58
- if( evaluate_dependency(values[fieldset_child_id], dependency["relationship"], dependency["value"]) ){
62
+ var fsc_id = dependency["fieldset_child_id"];
63
+ var full_field = '<%= DynamicFieldsets.config.form_fieldset_associator_prefix %>' + fsa_id + '_' + '<%=DynamicFieldsets.config.form_field_prefix %>' + fsc_id;
64
+ // does not bother to evaluate the values on fields that have been previosuly hidden
65
+ // CHANGE if there is a question that has dependents above it in order
66
+ // a different way of skipping evaluation of hidden fields will be needed
67
+ if( evaluate_dependency(values[full_field], dependency["relationship"], dependency["value"])
68
+ && $('#'+full_field).attr('style') != 'display: none;'){
59
69
  return true;
60
70
  }
61
71
  }
62
72
  return false;
63
73
  }
64
74
 
75
+ // looks at field values collected from divs and compares them to the values set to trigger dependencies
76
+ // relationship: how the given value must match expected values
77
+ // returns true if user_value and stored_value match correctly
65
78
  function evaluate_dependency(user_value, relationship, stored_value) {
66
79
  switch(relationship)
67
80
  {
@@ -82,47 +95,54 @@ function evaluate_dependency(user_value, relationship, stored_value) {
82
95
  }
83
96
  };
84
97
 
85
- function dependency_action(success_flag, action, group_fields, counter) {
86
- $.each(group_fields, function(index, group_field){
87
- if (success_flag){
88
- switch(action)
89
- {
90
- case 'show':
91
- $('[id$=' + group_field +']').show();
92
- case 'enable':
93
- $('#' + group_field + ' :input').removeAttr('disabled');
94
- }
95
-
96
- } else {
97
- switch(action)
98
- {
99
- case 'show':
100
- $('[id$=' + group_field +']').hide();
101
- case 'enable':
102
- $('#' + group_field + ' :input').attr('disabled', true);
103
- }
104
-
105
- //save from infinite recursion, only goes as deep as there are dependency groups
106
- if( counter < Object.keys(dynamic_fieldsets_dependencies).length ) {
107
- nested_dependencies(success_flag, action, group_field, counter);
108
- }
98
+ // enacts selected action on objects according to dependency
99
+ //
100
+ // current_div: div whose values are being read
101
+ // success_flag: whether the values was as expected in the dependency
102
+ // div_id: div on which action will be made according to dependency to current_div
103
+ //
104
+ // this function calls nested_dependencies whenever a field is hidden to hide any others dependent on it
105
+ function dependency_action(current_div, success_flag, action, div_id) {
106
+ if (success_flag){
107
+ switch(action)
108
+ {
109
+ case 'show':
110
+ $('[id$=' + div_id +']').show();
111
+ case 'enable':
112
+ $('#' + div_id + ' :input').removeAttr('disabled');
109
113
  }
110
- });
114
+ } else {
115
+ switch(action)
116
+ {
117
+ case 'show':
118
+ $('[id$=' + div_id +']').hide();
119
+ case 'enable':
120
+ $('#' + div_id + ' :input').attr('disabled', true);
121
+ }
122
+ nested_dependencies(success_flag, action, div_id);
123
+ }
111
124
  };
112
125
 
113
- function nested_dependencies(success_flag, action, group_field, counter) {
114
- var dependent_on = group_field.split("-").pop();
115
- for( var key in dynamic_fieldsets_dependencies ) {
116
- var child = dynamic_fieldsets_dependencies[key]
126
+ // looks through dependency hash to find dependent fields that should be hidden when current one is
127
+ //
128
+ // div_id: the div that was just hidden during the previous dependency evaluation
129
+ //
130
+ // this function ends up either making a call to hide another field through dependency_action
131
+ // or does nothing when the div it's evaluating has no dependents
132
+ function nested_dependencies(success_flag, action, div_id) {
133
+ var dependent_on = div_id.split("-").pop();
134
+ for( var key in dynamic_fieldsets_dependencies[current_fsa] ) {
135
+ var child = dynamic_fieldsets_dependencies[current_fsa][key]
117
136
  for( var keyg in child ) {
118
137
  var group_search = child[keyg];
119
138
  for( var keyc in group_search["clause"] ) {
120
139
  var clause = group_search["clause"][keyc];
121
140
  for( var keyd in clause ) {
122
141
  var dependency = clause[keyd];
142
+ //select dependent by comparing who the dependency belongs to
123
143
  if ( dependency["fieldset_child_id"] == dependent_on ) {
124
- var dependent_id = group_field.replace(dependent_on, group_search["fieldset_child_id"])
125
- dependency_action(success_flag, action, [dependent_id], counter+1);
144
+ var dependent_id = div_id.replace(dependent_on, group_search["fieldset_child_id"])
145
+ dependency_action(div_id, success_flag, action, dependent_id);
126
146
  }
127
147
  }
128
148
  }
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "dynamic_fieldsets"
8
- s.version = "0.1.18"
8
+ s.version = "0.1.19"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jeremiah Hemphill", "Ethan Pemble", "John Carter"]
12
- s.date = "2013-09-20"
12
+ s.date = "2013-10-22"
13
13
  s.description = "Dynamic fieldsets for rails controllers"
14
14
  s.email = "jeremiah@cloudspace.com"
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamic_fieldsets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.18
4
+ version: 0.1.19
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-09-20 00:00:00.000000000 Z
14
+ date: 2013-10-22 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rails
@@ -523,7 +523,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
523
523
  version: '0'
524
524
  segments:
525
525
  - 0
526
- hash: -1294392816585476854
526
+ hash: -3951729081308817073
527
527
  required_rubygems_version: !ruby/object:Gem::Requirement
528
528
  none: false
529
529
  requirements: