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