Projet

Général

Profil

Paste
Télécharger (13,3 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / webform / js / webform-admin.js @ 651307cd

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);