dynamic_fieldsets 0.1.18 → 0.1.19

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