1// Every file in scripts/ acts as an entry-point and gets tranformed to build/. 2// Feel free to create as much as you want. 3// Files in subdirectories will be ignored but you can require them in entry-point-files. 4// Add an _ to a file and it will just be ignored(good for tests). 5// Add your entry-point-files to templates/layout/yourlayout.html 6 7// =============================================================================== 8// CORE 9// =============================================================================== 10 11// ATOMS 12 13/** 14 * 15 * Detect current input method and add a class to the body 16 * so things can be styled accordingly, e.g. tab-key focussed focus styles 17 * 18 */ 19 20// Add body class if user is tabbing 21function handleFirstTab(e) { 22 if (e.keyCode === 9) { 23 document.body.classList.add('user-is-tabbing'); 24 window.removeEventListener('keydown', handleFirstTab); 25 26 // Start listening for mouse usage 27 window.addEventListener('mousedown', handleMouseDownOnce); 28 } 29} 30 31// Remove body class if user is using a mouse 32function handleMouseDownOnce() { 33 document.body.classList.remove('user-is-tabbing'); 34 window.removeEventListener('mousedown', handleMouseDownOnce); 35 window.addEventListener('keydown', handleFirstTab); 36} 37 38// Start listening for tab usage 39window.addEventListener('keydown', handleFirstTab); 40 41$(document).ready(function () { 42 var $button; 43 44 uploadInit(); 45 46 function bindMultipleDelete() { 47 $('.multiple__delete').on('click', function (event) { 48 $button = $(this); 49 50 event.preventDefault(); 51 52 if ($button.attr('data-multi-argument')) { 53 $template_path = 54 $button.attr('data-multi-path') + 55 '&' + 56 $button.attr('data-multi-argument') + 57 '=' + 58 $button.attr('data-multi-id'); 59 60 $.ajax({ 61 url: $template_path, 62 }).done(function (html) {}); 63 } else { 64 // 65 } 66 67 $button.parents('.multiple__wrap').remove(); 68 }); 69 } 70 71 function uploadInit() { 72 $('.upload input[type=file]:not(.upload-initialised)').each( 73 function () { 74 var eventNamespace = '.upload'; 75 var labelInputValueAttr = 'data-input-value'; 76 var $input = $(this); 77 $input.removeClass('empty'); 78 var $inputClone = $input.clone(true, true); 79 var $label = $input.next('label'); 80 81 var setLabelInputValue = function () { 82 var $input = $(this); 83 84 if ($input.val() && $input.val() !== '') { 85 $input.removeClass('empty'); 86 $label.attr( 87 labelInputValueAttr, 88 $input.val().split('\\').pop() 89 ); 90 } else { 91 $label.attr(labelInputValueAttr, ''); 92 $input.addClass('empty'); 93 } 94 }; 95 96 if (!$input.val() || $input.val() === '') { 97 $input.addClass('empty'); 98 } 99 100 $label.attr(labelInputValueAttr, ''); 101 $input.on('change' + eventNamespace, setLabelInputValue); 102 $label.on('click' + eventNamespace, function (event) { 103 if ( 104 $input.val() && 105 $input.val() !== '' && 106 $input.is(':valid') 107 ) { 108 event.preventDefault(); 109 $input.remove(); 110 $label.before($inputClone); // cant just empty val because of ie 111 $input = $inputClone; 112 113 if (!$input.val() || $input.val() === '') { 114 $input.addClass('empty'); 115 } 116 117 $inputClone = $input.clone(true, true); 118 $inputClone.removeClass('empty'); 119 $input.off('change' + eventNamespace); 120 $input.on( 121 'change' + eventNamespace, 122 setLabelInputValue 123 ); 124 125 $label.attr(labelInputValueAttr, ''); 126 } 127 }); 128 129 $input.addClass('upload-initialised'); 130 } 131 ); 132 } 133 134 (function () { 135 bindMultipleDelete(); 136 137 $('div[data-multi-btn]').on('click', function (event) { 138 $button = $(this); 139 event.preventDefault(); 140 141 if ($(this).attr('data-multi-argument')) { 142 $template_path = 143 $(this).attr('data-multi-path') + 144 '&' + 145 $(this).attr('data-multi-argument') + 146 '=' + 147 $(this).attr('data-multi-iteration'); 148 } else { 149 $template_path = $(this).attr('data-multi-path'); 150 } 151 152 $container = $('#' + $(this).attr('data-multi-cont')); 153 154 $.ajax({ 155 url: $template_path, 156 }).done(function (html) { 157 $container.append(html); 158 bindMultipleDelete(); 159 160 $button.attr( 161 'data-multi-iteration', 162 parseInt($button.attr('data-multi-iteration')) + 1 163 ); 164 uploadInit(); 165 }); 166 }); 167 })(); 168}); 169 170// //=require jquery.sumoselect.js 171 172$(document).ready(function () { 173 174 var lang = { 175 de: { 176 'PLEASE_CHOOSE': 'Bitte wählen', 177 'CHOOSE': 'auswählen', 178 'CHOOSE_ALL': 'Alle auswählen', 179 'CHOOSED': 'ausgewählt', 180 'ALL': 'Alle', 181 'SEARCH': 'Suche', 182 'NO_RESULTS_FOR': 'Keine Ergebnisse für ', 183 'OK': 'OK', 184 'CANCEL': 'Abbrechen' 185 }, 186 en: { 187 'PLEASE_CHOOSE': 'Please choose', 188 'CHOOSE': 'choose', 189 'CHOOSE_ALL': 'Choose all', 190 'CHOOSED': 'choosed', 191 'ALL': 'All', 192 'SEARCH': 'Search', 193 'NO_RESULTS_FOR': 'No results for ', 194 'OK': 'OK', 195 'CANCEL': 'Cancel' 196 } 197 } 198 199 lang = lang[$('html').attr('lang') || 'de']; 200 201 202 $('select.form-control, .js__sumoselect').each(function () { 203 var $this = $(this); 204 205 $this.SumoSelect({ 206 placeholder: $this.attr('placeholder') || lang['PLEASE_CHOOSE'], 207 floatWidth: 0, 208 forceCustomRendering: false, 209 nativeOnDevice: ['Android', 'BlackBerry', 'iPhone', 'iPad', 'iPod', 'Opera Mini', 'IEMobile', 'Silk'], 210 captionFormat: '{0} ' + lang['CHOOSED'], 211 captionFormatAllSelected: $this.attr('data-choose-all') || lang['CHOOSE_ALL'], 212 // selectAll: $this.attr('data-select-all') || true, 213 selectAll: false, 214 // okCancelInMulti: true, 215 search: $this.attr('data-search') || false, 216 searchText: lang['SEARCH'], 217 noMatch: lang['NO_RESULTS_FOR'] + ' "{0}"', 218 locale: [ 219 lang['OK'], 220 lang['CANCEL'], 221 $this.attr('data-choose-all') || lang['CHOOSE_ALL'] 222 ], 223 triggerChangeCombined: true 224 }); 225 }); 226 227}); 228 229 230$(document).ready(function(){ 231 232 233 $("select.select--submit-onchange, .js__select-submit-onchange").on("change", function(){ 234 $(this).parents("form").submit(); 235 }); 236 237 $("select.select--jump-onchange, .js__select-jump-onchange").on("change", function(){ 238 jumpMenu( 'parent',this,0); 239 }); 240 241}); 242 243 244function jumpMenu(targ,selObj,restore) { 245 window.location='http://'+window.location.hostname+'/'+selObj.options[selObj.selectedIndex].value; 246 if (restore) selObj.selectedIndex = 0; 247} 248 249/*! 250 * jQuery Validation Plugin v1.16.1-pre 251 * 252 * http://jqueryvalidation.org/ 253 * 254 * Copyright (c) 2017 Jörn Zaefferer 255 * Released under the MIT license 256 */ 257(function( factory ) { 258 if ( typeof define === "function" && define.amd ) { 259 define( ["jquery"], factory ); 260 } else if (typeof module === "object" && module.exports) { 261 module.exports = factory( require( "jquery" ) ); 262 } else { 263 factory( jQuery ); 264 } 265}(function( $ ) { 266 267$.extend( $.fn, { 268 269 // http://jqueryvalidation.org/validate/ 270 validate: function( options ) { 271 272 // If nothing is selected, return nothing; can't chain anyway 273 if ( !this.length ) { 274 if ( options && options.debug && window.console ) { 275 console.warn( "Nothing selected, can't validate, returning nothing." ); 276 } 277 return; 278 } 279 280 // Check if a validator for this form was already created
281 var validator = $.data( this[ 0 ], "validator" ); 282 if ( validator ) { 283 return validator; 284 } 285 286 // Add novalidate tag if HTML5. 287 this.attr( "novalidate", "novalidate" ); 288 289 validator = new $.validator( options, this[ 0 ] ); 290 $.data( this[ 0 ], "validator", validator ); 291 292 if ( validator.settings.onsubmit ) { 293 294 this.on( "click.validate", ":submit", function( event ) { 295 if ( validator.settings.submitHandler ) { 296 validator.submitButton = event.currentTarget; 297 } 298 299 // Allow suppressing validation by adding a cancel class to the submit button 300 if ( $( this ).hasClass( "cancel" ) ) { 301 validator.cancelSubmit = true; 302 } 303 304 // Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button 305 if ( $( this ).attr( "formnovalidate" ) !== undefined ) { 306 validator.cancelSubmit = true; 307 } 308 } ); 309 310 // Validate the form on submit 311 this.on( "submit.validate", function( event ) { 312 if ( validator.settings.debug ) { 313 314 // Prevent form submit to be able to see console output 315 event.preventDefault(); 316 } 317 function handle() { 318 var hidden, result; 319 if ( validator.settings.submitHandler ) { 320 if ( validator.submitButton ) { 321 322 // Insert a hidden input as a replacement for the missing submit button 323 hidden = $( "<input type='hidden'/>" ) 324 .attr( "name", validator.submitButton.name ) 325 .val( $( validator.submitButton ).val() ) 326 .appendTo( validator.currentForm ); 327 } 328 result = validator.settings.submitHandler.call( validator, validator.currentForm, event ); 329 if ( validator.submitButton ) { 330 331 // And clean up afterwards; thanks to no-block-scope, hidden can be referenced 332 hidden.remove(); 333 } 334 if ( result !== undefined ) { 335 return result; 336 } 337 return false; 338 } 339 return true; 340 } 341 342 // Prevent submit for invalid forms or custom submit handlers 343 if ( validator.cancelSubmit ) { 344 validator.cancelSubmit = false; 345 return handle(); 346 } 347 if ( validator.form() ) { 348 if ( validator.pendingRequest ) { 349 validator.formSubmitted = true; 350 return false; 351 } 352 return handle(); 353 } else { 354 validator.focusInvalid(); 355 return false; 356 } 357 } ); 358 } 359 360 return validator; 361 }, 362 363 // http://jqueryvalidation.org/valid/ 364 valid: function() { 365 var valid, validator, errorList; 366 367 if ( $( this[ 0 ] ).is( "form" ) ) { 368 valid = this.validate().form(); 369 } else { 370 errorList = []; 371 valid = true; 372 validator = $( this[ 0 ].form ).validate(); 373 this.each( function() { 374 valid = validator.element( this ) && valid; 375 if ( !valid ) { 376 errorList = errorList.concat( validator.errorList ); 377 } 378 } ); 379 validator.errorList = errorList; 380 } 381 return valid; 382 }, 383 384 // http://jqueryvalidation.org/rules/ 385 rules: function( command, argument ) { 386 var element = this[ 0 ], 387 settings, staticRules, existingRules, data, param, filtered; 388 389 // If nothing is selected, return empty object; can't chain anyway 390 if ( element == null ) { 391 return; 392 } 393 394 if ( !element.form && element.hasAttribute( "contenteditable" ) ) { 395 element.form = this.closest( "form" )[ 0 ]; 396 element.name = this.attr( "name" ); 397 } 398 399 if ( element.form == null ) { 400 return; 401 } 402 403 if ( command ) { 404 settings = $.data( element.form, "validator" ).settings; 405 staticRules = settings.rules; 406 existingRules = $.validator.staticRules( element ); 407 switch ( command ) { 408 case "add": 409 $.extend( existingRules, $.validator.normalizeRule( argument ) ); 410 411 // Remove messages from rules, but allow them to be set separately 412 delete existingRules.messages; 413 staticRules[ element.name ] = existingRules; 414 if ( argument.messages ) { 415 settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages ); 416 } 417 break; 418 case "remove": 419 if ( !argument ) { 420 delete staticRules[ element.name ]; 421 return existingRules; 422 } 423 filtered = {}; 424 $.each( argument.split( /\s/ ), function( index, method ) { 425 filtered[ method ] = existingRules[ method ]; 426 delete existingRules[ method ]; 427 if ( method === "required" ) { 428 $( element ).removeAttr( "aria-required" ); 429 } 430 } ); 431 return filtered; 432 } 433 } 434 435 data = $.validator.normalizeRules( 436 $.extend( 437 {}, 438 $.validator.classRules( element ), 439 $.validator.attributeRules( element ), 440 $.validator.dataRules( element ), 441 $.validator.staticRules( element ) 442 ), element ); 443 444 // Make sure required is at front 445 if ( data.required ) { 446 param = data.required; 447 delete data.required; 448 data = $.extend( { required: param }, data ); 449 $( element ).attr( "aria-required", "true" ); 450 } 451 452 // Make sure remote is at back 453 if ( data.remote ) { 454 param = data.remote; 455 delete data.remote; 456 data = $.extend( data, { remote: param } ); 457 } 458 459 return data; 460 } 461} ); 462 463// Custom selectors 464$.extend( $.expr.pseudos || $.expr[ ":" ], { // '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support 465 466 // http://jqueryvalidation.org/blank-selector/ 467 blank: function( a ) { 468 return !$.trim( "" + $( a ).val() ); 469 }, 470 471 // http://jqueryvalidation.org/filled-selector/ 472 filled: function( a ) { 473 var val = $( a ).val(); 474 return val !== null && !!$.trim( "" + val ); 475 }, 476 477 // http://jqueryvalidation.org/unchecked-selector/ 478 unchecked: function( a ) { 479 return !$( a ).prop( "checked" ); 480 } 481} ); 482 483// Constructor for validator 484$.validator = function( options, form ) { 485 this.settings = $.extend( true, {}, $.validator.defaults, options ); 486 this.currentForm = form; 487 this.init(); 488}; 489 490// http://jqueryvalidation.org/jQuery.validator.format/ 491$.validator.format = function( source, params ) { 492 if ( arguments.length === 1 ) { 493 return function() { 494 var args = $.makeArray( arguments ); 495 args.unshift( source ); 496 return $.validator.format.apply( this, args ); 497 }; 498 } 499 if ( params === undefined ) { 500 return source; 501 }
vendor: 10,001 bytes, lines 502-813
502 if ( arguments.length > 2 && params.constructor !== Array ) { 503 params = $.makeArray( arguments ).slice( 1 ); 504 } 505 if ( params.constructor !== Array ) { 506 params = [ params ]; 507 } 508 $.each( params, function( i, n ) { 509 source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() { 510 return n; 511 } ); 512 } ); 513 return source; 514}; 515 516$.extend( $.validator, { 517 518 defaults: { 519 messages: {}, 520 groups: {}, 521 rules: {}, 522 errorClass: "error", 523 pendingClass: "pending", 524 validClass: "valid", 525 errorElement: "label", 526 focusCleanup: false, 527 focusInvalid: true, 528 errorContainer: $( [] ), 529 errorLabelContainer: $( [] ), 530 onsubmit: true, 531 ignore: ":hidden", 532 ignoreTitle: false, 533 onfocusin: function( element ) { 534 this.lastActive = element; 535 536 // Hide error label and remove error class on focus if enabled 537 if ( this.settings.focusCleanup ) { 538 if ( this.settings.unhighlight ) { 539 this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); 540 } 541 this.hideThese( this.errorsFor( element ) ); 542 } 543 }, 544 onfocusout: function( element ) { 545 if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) { 546 this.element( element ); 547 } 548 }, 549 onkeyup: function( element, event ) { 550 551 // Avoid revalidate the field when pressing one of the following keys 552 // Shift => 16 553 // Ctrl => 17 554 // Alt => 18 555 // Caps lock => 20 556 // End => 35 557 // Home => 36 558 // Left arrow => 37 559 // Up arrow => 38 560 // Right arrow => 39 561 // Down arrow => 40 562 // Insert => 45 563 // Num lock => 144 564 // AltGr key => 225 565 var excludedKeys = [ 566 16, 17, 18, 20, 35, 36, 37, 567 38, 39, 40, 45, 144, 225 568 ]; 569 570 if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) { 571 return; 572 } else if ( element.name in this.submitted || element.name in this.invalid ) { 573 this.element( element ); 574 } 575 }, 576 onclick: function( element ) { 577 578 // Click on selects, radiobuttons and checkboxes 579 if ( element.name in this.submitted ) { 580 this.element( element ); 581 582 // Or option elements, check parent select in that case 583 } else if ( element.parentNode.name in this.submitted ) { 584 this.element( element.parentNode ); 585 } 586 }, 587 highlight: function( element, errorClass, validClass ) { 588 if ( element.type === "radio" ) { 589 this.findByName( element.name ).addClass( errorClass ).removeClass( validClass ); 590 } else { 591 $( element ).addClass( errorClass ).removeClass( validClass ); 592 } 593 }, 594 unhighlight: function( element, errorClass, validClass ) { 595 if ( element.type === "radio" ) { 596 this.findByName( element.name ).removeClass( errorClass ).addClass( validClass ); 597 } else { 598 $( element ).removeClass( errorClass ).addClass( validClass ); 599 } 600 } 601 }, 602 603 // http://jqueryvalidation.org/jQuery.validator.setDefaults/ 604 setDefaults: function( settings ) { 605 $.extend( $.validator.defaults, settings ); 606 }, 607 608 messages: { 609 required: "This field is required.", 610 remote: "Please fix this field.", 611 email: "Please enter a valid email address.", 612 url: "Please enter a valid URL.", 613 date: "Please enter a valid date.", 614 dateISO: "Please enter a valid date (ISO).", 615 number: "Please enter a valid number.", 616 digits: "Please enter only digits.", 617 equalTo: "Please enter the same value again.", 618 maxlength: $.validator.format( "Please enter no more than {0} characters." ), 619 minlength: $.validator.format( "Please enter at least {0} characters." ), 620 rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ), 621 range: $.validator.format( "Please enter a value between {0} and {1}." ), 622 max: $.validator.format( "Please enter a value less than or equal to {0}." ), 623 min: $.validator.format( "Please enter a value greater than or equal to {0}." ), 624 step: $.validator.format( "Please enter a multiple of {0}." ) 625 }, 626 627 autoCreateRanges: false, 628 629 prototype: { 630 631 init: function() { 632 this.labelContainer = $( this.settings.errorLabelContainer ); 633 this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm ); 634 this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer ); 635 this.submitted = {}; 636 this.valueCache = {}; 637 this.pendingRequest = 0; 638 this.pending = {}; 639 this.invalid = {}; 640 this.reset(); 641 642 var groups = ( this.groups = {} ), 643 rules; 644 $.each( this.settings.groups, function( key, value ) { 645 if ( typeof value === "string" ) { 646 value = value.split( /\s/ ); 647 } 648 $.each( value, function( index, name ) { 649 groups[ name ] = key; 650 } ); 651 } ); 652 rules = this.settings.rules; 653 $.each( rules, function( key, value ) { 654 rules[ key ] = $.validator.normalizeRule( value ); 655 } ); 656 657 function delegate( event ) { 658 659 // Set form expando on contenteditable 660 if ( !this.form && this.hasAttribute( "contenteditable" ) ) { 661 this.form = $( this ).closest( "form" )[ 0 ]; 662 this.name = $( this ).attr( "name" ); 663 } 664 665 var validator = $.data( this.form, "validator" ), 666 eventType = "on" + event.type.replace( /^validate/, "" ), 667 settings = validator.settings; 668 if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) { 669 settings[ eventType ].call( validator, this, event ); 670 } 671 } 672 673 $( this.currentForm ) 674 .on( "focusin.validate focusout.validate keyup.validate", 675 ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " + 676 "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " + 677 "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " + 678 "[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate ) 679 680 // Support: Chrome, oldIE 681 // "select" is provided as event.target when clicking a option 682 .on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate ); 683 684 if ( this.settings.invalidHandler ) { 685 $( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler ); 686 } 687 688 // Add aria-required to any Static/Data/Class required fields before first validation 689 // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html 690 $( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" ); 691 }, 692 693 // http://jqueryvalidation.org/Validator.form/ 694 form: function() { 695 this.checkForm(); 696 $.extend( this.submitted, this.errorMap ); 697 this.invalid = $.extend( {}, this.errorMap ); 698 if ( !this.valid() ) { 699 $( this.currentForm ).triggerHandler( "invalid-form", [ this ] ); 700 } 701 this.showErrors(); 702 return this.valid(); 703 }, 704 705 checkForm: function() { 706 this.prepareForm(); 707 for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) { 708 this.check( elements[ i ] ); 709 } 710 return this.valid(); 711 }, 712 713 // http://jqueryvalidation.org/Validator.element/ 714 element: function( element ) { 715 var cleanElement = this.clean( element ), 716 checkElement = this.validationTargetFor( cleanElement ), 717 v = this, 718 result = true, 719 rs, group; 720 721 if ( checkElement === undefined ) { 722 delete this.invalid[ cleanElement.name ]; 723 } else { 724 this.prepareElement( checkElement ); 725 this.currentElements = $( checkElement ); 726 727 // If this element is grouped, then validate all group elements already 728 // containing a value 729 group = this.groups[ checkElement.name ]; 730 if ( group ) { 731 $.each( this.groups, function( name, testgroup ) { 732 if ( testgroup === group && name !== checkElement.name ) { 733 cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) ); 734 if ( cleanElement && cleanElement.name in v.invalid ) { 735 v.currentElements.push( cleanElement ); 736 result = v.check( cleanElement ) && result; 737 } 738 } 739 } ); 740 } 741 742 rs = this.check( checkElement ) !== false; 743 result = result && rs; 744 if ( rs ) { 745 this.invalid[ checkElement.name ] = false; 746 } else { 747 this.invalid[ checkElement.name ] = true; 748 } 749 750 if ( !this.numberOfInvalids() ) { 751 752 // Hide error containers on last error 753 this.toHide = this.toHide.add( this.containers ); 754 } 755 this.showErrors(); 756 757 // Add aria-invalid status for screen readers 758 $( element ).attr( "aria-invalid", !rs ); 759 } 760 761 return result; 762 }, 763 764 // http://jqueryvalidation.org/Validator.showErrors/ 765 showErrors: function( errors ) { 766 if ( errors ) { 767 var validator = this; 768 769 // Add items to error list and map 770 $.extend( this.errorMap, errors ); 771 this.errorList = $.map( this.errorMap, function( message, name ) { 772 return { 773 message: message, 774 element: validator.findByName( name )[ 0 ] 775 }; 776 } ); 777 778 // Remove items from success list 779 this.successList = $.grep( this.successList, function( element ) { 780 return !( element.name in errors ); 781 } ); 782 } 783 if ( this.settings.showErrors ) { 784 this.settings.showErrors.call( this, this.errorMap, this.errorList ); 785 } else { 786 this.defaultShowErrors(); 787 } 788 }, 789 790 // http://jqueryvalidation.org/Validator.resetForm/ 791 resetForm: function() { 792 if ( $.fn.resetForm ) { 793 $( this.currentForm ).resetForm(); 794 } 795 this.invalid = {}; 796 this.submitted = {}; 797 this.prepareForm(); 798 this.hideErrors(); 799 var elements = this.elements() 800 .removeData( "previousValue" ) 801 .removeAttr( "aria-invalid" ); 802 803 this.resetElements( elements ); 804 }, 805 806 resetElements: function( elements ) { 807 var i; 808 809 if ( this.settings.unhighlight ) { 810 for ( i = 0; elements[ i ]; i++ ) { 811 this.settings.unhighlight.call( this, elements[ i ], 812 this.settings.errorClass, "" ); 813 this.findByName( elements[ i ].name ).removeClass( this.settings.val
813idClass ); 814 } 815 } else { 816 elements 817 .removeClass( this.settings.errorClass ) 818 .removeClass( this.settings.validClass ); 819 } 820 }, 821 822 numberOfInvalids: function() { 823 return this.objectLength( this.invalid ); 824 }, 825 826 objectLength: function( obj ) { 827 /* jshint unused: false */ 828 var count = 0, 829 i; 830 for ( i in obj ) { 831 832 // This check allows counting elements with empty error 833 // message as invalid elements 834 if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) { 835 count++; 836 } 837 } 838 return count; 839 }, 840 841 hideErrors: function() { 842 this.hideThese( this.toHide ); 843 }, 844 845 hideThese: function( errors ) { 846 errors.not( this.containers ).text( "" ); 847 this.addWrapper( errors ).hide(); 848 }, 849 850 valid: function() { 851 return this.size() === 0; 852 }, 853 854 size: function() { 855 return this.errorList.length; 856 }, 857 858 focusInvalid: function() { 859 if ( this.settings.focusInvalid ) { 860 try { 861 $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] ) 862 .filter( ":visible" ) 863 .focus() 864 865 // Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find 866 .trigger( "focusin" ); 867 } catch ( e ) { 868 869 // Ignore IE throwing errors when focusing hidden elements 870 } 871 } 872 }, 873 874 findLastActive: function() { 875 var lastActive = this.lastActive; 876 return lastActive && $.grep( this.errorList, function( n ) { 877 return n.element.name === lastActive.name; 878 } ).length === 1 && lastActive; 879 }, 880 881 elements: function() { 882 var validator = this, 883 rulesCache = {}; 884 885 // Select all valid inputs inside the form (no submit or reset buttons) 886 return $( this.currentForm ) 887 .find( "input, select, textarea, [contenteditable]" ) 888 .not( ":submit, :reset, :image, :disabled" ) 889 .not( this.settings.ignore ) 890 .filter( function() { 891 var name = this.name || $( this ).attr( "name" ); // For contenteditable 892 if ( !name && validator.settings.debug && window.console ) { 893 console.error( "%o has no name assigned", this ); 894 } 895 896 // Set form expando on contenteditable 897 if ( this.hasAttribute( "contenteditable" ) ) { 898 this.form = $( this ).closest( "form" )[ 0 ]; 899 this.name = name; 900 } 901 902 // Select only the first element for each name, and only those with rules specified 903 if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { 904 return false; 905 } 906 907 rulesCache[ name ] = true; 908 return true; 909 } ); 910 }, 911 912 clean: function( selector ) { 913 return $( selector )[ 0 ]; 914 }, 915 916 errors: function() { 917 var errorClass = this.settings.errorClass.split( " " ).join( "." ); 918 return $( this.settings.errorElement + "." + errorClass, this.errorContext ); 919 }, 920 921 resetInternals: function() { 922 this.successList = []; 923 this.errorList = []; 924 this.errorMap = {}; 925 this.toShow = $( [] ); 926 this.toHide = $( [] ); 927 }, 928 929 reset: function() { 930 this.resetInternals(); 931 this.currentElements = $( [] ); 932 }, 933 934 prepareForm: function() { 935 this.reset(); 936 this.toHide = this.errors().add( this.containers ); 937 }, 938 939 prepareElement: function( element ) { 940 this.reset(); 941 this.toHide = this.errorsFor( element ); 942 }, 943 944 elementValue: function( element ) { 945 var $element = $( element ), 946 type = element.type, 947 val, idx; 948 949 if ( type === "radio" || type === "checkbox" ) { 950 return this.findByName( element.name ).filter( ":checked" ).val(); 951 } else if ( type === "number" && typeof element.validity !== "undefined" ) { 952 return element.validity.badInput ? "NaN" : $element.val(); 953 } 954 955 if ( element.hasAttribute( "contenteditable" ) ) { 956 val = $element.text(); 957 } else { 958 val = $element.val(); 959 } 960 961 if ( type === "file" ) { 962 963 // Modern browser (chrome & safari) 964 if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) { 965 return val.substr( 12 ); 966 } 967 968 // Legacy browsers 969 // Unix-based path 970 idx = val.lastIndexOf( "/" ); 971 if ( idx >= 0 ) { 972 return val.substr( idx + 1 ); 973 } 974 975 // Windows-based path 976 idx = val.lastIndexOf( "\\" ); 977 if ( idx >= 0 ) { 978 return val.substr( idx + 1 ); 979 } 980 981 // Just the file name 982 return val; 983 } 984 985 if ( typeof val === "string" ) { 986 return val.replace( /\r/g, "" ); 987 } 988 return val; 989 }, 990 991 check: function( element ) { 992 element = this.validationTargetFor( this.clean( element ) ); 993 994 var rules = $( element ).rules(), 995 rulesCount = $.map( rules, function( n, i ) { 996 return i; 997 } ).length, 998 dependencyMismatch = false, 999 val = this.elementValue( element ), 1000 result, method, rule, normalizer; 1001 1002 // Prioritize the local normalizer defined for this element over the global one 1003 // if the former exists, otherwise user the global one in case it exists. 1004 if ( typeof rules.normalizer === "function" ) { 1005 normalizer = rules.normalizer; 1006 } else if ( typeof this.settings.normalizer === "function" ) { 1007 normalizer = this.settings.normalizer; 1008 } 1009 1010 // If normalizer is defined, then call it to retreive the changed value instead 1011 // of using the real one. 1012 // Note that `this` in the normalizer is `element`. 1013 if ( normalizer ) { 1014 val = normalizer.call( element, val ); 1015 1016 if ( typeof val !== "string" ) { 1017 throw new TypeError( "The normalizer should return a string value." ); 1018 } 1019 1020 // Delete the normalizer from rules to avoid treating it as a pre-defined method. 1021 delete rules.normalizer; 1022 } 1023 1024 for ( method in rules ) { 1025 rule = { method: method, parameters: rules[ method ] };
vendor: 4,525 bytes, lines 1026-1162
1026 try { 1027 result = $.validator.methods[ method ].call( this, val, element, rule.parameters ); 1028 1029 // If a method indicates that the field is optional and therefore valid, 1030 // don't mark it as valid when there are no other rules 1031 if ( result === "dependency-mismatch" && rulesCount === 1 ) { 1032 dependencyMismatch = true; 1033 continue; 1034 } 1035 dependencyMismatch = false; 1036 1037 if ( result === "pending" ) { 1038 this.toHide = this.toHide.not( this.errorsFor( element ) ); 1039 return; 1040 } 1041 1042 if ( !result ) { 1043 this.formatAndAdd( element, rule ); 1044 return false; 1045 } 1046 } catch ( e ) { 1047 if ( this.settings.debug && window.console ) { 1048 console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); 1049 } 1050 if ( e instanceof TypeError ) { 1051 e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method."; 1052 } 1053 1054 throw e; 1055 } 1056 } 1057 if ( dependencyMismatch ) { 1058 return; 1059 } 1060 if ( this.objectLength( rules ) ) { 1061 this.successList.push( element ); 1062 } 1063 return true; 1064 }, 1065 1066 // Return the custom message for the given element and validation method 1067 // specified in the element's HTML5 data attribute 1068 // return the generic message if present and no method specific message is present 1069 customDataMessage: function( element, method ) { 1070 return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() + 1071 method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" ); 1072 }, 1073 1074 // Return the custom message for the given element name and validation method 1075 customMessage: function( name, method ) { 1076 var m = this.settings.messages[ name ]; 1077 return m && ( m.constructor === String ? m : m[ method ] ); 1078 }, 1079 1080 // Return the first defined argument, allowing empty strings 1081 findDefined: function() { 1082 for ( var i = 0; i < arguments.length; i++ ) { 1083 if ( arguments[ i ] !== undefined ) { 1084 return arguments[ i ]; 1085 } 1086 } 1087 return undefined; 1088 }, 1089 1090 // The second parameter 'rule' used to be a string, and extended to an object literal 1091 // of the following form: 1092 // rule = { 1093 // method: "method name", 1094 // parameters: "the given method parameters" 1095 // } 1096 // 1097 // The old behavior still supported, kept to maintain backward compatibility with 1098 // old code, and will be removed in the next major release. 1099 defaultMessage: function( element, rule ) { 1100 if ( typeof rule === "string" ) { 1101 rule = { method: rule }; 1102 } 1103 1104 var message = this.findDefined( 1105 this.customMessage( element.name, rule.method ), 1106 this.customDataMessage( element, rule.method ), 1107 1108 // 'title' is never undefined, so handle empty string as undefined 1109 !this.settings.ignoreTitle && element.title || undefined, 1110 $.validator.messages[ rule.method ], 1111 "<strong>Warning: No message defined for " + element.name + "</strong>" 1112 ), 1113 theregex = /\$?\{(\d+)\}/g; 1114 if ( typeof message === "function" ) { 1115 message = message.call( this, rule.parameters, element ); 1116 } else if ( theregex.test( message ) ) { 1117 message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters ); 1118 } 1119 1120 return message; 1121 }, 1122 1123 formatAndAdd: function( element, rule ) { 1124 var message = this.defaultMessage( element, rule ); 1125 1126 this.errorList.push( { 1127 message: message, 1128 element: element, 1129 method: rule.method 1130 } ); 1131 1132 this.errorMap[ element.name ] = message; 1133 this.submitted[ element.name ] = message; 1134 }, 1135 1136 addWrapper: function( toToggle ) { 1137 if ( this.settings.wrapper ) { 1138 toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); 1139 } 1140 return toToggle; 1141 }, 1142 1143 defaultShowErrors: function() { 1144 var i, elements, error; 1145 for ( i = 0; this.errorList[ i ]; i++ ) { 1146 error = this.errorList[ i ]; 1147 if ( this.settings.highlight ) { 1148 this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); 1149 } 1150 this.showLabel( error.element, error.message ); 1151 } 1152 if ( this.errorList.length ) { 1153 this.toShow = this.toShow.add( this.containers ); 1154 } 1155 if ( this.settings.success ) { 1156 for ( i = 0; this.successList[ i ]; i++ ) { 1157 this.showLabel( this.successList[ i ] ); 1158 } 1159 } 1160 if ( this.settings.unhighlight ) { 1161 for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) { 1162 this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.val
1162idClass ); 1163 } 1164 } 1165 this.toHide = this.toHide.not( this.toShow ); 1166 this.hideErrors(); 1167 this.addWrapper( this.toShow ).show(); 1168 }, 1169 1170 validElements: function() { 1171 return this.currentElements.not( this.invalidElements() ); 1172 }, 1173 1174 invalidElements: function() { 1175 return $( this.errorList ).map( function() { 1176 return this.element; 1177 } ); 1178 }, 1179 1180 showLabel: function( element, message ) { 1181 var place, group, errorID, v, 1182 error = this.errorsFor( element ), 1183 elementID = this.idOrName( element ), 1184 describedBy = $( element ).attr( "aria-describedby" ); 1185 1186 if ( error.length ) { 1187 1188 // Refresh error/success class 1189 error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); 1190 1191 // Replace message on existing label 1192 error.html( message ); 1193 } else { 1194 1195 // Create error element 1196 error = $( "<" + this.settings.errorElement + ">" ) 1197 .attr( "id", elementID + "-error" ) 1198 .addClass( this.settings.errorClass ) 1199 .html( message || "" ); 1200 1201 // Maintain reference to the element to be placed into the DOM 1202 place = error; 1203 if ( this.settings.wrapper ) { 1204 1205 // Make sure the element is visible, even in IE 1206 // actually showing the wrapped element is handled elsewhere 1207 place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent(); 1208 } 1209 if ( this.labelContainer.length ) { 1210 this.labelContainer.append( place ); 1211 } else if ( this.settings.errorPlacement ) { 1212 this.settings.errorPlacement.call( this, place, $( element ) ); 1213 } else { 1214 place.insertAfter( element ); 1215 } 1216 1217 // Link error back to the element 1218 if ( error.is( "label" ) ) { 1219 1220 // If the error is a label, then associate using 'for' 1221 error.attr( "for", elementID ); 1222 1223 // If the element is not a child of an associated label, then it's necessary 1224 // to explicitly apply aria-describedby 1225 } else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) { 1226 errorID = error.attr( "id" ); 1227 1228 // Respect existing non-error aria-describedby 1229 if ( !describedBy ) { 1230 describedBy = errorID; 1231 } else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) { 1232 1233 // Add to end of list if not already present 1234 describedBy += " " + errorID; 1235 } 1236 $( element ).attr( "aria-describedby", describedBy ); 1237 1238 // If this element is grouped, then assign to all elements in the same group 1239 group = this.groups[ element.name ]; 1240 if ( group ) { 1241 v = this; 1242 $.each( v.groups, function( name, testgroup ) { 1243 if ( testgroup === group ) { 1244 $( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm ) 1245 .attr( "aria-describedby", error.attr( "id" ) ); 1246 } 1247 } ); 1248 } 1249 } 1250 } 1251 if ( !message && this.settings.success ) { 1252 error.text( "" ); 1253 if ( typeof this.settings.success === "string" ) { 1254 error.addClass( this.settings.success ); 1255 } else { 1256 this.settings.success( error, element ); 1257 } 1258 } 1259 this.toShow = this.toShow.add( error ); 1260 }, 1261 1262 errorsFor: function( element ) { 1263 var name = this.escapeCssMeta( this.idOrName( element ) ), 1264 describer = $( element ).attr( "aria-describedby" ), 1265 selector = "label[for='" + name + "'], label[for='" + name + "'] *"; 1266 1267 // 'aria-describedby' should directly reference the error element 1268 if ( describer ) { 1269 selector = selector + ", #" + this.escapeCssMeta( describer ) 1270 .replace( /\s+/g, ", #" ); 1271 } 1272 1273 return this 1274 .errors() 1275 .filter( selector ); 1276 }, 1277 1278 // See https://api.jquery.com/category/selectors/, for CSS 1279 // meta-characters that should be escaped in order to be used with JQuery 1280 // as a literal part of a name/id or any selector. 1281 escapeCssMeta: function( string ) { 1282 return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" ); 1283 }, 1284 1285 idOrName: function( element ) { 1286 return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name ); 1287 }, 1288 1289 validationTargetFor: function( element ) { 1290 1291 // If radio/checkbox, validate first element in group instead 1292 if ( this.checkable( element ) ) { 1293 element = this.findByName( element.name ); 1294 } 1295 1296 // Always apply ignore filter 1297 return $( element ).not( this.settings.ignore )[ 0 ]; 1298 }, 1299 1300 checkable: function( element ) { 1301 return ( /radio|checkbox/i ).test( element.type ); 1302 }, 1303 1304 findByName: function( name ) { 1305 return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" ); 1306 }, 1307 1308 getLength: function( value, element ) { 1309 switch ( element.nodeName.toLowerCase() ) { 1310 case "select": 1311 return $( "option:selected", element ).length; 1312 case "input": 1313 if ( this.checkable( element ) ) { 1314 return this.findByName( element.name ).filter( ":checked" ).length; 1315 } 1316 } 1317 return value.length; 1318 }, 1319 1320 depend: function( param, element ) { 1321 return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true; 1322 }, 1323 1324 dependTypes: { 1325 "boolean": function( param ) { 1326 return param; 1327 }, 1328 "string": function( param, element ) { 1329 return !!$( param, element.form ).length; 1330 }, 1331 "function": function( param, element ) { 1332 return param( element ); 1333 } 1334 }, 1335 1336 optional: function( element ) { 1337 var val = this.elementValue( element ); 1338 return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch"; 1339 }, 1340 1341 startRequest: function( element ) { 1342 if ( !this.pending[ element.name ] ) { 1343 this.pendingRequest++; 1344 $( element ).addClass( this.settings.pendingClass ); 1345 this.pending[ element.name ] = true; 1346 } 1347 }, 1348 1349 stopRequest: function( element, valid ) { 1350 this.pendingRequest--; 1351 1352 // Sometimes synchronization fails, make sure pendingRequest is never < 0 1353 if ( this.pendingRequest < 0 ) { 1354 this.pendingRequest = 0; 1355 } 1356 delete this.pending[ element.name ]; 1357 $( element ).removeClass( this.settings.pendingClass ); 1358 if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { 1359 $( this.currentForm ).submit(); 1360 this.formSubmitted = false;
vendor: 13,084 bytes, lines 1361-1766
1361 } else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) { 1362 $( this.currentForm ).triggerHandler( "invalid-form", [ this ] ); 1363 this.formSubmitted = false; 1364 } 1365 }, 1366 1367 previousValue: function( element, method ) { 1368 method = typeof method === "string" && method || "remote"; 1369 1370 return $.data( element, "previousValue" ) || $.data( element, "previousValue", { 1371 old: null, 1372 valid: true, 1373 message: this.defaultMessage( element, { method: method } ) 1374 } ); 1375 }, 1376 1377 // Cleans up all forms and elements, removes validator-specific events 1378 destroy: function() { 1379 this.resetForm(); 1380 1381 $( this.currentForm ) 1382 .off( ".validate" ) 1383 .removeData( "validator" ) 1384 .find( ".validate-equalTo-blur" ) 1385 .off( ".validate-equalTo" ) 1386 .removeClass( "validate-equalTo-blur" ); 1387 } 1388 1389 }, 1390 1391 classRuleSettings: { 1392 required: { required: true }, 1393 email: { email: true }, 1394 url: { url: true }, 1395 date: { date: true }, 1396 dateISO: { dateISO: true }, 1397 number: { number: true }, 1398 digits: { digits: true }, 1399 creditcard: { creditcard: true } 1400 }, 1401 1402 addClassRules: function( className, rules ) { 1403 if ( className.constructor === String ) { 1404 this.classRuleSettings[ className ] = rules; 1405 } else { 1406 $.extend( this.classRuleSettings, className ); 1407 } 1408 }, 1409 1410 classRules: function( element ) { 1411 var rules = {}, 1412 classes = $( element ).attr( "class" ); 1413 1414 if ( classes ) { 1415 $.each( classes.split( " " ), function() { 1416 if ( this in $.validator.classRuleSettings ) { 1417 $.extend( rules, $.validator.classRuleSettings[ this ] ); 1418 } 1419 } ); 1420 } 1421 return rules; 1422 }, 1423 1424 normalizeAttributeRule: function( rules, type, method, value ) { 1425 1426 // Convert the value to a number for number inputs, and for text for backwards compability 1427 // allows type="date" and others to be compared as strings 1428 if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) { 1429 value = Number( value ); 1430 1431 // Support Opera Mini, which returns NaN for undefined minlength 1432 if ( isNaN( value ) ) { 1433 value = undefined; 1434 } 1435 } 1436 1437 if ( value || value === 0 ) { 1438 rules[ method ] = value; 1439 } else if ( type === method && type !== "range" ) { 1440 1441 // Exception: the jquery validate 'range' method 1442 // does not test for the html5 'range' type 1443 rules[ method ] = true; 1444 } 1445 }, 1446 1447 attributeRules: function( element ) { 1448 var rules = {}, 1449 $element = $( element ), 1450 type = element.getAttribute( "type" ), 1451 method, value; 1452 1453 for ( method in $.validator.methods ) { 1454 1455 // Support for <input required> in both html5 and older browsers 1456 if ( method === "required" ) { 1457 value = element.getAttribute( method ); 1458 1459 // Some browsers return an empty string for the required attribute 1460 // and non-HTML5 browsers might have required="" markup 1461 if ( value === "" ) { 1462 value = true; 1463 } 1464 1465 // Force non-HTML5 browsers to return bool 1466 value = !!value; 1467 } else { 1468 value = $element.attr( method ); 1469 } 1470 1471 this.normalizeAttributeRule( rules, type, method, value ); 1472 } 1473 1474 // 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs 1475 if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) { 1476 delete rules.maxlength; 1477 } 1478 1479 return rules; 1480 }, 1481 1482 dataRules: function( element ) { 1483 var rules = {}, 1484 $element = $( element ), 1485 type = element.getAttribute( "type" ), 1486 method, value; 1487 1488 for ( method in $.validator.methods ) { 1489 value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() ); 1490 this.normalizeAttributeRule( rules, type, method, value ); 1491 } 1492 return rules; 1493 }, 1494 1495 staticRules: function( element ) { 1496 var rules = {}, 1497 validator = $.data( element.form, "validator" ); 1498 1499 if ( validator.settings.rules ) { 1500 rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {}; 1501 } 1502 return rules; 1503 }, 1504 1505 normalizeRules: function( rules, element ) { 1506 1507 // Handle dependency check 1508 $.each( rules, function( prop, val ) { 1509 1510 // Ignore rule when param is explicitly false, eg. required:false 1511 if ( val === false ) { 1512 delete rules[ prop ]; 1513 return; 1514 } 1515 if ( val.param || val.depends ) { 1516 var keepRule = true; 1517 switch ( typeof val.depends ) { 1518 case "string": 1519 keepRule = !!$( val.depends, element.form ).length; 1520 break; 1521 case "function": 1522 keepRule = val.depends.call( element, element ); 1523 break; 1524 } 1525 if ( keepRule ) { 1526 rules[ prop ] = val.param !== undefined ? val.param : true; 1527 } else { 1528 $.data( element.form, "validator" ).resetElements( $( element ) ); 1529 delete rules[ prop ]; 1530 } 1531 } 1532 } ); 1533 1534 // Evaluate parameters 1535 $.each( rules, function( rule, parameter ) { 1536 rules[ rule ] = $.isFunction( parameter ) && rule !== "normalizer" ? parameter( element ) : parameter; 1537 } ); 1538 1539 // Clean number parameters 1540 $.each( [ "minlength", "maxlength" ], function() { 1541 if ( rules[ this ] ) { 1542 rules[ this ] = Number( rules[ this ] ); 1543 } 1544 } ); 1545 $.each( [ "rangelength", "range" ], function() { 1546 var parts; 1547 if ( rules[ this ] ) { 1548 if ( $.isArray( rules[ this ] ) ) { 1549 rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ]; 1550 } else if ( typeof rules[ this ] === "string" ) { 1551 parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ ); 1552 rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ]; 1553 } 1554 } 1555 } ); 1556 1557 if ( $.validator.autoCreateRanges ) { 1558 1559 // Auto-create ranges 1560 if ( rules.min != null && rules.max != null ) { 1561 rules.range = [ rules.min, rules.max ]; 1562 delete rules.min; 1563 delete rules.max; 1564 } 1565 if ( rules.minlength != null && rules.maxlength != null ) { 1566 rules.rangelength = [ rules.minlength, rules.maxlength ]; 1567 delete rules.minlength; 1568 delete rules.maxlength; 1569 } 1570 } 1571 1572 return rules; 1573 }, 1574 1575 // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} 1576 normalizeRule: function( data ) { 1577 if ( typeof data === "string" ) { 1578 var transformed = {}; 1579 $.each( data.split( /\s/ ), function() { 1580 transformed[ this ] = true; 1581 } ); 1582 data = transformed; 1583 } 1584 return data; 1585 }, 1586 1587 // http://jqueryvalidation.org/jQuery.validator.addMethod/ 1588 addMethod: function( name, method, message ) { 1589 $.validator.methods[ name ] = method; 1590 $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ]; 1591 if ( method.length < 3 ) { 1592 $.validator.addClassRules( name, $.validator.normalizeRule( name ) ); 1593 } 1594 }, 1595 1596 // http://jqueryvalidation.org/jQuery.validator.methods/ 1597 methods: { 1598 1599 // http://jqueryvalidation.org/required-method/ 1600 required: function( value, element, param ) { 1601 1602 // Check if dependency is met 1603 if ( !this.depend( param, element ) ) { 1604 return "dependency-mismatch"; 1605 } 1606 if ( element.nodeName.toLowerCase() === "select" ) { 1607 1608 // Could be an array for select-multiple or a string, both are fine this way 1609 var val = $( element ).val(); 1610 return val && val.length > 0; 1611 } 1612 if ( this.checkable( element ) ) { 1613 return this.getLength( value, element ) > 0; 1614 } 1615 return value.length > 0; 1616 }, 1617 1618 // http://jqueryvalidation.org/email-method/ 1619 email: function( value, element ) { 1620 1621 // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address 1622 // Retrieved 2014-01-14 1623 // If you have a problem with this implementation, report a bug against the above spec 1624 // Or use custom methods to implement your own email validation 1625 return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value ); 1626 }, 1627 1628 // http://jqueryvalidation.org/url-method/ 1629 url: function( value, element ) { 1630 1631 // Copyright (c) 2010-2013 Diego Perini, MIT licensed 1632 // https://gist.github.com/dperini/729294 1633 // see also https://mathiasbynens.be/demo/url-regex 1634 // modified to allow protocol-relative URLs 1635 return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value ); 1636 }, 1637 1638 // http://jqueryvalidation.org/date-method/ 1639 date: function( value, element ) { 1640 return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() ); 1641 }, 1642 1643 // http://jqueryvalidation.org/dateISO-method/ 1644 dateISO: function( value, element ) { 1645 return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value ); 1646 }, 1647 1648 // http://jqueryvalidation.org/number-method/ 1649 number: function( value, element ) { 1650 return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value ); 1651 }, 1652 1653 // http://jqueryvalidation.org/digits-method/ 1654 digits: function( value, element ) { 1655 return this.optional( element ) || /^\d+$/.test( value ); 1656 }, 1657 1658 // http://jqueryvalidation.org/minlength-method/ 1659 minlength: function( value, element, param ) { 1660 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 1661 return this.optional( element ) || length >= param; 1662 }, 1663 1664 // http://jqueryvalidation.org/maxlength-method/ 1665 maxlength: function( value, element, param ) { 1666 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 1667 return this.optional( element ) || length <= param; 1668 }, 1669 1670 // http://jqueryvalidation.org/rangelength-method/ 1671 rangelength: function( value, element, param ) { 1672 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 1673 return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] ); 1674 }, 1675 1676 // http://jqueryvalidation.org/min-method/ 1677 min: function( value, element, param ) { 1678 return this.optional( element ) || value >= param; 1679 }, 1680 1681 // http://jqueryvalidation.org/max-method/ 1682 max: function( value, element, param ) { 1683 return this.optional( element ) || value <= param; 1684 }, 1685 1686 // http://jqueryvalidation.org/range-method/ 1687 range: function( value, element, param ) { 1688 return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] ); 1689 }, 1690 1691 // http://jqueryvalidation.org/step-method/ 1692 step: function( value, element, param ) { 1693 var type = $( element ).attr( "type" ), 1694 errorMessage = "Step attribute on input type " + type + " is not supported.", 1695 supportedTypes = [ "text", "number", "range" ], 1696 re = new RegExp( "\\b" + type + "\\b" ), 1697 notSupported = type && !re.test( supportedTypes.join() ), 1698 decimalPlaces = function( num ) { 1699 var match = ( "" + num ).match( /(?:\.(\d+))?$/ ); 1700 if ( !match ) { 1701 return 0; 1702 } 1703 1704 // Number of digits right of decimal point. 1705 return match[ 1 ] ? match[ 1 ].length : 0; 1706 }, 1707 toInt = function( num ) { 1708 return Math.round( num * Math.pow( 10, decimals ) ); 1709 }, 1710 valid = true, 1711 decimals; 1712 1713 // Works only for text, number and range input types 1714 // TODO find a way to support input types date, datetime, datetime-local, month, time and week 1715 if ( notSupported ) { 1716 throw new Error( errorMessage ); 1717 } 1718 1719 decimals = decimalPlaces( param ); 1720 1721 // Value can't have too many decimals 1722 if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) { 1723 valid = false; 1724 } 1725 1726 return this.optional( element ) || valid; 1727 }, 1728 1729 // http://jqueryvalidation.org/equalTo-method/ 1730 equalTo: function( value, element, param ) { 1731 1732 // Bind to the blur event of the target in order to revalidate whenever the target field is updated 1733 var target = $( param ); 1734 if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) { 1735 target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() { 1736 $( element ).valid(); 1737 } ); 1738 } 1739 return value === target.val(); 1740 }, 1741 1742 // http://jqueryvalidation.org/remote-method/ 1743 remote: function( value, element, param, method ) { 1744 if ( this.optional( element ) ) { 1745 return "dependency-mismatch"; 1746 } 1747 1748 method = typeof method === "string" && method || "remote"; 1749 1750 var previous = this.previousValue( element, method ), 1751 validator, data, optionDataString; 1752 1753 if ( !this.settings.messages[ element.name ] ) { 1754 this.settings.messages[ element.name ] = {}; 1755 } 1756 previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ]; 1757 this.settings.messages[ element.name ][ method ] = previous.message; 1758 1759 param = typeof param === "string" && { url: param } || param; 1760 optionDataString = $.param( $.extend( { data: value }, param.data ) ); 1761 if ( previous.old === optionDataString ) { 1762 return previous.valid; 1763 } 1764 1765 previous.old = optionDataString; 1766 validator = this;
1767 this.startRequest( element ); 1768 data = {}; 1769 data[ element.name ] = value; 1770 $.ajax( $.extend( true, { 1771 mode: "abort", 1772 port: "validate" + element.name, 1773 dataType: "json", 1774 data: data, 1775 context: validator.currentForm, 1776 success: function( response ) { 1777 var valid = response === true || response === "true", 1778 errors, message, submitted; 1779 1780 validator.settings.messages[ element.name ][ method ] = previous.originalMessage; 1781 if ( valid ) { 1782 submitted = validator.formSubmitted; 1783 validator.resetInternals(); 1784 validator.toHide = validator.errorsFor( element ); 1785 validator.formSubmitted = submitted; 1786 validator.successList.push( element ); 1787 validator.invalid[ element.name ] = false; 1788 validator.showErrors(); 1789 } else { 1790 errors = {}; 1791 message = response || validator.defaultMessage( element, { method: method, parameters: value } ); 1792 errors[ element.name ] = previous.message = message; 1793 validator.invalid[ element.name ] = true; 1794 validator.showErrors( errors ); 1795 } 1796 previous.valid = valid; 1797 validator.stopRequest( element, valid ); 1798 } 1799 }, param ) ); 1800 return "pending"; 1801 } 1802 } 1803 1804} ); 1805 1806// Ajax mode: abort 1807// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); 1808// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 1809 1810var pendingRequests = {}, 1811 ajax; 1812 1813// Use a prefilter if available (1.5+) 1814if ( $.ajaxPrefilter ) { 1815 $.ajaxPrefilter( function( settings, _, xhr ) { 1816 var port = settings.port; 1817 if ( settings.mode === "abort" ) { 1818 if ( pendingRequests[ port ] ) { 1819 pendingRequests[ port ].abort(); 1820 } 1821 pendingRequests[ port ] = xhr; 1822 } 1823 } ); 1824} else { 1825 1826 // Proxy ajax 1827 ajax = $.ajax; 1828 $.ajax = function( settings ) { 1829 var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, 1830 port = ( "port" in settings ? settings : $.ajaxSettings ).port; 1831 if ( mode === "abort" ) { 1832 if ( pendingRequests[ port ] ) { 1833 pendingRequests[ port ].abort(); 1834 } 1835 pendingRequests[ port ] = ajax.apply( this, arguments ); 1836 return pendingRequests[ port ]; 1837 } 1838 return ajax.apply( this, arguments ); 1839 }; 1840} 1841return $; 1842})); 1843(function( factory ) { 1844 if ( typeof define === "function" && define.amd ) { 1845 define( ["jquery", "../jquery.validate"], factory ); 1846 } else if (typeof module === "object" && module.exports) { 1847 module.exports = factory( require( "jquery" ) ); 1848 } else { 1849 factory( jQuery ); 1850 } 1851}(function( $ ) { 1852 1853/* 1854 * Translated default messages for the jQuery validation plugin. 1855 * Locale: DE (German, Deutsch) 1856 */ 1857$.extend( $.validator.messages, { 1858 required: "Dieses Feld ist ein Pflichtfeld.", 1859 maxlength: $.validator.format( "Geben Sie bitte maximal {0} Zeichen ein." ), 1860 minlength: $.validator.format( "Geben Sie bitte mindestens {0} Zeichen ein." ), 1861 rangelength: $.validator.format( "Geben Sie bitte mindestens {0} und maximal {1} Zeichen ein." ), 1862 email: "Geben Sie bitte eine gültige E-Mail Adresse ein.", 1863 url: "Geben Sie bitte eine gültige URL ein.", 1864 date: "Bitte geben Sie ein gültiges Datum ein.", 1865 number: "Geben Sie bitte eine Nummer ein.", 1866 digits: "Geben Sie bitte nur Ziffern ein.", 1867 equalTo: "Bitte denselben Wert wiederholen.", 1868 range: $.validator.format( "Geben Sie bitte einen Wert zwischen {0} und {1} ein." ), 1869 max: $.validator.format( "Geben Sie bitte einen Wert kleiner oder gleich {0} ein." ), 1870 min: $.validator.format( "Geben Sie bitte einen Wert gröÃer oder gleich {0} ein." ), 1871 creditcard: "Geben Sie bitte eine gültige Kreditkarten-Nummer ein." 1872} ); 1873return $; 1874})); 1875 1876$(document).ready(function () { 1877 1878 // validation 1879 $('form').each(function () { 1880 1881 // console.log( $(this).attr("id") + " _ " + $(this).attr("class") ); 1882 var $thisForm = $(this); 1883 1884 $thisForm.validate({ 1885 invalidHandler: function (event, validator) { 1886 // remove waiting spinner form submit button 1887 $thisForm.removeClass("submitting"); 1888 /* 1889 // 'this' refers to the form 1890 var errors = validator.numberOfInvalids(); 1891 if (errors) { 1892 var message = errors == 1 1893 ? 'You missed 1 field. It has been highlighted' 1894 : 'You missed ' + errors + ' fields. They have been highlighted'; 1895 $("div.error span").html(message); 1896 $("div.error").show(); 1897 } else { 1898 $("div.error").hide(); 1899 } 1900 */ 1901 }, 1902 errorPlacement: function (error, element) { 1903 if (element.attr("type") == "checkbox") { 1904 if ($(element).parents('.checkbox__error-container')) { 1905 error.appendTo($(element).parents('.checkbox__error-container')); 1906 } else { 1907 error.appendTo($(element).closest('.form-group')); 1908 } 1909 } else if (element.attr("type") == "radio") { 1910 if ($(element).parents('.radio__error-container')) { 1911 error.appendTo($(element).parents('.radio__error-container')); 1912 } else { 1913 error.appendTo($(element).closest('.form-group')); 1914 } 1915 } else { 1916 // something else if it's not a checkbox or radio 1917 error.appendTo($(element).closest('.form-group')); 1918 } 1919 } 1920 }); 1921 1922 // Require numbers for fields with data-field-type="number" 1923 $('[data-field-type="number"]', $thisForm).rules('add', { 1924 number: true 1925 }); 1926 1927 }); 1928 1929 // Require .TLD in email adresses 1930 /* 1931 $.validator.addMethod( 1932 'email', 1933 function(value, element){ 1934 return this.optional(element) || /(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*")@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}
1934\.?|[A-Z0-9-]{2,}\.?)$)|\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$/i.test(value); 1935 }); 1936 */ 1937 1938 // TODO: Is this better than "validator.addMethod"? 1939 $.validator.methods.email = function (value, element) { 1940 return this.optional(element) || /(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*")@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)$)|\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$/i.test(value); 1941 } 1942}); 1943 1944 1945// MOLECULES 1946 1947// navigation-main: hover intent 1948 1949$(document).ready(function () { 1950 var $navLis = $(".first-level__item"); 1951 1952 function over() { 1953 $(this).addClass("hoverIntent"); 1954 } 1955 1956 function out() { 1957 $(this).removeClass("hoverIntent"); 1958 } 1959 1960 $navLis.addClass("nohover"); 1961 1962 $navLis.hoverIntent({ 1963 over: over, 1964 out: out, 1965 timeout: 250, 1966 }); 1967}); 1968 1969// Accessible toggle for second level of main nav 1970 1971$(document).ready(function () { 1972 $(".sub-toggle").on("click", function (e) { 1973 if ($(this).parent("a").attr("aria-expanded") === "false") { 1974 $(this).parent("a").attr("aria-expanded", "true"); 1975 $(this) 1976 .parent() 1977 .parent(".first-level__item") 1978 .addClass("hoverIntent"); 1979 $(this).children().children("span").text("Menü schlieÃen"); 1980 } else { 1981 $(this).parent("a").attr("aria-expanded", "false"); 1982 $(this).parent().parent().removeClass("hoverIntent"); 1983 $(this).children().children("span").text("Menü öffnen"); 1984 } 1985 1986 e.preventDefault(); 1987 return false; 1988 }); 1989}); 1990 1991// Accessible toggle for mobile nav 1992 1993$(document).ready(function () { 1994 var $slideNavCheckbox = $("#slide-nav-checkbox-root"); 1995 var $slideNavToggle = $("#slide-nav-trigger"); 1996 1997 // uncheckAll(); 1998 1999 $slideNavToggle.on("click", function (e) { 2000 if ($slideNavCheckbox.prop("checked") === false) { 2001 $slideNavCheckbox.prop("checked", true); 2002 $slideNavToggle.children("span").text("Menü"); // schlieÃen 2003 2004 // console.log('new toggle is clicked to open'); 2005 // console.log('root checkbox is ' + $slideNavCheckbox.prop( 'checked' ) ); 2006 } else { 2007 $slideNavCheckbox.prop("checked", false); 2008 $slideNavToggle.children("span").text("Menü"); // öffnen 2009 2010 // console.log('new toggle is clicked to close'); 2011 // console.log('root checkbox is ' + $slideNavCheckbox.prop( 'checked' ) ); 2012 } 2013 2014 e.preventDefault(); 2015 return false; 2016 }); 2017}); 2018 2019// navigation-mobile: close all sub-navs on close 2020 2021$(document).ready(function () { 2022 var $body = $("body"); 2023 var $nav = $(".slide-nav-root"); 2024 var $navCheckboxes = $nav.find(".slide-nav-checkbox"); 2025 var $rootCheckbox = $("#slide-nav-checkbox-root"); 2026 2027 $rootCheckbox.on("change", function (event) { 2028 if ($rootCheckbox.prop("checked") === true) { 2029 $body.addClass("slide-nav-open"); 2030 console.log("root checkbox is checked"); 2031 } else { 2032 $body.removeClass("slide-nav-open"); 2033 $navCheckboxes.prop("checked", false); 2034 console.log("root checkbox is not checked"); 2035 } 2036 }); 2037}); 2038 2039// navigation-mobile: scroll up on checkbox change 2040 2041$(document).ready(function () { 2042 var $navCheckboxes = $(".slide-nav-checkbox"); 2043 2044 $navCheckboxes.on("change", function () { 2045 $(".slide-nav-root, .slide-nav-root *").scrollTop(0); 2046 }); 2047}); 2048 2049/* 2050 2051 2052$(document).ready(function() { 2053 2054 var labelId; 2055 2056 $('.pseudo-label').on('click', function(e) { 2057 2058 console.log('pseudo label was clicked'); 2059 labelId = $(this).children('label').attr('for'); 2060 2061 $('#'+labelId).trigger('click'); 2062 2063 e.preventDefault(); 2064 return false 2065 2066 }); 2067 2068}); 2069*/ 2070 2071/* 2072 2073$(document).ready(function() { 2074 2075 $('.slide-nav-checkbox').focus(function() { 2076 2077 $checkboxId = $(this).attr('id'); 2078 2079 $('label[for="' + $checkboxId + '"]').addClass('has-focus'); 2080 2081 }).blur(function() { 2082 $('label[for="' + $checkboxId + '"]').removeClass('has-focus'); 2083 }); 2084 2085});
2086*/ 2087 2088// .parent('a') 2089 2090/* 2091$(document).ready(function () { 2092 var $navServiceClone = $('nav.service').find('li').clone(); 2093 var $navSocialsClone = $('nav.socials').find('a').clone() 2094 var $navMobile = $('.slide-nav-root'); 2095 2096 $navServiceClone.addClass('slide-nav-service'); 2097 $navServiceClone.eq(0).addClass('slide-nav-service-first'); 2098 $navServiceClone.eq($navServiceClone.length - 1).addClass('slide-nav-service-last'); 2099 2100 $navSocialsClone.wrapAll('<li class="slide-nav-socials"></li>'); 2101 2102 $navServiceClone.appendTo($navMobile.find('> ul')); 2103 $navSocialsClone.parent('li').appendTo($navMobile.find('> ul')); 2104}); 2105*/ 2106 2107/* 2108 2109$("#demo6").hoverIntent({ 2110 over: makeTall, 2111 out: makeShort, 2112 selector: 'li' 2113}); 2114*/ 2115 2116$(document).ready(function () { 2117 $(".accordion__button button").each(function () { 2118 const $button = $(this); 2119 const $item = $button.parent().parent(".accordion__item"); 2120 const $panel = $item.children(".accordion__panel"); 2121 let isExpanded; 2122 2123 if (!$item || !$panel) return; 2124 2125 function init() { 2126 isExpanded = $item.hasClass("isExpanded"); 2127 isExpanded ? openAccordion() : closeAccordion(); 2128 } 2129 2130 function openAccordion() { 2131 $item.addClass("isExpanded"); 2132 $button.attr("aria-expanded", "true"); 2133 $panel.prop("hidden", false); 2134 isExpanded = true; 2135 } 2136 2137 function closeAccordion() { 2138 $item.removeClass("isExpanded"); 2139 $button.attr("aria-expanded", "false"); 2140 $panel.prop("hidden", true); 2141 isExpanded = false; 2142 } 2143 2144 function toggleAccordion() { 2145 if (isExpanded) { 2146 closeAccordion(); 2147 } else { 2148 openAccordion(); 2149 } 2150 } 2151 2152 $button.on("click", function (evt) { 2153 evt.preventDefault(); 2154 toggleAccordion(); 2155 return false; 2156 }); 2157 2158 init(); 2159 }); 2160}); 2161 2162$(document).ready(function () { 2163 var $carousel = $('.carousel__wrap'); 2164 var $carousel_status = $('.carousel__status'); 2165 2166 var $carousel_SlidesToShow = 3; 2167 var $carousel_SlidesToShow_Tablet = 2; 2168 var $carousel_SlidesToShow_Mobile = 1; 2169 2170 var $carousel_variableWidth = false; 2171 var $carousel_adaptiveHeight = false; 2172 var $carousel_centerMode = false; 2173 2174 // Getting current slide and total number of slides 2175 // for a compact replacement of the dot nav on mobile 2176 $('.carousel__wrap').on( 2177 'onLoad init reInit afterChange', 2178 function (event, slick, currentSlide, nextSlide) { 2179 // currentSlide is undefined on init 2180 // set it to 0 in this case (currentSlide is 0 based) 2181 var i = (currentSlide ? currentSlide : 0) + 1; 2182 2183 $carousel_status.html( 2184 '<span>' + 2185 i + 2186 '</span>' + 2187 '/' + 2188 '<span>' + 2189 slick.slideCount + 2190 '</span>' 2191 ); 2192 } 2193 ); 2194 2195 $('.carousel').each(function () { 2196 // Setting the max numbers of slides shown 2197 $carousel = $(this); 2198 2199 if ($(this).hasClass('carousel--col-1')) { 2200 $carousel_SlidesToShow = 1; 2201 $carousel_SlidesToShow_Tablet = 1; 2202 $carousel_SlidesToShow_Mobile = 1; 2203 } 2204 2205 if ($(this).hasClass('carousel--col-2')) { 2206 $carousel_SlidesToShow = 2; 2207 $carousel_SlidesToShow_Tablet = 2; 2208 $carousel_SlidesToShow_Mobile = 1; 2209 } 2210 2211 if ($(this).hasClass('carousel--col-4')) { 2212 $carousel_SlidesToShow = 4; 2213 $carousel_SlidesToShow_Tablet = 3; 2214 $carousel_SlidesToShow_Mobile = 2; 2215 } 2216 2217 if ($(this).hasClass('carousel--col-5')) { 2218 $carousel_SlidesToShow = 5; 2219 $carousel_SlidesToShow_Tablet = 3; 2220 $carousel_SlidesToShow_Mobile = 2; 2221 } 2222 2223 // Setting the handling of differently sized images 2224 if ($(this).hasClass('carousel--variable-width')) { 2225 $carousel_variableWidth = true; 2226 } 2227 2228 if ($(this).hasClass('carousel--center-mode')) { 2229 $carousel_centerMode = true; 2230 } 2231 2232 if ($(this).hasClass('carousel--adaptive-height')) { 2233 $carousel_adaptiveHeight = true; 2234 $carousel_SlidesToShow = 1; 2235 $carousel_SlidesToShow_Tablet = 1; 2236 $carousel_SlidesToShow_Mobile = 1; 2237 } 2238 2239 $('.carousel__wrap', this).slick({ 2240 prevArrow: 2241 '<button type="button" class="slick-prev"><span class="sr-only">Vorheriges</span></button>', 2242 nextArrow: 2243 '<button type="button" class="slick-next"><span class="sr-only">Nächstes</span></button>', 2244 slidesToShow: $carousel_SlidesToShow, 2245 slidesToScroll: $carousel_SlidesToShow, 2246 arrows: true, 2247 prevArrow: $carousel.find('.carousel__prev'), 2248 nextArrow: $carousel.find('.carousel__next'), 2249 dots: true, 2250 appendDots: $carousel.find('.carousel__dots'), 2251 slide: '.carousel__item', 2252 fade: false, 2253 speed: 500, 2254 autoplay: false, 2255 autoplaySpeed: 5000, 2256 variableWidth: $carousel_variableWidth, 2257 centerMode: $carousel_centerMode, 2258 adaptiveHeight: $carousel_adaptiveHeight, 2259 2260 responsive: [ 2261 { 2262 breakpoint: 992, 2263 settings: { 2264 slidesToShow: $carousel_SlidesToShow_Tablet, 2265 slidesToScroll: $carousel_SlidesToShow_Tablet, 2266 }, 2267 }, 2268 { 2269 breakpoint: 720, 2270 settings: { 2271 slidesToShow: $carousel_SlidesToShow_Mobile, 2272 slidesToScroll: $carousel_SlidesToShow_Mobile, 2273 dots: false, 2274 variableWidth: false, 2275 // adaptiveHeight: false, 2276 }, 2277 }, 2278 { 2279 breakpoint: 480, 2280 settings: { 2281 slidesToShow: 1, 2282 slidesToScroll: 1, 2283 dots: false, 2284 variableWidth: false, 2285 // adaptiveHeight: false, 2286 }, 2287 }, 2288 ], 2289 }); 2290 2291 $carousel_SlidesToShow = 3; 2292 $carousel_SlidesToShow_Tablet = 2; 2293 $carousel_SlidesToShow_Mobile = 1; 2294 $carousel_variableWidth = false;
2295 $carousel_adaptiveHeight = false; 2296 $carousel_centerMode = false; 2297 }); 2298}); 2299 2300(() => { 2301 const consentOpener = document.querySelector(".js-consent-dialog-opener"); 2302 2303 if (!consentOpener) return; 2304 2305 consentOpener.addEventListener("click", (event) => { 2306 window.DPCookieConsent.popup.revoke(); 2307 }); 2308})(); 2309 2310/** 2311 * 2312 * JavaScript 'polyfill' for HTML5's <details> and <summary> elements 2313 * and 'shim' to add accessiblity enhancements for all browsers 2314 * 2315 * http://caniuse.com/#feat=details 2316 */ 2317 2318// import '../../vendor/polyfills/Function/prototype/bind' 2319// import '../../vendor/polyfills/Event' // addEventListener and event.target normaliziation 2320// import { generateUniqueID } from '../../common.js' 2321 2322var KEY_ENTER = 13; 2323var KEY_SPACE = 32; 2324 2325function Details($module) { 2326 this.$module = $module; 2327} 2328 2329Details.prototype.init = function () { 2330 if (!this.$module) { 2331 return; 2332 } 2333 2334 // If there is native details support, we want to avoid 2335 // running code to polyfill native behaviour. 2336 var hasNativeDetails = typeof this.$module.open === 'boolean'; 2337 2338 if (hasNativeDetails) { 2339 return; 2340 } 2341 2342 this.polyfillDetails(); 2343}; 2344 2345Details.prototype.polyfillDetails = function () { 2346 var $module = this.$module; 2347 2348 // Save shortcuts to the inner summary and content elements 2349 var $summary = (this.$summary = $module 2350 .getElementsByTagName('summary') 2351 .item(0)); 2352 var $content = (this.$content = $module 2353 .getElementsByTagName('div') 2354 .item(0)); 2355 2356 // If <details> doesn't have a <summary> and a <div> representing the content 2357 // it means the required HTML structure is not met so the script will stop 2358 if (!$summary || !$content) { 2359 return; 2360 } 2361 2362 // If the content doesn't have an ID, assign it one now 2363 // which we'll need for the summary's aria-controls assignment 2364 if (!$content.id) { 2365 $content.id = 'details-content-' + generateUniqueID(); 2366 } 2367 2368 // Add ARIA role="group" to details 2369 $module.setAttribute('role', 'group'); 2370 2371 // Add role=button to summary 2372 $summary.setAttribute('role', 'button'); 2373 2374 // Add aria-controls 2375 $summary.setAttribute('aria-controls', $content.id); 2376 2377 // Set tabIndex so the summary is keyboard accessible 2378 // for non-native elements 2379 // 2380 // We have to use the camelcase `tabIndex` property as there is a bug 2381 // in IE6/IE7 when we set the correct attribute lowercase: 2382 // See http://web.archive.org/web/20170120194036/http://www.saliences.com/browserBugs/tabIndex.html 2383 $summary.tabIndex = 0; 2384 2385 // Detect initial open state 2386 var openAttr = $module.getAttribute('open') !== null; 2387 if (openAttr === true) { 2388 $summary.setAttribute('aria-expanded', 'true'); 2389 $content.setAttribute('aria-hidden', 'false'); 2390 } else { 2391 $summary.setAttribute('aria-expanded', 'false'); 2392 $content.setAttribute('aria-hidden', 'true'); 2393 $content.style.display = 'none'; 2394 } 2395 2396 // Bind an event to handle summary elements 2397 this.polyfillHandleInputs($summary, this.polyfillSetAttributes.bind(this)); 2398}; 2399 2400/** 2401 * Define a statechange function that updates aria-expanded and style.display 2402 * @param {object} summary element 2403 */ 2404Details.prototype.polyfillSetAttributes = function () { 2405 var $module = this.$module; 2406 var $summary = this.$summary; 2407 var $content = this.$content; 2408 2409 var expanded = $summary.getAttribute('aria-expanded') === 'true'; 2410 var hidden = $content.getAttribute('aria-hidden') === 'true'; 2411 2412 $summary.setAttribute('aria-expanded', expanded ? 'false' : 'true'); 2413 $content.setAttribute('aria-hidden', hidden ? 'false' : 'true'); 2414 2415 $content.style.display = expanded ? 'none' : ''; 2416 2417 var hasOpenAttr = $module.getAttribute('open') !== null; 2418 if (!hasOpenAttr) { 2419 $module.setAttribute('open', 'open'); 2420 } else { 2421 $module.removeAttribute('open'); 2422 } 2423 2424 return true; 2425}; 2426 2427/** 2428 * Handle cross-modal click events 2429 * @param {object} node element 2430 * @param {function} callback function 2431 */ 2432Details.prototype.polyfillHandleInputs = function (node, callback) { 2433 node.addEventListener('keypress', function (event) { 2434 var target = event.target; 2435 // When the key gets pressed - check if it is enter or space 2436 if (event.keyCode === KEY_ENTER || event.keyCode === KEY_SPACE) { 2437 if (target.nodeName.toLowerCase() === 'summary') { 2438 // Prevent space from scrolling the page 2439 // and enter from submitting a form 2440 event.preventDefault(); 2441 // Click to let the click event do all the necessary action 2442 if (target.click) { 2443 target.click(); 2444 } else { 2445 // except Safari 5.1 and under don't support .click() here 2446 callback(event); 2447 } 2448 } 2449 } 2450 }); 2451 2452 // Prevent keyup to prevent clicking twice in Firefox when using space key 2453 node.addEventListener('keyup', function (event) { 2454 var target = event.target; 2455 if (event.keyCode === KEY_SPACE) { 2456 if (target.nodeName.toLowerCase() === 'summary') { 2457 event.preventDefault(); 2458 } 2459 } 2460 }); 2461 2462 node.addEventListener('click', callback); 2463}; 2464 2465$(document).ready(function () { 2466 if ($(".donationBar").length > 0) { 2467 $("body").addClass("has-donationBar"); 2468 } 2469}); 2470 2471$(document).ready(function () { 2472 $(".donationQuickSearch__input input").change(function () { 2473 $(".donationQuickSearch__btn-group .btn") 2474 .removeClass("btn-primary") 2475 .addClass("btn-secondary"); 2476 $(this).addClass("is-active"); 2477 $(".donationQuickSearch__amount").val($(this).val()); 2478 }); 2479 2480 $(".donationQuickSearch__btn-1").click(function () { 2481 $(".donationQuickSearch__input input").val("").removeClass("is-active"); 2482 $(".donationQuickSearch__btn-group .btn") 2483 .removeClass("btn-primary") 2484 .addClass("btn-secondary"); 2485 $(this).addClass("btn-primary").removeClass("btn-secondary"); 2486 $(".donationQuickSearch__amount").val($(this).data("value")); 2487 }); 2488 2489 $(".donationQuickSearch__btn-2").click(function () { 2490 $(".donationQuickSearch__input input").val("").removeClass("is-active"); 2491 $(".donationQuickSearch__btn-group .btn") 2492 .removeClass("btn-primary") 2493 .addClass("btn-secondary"); 2494 $(this).addClass("btn-primary").removeClass("btn-secondary"); 2495 $(".donationQuickSearch__amount").val($(this).data("value")); 2496 }); 2497 2498 $(".donationQuickSearch__btn-3").click(function () { 2499 $(".donationQuickSearch__input input").val("").removeClass("is-active"); 2500 $(".donationQuickSearch__btn-group .btn") 2501 .removeClass("btn-primary") 2502 .addClass("btn-secondary"); 2503 $(this).addClass("btn-primary").removeClass("btn-secondary"); 2504 $(".donationQuickSearch__amount").val($(this).data("value")); 2505 }); 2506 2507 $(".donationQuickSearch__btn-group .btn") 2508 .removeClass("btn-primary") 2509 .addClass("btn-secondary"); 2510 if ($(".donationQuickSearch__amount").val() == 20) { 2511 $(".donationQuickSearch__btn-1") 2512 .removeClass("btn-secondary") 2513 .addClass("btn-primary"); 2514 } else if ($(".donationQuickSearch__amount").val() == 50) { 2515 $(".donationQuickSearch__btn-2") 2516 .removeClass("btn-secondary") 2517 .addClass("btn-primary"); 2518 } else if ($(".donationQuickSearch__amount").val() == 100) { 2519 $(".donationQuickSearch__btn-3") 2520 .removeClass("btn-secondary") 2521 .addClass("btn-primary"); 2522 } else if ($(".donationQuickSearch__amount").val()) { 2523 $(".donationQuickSearch__input input") 2524 .val($(".donationQuickSearch__amount").val()) 2525 .addClass("is-active"); 2526 } 2527}); 2528 2529$(document).ready(function () { 2530 $('.js-filter-reset').on('click', function (event) { 2531 event.preventDefault(); 2532 2533 $('.filter input[type="text"], .filter input[type="search"]').val(''); 2534 2535 $('.filter select').each(function () { 2536 if ($(this).attr('multiple')) { 2537 $('option', this).removeAttr('selected'); 2538 $(this) 2539 .parent() 2540 .find('.optWrapper.multiple .options .selected') 2541 .click(); 2542 } else { 2543 $('option', this).removeAttr('selected'); 2544 $(this).parent().find('.optWrapper .options li').eq(0).click(); 2545 } 2546 }); 2547 }); 2548}); 2549 2550$(document).ready(function () { 2551 var $heroSlideshow = $('.hero.hero--stage');
2552 var $slideshowPause = $('.js-hero__play'); 2553 2554 $heroSlideshow.slick({ 2555 prevArrow: 2556 '<button type="button" class="slick-prev"><span class="sr-only">Vorheriges</span></button>', 2557 nextArrow: 2558 '<button type="button" class="slick-next"><span class="sr-only">Nächstes</span></button>', 2559 slidesToShow: 1, 2560 slidesToScroll: 1, 2561 arrows: false, 2562 dots: true, 2563 slide: '.hero__item', 2564 adaptiveHeight: false, 2565 fade: false, 2566 speed: 500, 2567 autoplay: true, 2568 autoplaySpeed: 5000, 2569 }); 2570 2571 $slideshowPause.on('click', function () { 2572 var $this = $(this); 2573 2574 $this.toggleClass('hero__play--is-paused'); 2575 2576 if ($this.hasClass('hero__play--is-paused')) { 2577 $heroSlideshow.slick('slickPause'); 2578 $this.text('Play'); 2579 } else { 2580 $heroSlideshow.slick('slickPlay'); 2581 $this.text('Pause'); 2582 $heroSlideshow.slick('slickNext'); 2583 } 2584 }); 2585}); 2586 2587/* 2588function copyToClipboard() { 2589 var copyText = document.getElementById("iban").textContent; 2590 navigator.clipboard.writeText(copyText).then(() => { 2591 // Alert the user that the action took place. 2592 // Nobody likes hidden stuff being done under the hood! 2593 document.getElementById("ibanButton").blur(); 2594 document.getElementById("ibanTooltip").style.display = "block"; 2595 2596 setTimeout(function () { 2597 document.getElementById("ibanTooltip").style.display = "none"; 2598 }, 3000); 2599 }); 2600} 2601*/ 2602 2603$(document).ready(function(){ 2604 2605 2606 $("a.lightbox").attr('rel','image-in-lightbox'); 2607 $(".slideshow a.lightbox").attr('rel','slide-in-lightbox'); 2608 $(".carousel a.lightbox").attr('rel','carousel-in-lightbox'); 2609 2610 2611 // initialize fancybox 2612 $("a.lightbox").fancybox({ 2613 margin: 0, 2614 padding: 80, 2615 autoSize: true, 2616 fitToView: true, 2617 fixed: false, 2618 openEffect: 'fade', 2619 closeEffect: 'fade', 2620 nextEffect: 'fade', 2621 prevEffect: 'fade', 2622 openSpeed: 250, 2623 closeSpeed: 250, 2624 nextSpeed: 250, 2625 prevSpeed: 250, 2626 arrows: true, 2627 closeBtn: true, 2628 loop: true, 2629 wrapCSS: 'gal-fancy', 2630 helpers: 2631 { 2632 title: { 2633 type: 'inside' 2634 }, 2635 buttons: { 2636 position: 'bottom' 2637 } 2638 }, 2639 beforeLoad: function(){ 2640 2641 var obj = $(this.element); 2642 var caption = obj.attr('data-caption'); 2643 var credits = obj.attr('data-credits'); 2644 var download = obj.attr('data-download'); 2645 2646 if ( obj.parent().hasClass("media") ) { 2647 if ( !caption ) caption = obj.parent().next().html(); 2648 if ( !credits ) credits = obj.next().html(); 2649 } else { 2650 if ( !caption ) caption = obj.parent().find(".caption").html(); 2651 if ( !credits ) credits = obj.parent().find(".credits").html(); 2652 } 2653 2654 var text = ''; 2655 text += '<div class="text">'; 2656 if(credits) text += '<p class="credits">' + credits + '</p>'; 2657 2658 if(download) text += '<a href="' + download + '" title="Download starten" class="download" target="_blank">Download</a>'; 2659 2660 if(caption) text += '<p class="caption">' + caption + '</p>'; 2661 2662 text += '</div>'; 2663 2664 this.title = (caption || credits || download) ? text : ""; 2665 2666 }, 2667 beforeShow: function(){ 2668 // Disable right click 2669 $.fancybox.inner.bind("contextmenu", function(e){ return false; }); 2670 } 2671 2672 }); 2673}); 2674 2675// Fade in sticky newsletter teaser 2676 2677$(document).ready(function(){ 2678 2679 var $window = $(window); 2680 var $newsletterlSticky = $('.newsletter-sticky'); 2681 2682 $window.bind("scroll", function() { 2683 2684 if ($(this).scrollTop() > 400) { 2685 $newsletterlSticky.addClass('is-visible'); 2686 } else { 2687 $newsletterlSticky.removeClass('is-visible'); 2688 } 2689 2690 }); 2691 2692}); 2693 2694$(document).ready(function(){ 2695 2696 2697 2698}); 2699 2700$(document).ready(function(){ 2701 2702 $(".footer__zip-search form").on("submit", function( event ){ 2703 2704 event.preventDefault(); 2705 2706 window.location = $(this).attr("action") + "#/search?url&plz=" + $("#inline-search__input").val(); 2707 2708 }); 2709 2710}); 2711$(document).ready(function(){ 2712 2713 if( $(".share").length > 0 ){ 2714 2715 var currentLocation = encodeURIComponent( $("meta[property='og:url']").attr("content") ); 2716 var currentTitle= encodeURIComponent( $("meta[property='og:title']").attr("content") ); 2717 var currentSiteName= encodeURIComponent( $("meta[property='og:site_name']").attr("content") ); 2718 var currentDesc= encodeURIComponent( $("meta[property='og:description']").attr("content") ); 2719
2720 if(currentDesc == 'undefined') { 2721 currentDesc = ''; 2722 } 2723 if (currentSiteName == 'undefined') { 2724 currentSiteName = ''; 2725 } 2726 2727 $(".share .share__icon--email").attr( 2728 "href", 2729 //'mailto:?subject=Empfehlung:' + mailURI 2730 'mailto:?subject=Empfehlung: ' + currentTitle + ' von ' + currentSiteName + '&body=' + currentTitle + '%0D%0A'+ currentDesc + '%0D%0A%0D%0A' + currentLocation 2731 ); 2732 } 2733}); 2734 2735// Set tabindex -1 on skip link target 2736 2737// Prevent Safari on iOS to jump back to skip link 2738// on subsequent "tab" when using voice over 2739 2740$(document).ready(function(){ 2741 2742 $('.skip-link--content').click(function(e) { 2743 2744 e.preventDefault(); 2745 2746 $('#content').attr('tabindex', '-1').focus(); 2747 }); 2748 2749}); 2750 2751// show "reload cart button" if quantity in cart was changed 2752 2753$(document).ready(function() { 2754 $('.shop__item--input').on('change keyup paste', function() { 2755 2756 $('.btn--reload').addClass('shop__item--input-change'); 2757 $('.shop__cart .icon-enabled').addClass('disabled'); 2758 }); 2759}); 2760 2761class ElementHasLink { 2762 constructor($module) { 2763 this.$teaser = $module; 2764 this.$mainLink = this.$teaser.querySelector(".js-element-link"); 2765 2766 // bind `this` to methods where needed 2767 this.addClickListener = this.addClickListener.bind(this); 2768 this.handleTeaserClick = this.handleTeaserClick.bind(this); 2769 } 2770 init() { 2771 if (!this.$teaser || !this.$mainLink) { 2772 return; 2773 } 2774 window.addEventListener("DOMContentLoaded", this.addClickListener); 2775 } 2776 addClickListener() { 2777 window.removeEventListener("DOMContentLoaded", this.addClickListener); 2778 const $clickables = this.$teaser.querySelectorAll("a, button"); 2779 2780 // Listen for clicks on teaser 2781 this.$teaser.addEventListener("click", this.handleTeaserClick); 2782 2783 // Listen for clicks on clickable elements inside teaser
2784 $clickables.forEach(function ($clickable) { 2785 $clickable.addEventListener("click", function (event) { 2786 // Donât bubble up and trigger main link when a button or link is clicked 2787 event.stopPropagation(); 2788 }); 2789 }); 2790 } 2791 // Trigger main link when teaser is clicked, unless text 2792 // is being selected 2793 // TODO: handle clicks on modal buttons 2794 handleTeaserClick(event) { 2795 const noTextSelected = !window.getSelection().toString(); 2796 // const isNotFancyBox = !event.target.hasAttribute('data-fancybox'); 2797 // if (noTextSelected && isNotFancyBox) { 2798 if (noTextSelected) { 2799 this.$mainLink.click(); 2800 } 2801 } 2802} 2803 2804// export default TeaserHasLink; 2805 2806const $elementsHasLink = document.getElementsByClassName("js-element-has-link"); 2807for (const $elementHasLink of $elementsHasLink) { 2808 new ElementHasLink($elementHasLink).init(); 2809} 2810 2811$(document).ready(function () { 2812 $(".teaser--masonary").imagesLoaded(function () { 2813 $(".teaser--masonary").isotope({ 2814 itemSelector: ".teaser__item", 2815 percentPosition: true, 2816 stamp: ".stamp", 2817 masonry: { 2818 // use outer width of grid-sizer for columnWidth 2819 // columnWidth: 33.333333% 2820 columnWidth: ".grid-sizer", 2821 }, 2822 }); 2823 }); 2824 2825 /* 2826 $(".teaser--fit-in-row").isotope( 2827 { 2828 itemSelector: '.teaser-item', 2829 layoutMode: 'fitRows' 2830 } 2831 ); 2832 */ 2833 2834 // Teaser Slideshow - 2 columns 2835 2836 var $teaserSlideshow = $(".teaser--slideshow.teaser--col-2"); 2837 2838 $teaserSlideshow.slick({ 2839 prevArrow: 2840 '<button type="button" class="slick-prev"><span class="sr-only">Vorheriges</span></button>', 2841 nextArrow: 2842 '<button type="button" class="slick-next"><span class="sr-only">Nächstes</span></button>', 2843 slidesToShow: 1, 2844 slidesToScroll: 1, 2845 arrows: false, 2846 dots: true, 2847 slide: ".teaser__item", 2848 adaptiveHeight: false, 2849 fade: false, 2850 speed: 500, 2851 autoplay: false, 2852 autoplaySpeed: 5000, 2853 mobileFirst: true, 2854 responsive: [ 2855 { 2856 breakpoint: 960, 2857 settings: { 2858 slidesToShow: 2, 2859 slidesToScroll: 2, 2860 arrows: true, 2861 }, 2862 }, 2863 ], 2864 }); 2865 2866 // Teaser Slideshow - 3 columns 2867 2868 var $teaserSlideshow = $(".teaser--slideshow.teaser--col-3"); 2869 2870 $teaserSlideshow.slick({ 2871 prevArrow: 2872 '<button type="button" class="slick-prev"><span class="sr-only">Vorheriges</span></button>', 2873 nextArrow: 2874 '<button type="button" class="slick-next"><span class="sr-only">Nächstes</span></button>', 2875 slidesToShow: 1, 2876 slidesToScroll: 1, 2877 arrows: false, 2878 dots: true, 2879 slide: ".teaser__item", 2880 adaptiveHeight: false, 2881 fade: false, 2882 speed: 500, 2883 autoplay: false, 2884 autoplaySpeed: 5000, 2885 mobileFirst: true, 2886 responsive: [ 2887 { 2888 breakpoint: 640, 2889 settings: { 2890 slidesToShow: 2, 2891 slidesToScroll: 2, 2892 }, 2893 }, 2894 { 2895 breakpoint: 960, 2896 settings: { 2897 slidesToShow: 3, 2898 slidesToScroll: 3, 2899 arrows: true, 2900 }, 2901 }, 2902 ], 2903 }); 2904 2905 // Teaser Slideshow - 4 columns 2906 2907 var $teaserSlideshow = $(".teaser--slideshow.teaser--col-4"); 2908 2909 $teaserSlideshow.slick({ 2910 prevArrow: 2911 '<button type="button" class="slick-prev"><span class="sr-only">Vorheriges</span></button>', 2912 nextArrow: 2913 '<button type="button" class="slick-next"><span class="sr-only">Nächstes</span></button>', 2914 slidesToShow: 1, 2915 slidesToScroll: 1, 2916 arrows: false, 2917 dots: true, 2918 slide: ".teaser__item", 2919 adaptiveHeight: false, 2920 fade: false, 2921 speed: 500, 2922 autoplay: false, 2923 autoplaySpeed: 5000, 2924 mobileFirst: true, 2925 responsive: [ 2926 { 2927 breakpoint: 480, 2928 settings: { 2929 slidesToShow: 2, 2930 slidesToScroll: 2, 2931 }, 2932 }, 2933 { 2934 breakpoint: 720, 2935 settings: { 2936 slidesToShow: 3, 2937 slidesToScroll: 3, 2938 }, 2939 }, 2940 { 2941 breakpoint: 960, 2942 settings: { 2943 slidesToShow: 4, 2944 slidesToScroll: 4, 2945 }, 2946 }, 2947 ], 2948 }); 2949 2950 // Teaser Slideshow - 5 columns 2951 2952 var $teaserSlideshow = $(".teaser--slideshow.teaser--col-5"); 2953 2954 $teaserSlideshow.slick({ 2955 prevArrow: 2956 '<button type="button" class="slick-prev"><span class="sr-only">Vorheriges</span></button>', 2957 nextArrow: 2958 '<button type="button" class="slick-next"><span class="sr-only">Nächstes</span></button>', 2959 slidesToShow: 1, 2960 slidesToScroll: 1,
2961 arrows: false, 2962 dots: true, 2963 slide: ".teaser__item", 2964 adaptiveHeight: false, 2965 fade: false, 2966 speed: 500, 2967 autoplay: false, 2968 autoplaySpeed: 5000, 2969 mobileFirst: true, 2970 responsive: [ 2971 { 2972 breakpoint: 480, 2973 settings: { 2974 slidesToShow: 2, 2975 slidesToScroll: 2, 2976 }, 2977 }, 2978 { 2979 breakpoint: 720, 2980 settings: { 2981 slidesToShow: 3, 2982 slidesToScroll: 3, 2983 }, 2984 }, 2985 { 2986 breakpoint: 960, 2987 settings: { 2988 slidesToShow: 4, 2989 slidesToScroll: 4, 2990 }, 2991 }, 2992 { 2993 breakpoint: 1200, 2994 settings: { 2995 slidesToShow: 5, 2996 slidesToScroll: 5, 2997 }, 2998 }, 2999 ], 3000 }); 3001 3002 // Teaser Slideshow - Speaker 3003 3004 var $teaserSlideshowSpeaker = $(".teaser--slideshow.teaser--speaker"); 3005 3006 $teaserSlideshowSpeaker.slick({ 3007 prevArrow: 3008 '<button type="button" class="slick-prev"><span class="sr-only">Vorheriges</span></button>', 3009 nextArrow: 3010 '<button type="button" class="slick-next"><span class="sr-only">Nächstes</span></button>', 3011 slidesToShow: 1, 3012 slidesToScroll: 1, 3013 arrows: false, 3014 dots: true, 3015 slide: ".teaser__item", 3016 adaptiveHeight: false, 3017 fade: false, 3018 speed: 500, 3019 autoplay: false, 3020 autoplaySpeed: 5000, 3021 mobileFirst: true, 3022 responsive: [ 3023 { 3024 breakpoint: 960, 3025 settings: { 3026 slidesToShow: 2, 3027 slidesToScroll: 2, 3028 }, 3029 }, 3030 ], 3031 }); 3032}); 3033 3034$(document).ready(function () { 3035 /* 3036 $(".media-group.top").isotope( 3037 { 3038 itemSelector: '.media', 3039 layoutMode: 'fitRows' 3040 } 3041 ); 3042 3043 $(".media-group.above").isotope( 3044 { 3045 itemSelector: '.media', 3046 layoutMode: 'fitRows' 3047 } 3048 ); 3049 3050 $(".media-group.bottom").isotope( 3051 { 3052 itemSelector: '.media', 3053 layoutMode: 'fitRows' 3054 } 3055 ); 3056 */ 3057 3058 $(".textrow table").each(function () { 3059 $(this).wrap( 3060 '<div class="tableWrapOuter"><div class="tableWrapInner"></div></div>' 3061 ); 3062 }); 3063}); 3064 3065/** 3066 * Table of Contents 3067 * 3068 * Automatically generate a table of contents from the headings on the page. 3069 * 3070 * @param {String} content A selector for the element that the content is in 3071 * @param {String} target The selector for the container to render the table of contents into 3072 * @param {Object} options An object of user options [optional] 3073 */ 3074 3075var tableOfContents = function (content, target, options) { 3076 // Where to look for the headings to generate a table of contens from 3077 var contentWrap = document.querySelector(content); 3078 3079 // Where to append the generated table of contens 3080 var toc = document.querySelector(target); 3081 3082 if (!contentWrap || !toc) return; 3083 3084 // Settings & Defaults 3085 var defaults = { 3086 tocId: 'toc', 3087 tocClass: 'toc', 3088 toclistClass: 'toc__list', // Class name of the outer list 3089 tocListType: 'ol', 3090 levels: 'h2, h3', // The heading levels to generate a TOC from 3091 backToToc: false, 3092 backToTocClass: 'back-to-toc', 3093 backToTocText: 'Inhaltsverzeichnis', 3094 backToTopSelector: '.top-scroll__fixed ', 3095 }; 3096 3097 var settings = {}; 3098 var headings; 3099 3100 /** 3101 * Merge user options into defaults. 3102 * 3103 * @param {Object} obj The user options 3104 */ 3105 3106 var merge = function (obj) { 3107 for (var key in defaults) { 3108 if (Object.prototype.hasOwnProperty.call(defaults, key)) { 3109 settings[key] = Object.prototype.hasOwnProperty.call(obj, key) 3110 ? obj[key] 3111 : defaults[key]; 3112 } 3113 } 3114 }; 3115 3116 /** 3117 * Create an ID for a heading if one does not exist 3118 * 3119 * @param {Node} heading The heading element 3120 * @todo Handle umlauts instead of just dropping them 3121 */ 3122 3123 var createID = function (heading) { 3124 if (heading.id.length) return; 3125 heading.id = heading.innerText.toLowerCase().replace(/[^A-Za-z0-9]/g, '-'); 3126 }; 3127 3128 /** 3129 * Get the HTML to indent a list a specific number of levels 3130 * 3131 * @param {Integer} count The number of times to indent the list 3132 * @return {String} The HTML 3133 */ 3134 3135 var getIndent = function (count) { 3136 var html = ''; 3137 for (var i = 0; i < count; i++) { 3138 html += '<' + settings.tocListType + '>'; 3139 } 3140 return html; 3141 }; 3142 3143 /** 3144 * Get the HTML to close an indented list a specific number of levels 3145 * 3146 * @param {Integer} count The number of times to "outdent" the list 3147 * @return {String} The HTML 3148 */ 3149 3150 var getOutdent = function (count) { 3151 var html = ''; 3152 for (var i = 0; i < count; i++) { 3153 html += '</' + settings.tocListType + '></li>'; 3154 } 3155 return html; 3156 }; 3157 3158 /** 3159 * Get the HTML string to start a new list of headings 3160 * 3161 * @param {Integer} diff The number of levels in or out from the current level the list is 3162 * @param {Integer} index The index of the heading in the "headings" NodeList 3163 * @return {String} The HTML 3164 */ 3165 3166 var getStartingHTML = function (diff, index) { 3167 // If indenting 3168 if (diff > 0) { 3169 return getIndent(diff); 3170 } 3171
3172 // If outdenting 3173 if (diff < 0) { 3174 return getOutdent(Math.abs(diff)); 3175 } 3176 3177 // If it's not the first item and there's no difference 3178 if (index && !diff) { 3179 return '</li>'; 3180 } 3181 3182 return ''; 3183 }; 3184 3185 /** 3186 * Inject the back-to-top linkâs HTML into the DOM 3187 */ 3188 3189 var injectBackToToc = function () { 3190 // Get the current URL without any possible hash 3191 var currentURL = window.location.href.split('#')[0]; 3192 3193 // Create the HTML 3194 var backToTocHTML = document.createElement('a'); 3195 3196 backToTocHTML.classList.add(settings.backToTocClass); 3197 backToTocHTML.setAttribute('href', currentURL + '#' + settings.tocId); 3198 backToTocHTML.textContent += settings.backToTocText; 3199 3200 // Inject the HTML 3201 document.body.appendChild(backToTocHTML); 3202 }; 3203 3204 /** 3205 * Inject the tocâs HTML into the DOM 3206 */ 3207 3208 var injectToc = function () { 3209 // Get the current URL without any possible hash 3210 var currentURL = window.location.href.split('#')[0]; 3211 3212 // Get the current heading level 3213 var level = headings[0].tagName.slice(1); 3214 var startingLevel = level; 3215 3216 // Cache the number of headings 3217 var len = headings.length - 1; 3218 3219 // Create the HTML 3220 var tocHTML = 3221 '<' + 3222 settings.tocListType + 3223 ' class="' + 3224 settings.toclistClass + 3225 // '" id="' + 3226 // settings.tocId + 3227 '">' + 3228 Array.prototype.map 3229 .call(headings, function (heading, index) { 3230 // Add an ID if none is present 3231 createID(heading); 3232 3233 // Check the heading level vs. the current list 3234 var currentLevel = heading.tagName.slice(1); 3235 var levelDifference = currentLevel - level; 3236 3237 level = currentLevel; 3238 3239 var HTML = getStartingHTML(levelDifference, index); 3240 3241 // Generate the list HTML 3242 HTML += 3243 '<li>' + 3244 '<a href="' + 3245 currentURL + 3246 '#' + 3247 heading.id + 3248 '">' + 3249 heading.innerText.trim() + 3250 '</a>'; 3251 3252 // If the last item, close it 3253 if (index === len) { 3254 HTML += getOutdent(Math.abs(startingLevel - currentLevel)); 3255 } 3256 3257 return HTML; 3258 }) 3259 .join('') + 3260 '</' + 3261 settings.tocListType + 3262 '>'; 3263 3264 // Inject the HTML into the DOM 3265 toc.innerHTML = tocHTML; 3266 }; 3267 3268 /** 3269 * Initialize the TOC 3270 */ 3271 3272 var init = function () { 3273 // Merge user settings into the defaults 3274 merge(options || {}); 3275 3276 // Get all heading candidates 3277 headings = contentWrap.querySelectorAll(settings.levels); 3278 if (!headings.length) return; 3279 3280 // Inject the TOC 3281 injectToc(); 3282 3283 // Inject the back-to-toc link 3284 if (settings.backToToc) injectBackToToc(); 3285 }; 3286 3287 init(); 3288}; 3289 3290tableOfContents('.article', '.js-toc', { 3291 levels: 'h2, h3', 3292 backToToc: true, 3293}); 3294 3295$(document).ready(function () { 3296 // Top Button Fixed 3297 var $window = $(window); 3298 var offsetTop = $window.height() / 4; 3299 3300 var $donate = $(".donationBar"); 3301 var $toc = $(".back-to-toc"); 3302 var $top = $( 3303 '<div class="top-scroll__fixed"><span class="sr-only">Zum Seitenanfang</span></div>' 3304 ).appendTo("body"); 3305 3306 $top.on("click", function (event) { 3307 // Disable native smooth scroll before scrolling with velocity 3308 // Scroll easing is buggy when native smooth scroll is set 3309 $("html").css("scroll-behavior", "auto"); 3310 3311 $("body").velocity("scroll", { 3312 duration: 800, 3313 }); 3314 3315 // Reenable native smooth scroll 3316 setTimeout(function () { 3317 $("html").css("scroll-behavior", "smooth"); 3318 }, 1000); 3319 }); 3320 3321 function topVisible(event) { 3322 var windowScrollTop = $window.scrollTop(); 3323 3324 if (windowScrollTop > offsetTop && topVisible.state !== true) { 3325 topVisible.state = true; 3326 3327 $top.addClass("is-visible"); 3328 $toc.addClass("is-visible"); 3329 $donate.addClass("is-visible"); 3330 } else if (windowScrollTop <= offsetTop && topVisible.state !== false) { 3331 topVisible.state = false; 3332 3333 $top.removeClass("is-visible"); 3334 $toc.removeClass("is-visible"); 3335 $donate.removeClass("is-visible"); 3336 } 3337 } 3338 3339 topVisible.state = undefined; 3340 3341 $window.on("scroll.top", topVisible); 3342 3343 topVisible(); 3344}); 3345 3346 3347// ORGANISMS 3348 3349$(document).ready(function(){ 3350 3351 var $fbslide = $('.js-facebookstream__slider'); 3352 3353 $fbslide.slick({ 3354 3355 prevArrow: '<button type="button" class="slick-prev"><span class="sr-only">Vorheriges</span></button>', 3356 nextArrow: '<button type="button" class="slick-next"><span class="sr-only">Nächstes</span></button>', 3357 arrows : false, 3358 dots: true, 3359 slide : '.js-facebookstream__item', 3360 adaptiveHeight: false, 3361 fade: false, 3362 speed: 500, 3363 autoplay : true, 3364 autoplaySpeed : 5000, 3365 variableWidth : false, 3366 slidesToShow:3, 3367 slidesToScroll:3, 3368 responsive : [ 3369 { 3370 breakpoint: 960, 3371 settings: { 3372 slidesToShow: 2, 3373 slidesToScroll: 2 3374 } 3375 },{ 3376 breakpoint: 640, 3377 settings: { 3378 adaptiveHeight: true, 3379 autoplay : false, 3380 slidesToShow: 1, 3381 slidesToScroll: 1 3382 } 3383 } 3384 ] 3385 3386 }); 3387 3388}); 3389$(document).ready(function() { 3390 3391 if ($('.header').length > 0) { 3392 3393 var $window = $(window); 3394 3395 function checkWidth() { 3396 3397 var windowsize = $window.width(); 3398 3399 if (windowsize > 960) { 3400 3401 var $header = $('.header');
3402 var $headerSticky = $('.header__bottom') 3403 3404 $headerSticky.elementDirectionAndOffsetByScroll('init', { 3405 offsetSmall : $header.outerHeight() - $headerSticky.outerHeight(), // Best practice: header-height - header-small-height 3406 offsetOut : $header.outerHeight() * 1 // Best practice: header-height, 3407 3408 }); 3409 3410 } else { 3411 3412 var $header = $('.header'); 3413 var $headerSticky = $('.header__middle') 3414 3415 $headerSticky.elementDirectionAndOffsetByScroll('init', { 3416 offsetSmall : $header.outerHeight() - $headerSticky.outerHeight(), // Best practice: header-height - header-small-height 3417 offsetOut : $header.outerHeight() * 1 // Best practice: header-height, 3418 3419 }); 3420 } 3421 } 3422 3423 checkWidth(); 3424 3425 $(window).resize(checkWidth); 3426 3427 } 3428}); 3429 3430// Get Publication Shop Item's Width and set it's Height Accordingly 3431 3432$(document).ready(pubHeight); 3433$(window).on('resize',pubHeight); 3434 3435function pubHeight() { 3436 $('.shop-detail .publication-wrap').each(function() { 3437 $(this).height($(this).outerWidth()); 3438 }); 3439} 3440 3441 3442 3443// showing/hiding additional form fields during checkout 3444 3445$(document).ready(function() { 3446 3447 if ($("#alt-shipping-toggle").prop("checked") === true) { 3448 3449 // showing additional form fields 3450 $(".alt-shipping").show(); 3451 3452 // setting shown form fields to required 3453 $("input.alt-shipping__required").prop("required", true); 3454 } 3455 3456 $("#alt-shipping-toggle").click(function() { 3457 if ($(this).prop("checked") === true) { 3458 3459 // showing additional form fields 3460 $(".alt-shipping").show(); 3461 3462 // setting shown form fields to required 3463 $("input.alt-shipping__required").prop("required", true); 3464 } else { 3465 3466 // removing focus and clearing content of hidden form fields 3467 $(".alt-shipping input") 3468 .blur() 3469 .val(""); 3470 3471 // hiding additional form fields again 3472 $(".alt-shipping").hide(); 3473 3474 // setting hidden form fields to not required 3475 $("input.alt-shipping__required").prop("required", false); 3476 } 3477 }); 3478}); 3479 3480 3481$(document).ready(function() { 3482 3483 if ($("#alt-billing-toggle").prop("checked") === true) { 3484 3485 // showing additional form fields 3486 $(".alt-billing").show(); 3487 3488 // setting shown form fields to required 3489 $("input.alt-billing__required").prop("required", true); 3490 } 3491 3492 $("#alt-billing-toggle").click(function() { 3493 if ($(this).prop("checked") === true) { 3494 3495 // showing additional form fields 3496 $(".alt-billing").show(); 3497 3498 // setting shown form fields to required 3499 $("input.alt-billing__required").prop("required", true); 3500 } else { 3501 3502 // removing focus and clearing content of hidden form fields 3503 $(".alt-billing input") 3504 .blur() 3505 .val(""); 3506 3507 // hiding additional form fields again 3508 $(".alt-billing").hide(); 3509 3510 // setting hidden form fields to not required 3511 $("input.alt-billing__required").prop("required", false); 3512 } 3513 }); 3514}); 3515 3516 3517 3518 3519 3520// show "reload cart button" if quantity in cart was changed 3521 3522$(document).ready(function() { 3523 3524 $('.item__quantity__input').on('change keyup paste', function () { 3525 3526 $('.reload-cart').addClass('cart-has-changed'); 3527 3528 }); 3529}); 3530 3531$(document).ready(function() { 3532 3533 if (!$("#form-termine-register")) return; 3534 3535 $(".company").hide(); 3536 $(".email-organization").hide(); 3537 $("#company").prop('required', false); 3538 $("#email2").prop('required', false); 3539 3540 $('input[name="tx_lfseminars_registration[newRegistration][addressType]"]').on("change", function() { 3541 3542 if (this.value == 'company') { 3543 $(".company").show(); 3544 $("#company").attr("required", true); 3545 $(".email-organization").show(); 3546 $("#email2").attr("required", true); 3547 $('.note-company').show() 3548 $('.note-company').siblings().hide() 3549 } else { 3550 $(".company").hide(); 3551 $(".email-organization").hide(); 3552 $("#company").prop('required', false); 3553 $("#email2").prop('required',false); 3554 $("#company").val(""); 3555 $("#email2").val(""); 3556 $('.note-company').hide(); 3557 $('.note-company').siblings().show(); 3558 } 3559 }) 3560}); 3561 3562
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.