3 * Webform node form interface enhancments.
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
26 Drupal
.webform
.radioLabelAutoClick(context
);
29 Drupal
.webform
= Drupal
.webform
|| {};
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);
35 $('.webform-set-active', context
).change(function (e
) {
37 $(this).closest('.form-type-radio').find('input[type=radio]').webformProp('checked', true);
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');
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
);
57 var updateTemplateSelect = function () {
58 if ($(this).val() == defaultTemplate
) {
59 $templateSelect
.val('default');
62 $templateSelect
.val('custom');
66 var updateTemplateText = function () {
67 if ($(this).val() == 'default' && $templateTextarea
.val() != defaultTemplate
) {
68 if (confirm(Drupal
.settings
.webform
.revertConfirm
)) {
69 $templateTextarea
.val(defaultTemplate
);
72 $(this).val('custom');
77 $templateTextarea
.keyup(updateTemplateSelect
);
78 $templateSelect
.change(updateTemplateText
);
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
;
89 $checkboxes
.trigger('change');
92 $('a.webform-select-link', context
).click(selectCheckboxes
);
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
) {
107 $rows
.eq(n
).find('input.form-checkbox').webformProp('checked', this.checked
);
113 * Attach behaviors for Webform results download page.
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
;
123 * Attach behaviors for Webform conditional administration.
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
) {
133 var $target
= $(e
.target
);
134 if ($target
.is('.webform-conditional-source select')) {
135 Drupal
.webform
.conditionalSourceChange
.apply(e
.target
);
138 if ($target
.is('.webform-conditional-operator select')) {
139 Drupal
.webform
.conditionalOperatorChange
.apply(e
.target
);
142 if ($target
.is('.webform-conditional-andor select')) {
143 Drupal
.webform
.conditionalAndOrChange
.apply(e
.target
);
146 if ($target
.is('.webform-conditional-action select')) {
147 Drupal
.webform
.conditionalActionChange
.apply(e
.target
);
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');
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');
165 // Trigger defaults handlers on the action element.
166 $context
.find('.webform-conditional-action select').trigger('change');
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();
175 $context
.removeClass('ajax-new-content');
180 * Event callback for the remove button next to an individual rule.
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
;
186 var $tableRow
= $(this).parents('tr:first');
187 var $table
= $('#webform-conditionals-table');
188 if ($tableRow
.length
&& $table
.length
) {
190 Drupal
.webform
.restripeTable($table
[0]);
196 * Event callback to update the list of operators after a source change.
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');
203 // Store a the original list of all operators for all data types in the select
205 if (!$operator
[0]['webformConditionalOriginal']) {
206 $operator
[0]['webformConditionalOriginal'] = $operator
[0].innerHTML
;
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
;
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
);
220 // Trigger the change in case the source component changed from one select
221 // component to another.
222 $operator
.trigger('change');
227 * Event callback to update the value field after an operator change.
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;
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
;
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();
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
) {
253 // Store the current form key for checking the next time the operator changes.
254 $value
[0]['webformConditionalFormKey'] = formKey
;
255 $value
[0]['webformConditionalFormSource'] = formSource
;
257 // If using the default (a textfield), restore the original field.
258 if (formKey
=== 'default') {
259 $value
[0].innerHTML
= $value
[0]['webformConditionalOriginal'];
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;" >';
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
];
270 // Otherwise all the sources use a generic field (e.g. a text field).
272 $value
[0].innerHTML
= Drupal
.settings
.webform
.conditionalValues
.forms
[formKey
];
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
);
280 $firstElement
.val(originalValue
);
285 * Event callback to make sure all group and/or operators match.
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
);
294 * Event callback to show argument only for appropriate actions.
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');
316 * Triggers a change event when a label receives a click.
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
323 Drupal
.webform
.radioLabelAutoClick = function (context
) {
324 $('label').once('webform-label').click(function () {
325 $(this).prev('input:radio').change();
330 * Make a prop shim for jQuery < 1.9.
332 $.fn
.webformProp
= $.fn
.webformProp
|| function (name
, value
) {
334 return $.fn
.prop
? this.prop(name
, true) : this.attr(name
, true);
337 return $.fn
.prop
? this.prop(name
, false) : this.removeAttr(name
);