1(function ($) { 2 3Drupal.behaviors.textarea = { 4 attach: function (context, settings) { 5 $('.form-textarea-wrapper.resizable', context).once('textarea', function () { 6 var staticOffset = null; 7 var textarea = $(this).addClass('resizable-textarea').find('textarea'); 8 var grippie = $('<div class="grippie"></div>').mousedown(startDrag); 9 10 grippie.insertAfter(textarea); 11 12 function startDrag(e) { 13 staticOffset = textarea.height() - e.pageY; 14 textarea.css('opacity', 0.25); 15 $(document).mousemove(performDrag).mouseup(endDrag); 16 return false; 17 } 18 19 function performDrag(e) { 20 textarea.height(Math.max(32, staticOffset + e.pageY) + 'px'); 21 return false; 22 } 23 24 function endDrag(e) { 25 $(document).unbind('mousemove', performDrag).unbind('mouseup', endDrag); 26 textarea.css('opacity', 1); 27 } 28 }); 29 } 30}; 31 32})(jQuery); 33; 34/** 35 * @file 36 * JavaScript behaviors for the front-end display of webforms. 37 */ 38 39(function ($) { 40 41 "use strict"; 42 43 Drupal.behaviors.webform = Drupal.behaviors.webform || {}; 44 45 Drupal.behaviors.webform.attach = function (context) { 46 // Calendar datepicker behavior. 47 Drupal.webform.datepicker(context); 48 49 // Conditional logic. 50 if (Drupal.settings.webform && Drupal.settings.webform.conditionals) { 51 Drupal.webform.conditional(context); 52 } 53 }; 54 55 Drupal.webform = Drupal.webform || {}; 56 57 Drupal.webform.datepicker = function (context) { 58 $('div.webform-datepicker').each(function () { 59 var $webformDatepicker = $(this); 60 var $calendar = $webformDatepicker.find('input.webform-calendar'); 61 62 // Ensure the page we're on actually contains a datepicker. 63 if ($calendar.length == 0) { 64 return; 65 } 66 67 var startDate = $calendar[0].className.replace(/.*webform-calendar-start-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-'); 68 var endDate = $calendar[0].className.replace(/.*webform-calendar-end-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-'); 69 var firstDay = $calendar[0].className.replace(/.*webform-calendar-day-(\d).*/, '$1'); 70 // Convert date strings into actual Date objects. 71 startDate = new Date(startDate[0], startDate[1] - 1, startDate[2]); 72 endDate = new Date(endDate[0], endDate[1] - 1, endDate[2]); 73 74 // Ensure that start comes before end for datepicker. 75 if (startDate > endDate) { 76 var laterDate = startDate; 77 startDate = endDate; 78 endDate = laterDate; 79 } 80 81 var startYear = startDate.getFullYear(); 82 var endYear = endDate.getFullYear(); 83 84 // Set up the jQuery datepicker element. 85 $calendar.datepicker({ 86 dateFormat: 'yy-mm-dd', 87 yearRange: startYear + ':' + endYear, 88 firstDay: parseInt(firstDay), 89 minDate: startDate, 90 maxDate: endDate, 91 onSelect: function (dateText, inst) { 92 var date = dateText.split('-'); 93 $webformDatepicker.find('select.year, input.year').val(+date[0]).trigger('change'); 94 $webformDatepicker.find('select.month').val(+date[1]).trigger('change'); 95 $webformDatepicker.find('select.day').val(+date[2]).trigger('change'); 96 }, 97 beforeShow: function (input, inst) { 98 // Get the select list values. 99 var year = $webformDatepicker.find('select.year, input.year').val(); 100 var month = $webformDatepicker.find('select.month').val(); 101 var day = $webformDatepicker.find('select.day').val(); 102 103 // If empty, default to the current year/month/day in the popup. 104 var today = new Date(); 105 year = year ? year : today.getFullYear(); 106 month = month ? month : today.getMonth() + 1; 107 day = day ? day : today.getDate(); 108 109 // Make sure that the default year fits in the available options. 110 year = (year < startYear || year > endYear) ? startYear : year; 111 112 // jQuery UI Datepicker will read the input field and base its date 113 // off of that, even though in our case the input field is a button. 114 $(input).val(year + '-' + month + '-' + day); 115 } 116 }); 117 118 // Prevent the calendar button from submitting the form. 119 $calendar.click(function (event) { 120 // This event is triggered also when pressing enter when the focus is on 121 // previous webform components, but we only want to do something when 122 // we are on the calendar component. By checking the event client x/y 123 // position we known if it was the user clicking. For keyboard navigators 124 // simply the focus handles the date picker so we don't have to do 125 // anything special for them. 126 if (event.clientX !== 0 && event.clientY !== 0) { 127 // Focus is only necessary for Safari. But it has no impact on other 128 // browsers. 129 $(this).focus(); 130 event.preventDefault(); 131 } 132 }); 133 134 // Clear date on backspace or delete. 135 $calendar.keyup(function (e) { 136 if (e.keyCode == 8 || e.keyCode == 46) { 137 $.datepicker._clearDate(this); 138 } 139 }); 140 }); 141 }; 142 143 Drupal.webform.conditional = function (context) { 144 // Add the bindings to each webform on the page. 145 $.each(Drupal.settings.webform.conditionals, function (formKey, settings) { 146 var $form = $('.' + formKey + ':not(.webform-conditional-processed)'); 147 $form.each(function (index, currentForm) { 148 var $currentForm = $(currentForm); 149 $currentForm.addClass('webform-conditional-processed'); 150 $currentForm.bind('change', {'settings': settings}, Drupal.webform.conditionalCheck); 151 152 // Trigger all the elements that cause conditionals on this form. 153 Drupal.webform.doConditions($currentForm, settings); 154 }); 155 }); 156 }; 157 158 /** 159 * Event handler to respond to field changes in a form. 160 * 161 * This event is bound to the entire form, not individual fields. 162 */ 163 Drupal.webform.conditionalCheck = function (e) { 164 var $triggerElement = $(e.target).closest('.webform-component'); 165 if (!$triggerElement.length) { 166 return; 167 } 168 var $form = $triggerElement.closest('form'); 169 var triggerElementKey = $triggerElement.attr('class').match(/webform-component--[^ ]+/)[0]; 170 var settings = e.data.settings; 171 if (settings.sourceMap[triggerElementKey]) { 172 Drupal.webform.doConditions($form, settings); 173 } 174 }; 175 176 /** 177 * Processes all conditional. 178 */ 179 Drupal.webform.doConditions = function ($form, settings) { 180 181 var stackPointer; 182 var resultStack; 183 184 /** 185 * Initializes an execution stack for a conditional group's rules. 186 * 187 * Also initializes sub-conditional rules. 188 */ 189 function executionStackInitialize(andor) { 190 stackPointer = -1; 191 resultStack = []; 192 executionStackPush(andor); 193 } 194 195 /** 196 * Starts a new subconditional for the given and/or operator. 197 */ 198 function executionStackPush(andor) { 199 resultStack[++stackPointer] = { 200 results: [], 201 andor: andor, 202 }; 203 } 204 205 /** 206 * Adds a rule's result to the current sub-conditional. 207 */ 208 function executionStackAccumulate(result) { 209 resultStack[stackPointer]['results'].push(result); 210 } 211 212 /** 213 * Finishes a sub-conditional and adds the result to the parent stack frame. 214 */ 215 function executionStackPop() { 216 // Calculate the and/or result. 217 var stackFrame = resultStack[stackPointer]; 218 // Pop stack and protect against stack underflow. 219 stackPointer = Math.max(0, stackPointer - 1); 220 var $conditionalResults = stackFrame['results']; 221 var filteredResults = $.map($conditionalResults, function (val) { 222 return val ? val : null; 223 }); 224 return stackFrame['andor'] === 'or' 225 ? filteredResults.length > 0 226 : filteredResults.length === $conditionalResults.length; 227 } 228 229 // Track what has been set/hidden for each target component's elements. 230 // Hidden elements must be disabled because if they are required and don't 231 // have a value, they will prevent submission due to html5 validation. 232 // Each execution of the conditionals adds a temporary class 233 // webform-disabled-flag so that elements hidden or set can be disabled and 234 // also be prevented from being re-enabled by another conditional (such as a 235 // parent fieldset). After processing conditionals, this temporary class 236 // must be removed in preparation for the next execution of the 237 // conditionals. 238 $.each(settings.ruleGroups, function (rgid_key, rule_group) { 239 var ruleGroup = settings.ruleGroups[rgid_key]; 240 241 // Perform the comparison callback and build the results for this group. 242 executionStackInitialize(ruleGroup['andor']); 243 $.each(ruleGroup['rules'], function (m, rule) { 244 switch (rule['source_type']) { 245 case 'component':
246 var elementKey = rule['source']; 247 var element = $form.find('.' + elementKey)[0]; 248 var existingValue = settings.values[elementKey] ? settings.values[elementKey] : null; 249 executionStackAccumulate(window['Drupal']['webform'][rule.callback](element, existingValue, rule['value'])); 250 break; 251 252 case 'conditional_start': 253 executionStackPush(rule['andor']); 254 break; 255 256 case 'conditional_end': 257 executionStackAccumulate(executionStackPop()); 258 break; 259 } 260 }); 261 var conditionalResult = executionStackPop(); 262 263 $.each(ruleGroup['actions'], function (aid, action) { 264 var $target = $form.find('.' + action['target']); 265 var actionResult = action['invert'] ? !conditionalResult : conditionalResult; 266 switch (action['action']) { 267 case 'show': 268 var changed = actionResult != Drupal.webform.isVisible($target); 269 if (actionResult) { 270 $target.find('.webform-conditional-disabled:not(.webform-disabled-flag)') 271 .removeClass('webform-conditional-disabled') 272 .webformProp('disabled', false); 273 $target 274 .removeClass('webform-conditional-hidden') 275 .show(); 276 $form.find('.chosen-disabled').prev().trigger('chosen:updated.chosen'); 277 } 278 else { 279 $target 280 .hide() 281 .addClass('webform-conditional-hidden') 282 .find(':input') 283 .addClass('webform-conditional-disabled webform-disabled-flag') 284 .webformProp('disabled', true); 285 } 286 if (changed && $target.is('tr')) { 287 Drupal.webform.restripeTable($target.closest('table').first()); 288 } 289 break; 290 291 case 'require': 292 var $requiredSpan = $target.find('.form-required, .form-optional').first(); 293 if (actionResult != $requiredSpan.hasClass('form-required')) { 294 var $targetInputElements = $target.find("input:text,textarea,input[type='email'],select,input:radio,input:checkbox,input:file"); 295 // Rather than hide the required tag, remove it so that other 296 // jQuery can respond via Drupal behaviors. 297 Drupal.detachBehaviors($requiredSpan); 298 $targetInputElements 299 .webformProp('required', actionResult) 300 .toggleClass('required', actionResult); 301 if (actionResult) { 302 $requiredSpan.replaceWith('<span class="form-required" title="' + Drupal.t('This field is required.') + '">*</span>'); 303 } 304 else { 305 $requiredSpan.replaceWith('<span class="form-optional"></span>'); 306 } 307 Drupal.attachBehaviors($requiredSpan); 308 } 309 break; 310 311 case 'set': 312 var $texts = $target.find("input:text,textarea,input[type='email']"); 313 var $selects = $target.find('select,select option,input:radio,input:checkbox'); 314 var $markups = $target.filter('.webform-component-markup'); 315 if (actionResult) { 316 var multiple = $.map(action['argument'].split(','), $.trim); 317 $selects 318 .webformVal(multiple) 319 .webformProp('disabled', true) 320 .addClass('webform-disabled-flag'); 321 $texts 322 .val([action['argument']]) 323 .webformProp('readonly', true) 324 .addClass('webform-disabled-flag'); 325 // A special case is made for markup. It is sanitized with 326 // filter_xss_admin on the server. otherwise text() should be used 327 // to avoid an XSS vulnerability. text() however would preclude 328 // the use of tags like <strong> or <a>. 329 $markups.html(action['argument']); 330 } 331 else { 332 $selects.not('.webform-disabled-flag') 333 .webformProp('disabled', false); 334 $texts.not('.webform-disabled-flag') 335 .webformProp('readonly', false); 336 // Markup not set? Then restore original markup as provided in 337 // the attribute data-webform-markup. 338 $markups.each(function () { 339 var $this = $(this); 340 var original = $this.data('webform-markup'); 341 if (original !== undefined) { 342 $this.html(original); 343 } 344 }); 345 } 346 break; 347 } 348 }); // End look on each action for one conditional. 349 }); // End loop on each conditional. 350 351 $form.find('.webform-disabled-flag').removeClass('webform-disabled-flag'); 352 }; 353 354 /** 355 * Event handler to prevent propagation of events. 356 * 357 * Typically click for disabling radio and checkboxes. 358 */ 359 Drupal.webform.stopEvent = function () { 360 return false;
361 }; 362 363 Drupal.webform.conditionalOperatorStringEqual = function (element, existingValue, ruleValue) { 364 var returnValue = false; 365 var currentValue = Drupal.webform.stringValue(element, existingValue); 366 $.each(currentValue, function (n, value) { 367 if (value.toLowerCase() === ruleValue.toLowerCase()) { 368 returnValue = true; 369 return false; // break. 370 } 371 }); 372 return returnValue; 373 }; 374 375 Drupal.webform.conditionalOperatorStringNotEqual = function (element, existingValue, ruleValue) { 376 var found = false; 377 var currentValue = Drupal.webform.stringValue(element, existingValue); 378 $.each(currentValue, function (n, value) { 379 if (value.toLowerCase() === ruleValue.toLowerCase()) { 380 found = true; 381 } 382 }); 383 return !found; 384 }; 385 386 Drupal.webform.conditionalOperatorStringContains = function (element, existingValue, ruleValue) { 387 var returnValue = false; 388 var currentValue = Drupal.webform.stringValue(element, existingValue); 389 $.each(currentValue, function (n, value) { 390 if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) { 391 returnValue = true; 392 return false; // break. 393 } 394 }); 395 return returnValue; 396 }; 397 398 Drupal.webform.conditionalOperatorStringDoesNotContain = function (element, existingValue, ruleValue) { 399 var found = false; 400 var currentValue = Drupal.webform.stringValue(element, existingValue); 401 $.each(currentValue, function (n, value) { 402 if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) { 403 found = true; 404 } 405 }); 406 return !found; 407 }; 408 409 Drupal.webform.conditionalOperatorStringBeginsWith = function (element, existingValue, ruleValue) { 410 var returnValue = false; 411 var currentValue = Drupal.webform.stringValue(element, existingValue); 412 $.each(currentValue, function (n, value) { 413 if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) === 0) { 414 returnValue = true; 415 return false; // break. 416 } 417 }); 418 return returnValue; 419 }; 420 421 Drupal.webform.conditionalOperatorStringEndsWith = function (element, existingValue, ruleValue) { 422 var returnValue = false; 423 var currentValue = Drupal.webform.stringValue(element, existingValue); 424 $.each(currentValue, function (n, value) { 425 if (value.toLowerCase().lastIndexOf(ruleValue.toLowerCase()) === value.length - ruleValue.length) { 426 returnValue = true; 427 return false; // break. 428 } 429 }); 430 return returnValue; 431 }; 432 433 Drupal.webform.conditionalOperatorStringEmpty = function (element, existingValue, ruleValue) { 434 var currentValue = Drupal.webform.stringValue(element, existingValue); 435 var returnValue = true; 436 $.each(currentValue, function (n, value) { 437 if (value !== '') { 438 returnValue = false; 439 return false; // break. 440 } 441 }); 442 return returnValue; 443 }; 444 445 Drupal.webform.conditionalOperatorStringNotEmpty = function (element, existingValue, ruleValue) { 446 return !Drupal.webform.conditionalOperatorStringEmpty(element, existingValue, ruleValue); 447 }; 448 449 Drupal.webform.conditionalOperatorSelectGreaterThan = function (element, existingValue, ruleValue) { 450 var currentValue = Drupal.webform.stringValue(element, existingValue); 451 return Drupal.webform.compare_select(currentValue[0], ruleValue, element) > 0; 452 }; 453 454 Drupal.webform.conditionalOperatorSelectGreaterThanEqual = function (element, existingValue, ruleValue) { 455 var currentValue = Drupal.webform.stringValue(element, existingValue); 456 var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element); 457 return comparison > 0 || comparison === 0; 458 }; 459 460 Drupal.webform.conditionalOperatorSelectLessThan = function (element, existingValue, ruleValue) { 461 var currentValue = Drupal.webform.stringValue(element, existingValue); 462 return Drupal.webform.compare_select(currentValue[0], ruleValue, element) < 0; 463 }; 464 465 Drupal.webform.conditionalOperatorSelectLessThanEqual = function (element, existingValue, ruleValue) { 466 var currentValue = Drupal.webform.stringValue(element, existingV
466alue); 467 var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element); 468 return comparison < 0 || comparison === 0; 469 }; 470 471 Drupal.webform.conditionalOperatorNumericEqual = function (element, existingValue, ruleValue) { 472 // See float comparison: http://php.net/manual/en/language.types.float.php 473 var currentValue = Drupal.webform.stringValue(element, existingValue); 474 var epsilon = 0.000001; 475 // An empty string does not match any number. 476 return currentValue[0] === '' ? false : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) < epsilon); 477 }; 478 479 Drupal.webform.conditionalOperatorNumericNotEqual = function (element, existingValue, ruleValue) { 480 // See float comparison: http://php.net/manual/en/language.types.float.php 481 var currentValue = Drupal.webform.stringValue(element, existingValue); 482 var epsilon = 0.000001; 483 // An empty string does not match any number. 484 return currentValue[0] === '' ? true : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) >= epsilon); 485 }; 486 487 Drupal.webform.conditionalOperatorNumericGreaterThan = function (element, existingValue, ruleValue) { 488 var currentValue = Drupal.webform.stringValue(element, existingValue); 489 return parseFloat(currentValue[0]) > parseFloat(ruleValue); 490 }; 491 492 Drupal.webform.conditionalOperatorNumericGreaterThanEqual = function (element, existingValue, ruleValue) { 493 return Drupal.webform.conditionalOperatorNumericGreaterThan(element, existingValue, ruleValue) || 494 Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue); 495 }; 496 497 Drupal.webform.conditionalOperatorNumericLessThan = function (element, existingValue, ruleValue) { 498 var currentValue = Drupal.webform.stringValue(element, existingValue); 499 return parseFloat(currentValue[0]) < parseFloat(ruleValue); 500 }; 501 502 Drupal.webform.conditionalOperatorNumericLessThanEqual = function (element, existingValue, ruleValue) { 503 return Drupal.webform.conditionalOperatorNumericLessThan(element, existingValue, ruleValue) || 504 Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue); 505 }; 506 507 Drupal.webform.conditionalOperatorDateEqual = function (element, existingValue, ruleValue) { 508 var currentValue = Drupal.webform.dateValue(element, existingValue); 509 return currentValue === ruleValue; 510 }; 511 512 Drupal.webform.conditionalOperatorDateNotEqual = function (element, existingValue, ruleValue) { 513 return !Drupal.webform.conditionalOperatorDateEqual(element, existingValue, ruleValue); 514 }; 515 516 Drupal.webform.conditionalOperatorDateBefore = function (element, existingValue, ruleValue) { 517 var currentValue = Drupal.webform.dateValue(element, existingValue); 518 return (currentValue !== false) && currentValue < ruleValue; 519 }; 520 521 Drupal.webform.conditionalOperatorDateBeforeEqual = function (element, existingValue, ruleValue) { 522 var currentValue = Drupal.webform.dateValue(element, existingValue); 523 return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue); 524 }; 525 526 Drupal.webform.conditionalOperatorDateAfter = function (element, existingValue, ruleValue) { 527 var currentValue = Drupal.webform.dateValue(element, existingValue); 528 return (currentValue !== false) && currentValue > ruleValue; 529 }; 530 531 Drupal.webform.conditionalOperatorDateAfterEqual = function (element, existingValue, ruleValue) { 532 var currentValue = Drupal.webform.dateValue(element, existingValue); 533 return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue); 534 }; 535 536 Drupal.webform.conditionalOperatorTimeEqual = function (element, existingValue, ruleValue) { 537 var currentValue = Drupal.webform.timeValue(element, existingValue); 538 return currentValue === ruleValue; 539 }; 540 541 Drupal.webform.conditionalOperatorTimeNotEqual = function (element, existingValue, ruleValue) { 542 return !Drupal.webform.conditionalOperatorTimeEqual(element, existingValue, ruleValue); 543 }; 544 545 Drupal.webform.conditionalOperatorTimeBefore = function (element, existingV
545alue, ruleValue) { 546 // Date and time operators intentionally exclusive for "before". 547 var currentValue = Drupal.webform.timeValue(element, existingValue); 548 return (currentValue !== false) && (currentValue < ruleValue); 549 }; 550 551 Drupal.webform.conditionalOperatorTimeBeforeEqual = function (element, existingValue, ruleValue) { 552 // Date and time operators intentionally exclusive for "before". 553 var currentValue = Drupal.webform.timeValue(element, existingValue); 554 return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue); 555 }; 556 557 Drupal.webform.conditionalOperatorTimeAfter = function (element, existingValue, ruleValue) { 558 // Date and time operators intentionally inclusive for "after". 559 var currentValue = Drupal.webform.timeValue(element, existingValue); 560 return (currentValue !== false) && (currentValue > ruleValue); 561 }; 562 563 Drupal.webform.conditionalOperatorTimeAfterEqual = function (element, existingValue, ruleValue) { 564 // Date and time operators intentionally inclusive for "after". 565 var currentValue = Drupal.webform.timeValue(element, existingValue); 566 return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue); 567 }; 568 569 /** 570 * Utility function to compare values of a select component. 571 * 572 * @param string a 573 * First select option key to compare 574 * @param string b 575 * Second select option key to compare 576 * @param array options 577 * Associative array where the a and b are within the keys 578 * 579 * @return integer based upon position of $a and $b in $options 580 * -N if $a above (<) $b 581 * 0 if $a = $b 582 * +N if $a is below (>) $b 583 */ 584 Drupal.webform.compare_select = function (a, b, element) { 585 var optionList = []; 586 $('option,input:radio,input:checkbox', element).each(function () { 587 optionList.push($(this).val()); 588 }); 589 var a_position = optionList.indexOf(a); 590 var b_position = optionList.indexOf(b); 591 return (a_position < 0 || b_position < 0) ? null : a_position - b_position; 592 }; 593 594 /** 595 * Utility to return current visibility. 596 * 597 * Uses actual visibility, except for hidden components which use the applied 598 * disabled class. 599 */ 600 Drupal.webform.isVisible = function ($element) { 601 return $element.hasClass('webform-component-hidden') 602 ? !$element.find('input').first().hasClass('webform-conditional-disabled') 603 : $element.closest('.webform-conditional-hidden').length == 0; 604 }; 605 606 /** 607 * Function to get a string value from a select/radios/text/etc. field. 608 */ 609 Drupal.webform.stringValue = function (element, existingValue) { 610 var value = []; 611 if (element) { 612 var $element = $(element); 613 if (Drupal.webform.isVisible($element)) { 614 // Checkboxes and radios. 615 $element.find('input[type=checkbox]:checked,input[type=radio]:checked').each(function () { 616 value.push(this.value); 617 }); 618 // Select lists. 619 if (!value.length) { 620 var selectValue = $element.find('select').val(); 621 if (selectValue) { 622 if ($.isArray(selectValue)) { 623 value = selectValue; 624 } 625 else { 626 value.push(selectValue); 627 } 628 } 629 } 630 // Simple text fields. This check is done last so that the select list 631 // in select-or-other fields comes before the "other" text field. 632 if (!value.length) { 633 $element.find('input:not([type=checkbox],[type=radio]),textarea').each(function () { 634 value.push(this.value); 635 }); 636 } 637 } 638 } 639 else { 640 switch ($.type(existingValue)) { 641 case 'array':
642 value = existingValue; 643 break; 644 645 case 'string': 646 value.push(existingValue); 647 break; 648 } 649 } 650 return value; 651 }; 652 653 /** 654 * Utility function to calculate a second-based timestamp from a time field. 655 */ 656 Drupal.webform.dateValue = function (element, existingValue) { 657 var value = false; 658 if (element) { 659 var $element = $(element); 660 if (Drupal.webform.isVisible($element)) { 661 var day = $element.find('[name*=day]').val(); 662 var month = $element.find('[name*=month]').val(); 663 var year = $element.find('[name*=year]').val(); 664 // Months are 0 indexed in JavaScript. 665 if (month) { 666 month--; 667 } 668 if (year !== '' && month !== '' && day !== '') { 669 value = Date.UTC(year, month, day) / 1000; 670 } 671 } 672 } 673 else { 674 if ($.type(existingValue) === 'array' && existingValue.length) { 675 existingValue = existingValue[0]; 676 } 677 if ($.type(existingValue) === 'string') { 678 existingValue = existingV
678alue.split('-'); 679 } 680 if (existingValue.length === 3) { 681 value = Date.UTC(existingValue[0], existingValue[1], existingValue[2]) / 1000; 682 } 683 } 684 return value; 685 }; 686 687 /** 688 * Utility function to calculate a millisecond timestamp from a time field. 689 */ 690 Drupal.webform.timeValue = function (element, existingValue) { 691 var value = false; 692 if (element) { 693 var $element = $(element); 694 if (Drupal.webform.isVisible($element)) { 695 var hour = $element.find('[name*=hour]').val(); 696 var minute = $element.find('[name*=minute]').val(); 697 var ampm = $element.find('[name*=ampm]:checked').val(); 698 699 // Convert to integers if set. 700 hour = (hour === '') ? hour : parseInt(hour); 701 minute = (minute === '') ? minute : parseInt(minute); 702 703 if (hour !== '') { 704 hour = (hour < 12 && ampm == 'pm') ? hour + 12 : hour; 705 hour = (hour === 12 && ampm == 'am') ? 0 : hour; 706 } 707 if (hour !== '' && minute !== '') { 708 value = Date.UTC(1970, 0, 1, hour, minute) / 1000; 709 } 710 } 711 } 712 else { 713 if ($.type(existingValue) === 'array' && existingValue.length) {
714 existingValue = existingValue[0]; 715 } 716 if ($.type(existingValue) === 'string') { 717 existingValue = existingValue.split(':'); 718 } 719 if (existingValue.length >= 2) { 720 value = Date.UTC(1970, 0, 1, existingValue[0], existingValue[1]) / 1000; 721 } 722 } 723 return value; 724 }; 725 726 /** 727 * Make a prop shim for jQuery < 1.9. 728 */ 729 $.fn.webformProp = $.fn.webformProp || function (name, value) { 730 if (value) { 731 return $.fn.prop ? this.prop(name, true) : this.attr(name, true); 732 } 733 else { 734 return $.fn.prop ? this.prop(name, false) : this.removeAttr(name); 735 } 736 }; 737 738 /** 739 * Make a multi-valued val() function. 740 * 741 * This is for setting checkboxes, radios, and select elements. 742 */ 743 $.fn.webformVal = function (values) { 744 this.each(function () { 745 var $this = $(this); 746 var value = $this.val(); 747 var on = $.inArray($this.val(), values) != -1; 748 if (this.nodeName == 'OPTION') { 749 $this.webformProp('selected', on ? value : false); 750 } 751 else { 752 $this.val(on ? [value] : false); 753 } 754 }); 755 return this; 756 }; 757 758 /** 759 * Given a table's DOM element, restripe the odd/even classes. 760 */ 761 Drupal.webform.restripeTable = function (table) { 762 // :even and :odd are reversed because jQuery counts from 0 and 763 // we count from 1, so we're out of sync. 764 // Match immediate children of the parent element to allow nesting. 765 $('> tbody > tr, > tr', table) 766 .filter(':visible:odd').filter('.odd') 767 .removeClass('odd').addClass('even') 768 .end().end() 769 .filter(':visible:even').filter('.even') 770 .removeClass('even').addClass('odd'); 771 }; 772 773})(jQuery); 774;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.