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