Mercurial > hg > rr-repo
comparison sites/all/modules/ctools/js/dependent.js @ 0:ff03f76ab3fe
initial version
author | danieleb <danielebarchiesi@me.com> |
---|---|
date | Wed, 21 Aug 2013 18:51:11 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ff03f76ab3fe |
---|---|
1 /** | |
2 * @file | |
3 * Provides dependent visibility for form items in CTools' ajax forms. | |
4 * | |
5 * To your $form item definition add: | |
6 * - '#process' => array('ctools_process_dependency'), | |
7 * - '#dependency' => array('id-of-form-item' => array(list, of, values, that, | |
8 * make, this, item, show), | |
9 * | |
10 * Special considerations: | |
11 * - Radios are harder. Because Drupal doesn't give radio groups individual IDs, | |
12 * use 'radio:name-of-radio'. | |
13 * | |
14 * - Checkboxes don't have their own id, so you need to add one in a div | |
15 * around the checkboxes via #prefix and #suffix. You actually need to add TWO | |
16 * divs because it's the parent that gets hidden. Also be sure to retain the | |
17 * 'expand_checkboxes' in the #process array, because the CTools process will | |
18 * override it. | |
19 */ | |
20 | |
21 (function ($) { | |
22 Drupal.CTools = Drupal.CTools || {}; | |
23 Drupal.CTools.dependent = {}; | |
24 | |
25 Drupal.CTools.dependent.bindings = {}; | |
26 Drupal.CTools.dependent.activeBindings = {}; | |
27 Drupal.CTools.dependent.activeTriggers = []; | |
28 | |
29 Drupal.CTools.dependent.inArray = function(array, search_term) { | |
30 var i = array.length; | |
31 while (i--) { | |
32 if (array[i] == search_term) { | |
33 return true; | |
34 } | |
35 } | |
36 return false; | |
37 } | |
38 | |
39 | |
40 Drupal.CTools.dependent.autoAttach = function() { | |
41 // Clear active bindings and triggers. | |
42 for (i in Drupal.CTools.dependent.activeTriggers) { | |
43 $(Drupal.CTools.dependent.activeTriggers[i]).unbind('change'); | |
44 } | |
45 Drupal.CTools.dependent.activeTriggers = []; | |
46 Drupal.CTools.dependent.activeBindings = {}; | |
47 Drupal.CTools.dependent.bindings = {}; | |
48 | |
49 if (!Drupal.settings.CTools) { | |
50 return; | |
51 } | |
52 | |
53 // Iterate through all relationships | |
54 for (id in Drupal.settings.CTools.dependent) { | |
55 // Test to make sure the id even exists; this helps clean up multiple | |
56 // AJAX calls with multiple forms. | |
57 | |
58 // Drupal.CTools.dependent.activeBindings[id] is a boolean, | |
59 // whether the binding is active or not. Defaults to no. | |
60 Drupal.CTools.dependent.activeBindings[id] = 0; | |
61 // Iterate through all possible values | |
62 for(bind_id in Drupal.settings.CTools.dependent[id].values) { | |
63 // This creates a backward relationship. The bind_id is the ID | |
64 // of the element which needs to change in order for the id to hide or become shown. | |
65 // The id is the ID of the item which will be conditionally hidden or shown. | |
66 // Here we're setting the bindings for the bind | |
67 // id to be an empty array if it doesn't already have bindings to it | |
68 if (!Drupal.CTools.dependent.bindings[bind_id]) { | |
69 Drupal.CTools.dependent.bindings[bind_id] = []; | |
70 } | |
71 // Add this ID | |
72 Drupal.CTools.dependent.bindings[bind_id].push(id); | |
73 // Big long if statement. | |
74 // Drupal.settings.CTools.dependent[id].values[bind_id] holds the possible values | |
75 | |
76 if (bind_id.substring(0, 6) == 'radio:') { | |
77 var trigger_id = "input[name='" + bind_id.substring(6) + "']"; | |
78 } | |
79 else { | |
80 var trigger_id = '#' + bind_id; | |
81 } | |
82 | |
83 Drupal.CTools.dependent.activeTriggers.push(trigger_id); | |
84 | |
85 if ($(trigger_id).attr('type') == 'checkbox') { | |
86 $(trigger_id).siblings('label').addClass('hidden-options'); | |
87 } | |
88 | |
89 var getValue = function(item, trigger) { | |
90 if ($(trigger).size() == 0) { | |
91 return null; | |
92 } | |
93 | |
94 if (item.substring(0, 6) == 'radio:') { | |
95 var val = $(trigger + ':checked').val(); | |
96 } | |
97 else { | |
98 switch ($(trigger).attr('type')) { | |
99 case 'checkbox': | |
100 var val = $(trigger).attr('checked') ? true : false; | |
101 | |
102 if (val) { | |
103 $(trigger).siblings('label').removeClass('hidden-options').addClass('expanded-options'); | |
104 } | |
105 else { | |
106 $(trigger).siblings('label').removeClass('expanded-options').addClass('hidden-options'); | |
107 } | |
108 | |
109 break; | |
110 default: | |
111 var val = $(trigger).val(); | |
112 } | |
113 } | |
114 return val; | |
115 } | |
116 | |
117 var setChangeTrigger = function(trigger_id, bind_id) { | |
118 // Triggered when change() is clicked. | |
119 var changeTrigger = function() { | |
120 var val = getValue(bind_id, trigger_id); | |
121 | |
122 if (val == null) { | |
123 return; | |
124 } | |
125 | |
126 for (i in Drupal.CTools.dependent.bindings[bind_id]) { | |
127 var id = Drupal.CTools.dependent.bindings[bind_id][i]; | |
128 // Fix numerous errors | |
129 if (typeof id != 'string') { | |
130 continue; | |
131 } | |
132 | |
133 // This bit had to be rewritten a bit because two properties on the | |
134 // same set caused the counter to go up and up and up. | |
135 if (!Drupal.CTools.dependent.activeBindings[id]) { | |
136 Drupal.CTools.dependent.activeBindings[id] = {}; | |
137 } | |
138 | |
139 if (val != null && Drupal.CTools.dependent.inArray(Drupal.settings.CTools.dependent[id].values[bind_id], val)) { | |
140 Drupal.CTools.dependent.activeBindings[id][bind_id] = 'bind'; | |
141 } | |
142 else { | |
143 delete Drupal.CTools.dependent.activeBindings[id][bind_id]; | |
144 } | |
145 | |
146 var len = 0; | |
147 for (i in Drupal.CTools.dependent.activeBindings[id]) { | |
148 len++; | |
149 } | |
150 | |
151 var object = $('#' + id + '-wrapper'); | |
152 if (!object.size()) { | |
153 // Some elements can't use the parent() method or they can | |
154 // damage things. They are guaranteed to have wrappers but | |
155 // only if dependent.inc provided them. This check prevents | |
156 // problems when multiple AJAX calls cause settings to build | |
157 // up. | |
158 var $original = $('#' + id); | |
159 if ($original.is('fieldset') || $original.is('textarea')) { | |
160 continue; | |
161 } | |
162 | |
163 object = $('#' + id).parent(); | |
164 } | |
165 | |
166 if (Drupal.settings.CTools.dependent[id].type == 'disable') { | |
167 if (Drupal.settings.CTools.dependent[id].num <= len) { | |
168 // Show if the element if criteria is matched | |
169 object.attr('disabled', false); | |
170 object.addClass('dependent-options'); | |
171 object.children().attr('disabled', false); | |
172 } | |
173 else { | |
174 // Otherwise hide. Use css rather than hide() because hide() | |
175 // does not work if the item is already hidden, for example, | |
176 // in a collapsed fieldset. | |
177 object.attr('disabled', true); | |
178 object.children().attr('disabled', true); | |
179 } | |
180 } | |
181 else { | |
182 if (Drupal.settings.CTools.dependent[id].num <= len) { | |
183 // Show if the element if criteria is matched | |
184 object.show(0); | |
185 object.addClass('dependent-options'); | |
186 } | |
187 else { | |
188 // Otherwise hide. Use css rather than hide() because hide() | |
189 // does not work if the item is already hidden, for example, | |
190 // in a collapsed fieldset. | |
191 object.css('display', 'none'); | |
192 } | |
193 } | |
194 } | |
195 } | |
196 | |
197 $(trigger_id).change(function() { | |
198 // Trigger the internal change function | |
199 // the attr('id') is used because closures are more confusing | |
200 changeTrigger(trigger_id, bind_id); | |
201 }); | |
202 // Trigger initial reaction | |
203 changeTrigger(trigger_id, bind_id); | |
204 } | |
205 setChangeTrigger(trigger_id, bind_id); | |
206 } | |
207 } | |
208 } | |
209 | |
210 Drupal.behaviors.CToolsDependent = { | |
211 attach: function (context) { | |
212 Drupal.CTools.dependent.autoAttach(); | |
213 | |
214 // Really large sets of fields are too slow with the above method, so this | |
215 // is a sort of hacked one that's faster but much less flexible. | |
216 $("select.ctools-master-dependent") | |
217 .once('ctools-dependent') | |
218 .change(function() { | |
219 var val = $(this).val(); | |
220 if (val == 'all') { | |
221 $('.ctools-dependent-all').show(0); | |
222 } | |
223 else { | |
224 $('.ctools-dependent-all').hide(0); | |
225 $('.ctools-dependent-' + val).show(0); | |
226 } | |
227 }) | |
228 .trigger('change'); | |
229 } | |
230 } | |
231 })(jQuery); |