Projet

Général

Profil

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

root / drupal7 / sites / all / modules / webform / js / webform.js @ 27370441

1
/**
2
 * @file
3
 * JavaScript behaviors for the front-end display of webforms.
4
 */
5

    
6
(function ($) {
7

    
8
  "use strict";
9

    
10
  Drupal.behaviors.webform = Drupal.behaviors.webform || {};
11

    
12
  Drupal.behaviors.webform.attach = function (context) {
13
    // Calendar datepicker behavior.
14
    Drupal.webform.datepicker(context);
15

    
16
    // Conditional logic.
17
    if (Drupal.settings.webform && Drupal.settings.webform.conditionals) {
18
      Drupal.webform.conditional(context);
19
    }
20
  };
21

    
22
  Drupal.webform = Drupal.webform || {};
23

    
24
  Drupal.webform.datepicker = function (context) {
25
    $('div.webform-datepicker').each(function () {
26
      var $webformDatepicker = $(this);
27
      var $calendar = $webformDatepicker.find('input.webform-calendar');
28

    
29
      // Ensure the page we're on actually contains a datepicker.
30
      if ($calendar.length == 0) {
31
        return;
32
      }
33

    
34
      var startDate = $calendar[0].className.replace(/.*webform-calendar-start-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-');
35
      var endDate = $calendar[0].className.replace(/.*webform-calendar-end-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-');
36
      var firstDay = $calendar[0].className.replace(/.*webform-calendar-day-(\d).*/, '$1');
37
      // Convert date strings into actual Date objects.
38
      startDate = new Date(startDate[0], startDate[1] - 1, startDate[2]);
39
      endDate = new Date(endDate[0], endDate[1] - 1, endDate[2]);
40

    
41
      // Ensure that start comes before end for datepicker.
42
      if (startDate > endDate) {
43
        var laterDate = startDate;
44
        startDate = endDate;
45
        endDate = laterDate;
46
      }
47

    
48
      var startYear = startDate.getFullYear();
49
      var endYear = endDate.getFullYear();
50

    
51
      // Set up the jQuery datepicker element.
52
      $calendar.datepicker({
53
        dateFormat: 'yy-mm-dd',
54
        yearRange: startYear + ':' + endYear,
55
        firstDay: parseInt(firstDay),
56
        minDate: startDate,
57
        maxDate: endDate,
58
        onSelect: function (dateText, inst) {
59
          var date = dateText.split('-');
60
          $webformDatepicker.find('select.year, input.year').val(+date[0]).trigger('change');
61
          $webformDatepicker.find('select.month').val(+date[1]).trigger('change');
62
          $webformDatepicker.find('select.day').val(+date[2]).trigger('change');
63
        },
64
        beforeShow: function (input, inst) {
65
          // Get the select list values.
66
          var year = $webformDatepicker.find('select.year, input.year').val();
67
          var month = $webformDatepicker.find('select.month').val();
68
          var day = $webformDatepicker.find('select.day').val();
69

    
70
          // If empty, default to the current year/month/day in the popup.
71
          var today = new Date();
72
          year = year ? year : today.getFullYear();
73
          month = month ? month : today.getMonth() + 1;
74
          day = day ? day : today.getDate();
75

    
76
          // Make sure that the default year fits in the available options.
77
          year = (year < startYear || year > endYear) ? startYear : year;
78

    
79
          // jQuery UI Datepicker will read the input field and base its date off
80
          // of that, even though in our case the input field is a button.
81
          $(input).val(year + '-' + month + '-' + day);
82
        }
83
      });
84

    
85
      // Prevent the calendar button from submitting the form.
86
      $calendar.click(function (event) {
87
        $(this).focus();
88
        event.preventDefault();
89
      });
90
    });
91
  };
92

    
93
  Drupal.webform.conditional = function (context) {
94
    // Add the bindings to each webform on the page.
95
    $.each(Drupal.settings.webform.conditionals, function (formKey, settings) {
96
      var $form = $('.' + formKey + ':not(.webform-conditional-processed)');
97
      $form.each(function (index, currentForm) {
98
        var $currentForm = $(currentForm);
99
        $currentForm.addClass('webform-conditional-processed');
100
        $currentForm.bind('change', {'settings': settings}, Drupal.webform.conditionalCheck);
101

    
102
        // Trigger all the elements that cause conditionals on this form.
103
        Drupal.webform.doConditions($form, settings);
104
      });
105
    });
106
  };
107

    
108
  /**
109
   * Event handler to respond to field changes in a form.
110
   *
111
   * This event is bound to the entire form, not individual fields.
112
   */
113
  Drupal.webform.conditionalCheck = function (e) {
114
    var $triggerElement = $(e.target).closest('.webform-component');
115
    var $form = $triggerElement.closest('form');
116
    var triggerElementKey = $triggerElement.attr('class').match(/webform-component--[^ ]+/)[0];
117
    var settings = e.data.settings;
118
    if (settings.sourceMap[triggerElementKey]) {
119
      Drupal.webform.doConditions($form, settings);
120
    }
121
  };
122

    
123
  /**
124
   * Processes all conditional.
125
   */
126
  Drupal.webform.doConditions = function ($form, settings) {
127
    // Track what has be set/shown for each target component.
128
    var targetLocked = [];
129

    
130
    $.each(settings.ruleGroups, function (rgid_key, rule_group) {
131
      var ruleGroup = settings.ruleGroups[rgid_key];
132

    
133
      // Perform the comparison callback and build the results for this group.
134
      var conditionalResult = true;
135
      var conditionalResults = [];
136
      $.each(ruleGroup['rules'], function (m, rule) {
137
        var elementKey = rule['source'];
138
        var element = $form.find('.' + elementKey)[0];
139
        var existingValue = settings.values[elementKey] ? settings.values[elementKey] : null;
140
        conditionalResults.push(window['Drupal']['webform'][rule.callback](element, existingValue, rule['value']));
141
      });
142

    
143
      // Filter out false values.
144
      var filteredResults = [];
145
      for (var i = 0; i < conditionalResults.length; i++) {
146
        if (conditionalResults[i]) {
147
          filteredResults.push(conditionalResults[i]);
148
        }
149
      }
150

    
151
      // Calculate the and/or result.
152
      if (ruleGroup['andor'] === 'or') {
153
        conditionalResult = filteredResults.length > 0;
154
      }
155
      else {
156
        conditionalResult = filteredResults.length === conditionalResults.length;
157
      }
158

    
159
      $.each(ruleGroup['actions'], function (aid, action) {
160
        var $target = $form.find('.' + action['target']);
161
        var actionResult = action['invert'] ? !conditionalResult : conditionalResult;
162
        switch (action['action']) {
163
          case 'show':
164
            if (actionResult != Drupal.webform.isVisible($target)) {
165
              var $targetElements = actionResult
166
                                      ? $target.find('.webform-conditional-disabled').removeClass('webform-conditional-disabled')
167
                                      : $target.find(':input').addClass('webform-conditional-disabled');
168
              $targetElements.webformProp('disabled', !actionResult);
169
              $target.toggleClass('webform-conditional-hidden', !actionResult);
170
              if (actionResult) {
171
                $target.show();
172
              }
173
              else {
174
                $target.hide();
175
                // Record that the target was hidden.
176
                targetLocked[action['target']] = 'hide';
177
              }
178
              if ($target.is('tr')) {
179
                Drupal.webform.restripeTable($target.closest('table').first());
180
              }
181
            }
182
            break;
183
          case 'require':
184
            var $requiredSpan = $target.find('.form-required, .form-optional').first();
185
            if (actionResult != $requiredSpan.hasClass('form-required')) {
186
              var $targetInputElements = $target.find("input:text,textarea,input[type='email'],select,input:radio,input:file");
187
              // Rather than hide the required tag, remove it so that other jQuery can respond via Drupal behaviors.
188
              Drupal.detachBehaviors($requiredSpan);
189
              $targetInputElements
190
                .webformProp('required', actionResult)
191
                .toggleClass('required', actionResult);
192
              if (actionResult) {
193
                $requiredSpan.replaceWith('<span class="form-required" title="' + Drupal.t('This field is required.') + '">*</span>');
194
              }
195
              else {
196
                $requiredSpan.replaceWith('<span class="form-optional"></span>');
197
              }
198
              Drupal.attachBehaviors($requiredSpan);
199
            }
200
            break;
201
          case 'set':
202
            var isLocked = targetLocked[action['target']];
203
            var $texts = $target.find("input:text,textarea,input[type='email']");
204
            var $selects = $target.find('select,select option,input:radio,input:checkbox');
205
            var $markups = $target.filter('.webform-component-markup');
206
            if (actionResult) {
207
              var multiple = $.map(action['argument'].split(','), $.trim);
208
              $selects.webformVal(multiple);
209
              $texts.val([action['argument']]);
210
              // A special case is made for markup. It is sanitized with filter_xss_admin on the server.
211
              // otherwise text() should be used to avoid an XSS vulnerability. text() however would
212
              // preclude the use of tags like <strong> or <a>
213
              $markups.html(action['argument']);
214
            }
215
            else {
216
              // Markup not set? Then restore original markup as provided in
217
              // the attribute data-webform-markup.
218
              $markups.each(function() {
219
                var $this = $(this);
220
                var original = $this.data('webform-markup');
221
                if (original !== undefined) {
222
                  $this.html(original);
223
                }
224
              });
225
            }
226
            if (!isLocked) {
227
              // If not previously hidden or set, disable the element readonly or readonly-like behavior.
228
              $selects.webformProp('disabled', actionResult);
229
              $texts.webformProp('readonly', actionResult);
230
              targetLocked[action['target']] = actionResult ? 'set' : false;
231
            }
232
            break;
233
        }
234
      }); // End look on each action for one conditional
235
    }); // End loop on each conditional
236
  };
237

    
238
  /**
239
   * Event handler to prevent propogation of events, typically click for disabling
240
   * radio and checkboxes.
241
   */
242
  Drupal.webform.stopEvent = function () {
243
    return false;
244
  };
245

    
246
  Drupal.webform.conditionalOperatorStringEqual = function (element, existingValue, ruleValue) {
247
    var returnValue = false;
248
    var currentValue = Drupal.webform.stringValue(element, existingValue);
249
    $.each(currentValue, function (n, value) {
250
      if (value.toLowerCase() === ruleValue.toLowerCase()) {
251
        returnValue = true;
252
        return false; // break.
253
      }
254
    });
255
    return returnValue;
256
  };
257

    
258
  Drupal.webform.conditionalOperatorStringNotEqual = function (element, existingValue, ruleValue) {
259
    var found = false;
260
    var currentValue = Drupal.webform.stringValue(element, existingValue);
261
    $.each(currentValue, function (n, value) {
262
      if (value.toLowerCase() === ruleValue.toLowerCase()) {
263
        found = true;
264
      }
265
    });
266
    return !found;
267
  };
268

    
269
  Drupal.webform.conditionalOperatorStringContains = function (element, existingValue, ruleValue) {
270
    var returnValue = false;
271
    var currentValue = Drupal.webform.stringValue(element, existingValue);
272
    $.each(currentValue, function (n, value) {
273
      if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) {
274
        returnValue = true;
275
        return false; // break.
276
      }
277
    });
278
    return returnValue;
279
  };
280

    
281
  Drupal.webform.conditionalOperatorStringDoesNotContain = function (element, existingValue, ruleValue) {
282
    var found = false;
283
    var currentValue = Drupal.webform.stringValue(element, existingValue);
284
    $.each(currentValue, function (n, value) {
285
      if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) {
286
        found = true;
287
      }
288
    });
289
    return !found;
290
  };
291

    
292
  Drupal.webform.conditionalOperatorStringBeginsWith = function (element, existingValue, ruleValue) {
293
    var returnValue = false;
294
    var currentValue = Drupal.webform.stringValue(element, existingValue);
295
    $.each(currentValue, function (n, value) {
296
      if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) === 0) {
297
        returnValue = true;
298
        return false; // break.
299
      }
300
    });
301
    return returnValue;
302
  };
303

    
304
  Drupal.webform.conditionalOperatorStringEndsWith = function (element, existingValue, ruleValue) {
305
    var returnValue = false;
306
    var currentValue = Drupal.webform.stringValue(element, existingValue);
307
    $.each(currentValue, function (n, value) {
308
      if (value.toLowerCase().lastIndexOf(ruleValue.toLowerCase()) === value.length - ruleValue.length) {
309
        returnValue = true;
310
        return false; // break.
311
      }
312
    });
313
    return returnValue;
314
  };
315

    
316
  Drupal.webform.conditionalOperatorStringEmpty = function (element, existingValue, ruleValue) {
317
    var currentValue = Drupal.webform.stringValue(element, existingValue);
318
    var returnValue = true;
319
    $.each(currentValue, function (n, value) {
320
      if (value !== '') {
321
        returnValue = false;
322
        return false; // break.
323
      }
324
    });
325
    return returnValue;
326
  };
327

    
328
  Drupal.webform.conditionalOperatorStringNotEmpty = function (element, existingValue, ruleValue) {
329
    return !Drupal.webform.conditionalOperatorStringEmpty(element, existingValue, ruleValue);
330
  };
331

    
332
  Drupal.webform.conditionalOperatorSelectGreaterThan = function (element, existingValue, ruleValue) {
333
    var currentValue = Drupal.webform.stringValue(element, existingValue);
334
    return Drupal.webform.compare_select(currentValue[0], ruleValue, element) > 0;
335
  };
336

    
337
  Drupal.webform.conditionalOperatorSelectGreaterThanEqual = function (element, existingValue, ruleValue) {
338
    var currentValue = Drupal.webform.stringValue(element, existingValue);
339
    var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element);
340
    return comparison > 0 || comparison === 0;
341
  };
342

    
343
  Drupal.webform.conditionalOperatorSelectLessThan = function (element, existingValue, ruleValue) {
344
    var currentValue = Drupal.webform.stringValue(element, existingValue);
345
    return Drupal.webform.compare_select(currentValue[0], ruleValue, element) < 0;
346
  };
347

    
348
  Drupal.webform.conditionalOperatorSelectLessThanEqual = function (element, existingValue, ruleValue) {
349
    var currentValue = Drupal.webform.stringValue(element, existingValue);
350
    var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element);
351
    return comparison < 0 || comparison === 0;
352
  };
353

    
354
  Drupal.webform.conditionalOperatorNumericEqual = function (element, existingValue, ruleValue) {
355
    // See float comparison: http://php.net/manual/en/language.types.float.php
356
    var currentValue = Drupal.webform.stringValue(element, existingValue);
357
    var epsilon = 0.000001;
358
    // An empty string does not match any number.
359
    return currentValue[0] === '' ? false : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) < epsilon);
360
  };
361

    
362
  Drupal.webform.conditionalOperatorNumericNotEqual = function (element, existingValue, ruleValue) {
363
    // See float comparison: http://php.net/manual/en/language.types.float.php
364
    var currentValue = Drupal.webform.stringValue(element, existingValue);
365
    var epsilon = 0.000001;
366
    // An empty string does not match any number.
367
    return currentValue[0] === '' ? true : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) >= epsilon);
368
  };
369

    
370
  Drupal.webform.conditionalOperatorNumericGreaterThan = function (element, existingValue, ruleValue) {
371
    var currentValue = Drupal.webform.stringValue(element, existingValue);
372
    return parseFloat(currentValue[0]) > parseFloat(ruleValue);
373
  };
374

    
375
  Drupal.webform.conditionalOperatorNumericGreaterThanEqual = function (element, existingValue, ruleValue) {
376
    return Drupal.webform.conditionalOperatorNumericGreaterThan(element, existingValue, ruleValue) ||
377
           Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue);
378
  };
379

    
380
  Drupal.webform.conditionalOperatorNumericLessThan = function (element, existingValue, ruleValue) {
381
    var currentValue = Drupal.webform.stringValue(element, existingValue);
382
    return parseFloat(currentValue[0]) < parseFloat(ruleValue);
383
  };
384

    
385
  Drupal.webform.conditionalOperatorNumericLessThanEqual = function (element, existingValue, ruleValue) {
386
    return Drupal.webform.conditionalOperatorNumericLessThan(element, existingValue, ruleValue) ||
387
           Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue);
388
  };
389

    
390
  Drupal.webform.conditionalOperatorDateEqual = function (element, existingValue, ruleValue) {
391
    var currentValue = Drupal.webform.dateValue(element, existingValue);
392
    return currentValue === ruleValue;
393
  };
394

    
395
  Drupal.webform.conditionalOperatorDateNotEqual = function (element, existingValue, ruleValue) {
396
    return !Drupal.webform.conditionalOperatorDateEqual(element, existingValue, ruleValue);
397
  };
398

    
399
  Drupal.webform.conditionalOperatorDateBefore = function (element, existingValue, ruleValue) {
400
    var currentValue = Drupal.webform.dateValue(element, existingValue);
401
    return (currentValue !== false) && currentValue < ruleValue;
402
  };
403

    
404
  Drupal.webform.conditionalOperatorDateBeforeEqual = function (element, existingValue, ruleValue) {
405
    var currentValue = Drupal.webform.dateValue(element, existingValue);
406
    return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue);
407
  };
408

    
409
  Drupal.webform.conditionalOperatorDateAfter = function (element, existingValue, ruleValue) {
410
    var currentValue = Drupal.webform.dateValue(element, existingValue);
411
    return (currentValue !== false) && currentValue > ruleValue;
412
  };
413

    
414
  Drupal.webform.conditionalOperatorDateAfterEqual = function (element, existingValue, ruleValue) {
415
    var currentValue = Drupal.webform.dateValue(element, existingValue);
416
    return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue);
417
  };
418

    
419
  Drupal.webform.conditionalOperatorTimeEqual = function (element, existingValue, ruleValue) {
420
    var currentValue = Drupal.webform.timeValue(element, existingValue);
421
    return currentValue === ruleValue;
422
  };
423

    
424
  Drupal.webform.conditionalOperatorTimeNotEqual = function (element, existingValue, ruleValue) {
425
    return !Drupal.webform.conditionalOperatorTimeEqual(element, existingValue, ruleValue);
426
  };
427

    
428
  Drupal.webform.conditionalOperatorTimeBefore = function (element, existingValue, ruleValue) {
429
    // Date and time operators intentionally exclusive for "before".
430
    var currentValue = Drupal.webform.timeValue(element, existingValue);
431
    return (currentValue !== false) && (currentValue < ruleValue);
432
  };
433

    
434
  Drupal.webform.conditionalOperatorTimeBeforeEqual = function (element, existingValue, ruleValue) {
435
    // Date and time operators intentionally exclusive for "before".
436
    var currentValue = Drupal.webform.timeValue(element, existingValue);
437
    return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue);
438
  };
439

    
440
  Drupal.webform.conditionalOperatorTimeAfter = function (element, existingValue, ruleValue) {
441
    // Date and time operators intentionally inclusive for "after".
442
    var currentValue = Drupal.webform.timeValue(element, existingValue);
443
    return (currentValue !== false) && (currentValue > ruleValue);
444
  };
445

    
446
  Drupal.webform.conditionalOperatorTimeAfterEqual = function (element, existingValue, ruleValue) {
447
    // Date and time operators intentionally inclusive for "after".
448
    var currentValue = Drupal.webform.timeValue(element, existingValue);
449
    return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue);
450
  };
451

    
452
  /**
453
   * Utility function to compare values of a select component.
454
   * @param string a
455
   *   First select option key to compare
456
   * @param string b
457
   *   Second select option key to compare
458
   * @param array options
459
   *   Associative array where the a and b are within the keys
460
   * @return integer based upon position of $a and $b in $options
461
   *   -N if $a above (<) $b
462
   *   0 if $a = $b
463
   *   +N if $a is below (>) $b
464
   */
465
  Drupal.webform.compare_select = function (a, b, element) {
466
    var optionList = [];
467
    $('option,input:radio,input:checkbox', element).each(function () {
468
      optionList.push($(this).val());
469
    });
470
    var a_position = optionList.indexOf(a);
471
    var b_position = optionList.indexOf(b);
472
    return (a_position < 0 || b_position < 0) ? null : a_position - b_position;
473
  };
474

    
475
  /**
476
   * Utility to return current visibility. Uses actual visibility, except for
477
   * hidden components which use the applied disabled class.
478
   */
479
  Drupal.webform.isVisible = function ($element) {
480
    return $element.hasClass('webform-component-hidden')
481
              ? !$element.find('input').first().hasClass('webform-conditional-disabled')
482
              : $element.closest('.webform-conditional-hidden').length == 0;
483
  };
484

    
485
  /**
486
   * Utility function to get a string value from a select/radios/text/etc. field.
487
   */
488
  Drupal.webform.stringValue = function (element, existingValue) {
489
    var value = [];
490
    if (element) {
491
      var $element = $(element);
492
      if (Drupal.webform.isVisible($element)) {
493
        // Checkboxes and radios.
494
        $element.find('input[type=checkbox]:checked,input[type=radio]:checked').each(function () {
495
          value.push(this.value);
496
        });
497
        // Select lists.
498
        if (!value.length) {
499
          var selectValue = $element.find('select').val();
500
          if (selectValue) {
501
            if ($.isArray(selectValue)) {
502
              value = selectValue;
503
            }
504
            else {
505
              value.push(selectValue);
506
            }
507
          }
508
        }
509
        // Simple text fields. This check is done last so that the select list in
510
        // select-or-other fields comes before the "other" text field.
511
        if (!value.length) {
512
          $element.find('input:not([type=checkbox],[type=radio]),textarea').each(function () {
513
            value.push(this.value);
514
          });
515
        }
516
      }
517
    }
518
    else {
519
      switch ($.type(existingValue)) {
520
        case 'array':
521
          value = existingValue;
522
          break;
523
        case 'string':
524
          value.push(existingValue);
525
          break;
526
      }
527
    }
528
    return value;
529
  };
530

    
531
  /**
532
   * Utility function to calculate a second-based timestamp from a time field.
533
   */
534
  Drupal.webform.dateValue = function (element, existingValue) {
535
    var value = false;
536
    if (element) {
537
      var $element = $(element);
538
      if (Drupal.webform.isVisible($element)) {
539
        var day = $element.find('[name*=day]').val();
540
        var month = $element.find('[name*=month]').val();
541
        var year = $element.find('[name*=year]').val();
542
        // Months are 0 indexed in JavaScript.
543
        if (month) {
544
          month--;
545
        }
546
        if (year !== '' && month !== '' && day !== '') {
547
          value = Date.UTC(year, month, day) / 1000;
548
        }
549
      }
550
    }
551
    else {
552
      if ($.type(existingValue) === 'array' && existingValue.length) {
553
        existingValue = existingValue[0];
554
      }
555
      if ($.type(existingValue) === 'string') {
556
        existingValue = existingValue.split('-');
557
      }
558
      if (existingValue.length === 3) {
559
        value = Date.UTC(existingValue[0], existingValue[1], existingValue[2]) / 1000;
560
      }
561
    }
562
    return value;
563
  };
564

    
565
  /**
566
   * Utility function to calculate a millisecond timestamp from a time field.
567
   */
568
  Drupal.webform.timeValue = function (element, existingValue) {
569
    var value = false;
570
    if (element) {
571
      var $element = $(element);
572
      if (Drupal.webform.isVisible($element)) {
573
        var hour = $element.find('[name*=hour]').val();
574
        var minute = $element.find('[name*=minute]').val();
575
        var ampm = $element.find('[name*=ampm]:checked').val();
576

    
577
        // Convert to integers if set.
578
        hour = (hour === '') ? hour : parseInt(hour);
579
        minute = (minute === '') ? minute : parseInt(minute);
580

    
581
        if (hour !== '') {
582
          hour = (hour < 12 && ampm == 'pm') ? hour + 12 : hour;
583
          hour = (hour === 12 && ampm == 'am') ? 0 : hour;
584
        }
585
        if (hour !== '' && minute !== '') {
586
          value = Date.UTC(1970, 0, 1, hour, minute) / 1000;
587
        }
588
      }
589
    }
590
    else {
591
      if ($.type(existingValue) === 'array' && existingValue.length) {
592
        existingValue = existingValue[0];
593
      }
594
      if ($.type(existingValue) === 'string') {
595
        existingValue = existingValue.split(':');
596
      }
597
      if (existingValue.length >= 2) {
598
        value = Date.UTC(1970, 0, 1, existingValue[0], existingValue[1]) / 1000;
599
      }
600
    }
601
    return value;
602
  };
603

    
604
  /**
605
   * Make a prop shim for jQuery < 1.9.
606
   */
607
  $.fn.webformProp = $.fn.webformProp || function (name, value) {
608
    if (value) {
609
      return $.fn.prop ? this.prop(name, true) : this.attr(name, true);
610
    }
611
    else {
612
      return $.fn.prop ? this.prop(name, false) : this.removeAttr(name);
613
    }
614
  };
615

    
616
  /**
617
   * Make a multi-valued val() function for setting checkboxes, radios, and select
618
   * elements.
619
   */
620
  $.fn.webformVal = function (values) {
621
    this.each(function () {
622
      var $this = $(this);
623
      var value = $this.val();
624
      var on = $.inArray($this.val(), values) != -1;
625
      if (this.nodeName == 'OPTION') {
626
        $this.webformProp('selected', on ? value : false);
627
      }
628
      else {
629
        $this.val(on ? [value] : false);
630
      }
631
    });
632
    return this;
633
  };
634

    
635
  /**
636
   * Given a table's DOM element, restripe the odd/even classes.
637
   */
638
  Drupal.webform.restripeTable = function (table) {
639
    // :even and :odd are reversed because jQuery counts from 0 and
640
    // we count from 1, so we're out of sync.
641
    // Match immediate children of the parent element to allow nesting.
642
    $('> tbody > tr, > tr', table)
643
      .filter(':visible:odd').filter('.odd')
644
        .removeClass('odd').addClass('even')
645
      .end().end()
646
      .filter(':visible:even').filter('.even')
647
        .removeClass('even').addClass('odd');
648
  };
649

    
650
})(jQuery);