root / drupal7 / sites / all / modules / ctools / js / dependent.js @ 6e3ce7c2
1 | 85ad3d82 | Assos Assos | /**
|
---|---|---|---|
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 | 6e3ce7c2 | Assos Assos | * 'form_process_checkboxes' in the #process array, because the CTools process will
|
18 | 85ad3d82 | Assos Assos | * 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 | 6e3ce7c2 | Assos Assos | }; |
38 | 85ad3d82 | Assos Assos | |
39 | |||
40 | Drupal.CTools.dependent.autoAttach = function() { |
||
41 | // Clear active bindings and triggers.
|
||
42 | 219d19c4 | Assos Assos | for (var i in Drupal.CTools.dependent.activeTriggers) { |
43 | e4c061ad | Assos Assos | $(Drupal.CTools.dependent.activeTriggers[i]).unbind('change.ctools-dependent'); |
44 | 85ad3d82 | Assos Assos | } |
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 | 219d19c4 | Assos Assos | for (var id in Drupal.settings.CTools.dependent) { |
55 | 85ad3d82 | Assos Assos | // 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 | 219d19c4 | Assos Assos | for (var bind_id in Drupal.settings.CTools.dependent[id].values) { |
63 | 85ad3d82 | Assos Assos | // 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 | 219d19c4 | Assos Assos | if ($(trigger).length == 0) { |
91 | 85ad3d82 | Assos Assos | 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 | 136a805a | Assos Assos | // **This check determines if using a jQuery version 1.7 or newer which requires the use of the prop function instead of the attr function when not called on an attribute
|
101 | if ($().prop) { |
||
102 | var val = $(trigger).prop('checked') ? true : false; |
||
103 | } |
||
104 | else {
|
||
105 | var val = $(trigger).attr('checked') ? true : false; |
||
106 | } |
||
107 | 85ad3d82 | Assos Assos | |
108 | if (val) {
|
||
109 | $(trigger).siblings('label').removeClass('hidden-options').addClass('expanded-options'); |
||
110 | } |
||
111 | else {
|
||
112 | $(trigger).siblings('label').removeClass('expanded-options').addClass('hidden-options'); |
||
113 | } |
||
114 | |||
115 | break;
|
||
116 | default:
|
||
117 | var val = $(trigger).val(); |
||
118 | } |
||
119 | } |
||
120 | return val;
|
||
121 | 6e3ce7c2 | Assos Assos | }; |
122 | 85ad3d82 | Assos Assos | |
123 | var setChangeTrigger = function(trigger_id, bind_id) { |
||
124 | // Triggered when change() is clicked.
|
||
125 | var changeTrigger = function() { |
||
126 | var val = getValue(bind_id, trigger_id);
|
||
127 | |||
128 | if (val == null) { |
||
129 | return;
|
||
130 | } |
||
131 | |||
132 | 219d19c4 | Assos Assos | for (var i in Drupal.CTools.dependent.bindings[bind_id]) { |
133 | 85ad3d82 | Assos Assos | var id = Drupal.CTools.dependent.bindings[bind_id][i];
|
134 | // Fix numerous errors
|
||
135 | if (typeof id != 'string') { |
||
136 | continue;
|
||
137 | } |
||
138 | |||
139 | // This bit had to be rewritten a bit because two properties on the
|
||
140 | // same set caused the counter to go up and up and up.
|
||
141 | if (!Drupal.CTools.dependent.activeBindings[id]) {
|
||
142 | Drupal.CTools.dependent.activeBindings[id] = {}; |
||
143 | } |
||
144 | |||
145 | if (val != null && Drupal.CTools.dependent.inArray(Drupal.settings.CTools.dependent[id].values[bind_id], val)) { |
||
146 | Drupal.CTools.dependent.activeBindings[id][bind_id] = 'bind';
|
||
147 | } |
||
148 | else {
|
||
149 | delete Drupal.CTools.dependent.activeBindings[id][bind_id];
|
||
150 | } |
||
151 | |||
152 | var len = 0; |
||
153 | 219d19c4 | Assos Assos | for (var i in Drupal.CTools.dependent.activeBindings[id]) { |
154 | 85ad3d82 | Assos Assos | len++; |
155 | } |
||
156 | |||
157 | 136a805a | Assos Assos | var $original = $('#' + id); |
158 | if ($original.is('fieldset') || $original.is('textarea')) { |
||
159 | continue;
|
||
160 | 85ad3d82 | Assos Assos | } |
161 | |||
162 | 136a805a | Assos Assos | var object = $original.parent(); |
163 | |||
164 | 85ad3d82 | Assos Assos | if (Drupal.settings.CTools.dependent[id].type == 'disable') { |
165 | if (Drupal.settings.CTools.dependent[id].num <= len) {
|
||
166 | // Show if the element if criteria is matched
|
||
167 | 136a805a | Assos Assos | // **This check determines if using a jQuery version 1.7 or newer which requires the use of the prop function instead of the attr function when not called on an attribute
|
168 | if (typeof $().prop == 'function') { |
||
169 | object.prop('disabled', false); |
||
170 | object.addClass('dependent-options');
|
||
171 | object.children().prop('disabled', false); |
||
172 | } |
||
173 | else {
|
||
174 | object.attr('disabled', false); |
||
175 | object.addClass('dependent-options');
|
||
176 | object.children().attr('disabled', false); |
||
177 | } |
||
178 | 85ad3d82 | Assos Assos | } |
179 | else {
|
||
180 | // Otherwise hide. Use css rather than hide() because hide()
|
||
181 | // does not work if the item is already hidden, for example,
|
||
182 | // in a collapsed fieldset.
|
||
183 | 136a805a | Assos Assos | // **This check determines if using a jQuery version 1.7 or newer which requires the use of the prop function instead of the attr function when not called on an attribute
|
184 | if (typeof $().prop == 'function') { |
||
185 | object.prop('disabled', true); |
||
186 | object.children().prop('disabled', true); |
||
187 | } |
||
188 | else {
|
||
189 | object.attr('disabled', true); |
||
190 | object.children().attr('disabled', true); |
||
191 | } |
||
192 | 85ad3d82 | Assos Assos | } |
193 | } |
||
194 | else {
|
||
195 | if (Drupal.settings.CTools.dependent[id].num <= len) {
|
||
196 | // Show if the element if criteria is matched
|
||
197 | object.show(0);
|
||
198 | object.addClass('dependent-options');
|
||
199 | } |
||
200 | else {
|
||
201 | // Otherwise hide. Use css rather than hide() because hide()
|
||
202 | // does not work if the item is already hidden, for example,
|
||
203 | // in a collapsed fieldset.
|
||
204 | object.css('display', 'none'); |
||
205 | } |
||
206 | } |
||
207 | } |
||
208 | 6e3ce7c2 | Assos Assos | }; |
209 | 85ad3d82 | Assos Assos | |
210 | e4c061ad | Assos Assos | $(trigger_id).bind('change.ctools-dependent', function() { |
211 | 85ad3d82 | Assos Assos | // Trigger the internal change function
|
212 | // the attr('id') is used because closures are more confusing
|
||
213 | changeTrigger(trigger_id, bind_id); |
||
214 | }); |
||
215 | // Trigger initial reaction
|
||
216 | changeTrigger(trigger_id, bind_id); |
||
217 | 6e3ce7c2 | Assos Assos | }; |
218 | 85ad3d82 | Assos Assos | setChangeTrigger(trigger_id, bind_id); |
219 | } |
||
220 | } |
||
221 | 6e3ce7c2 | Assos Assos | }; |
222 | 85ad3d82 | Assos Assos | |
223 | Drupal.behaviors.CToolsDependent = { |
||
224 | attach: function (context) { |
||
225 | Drupal.CTools.dependent.autoAttach(); |
||
226 | |||
227 | // Really large sets of fields are too slow with the above method, so this
|
||
228 | // is a sort of hacked one that's faster but much less flexible.
|
||
229 | $("select.ctools-master-dependent") |
||
230 | .once('ctools-dependent')
|
||
231 | e4c061ad | Assos Assos | .bind('change.ctools-dependent', function() { |
232 | 85ad3d82 | Assos Assos | var val = $(this).val(); |
233 | if (val == 'all') { |
||
234 | $('.ctools-dependent-all').show(0); |
||
235 | } |
||
236 | else {
|
||
237 | $('.ctools-dependent-all').hide(0); |
||
238 | $('.ctools-dependent-' + val).show(0); |
||
239 | } |
||
240 | }) |
||
241 | e4c061ad | Assos Assos | .trigger('change.ctools-dependent');
|
242 | 85ad3d82 | Assos Assos | } |
243 | 6e3ce7c2 | Assos Assos | }; |
244 | 85ad3d82 | Assos Assos | })(jQuery); |