commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-old / webform / js / webform-admin.js
1 /**
2 * @file
3 * Webform node form interface enhancments.
4 */
5
6 (function ($) {
7
8 "use strict";
9
10 Drupal.behaviors.webformAdmin = {};
11 Drupal.behaviors.webformAdmin.attach = function (context) {
12 // On click or change, make a parent radio button selected.
13 Drupal.webform.setActive(context);
14 Drupal.webform.updateTemplate(context);
15 // Update the template select list upon changing a template.
16 // Select all link for file extensions.
17 Drupal.webform.selectCheckboxesLink(context);
18 // Enhance the normal tableselect.js file to support indentations.
19 Drupal.webform.tableSelectIndentation(context);
20 // Automatically download exports if available.
21 Drupal.webform.downloadExport(context);
22 // Enhancements for the conditionals administrative page.
23 Drupal.webform.conditionalAdmin(context);
24 // Trigger radio/checkbox change when label click automatically selected by
25 // browser.
26 Drupal.webform.radioLabelAutoClick(context);
27 };
28
29 Drupal.webform = Drupal.webform || {};
30
31 Drupal.webform.setActive = function (context) {
32 $('.webform-inline-radio', context).click(function (e) {
33 $(this).closest('.form-type-radio').find('input[type=radio]').webformProp('checked', true);
34 });
35 $('.webform-set-active', context).change(function (e) {
36 if ($(this).val()) {
37 $(this).closest('.form-type-radio').find('input[type=radio]').webformProp('checked', true);
38 }
39 e.preventDefault();
40 });
41
42 // Firefox improperly selects the parent radio button when clicking inside
43 // a label that contains an input field. The only way of preventing this
44 // currently is to remove the "for" attribute on the label.
45 // See https://bugzilla.mozilla.org/show_bug.cgi?id=213519.
46 if (navigator.userAgent.match(/Firefox/)) {
47 $('.webform-inline-radio', context).removeAttr('for');
48 }
49 };
50
51 // Update e-mail templates between default and custom.
52 Drupal.webform.updateTemplate = function (context) {
53 var defaultTemplate = $('#edit-templates-default').val();
54 var $templateSelect = $('#webform-template-fieldset select#edit-template-option', context);
55 var $templateTextarea = $('#webform-template-fieldset textarea:visible', context);
56
57 var updateTemplateSelect = function () {
58 if ($(this).val() == defaultTemplate) {
59 $templateSelect.val('default');
60 }
61 else {
62 $templateSelect.val('custom');
63 }
64 };
65
66 var updateTemplateText = function () {
67 if ($(this).val() == 'default' && $templateTextarea.val() != defaultTemplate) {
68 if (confirm(Drupal.settings.webform.revertConfirm)) {
69 $templateTextarea.val(defaultTemplate);
70 }
71 else {
72 $(this).val('custom');
73 }
74 }
75 };
76
77 $templateTextarea.keyup(updateTemplateSelect);
78 $templateSelect.change(updateTemplateText);
79 };
80
81 Drupal.webform.selectCheckboxesLink = function (context) {
82 function selectCheckboxes() {
83 var group = this.className.replace(/.*?webform-select-link-([^ ]*).*/, '$1');
84 var $checkboxes = $('.webform-select-group-' + group + ' input[type=checkbox]');
85 var reverseCheck = !$checkboxes[0].checked;
86 $checkboxes.each(function () {
87 this.checked = reverseCheck;
88 });
89 $checkboxes.trigger('change');
90 return false;
91 }
92 $('a.webform-select-link', context).click(selectCheckboxes);
93 };
94
95 Drupal.webform.tableSelectIndentation = function (context) {
96 var $tables = $('th.select-all', context).parents('table');
97 $tables.find('input.form-checkbox').change(function () {
98 var $rows = $(this).parents('table:first').find('tr');
99 var row = $(this).parents('tr:first').get(0);
100 var rowNumber = $rows.index(row);
101 var rowTotal = $rows.size();
102 var indentLevel = $(row).find('div.indentation').size();
103 for (var n = rowNumber + 1; n < rowTotal; n++) {
104 if ($rows.eq(n).find('div.indentation').size() <= indentLevel) {
105 break;
106 }
107 $rows.eq(n).find('input.form-checkbox').webformProp('checked', this.checked);
108 }
109 });
110 };
111
112 /**
113 * Attach behaviors for Webform results download page.
114 */
115 Drupal.webform.downloadExport = function (context) {
116 if (context === document && Drupal.settings && Drupal.settings.webformExport && document.cookie.match(/webform_export_info=1/)) {
117 window.location = Drupal.settings.webformExport;
118 delete Drupal.settings.webformExport;
119 }
120 };
121
122 /**
123 * Attach behaviors for Webform conditional administration.
124 */
125 Drupal.webform.conditionalAdmin = function (context) {
126 var $context = $(context);
127 // Bind to the entire form and allow events to bubble-up from elements. This
128 // saves a lot of processing when new conditions are added/removed.
129 $context.find('#webform-conditionals-ajax:not(.webform-conditional-processed)')
130 .addClass('webform-conditional-processed')
131 .bind('change', function (e) {
132
133 var $target = $(e.target);
134 if ($target.is('.webform-conditional-source select')) {
135 Drupal.webform.conditionalSourceChange.apply(e.target);
136 }
137
138 if ($target.is('.webform-conditional-operator select')) {
139 Drupal.webform.conditionalOperatorChange.apply(e.target);
140 }
141
142 if ($target.is('.webform-conditional-andor select')) {
143 Drupal.webform.conditionalAndOrChange.apply(e.target);
144 }
145
146 if ($target.is('.webform-conditional-action select')) {
147 Drupal.webform.conditionalActionChange.apply(e.target);
148 }
149 });
150
151 // Add event handlers to delete the entire row if the last rule or action is removed.
152 $context.find('.webform-conditional-rule-remove:not(.webform-conditional-processed)').bind('click', function () {
153 this.webformRemoveClass = '.webform-conditional-rule-remove';
154 window.setTimeout($.proxy(Drupal.webform.conditionalRemove, this), 100);
155 }).addClass('webform-conditional-processed');
156 $context.find('.webform-conditional-action-remove:not(.webform-conditional-processed)').bind('click', function () {
157 this.webformRemoveClass = '.webform-conditional-action-remove';
158 window.setTimeout($.proxy(Drupal.webform.conditionalRemove, this), 100);
159 }).addClass('webform-conditional-processed');
160
161 // Trigger default handlers on the source element, this in turn will trigger
162 // the operator handlers.
163 $context.find('.webform-conditional-source select').trigger('change');
164
165 // Trigger defaults handlers on the action element.
166 $context.find('.webform-conditional-action select').trigger('change');
167
168 // When adding a new table row, make it draggable and hide the weight column.
169 if ($context.is('tr.ajax-new-content') && $context.find('.webform-conditional').length === 1) {
170 Drupal.tableDrag['webform-conditionals-table'].makeDraggable($context[0]);
171 $context.find('.webform-conditional-weight').closest('td').addClass('tabledrag-hide');
172 if ($.cookie('Drupal.tableDrag.showWeight') !== '1') {
173 Drupal.tableDrag['webform-conditionals-table'].hideColumns();
174 }
175 $context.removeClass('ajax-new-content');
176 }
177 };
178
179 /**
180 * Event callback for the remove button next to an individual rule.
181 */
182 Drupal.webform.conditionalRemove = function () {
183 // See if there are any remaining rules in this element.
184 var rowCount = $(this).parents('.webform-conditional:first').find(this.webformRemoveClass).length;
185 if (rowCount <= 1) {
186 var $tableRow = $(this).parents('tr:first');
187 var $table = $('#webform-conditionals-table');
188 if ($tableRow.length && $table.length) {
189 $tableRow.remove();
190 Drupal.webform.restripeTable($table[0]);
191 }
192 }
193 };
194
195 /**
196 * Event callback to update the list of operators after a source change.
197 */
198 Drupal.webform.conditionalSourceChange = function () {
199 var source = $(this).val();
200 var dataType = Drupal.settings.webform.conditionalValues.sources[source]['data_type'];
201 var $operator = $(this).parents('.webform-conditional-rule:first').find('.webform-conditional-operator select');
202
203 // Store a the original list of all operators for all data types in the select
204 // list DOM element.
205 if (!$operator[0]['webformConditionalOriginal']) {
206 $operator[0]['webformConditionalOriginal'] = $operator[0].innerHTML;
207 }
208
209 // Reference the original list to create a new list matching the data type.
210 var $originalList = $($operator[0]['webformConditionalOriginal']);
211 var $newList = $originalList.filter('optgroup[label=' + dataType + ']');
212 var newHTML = $newList[0].innerHTML;
213
214 // Update the options and fire the change event handler on the list to update
215 // the value field, only if the options have changed. This avoids resetting
216 // existing selections.
217 if (newHTML != $operator.html()) {
218 $operator.html(newHTML);
219 }
220 // Trigger the change in case the source component changed from one select
221 // component to another.
222 $operator.trigger('change');
223
224 };
225
226 /**
227 * Event callback to update the value field after an operator change.
228 */
229 Drupal.webform.conditionalOperatorChange = function () {
230 var source = $(this).parents('.webform-conditional-rule:first').find('.webform-conditional-source select').val();
231 var dataType = Drupal.settings.webform.conditionalValues.sources[source]['data_type'];
232 var operator = $(this).val();
233 var $value = $(this).parents('.webform-conditional-rule:first').find('.webform-conditional-value');
234 var name = $value.find('input, select, textarea').attr('name');
235 var originalValue = false;
236
237 // Given the dataType and operator, we can determine the form key.
238 var formKey = Drupal.settings.webform.conditionalValues.operators[dataType][operator]['form'];
239 var formSource = typeof Drupal.settings.webform.conditionalValues.forms[formKey] == 'undefined' ? false : source;
240
241 // On initial request, save the default field as printed on the original page.
242 if (!$value[0]['webformConditionalOriginal']) {
243 $value[0]['webformConditionalOriginal'] = $value[0].innerHTML;
244 originalValue = $value.find('input:first').val();
245 }
246 // On changes to an existing operator, check if the form key is different
247 // (and any per-source form, such as a select option list) before replacing
248 // the form with an identical version.
249 else if ($value[0]['webformConditionalFormKey'] == formKey && $value[0]['webformConditionalFormSource'] == formSource) {
250 return;
251 }
252
253 // Store the current form key for checking the next time the operator changes.
254 $value[0]['webformConditionalFormKey'] = formKey;
255 $value[0]['webformConditionalFormSource'] = formSource;
256
257 // If using the default (a textfield), restore the original field.
258 if (formKey === 'default') {
259 $value[0].innerHTML = $value[0]['webformConditionalOriginal'];
260 }
261 // If the operator does not need a source value (i.e. is empty), hide it.
262 else if (formKey === false) {
263 $value[0].innerHTML = '<input type="text" value="" style="display: none;" >';
264 }
265 // If there is a per-source form for this operator (e.g. option lists), use
266 // the specialized value form.
267 else if (typeof Drupal.settings.webform.conditionalValues.forms[formKey] == 'object') {
268 $value[0].innerHTML = Drupal.settings.webform.conditionalValues.forms[formKey][source];
269 }
270 // Otherwise all the sources use a generic field (e.g. a text field).
271 else {
272 $value[0].innerHTML = Drupal.settings.webform.conditionalValues.forms[formKey];
273 }
274
275 // Set the name attribute to match the original placeholder field.
276 var $firstElement = $value.find('input, select, textarea').filter(':first');
277 $firstElement.attr('name', name);
278
279 if (originalValue) {
280 $firstElement.val(originalValue);
281 }
282 };
283
284 /**
285 * Event callback to make sure all group and/or operators match.
286 */
287 Drupal.webform.conditionalAndOrChange = function () {
288 var rid = this.getAttribute('data-rid');
289 var text = $(this).find('option:selected').text();
290 $(this).parents('.webform-conditional:first').find('.webform-conditional-andor div[data-rid="' + rid + '"]').text(text);
291 };
292
293 /**
294 * Event callback to show argument only for appropriate actions.
295 */
296 Drupal.webform.conditionalActionChange = function () {
297 var action = $(this).val();
298 var $argument = $(this).parents('.webform-conditional-condition:first').find('.webform-conditional-argument input');
299 var isShown = $argument.is(':visible');
300 switch (action) {
301 case 'show':
302 case 'require':
303 if (isShown) {
304 $argument.hide();
305 }
306 break;
307 case 'set':
308 if (!isShown) {
309 $argument.show();
310 }
311 break;
312 }
313 };
314
315 /**
316 * Triggers a change event when a label receives a click.
317 *
318 * When the browser automatically selects a radio button when it's label is
319 * clicked, the FAPI states jQuery code doesn't receive an event. This function
320 * ensures that automatically-selected radio buttons keep in sync with the
321 * FAPI states.
322 */
323 Drupal.webform.radioLabelAutoClick = function (context) {
324 $('label').once('webform-label').click(function () {
325 $(this).prev('input:radio').change();
326 });
327 };
328
329 /**
330 * Make a prop shim for jQuery < 1.9.
331 */
332 $.fn.webformProp = $.fn.webformProp || function (name, value) {
333 if (value) {
334 return $.fn.prop ? this.prop(name, true) : this.attr(name, true);
335 }
336 else {
337 return $.fn.prop ? this.prop(name, false) : this.removeAttr(name);
338 }
339 };
340
341 })(jQuery);