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 +10 -1
- data/VERSION +1 -1
- data/app/helpers/dynamic_fieldsets_helper.rb +4 -2
- data/app/views/dynamic_fieldsets/fieldset_children/_dependency_fields.html.erb +1 -1
- data/app/views/dynamic_fieldsets/shared/_form_javascript_watcher.html.erb +46 -48
- data/app/views/dynamic_fieldsets/shared/_show_javascript_watcher.html.erb +76 -56
- data/dynamic_fieldsets.gemspec +2 -2
- metadata +3 -3
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 '
|
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.
|
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 =
|
153
|
+
var dynamic_fieldsets_dependencies = {};
|
154
|
+
dynamic_fieldsets_dependencies[current_fsa] = #{fsa.dependency_child_hash.to_json};
|
153
155
|
} else {
|
154
|
-
|
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
|
-
|
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
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
-
//
|
132
|
-
function update_dependency_group_for_fieldset_child(fieldset_child_id,
|
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
|
136
|
-
|
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
|
-
//
|
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
|
-
|
255
|
-
|
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
|
265
|
-
|
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[
|
10
|
+
values[div_id] = div.innerHTML;
|
13
11
|
} else {
|
14
|
-
if($(div).attr('type') ==
|
15
|
-
values[
|
12
|
+
if($(div).attr('type') == "single"){
|
13
|
+
values[div_id] = $(div).find('span').find('span').text();
|
16
14
|
} else {
|
17
|
-
values[
|
18
|
-
return $(
|
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
|
-
|
24
|
-
|
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
|
-
|
27
|
-
|
28
|
-
})
|
28
|
+
process_dependencies(div_id, group, values);
|
29
|
+
});
|
29
30
|
}
|
30
31
|
});
|
31
32
|
}
|
32
33
|
|
33
|
-
|
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
|
37
|
-
var
|
38
|
-
|
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
|
-
|
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
|
-
|
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
|
58
|
-
|
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
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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 =
|
125
|
-
dependency_action(success_flag, action,
|
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
|
}
|
data/dynamic_fieldsets.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "dynamic_fieldsets"
|
8
|
-
s.version = "0.1.
|
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-
|
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.
|
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-
|
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: -
|
526
|
+
hash: -3951729081308817073
|
527
527
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
528
528
|
none: false
|
529
529
|
requirements:
|