1( function( $ ) { 2 3 /** 4 * Hook to $( window ).load() to correctly capture the rendered attribute values. 5 * @since 3.5.1.2 6 */ 7 $( window ).ready( function() { 8 9 /** 10 * Payment Method selection. 11 * Expand the first Payment Method in Payment Page. 12 */ 13 setTimeout( function() { 14 let selected_method = $( 'input.tc_choose_gateway:checked' ).val(), 15 max_height = $( 'div#' + selected_method + ' > .inner-wrapper' ).outerHeight(); 16 $( 'div#' + selected_method ).css( { 'max-height': max_height + 'px' } ); 17 }, 500 ); 18 }); 19 20 $( document ).ready( function() { 21 22 /** 23 * Provides additional focus functionality. 24 * This method can be used to enhance or customize the behavior of the 25 * focus event on selected elements in the DOM. 26 */ 27 $.fn.tcFocus = function () { 28 return this.each(function () { 29 var $element = $(this); 30 $( '.tc-focus' ).removeClass( 'tc-focus' ); 31 $element.addClass( 'tc-focus' ); 32 }); 33 }; 34 35 const tc_cart = { 36 37 quantity: function() { 38 39 var quantity = 0; 40 $( 'input[name="ticket_quantity[]"]' ).each( function() { 41 quantity = quantity + parseInt( $( this ).val() ); 42 } ); 43 44 return quantity; 45 }, 46 47 /** 48 * Initialize Listeners 49 */ 50 init: function() { 51 tc_cart.tc_empty_cart(); 52 tc_cart.tc_cart_listeners(); 53 }, 54 55 /** 56 * Listeners for add item to cart 57 * 58 * @returns {undefined} 59 */ 60 tc_cart_listeners: function() { 61 62 $( 'body' ).on( 'click', 'input.tc_button_addcart', function() { 63 64 var input = $( this ), 65 formElm = $( input ).parents( 'form.tc_buy_form' ), 66 tempHtml = formElm.html(), 67 serializedForm = formElm.serialize(); 68 69 formElm.html( '<img src="' + tc_ajax.imgUrl + '" alt="' + tc_ajax.addingMsg + '" />' ); 70 71 $.post( tc_ajax.ajaxUrl, serializedForm, function( data ) { 72 73 var result = data.split( '||', 2 ); 74 75 if ( 'error' == result[ 0 ] ) { 76 77 alert( result[ 1 ] ); 78 formElm.html( tempHtml ); 79 tc_cart.tc_cart_listeners(); 80 81 } else { 82 83 formElm.html( '<span class="tc_adding_to_cart">' + tc_ajax.successMsg + '</span>' ); 84 $( 'div.tc_cart_widget_content' ).html( result[ 1 ] ); 85 86 if ( result[ 0 ] > 0 ) { 87 88 formElm.fadeOut( 2000, function() { 89 formElm.html( tempHtml ).fadeIn( 'fast' ); 90 tc_cart.tc_cart_listeners(); 91 } ); 92 93 } else { 94 formElm.fadeOut( 2000, function() { 95 formElm.html( '<span class="tc_no_stock">' + tc_ajax.outMsg + '</span>' ).fadeIn( 'fast' ); 96 tc_cart.tc_cart_listeners(); 97 } ); 98 } 99 100 tc_cart.tc_empty_cart(); // Re-init empty script as the widget was reloaded 101 } 102 } ); 103 return false; 104 } ); 105 }, 106 107 /** 108 * Empty Cart 109 * 110 * @returns {undefined} 111 */ 112 tc_empty_cart: function() { 113 114 if ( $( 'a.tc_empty_cart' ).attr( 'onClick' ) != undefined ) { 115 return; 116 } 117 118 $( 'body' ).on( 'click', 'a.tc_empty_cart', function() { 119 120 var answer = confirm( tc_ajax.empty_cart_message ); 121 122 if ( answer ) { 123 124 $( this ).html( '<img src="' + tc_ajax.imgUrl + '" />' ); 125 126 $.post( tc_ajax.ajaxUrl, { action: 'mp-update-cart', empty_cart: 1 }, function( data ) { 127 $( 'div.tc_cart_widget_content' ).html( data ); 128 } ); 129 } 130 131 return false; 132 } ); 133 } 134 }; 135 136 /** 137 * ======================================================================= 138 * Check age restriction. 139 * Woocommerce + Bridge for Woocommerce 140 * ======================================================================= 141 */ 142 $( 'form.checkout' ).on( 'checkout_place_order', function( event ) { 143 if ( $( '#tc_age_check' ).length !== 0 ) { 144 if ( false == $( '#tc_age_check' ).is( ':checked' ) ) { 145 $( '.tc-age-check-error' ).remove(); 146 $( '.tc-age-check-label' ).append( '<span class="tc-age-check-error">' + tc_ajax.tc_error_message + '</span>' ); 147 $( 'html, body' ).stop().animate( { 'scrollTop': ( $( '#tc_age_check' ).offset().top ) - 100 }, 350, 'swing', function() { window.location.hash = target; }); 148 return false; 149 } 150 } 151 } ); 152 153 154 if ( $( '.tc_cart_widget' ).length > 0 ) { 155 156 function tc_update_cart_ajax() { 157 158 $( '.tc_cart_ul' ).css( 'opacity', '0.5' ); 159 160 // Since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php 161 $.post( tc_ajax.ajaxUrl, { 162 action: 'tickera_update_widget_cart', 163 nonce: tc_ajax.ajaxNonce 164 }, function( response ) { 165 $( '.tc_cart_ul' ).css( 'opacity', '1' ); 166 $( '.tc_cart_ul' ).html( '' ); 167 $( '.tc_cart_ul' ).html( response ); 168 } ); 169 } 170 171 // Listen DOM changes 172 $( '.event_tickets, .cart_form' ).bind( 'DOMSubtreeModified', tc_update_cart_ajax ); 173 } 174 175 $( document ).on( 'submit', '#tc_payment_form', function() { 176 $( '#tc_payment_confirm' ).attr( 'disabled', 'disabled' ); 177 } ); 178 179 /** 180 * ======================================================================= 181 * Handles cart page and Events - Add to cart quantity field incrementation. 182 * ======================================================================= 183 */ 184 $( 'body' ).on( 'click', 'input.tickera_button.plus', function() { 185 186 let parentContainer = $( this ).parent(), 187 quantitySelector = parentContainer.find( '.tc_quantity_selector' ), 188 quantity = parseInt( quantitySelector.val() ); 189 190 let min = typeof quantitySelector.attr( 'min' ) !== 'undefined' ? parseInt( quantitySelector.attr( 'min' ) ) : 1, 191 max = typeof quantitySelector.attr( 'max' ) !== 'undefined' ? parseInt( quantitySelector.attr( 'max' ) ) : 999, 192 step = typeof quantitySelector.attr( 'step' ) !== 'undefined' ? parseInt( quantitySelector.attr( 'step' ) ) : 1; 193 194 quantity += step; 195 196 if ( quantity < min ) { 197 quantity = min; 198 199 } else if ( quantity > max ) { 200 quantity = max; 201 202 } else if ( quantity < 0) { 203 quantity = 0 204 } 205 206 parentContainer.find( '.tc_quantity_selector' ).val( quantity ); 207 } ); 208 209 /** 210 * ======================================================================= 211 * Handles cart page and Events - Add to cart quantity field decrementation. 212 * ======================================================================= 213 */ 214 $( 'body' ).on( 'click', 'input.tickera_button.minus', function() { 215 216 let parentContainer = $( this ).parent(), 217 quantitySelector = parentContainer.find( '.tc_quantity_selector' ), 218 quantity = parseInt( quantitySelector.val() ); 219 220 let min = typeof quantitySelector.attr( 'min' ) !== 'undefined' ? parseInt( quantitySelector.attr( 'min' ) ) : 1, 221 max = typeof quantitySelector.attr( 'max' ) !== 'undefined' ? parseInt( quantitySelector.attr( 'max' ) ) : 999, 222 step = typeof quantitySelector.attr( 'step' ) !== 'undefined' ? parseInt( quantitySelector.attr( 'step' ) ) : 1; 223 224 quantity -= step; 225 226 if ( quantity < min ) { 227 quantity = min; 228 229 } else if ( quantity > max ) { 230 quantity = max; 231 232 } else if ( quantity < 0) { 233 quantity = 0 234 } 235 236 parentContainer.find( '.tc_quantity_selector' ).val( quantity ); 237 } ); 238 239 $( 'body' ).on( 'input', 'form#tickera_cart .tc_quantity_selector, form#tickera_cart .tickera-input-field[inputmode="numeric"]', function() { 240 this.value = this.value.replace(/\D/g, ''); 241 } ); 242 243 244 /** 245 * ======================================================================= 246 * Handles quantity field incrementation/decrementation on focus. 247 * ======================================================================= 248 */ 249 $( 'body' ).on( 'keydown', 'form#tickera_cart .tickera-input-field[inputmode="numeric"], .tc_quantity_selector', function( e ) { 250 251 if ( e.keyCode === 38 || e.keyCode === 40 ) { 252 253 e.preventDefault(); 254 255 let min = typeof $( this ).attr( 'min' ) !== 'undefined' ? parseInt( $( this ).attr( 'min' ) ) : 1, 256 max = typeof $( this ).attr( 'max' ) !== 'undefined' ? parseInt( $( this ).attr( 'max' ) ) : 999, 257 step = typeof $( this ).attr( 'step' ) !== 'undefined' ? parseInt( $( this ).attr( 'step' ) ) : 1; 258 259 this.value = ( isNaN( this.value ) || this.value === '' ) ? min : parseInt( this.value ); 260 261 switch( e.keyCode ) { 262 263 case 38: // Arrow key up 264 e.preventDefault(); 265 this.value = parseInt( this.value ) + step; 266 break; 267 268 case 40: // Arrow key down 269 e.preventDefault(); 270 this.value = parseInt( this.value ) - step; 271 break; 272 } 273 274 if ( this.value < min ) { 275 this.value = min; 276 277 } else if ( this.value > max ) { 278 this.value = max; 279 280 } else if ( this.value < 0) { 281 this.value = 0 282 } 283 } 284 } ); 285 286 /** 287 * ======================================================================= 288 * Handles quantity field value to trim leading zero value (e.g 01 to 1) 289 * ======================================================================= 290 */ 291 $( 'body' ).on( 'focusout', 'form#tickera_cart .tickera-input-field[inputmode="numeric"], .tc_quantity_selector', function( e ) { 292 this.value = Number( this.value ); 293 } ); 294 295 /** 296 * ======================================================================= 297 * When user clicks on the empty cart button 298 * ======================================================================= 299 */ 300 $( 'body' ).on( 'click', '#empty_cart', function( event ) { 301 302 let proceed = confirm( tc_ajax.empty_cart_confirmation ); 303 304 if ( proceed ) { 305 $( 'input[name="cart_action"]' ).val( 'empty_cart' ); 306 307 } else { 308 event.preventDefault(); 309 } 310 } ); 311 312 /** 313 * ======================================================================= 314 * When user clicks on the update button 315 * ======================================================================= 316 */ 317 $( 'body' ).on( 'click', '#update_cart', function() { 318 $( 'input[name="cart_action"]' ).val( 'update_cart' ); 319 } ); 320 321 /** 322 * ======================================================================= 323 * Toggle Customer Age Checkbox 324 * ======================================================================= 325 */ 326 $( document ).on( 'change', '#tc_age_check', function() { 327 328 if ( $( this ).is( ':checked' ) ) { 329 $( this ).removeClass( 'has-error' ); 330 $( '.tc-age-check-error' ).remove(); 331 332 } else { 333 $( this ).addClass( 'has-error' ); 334 $( '.tc-age-check-error' ).remove(); 335 $( this ).parent().append( '<span class="tc-age-check-error">' + tc_ajax.tc_error_message + '</span>' ); 336 } 337 } ); 338 339 /** 340 * ======================================================================= 341 * Tickera Standalone 342 * When user click on the proceed to checkout button 343 * ======================================================================= 344 */ 345 var current_quantity = tc_cart.quantity();
346 $( document ).on( 'click', '#proceed_to_checkout', function( event ) { 347 348 // Make sure to update the cart if there's some changes before moving to checkout page. 349 let input_quantity = tc_cart.quantity(); 350 if ( typeof tc_cart.quantity() === 'undefined' || 0 == tc_cart.quantity() || current_quantity != input_quantity ) { 351 event.preventDefault(); 352 353 let target = $( '.tc_cart_errors' ); 354 if ( target.find( 'ul' ).length ) { 355 target.find( 'ul' ).append( '<li>' + tc_ajax.update_cart_message + '</li>' ); 356 357 } else { 358 target.html( '<ul><li>' + tc_ajax.update_cart_message + '</li></ul>' ); 359 } 360 361 $( 'html, body' ).stop().animate( { 'scrollTop': ( target.offset().top ) - 40 }, 350, 'swing', function() { 362 window.location.hash = target; 363 } ); 364 } 365 366 // Make sure confirm age before proceeding to checkout 367 if ( $( '#tc_age_check' ).length ) { 368 let age_confirmation_field = $( '#tc_age_check' ); 369 if ( age_confirmation_field.is( ':checked' ) ) { 370 age_confirmation_field.removeClass( 'has-error' ); 371 $( '.tc-age-check-error' ).remove(); 372 373 } else { 374 event.preventDefault(); 375 $( '.tc-age-check-error' ).remove(); 376 age_confirmation_field.addClass( 'has-error' ); 377 age_confirmation_field.closest( 'label' ).append( '<span class="tc-age-check-error">' + tc_ajax.tc_error_message + '</span>' ); 378 } 379 } 380 } ); 381 382 /** 383 * ======================================================================= 384 * When user click on the proceed to checkout button 385 * ======================================================================= 386 */ 387 $( 'body' ).on( 'click', '#apply_coupon', function() { 388 $( 'input[name="cart_action"]' ).val( 'apply_coupon' ); 389 } ); 390 391 /** 392 * ======================================================================= 393 * Add to cart button 394 * ======================================================================= 395 */ 396 $( 'body' ).on( 'click', 'a.add_to_cart', function( event ) { 397 398 event.preventDefault(); 399 400 let btn = $( this ); 401 btn.fadeOut( 'fast' ).fadeIn( 'fast' ); 402 403 var button_type = btn.attr( 'data-button-type' ), 404 open_method = btn.attr( 'data-open-method' ), 405 current_form = btn.closest( 'form.cart_form' ), 406 parent_container = current_form.parent(), 407 ticket_id = current_form.find( '.ticket_id' ).val(), 408 qtySelector = btn.closest( 'tr' ).find( '.tc_quantity_selector' ); 409 410 // Dropdown quantity selector 411 if ( qtySelector.length === 0 ) { 412 qtySelector = current_form.find( '.tc_quantity_selector' ); 413 } 414 415 let qty = qtySelector.val(), 416 nonce = btn.closest( 'form.cart_form' ).find( '[name="nonce"]' ).val(); 417 418 qty = ( typeof qty === 'undefined' ) ? btn.closest( '.cart_form' ).find( '.tc_quantity_selector' ).val() : qty; 419 420 $.post( tc_ajax.ajaxUrl, { action: 'add_to_cart', ticket_id: ticket_id, tc_qty: qty, nonce: nonce }, function( data ) { 421 422 // btn.tc_tooltip( { 'detach': true } ); 423 424 if ( 'error' != data ) { 425 426 parent_container.html( data ); 427 428 let cart = parent_container.find( '.tc_in_cart a'); 429 // cart.tc_tooltip(); 430 431 if ( $( '.tc_cart_contents' ).length > 0 ) { 432 $.post( tc_ajax.ajaxUrl, { action: 'update_cart_widget', nonce: nonce }, function( widget_data ) { 433 $( '.tc_cart_contents' ).html( widget_data ); 434 } ); 435 } 436 437 if ( 'new' == open_method && 'buynow' == button_type ) { 438 window.open( tc_ajax.cart_url, '_blank' ); 439 } 440 441 if ( 'buynow' == button_type && 'new' !== open_method ) { 442 window.location = tc_ajax.cart_url; 443 } 444 445 } else { 446 parent_container.html( data ); 447 } 448 } ); 449 } ); 450 451 /** 452 * ======================================================================= 453 * Cart Widget 454 * ======================================================================= 455 */ 456 $( 'body' ).on( 'click', '.tc_widget_cart_button', function() { 457 window.location.href = $( this ).data( 'url' ); 458 } ); 459 460 /** 461 * ======================================================================= 462 * Proceed to checkout button 463 * ======================================================================= 464 */ 465 $( 'body' ).on( 'click', '#proceed_to_checkout', function() { 466 $( 'input[name="cart_action"]' ).val( 'proceed_to_checkout' ); 467 } ); 468 469 /** 470 * ======================================================================= 471 * Check email-verification for owner field with Woocommerce 472 * ======================================================================= 473 */ 474 $( 'form.checkout' ).on( 'click', 'button[type="submit"][name="woocommerce_checkout_place_order"]', function() { 475 476 // Disable "Place Order" button 477 var owner_email = $( '.tc_owner_email' ).val(),
478 owner_confirm_email = $( '.tc_owner_confirm_email' ).val(); 479 480 if ( ( owner_email && owner_confirm_email ) ) { 481 482 if ( ( owner_email !== owner_confirm_email ) || owner_email === "" || owner_confirm_email === "" ) { 483 $( '.tc_owner_email,.tc_owner_confirm_email' ).css( 'border-left', '2px solid #ff0000' ); 484 485 } else { 486 $( '.tc_owner_email,.tc_owner_confirm_email' ).css( 'border-left', '2px solid #09a10f' ); 487 } 488 } 489 } ); 490 491 /** 492 * ======================================================================= 493 * Payment Method selection. 494 * Accordion effect in Payment Page. 495 * ======================================================================= 496 */ 497 $( document ).on( 'change', '.tickera-payment-gateways input.tc_choose_gateway', function() { 498 499 let selected_method = $( 'input.tc_choose_gateway:checked' ).val(), 500 parent_container = $( this ).closest( '.tickera-payment-gateways' ), 501 max_height = parent_container.find( 'div#' + selected_method + ' > .inner-wrapper' ).outerHeight(); 502 503 $( '.tickera-payment-gateways' ).removeClass( 'active' ); 504 parent_container.addClass( 'active' ); 505 506 parent_container.siblings().find( '.tc_gateway_form' ).removeAttr( 'style' ); 507 $( 'div#' + selected_method ).css( { 'max-height': max_height + 'px' } ); 508 }); 509 510 /** 511 * ======================================================================= 512 * Handles keypress 'enter' key in cart page. 513 * ======================================================================= 514 */ 515 $( document ).on( 'keypress', '#tickera_cart input', function( e ) { 516 517 if ( 13 === e.keyCode ) { 518 519 e.preventDefault(); 520 521 if ( $( this ).hasClass( 'quantity' ) ) { 522 $( '#update_cart' ).trigger( 'click' ); 523 524 } else if ( $( this ).hasClass( 'coupon_code' ) ) { 525 $( '#apply_coupon' ).trigger( 'click' ); 526 527 } else if ( $( this ).hasClass( 'tickera_empty' ) ) { 528 $( '#empty_cart' ).trigger( 'click' ); 529 } 530 } 531 } ); 532 533 /** 534 * ======================================================================= 535 * Handles keypress 'enter' key in event add-to-cart table. 536 * ======================================================================= 537 */ 538 $( document ).on( 'keypress', '.event_tickets.tickera .tc_quantity_selector', function( e ) { 539 if ( 13 === e.keyCode ) { 540 e.preventDefault(); 541 let ticketRow = $( this ).closest( 'tr' ), 542 addToCart = ticketRow.find( '.add_to_cart' ); 543 addToCart.trigger( 'click' ); 544 } 545 } ); 546 547 /** 548 * ======================================================================= 549 * Handles keypress 'enter' key in event add-to-cart dropdown. 550 * ======================================================================= 551 */ 552 $( document ).on( 'keypress', '.tc-event-dropdown-wrap .tc_quantity_selector, .tc-add-to-cart-wrap .tc_quantity_selector', function( e ) { 553 if ( 13 === e.keyCode ) { 554 e.preventDefault(); 555 let ticketRow = $( this ).closest( 'form.cart_form' ), 556 addToCart = ticketRow.find( 'a.add_to_cart' ); 557 addToCart.trigger( 'click' ); 558 } 559 } ); 560 561 /** 562 * ======================================================================= 563 * Handles left and right arrow keys to move within the cart form fields. 564 * ======================================================================= 565 */ 566 $( document ).on( 'keydown', 'form#tickera_cart, table.event_tickets.tickera, .tc-event-dropdown-wrap, .tc-add-to-cart-group-wrap ~ .tc-add-to-cart-wrap', function( e ) { 567 568 let fields = $( this ).find('input, select, textarea, a').filter(':visible:not([disabled]):not([type="hidden"]):not(.tc-hidden-important)'), 569 currentField = $( this ).find( ':focus' ); 570 571 let currentFieldElementType = $( currentField ).prop( 'tagName' ).toLowerCase(), 572 currentFieldType = $( currentField ).attr( 'type' ), 573 index = $( fields ).index( currentField ); 574 575 if ( ( currentFieldElementType === 'input' && currentFieldType.includes( 'text' ) ) || currentFieldElementType === 'textarea' ) { 576 577 let caretPlacement = $(currentField).prop('selectionStart'), 578 fieldValueLength = $(currentField).val().length; 579 580 if (e.keyCode == 37 && caretPlacement === 0) { 581 $(fields[index - 1]).focus(); 582 583 } else if (e.keyCode == 39 && caretPlacement === fieldValueLength) { 584 $(fields[index + 1]).focus(); 585 586 } else if (e.keyCode == 13) { 587 $('#proceed_to_checkout').trigger('click'); 588 } 589 590 } else if ( currentFieldElementType === 'input' && currentFieldType.includes( 'checkbox' ) && e.keyCode == 13 ) { 591 592 if (currentField.prop('checked')) { 593 currentField.prop('checked', false).trigger('change'); 594 595 } else { 596 currentField.prop('checked', true).trigger('change'); 597 } 598 599 } else if ( currentFieldElementType === 'input' && currentFieldType.includes( 'radio' ) ) { 600 601 e.preventDefault(); 602 603 switch (e.keyCode) { 604 605 case 37: // Left arrow key 606 $(fields[index - 1]).focus(); 607 break; 608 609 case 39: // Right arrow key 610 $(fields[index + 1]).focus(); 611 break; 612 613 case 13: // Enter key 614 if (currentField.prop('checked')) { 615 currentField.prop('checked', false).trigger('change'); 616 } else { 617 currentField.prop('checked', true).trigger('change'); 618 } 619 break; 620 } 621 622 } else if ( currentFieldElementType === 'input' && currentFieldType.includes( 'button' ) && currentField.hasClass( 'tickera_button' ) ) { 623 624 e.preventDefault(); 625 626 let action = currentField.data( 'action' ), 627 quantitySelector = currentField.parent().find( '.tc_quantity_selector' ), 628 quantitySelectorValue = parseInt( quantitySelector.val() ), 629 min = typeof quantitySelector.attr( 'min' ) !== 'undefined' ? parseInt( quantitySelector.attr( 'min' ) ) : 1, 630 max = typeof quantitySelector.attr( 'max' ) !== 'undefined' ? parseInt( quantitySelector.attr( 'max' ) ) : 999, 631 step = typeof quantitySelector.attr( 'step' ) !== 'undefined' ? parseInt( quantitySelector.attr( 'step' ) ) : 1; 632 633 switch ( e.keyCode ) { 634 635 case 37: // Left arrow key 636 $( fields[ index - 1 ] ).focus(); 637 break; 638 639 case 39: // Right arrow key 640 case 9: // Since e.preventDefault(), this is to handle conflict between cart and event add to cart quantity selectors 641 $( fields[ index + 1 ] ).focus(); 642 break; 643 644 case 13: // Enter key 645 646 if ( currentField.hasClass( 'plus' ) ) { 647 quantitySelectorValue = quantitySelectorValue + step; 648 649 } else { 650 quantitySelectorValue = quantitySelectorValue - step; 651 } 652 653 if ( quantitySelectorValue < min ) { 654 quantitySelectorValue = min; 655 656 } else if ( quantitySelectorValue > max ) { 657 quantitySelectorValue = max; 658 659 } else if ( quantitySelectorValue < 1) { 660 quantitySelectorValue = 1 661 } 662 663 quantitySelector.val( quantitySelectorValue ); 664 break; 665 } 666 667 } else { 668 669 switch ( e.keyCode ) { 670 671 case 37: // Left arrow key 672 $( fields[ index - 1 ] ).focus(); 673 break; 674 675 case 39: // Right arrow key 676 $( fields[ index + 1 ] ).focus(); 677 break; 678 } 679 } 680 } ); 681 682 /** 683 * ======================================================================= 684 * Handles payment page's gateway selection. 685 * ======================================================================= 686 */ 687 $( document ).on( 'keydown', 'form#tc_payment_form .tickera-payment-gateways.active', function( e ) { 688 689 let fields = $( this ).find('input, select, textarea').filter(':visible:not([disabled])'), 690 currentField = $( this ).find( ':focus' ); 691 692 let currentFieldElementType = $( currentField ).prop( 'tagName' ).toLowerCase(), 693 currentFieldType = $( currentField ).attr( 'type' ), 694 index = $( fields ).index( currentField ); 695 696 if ( currentFieldElementType === 'input' && currentFieldType.includes( 'text' ) ) { 697 698 let caretPlacement = $( currentField ).prop( 'selectionStart' ), 699 fieldValueLength = $( currentField ).val().length; 700 701 if ( e.keyCode == 37 && caretPlacement === 0 ) { 702 $( fields[ index - 1 ] ).focus(); 703 704 } else if ( e.keyCode == 39 && caretPlacement === fieldValueLength ) { 705 $( fields[ index + 1 ] ).focus(); 706 } 707 708 709 } else { 710 711 switch ( e.keyCode ) { 712 713 case 37: // Left arrow key 714 $( fields[ index - 1 ] ).focus(); 715 break; 716 717 case 39: // Right arrow key 718 $( fields[ index + 1 ] ).focus(); 719 break; 720 721 case 9: 722 if ( ! $( fields[ index + 1 ] ).length ) { 723 $( this ).removeClass( 'active' ); 724 $( this ).find( '.tc_gateway_form' ).css( 'max-height', '0' ); 725 726 let nextGateway = $( this ).next(); 727 nextGateway.addClass( 'active' ).find( '.tc_choose_gateway' ).prop( 'checked', true ); 728 nextGateway.find( '.tc_gateway_form' ).css( 'max-height', nextGateway.find( '.inner-wrapper' ).outerHeight() + 'px' ); 729 } 730 break; 731 } 732 } 733 } ); 734 735 /** 736 * ======================================================================= 737 * Handles cart page's discount field. 738 * ======================================================================= 739 */ 740 let coupon_code_value = $( '.tickera-checkout .coupon_code' ).val(); 741 $( document ).on( 'keyup', '.tickera-checkout .coupon_code', function() { 742 743 if ( coupon_code_value !== $( this ).val() || ! $( this ).val() ) { 744 $( this ).parent().find( '.message').hide(); 745 $( this ).parent().find( '.apply_coupon').show(); 746 747 } else { 748 $( this ).parent().find( '.message').show(); 749 $( this ).parent().find( '.apply_coupon').hide(); 750 } 751 }); 752 753 /** 754 * ======================================================================= 755 * Payment Gateway Page - Frontend 756 * ======================================================================= 757 */ 758 $( document ).on( 'keypress', '.tc-numbers-only', function( e ) { 759 if ( e.which != 8 && e.which != 0 && ( e.which < 48 || e.which > 57 ) ) { 760 return false; 761 } 762 } ); 763 764 /** 765 * ======================================================================= 766 * Update add to cart link value/ticket type id 767 * Event Tickets - Shortcode
768 * Display Type: Dropdown 769 * ======================================================================= 770 */ 771 $( document ).on( 'change', '.tc-event-dropdown-wrap select.ticket-type-id', function() { 772 773 let wrapper = $( this ).closest( '.tc-event-dropdown-wrap' ), 774 ticketId = $( this ).val(), 775 actionsContainer = wrapper.find( '.actions' ), 776 addToCartContainer = actionsContainer.find( '[id="ticket-type-' + ticketId + '"]' ); 777 778 addToCartContainer.prependTo( actionsContainer ); 779 }); 780 } ); 781 782 /** 783 * Tickera Standalone, Woocommerce + Bridge for Woocommerce 784 * Check custom form error notification 785 */ 786 $( document ).ready( function() { 787 788 /** 789 * Cart/Checkout Form validation 790 */ 791 if ( $( 'form#tickera_cart' ).length || $( 'form.checkout' ).length ) { 792 793 $.validator.addMethod( 'alphanumericOnly', function( value, element ) { 794 if ( ! value ) return true; // Valid if empty value 795 let regex = new RegExp( "^[^<?=^>]+$" ); 796 return ( !regex.test( value ) ) ? false : true; 797 }, tc_ajax.alphanumeric_characters_only ); 798 799 $( 'form#tickera_cart, form.checkout' ).validate( { 800 debug: false, 801 ignore: ".tc_quantity_selector", 802 errorClass: 'has-error', 803 validClass: 'valid', 804 highlight: function( element, errorClass, validClass ) { 805 $( element ).addClass( errorClass ).removeClass( validClass ); 806 }, 807 unhighlight: function( element, errorClass, validClass ) { 808 $( element ).removeClass( errorClass ).addClass( validClass ); 809 } 810 } ); 811 812 $( '.tickera-input-field' ).each( function() { 813 814 let field = $( this ), 815 field_type = field.attr( 'type' ), 816 field_name = field.attr( 'name' ); 817 818 if ( ( ( 'text' == field_type && ! field.hasClass( 'checkbox_values' ) ) // Include Text but not checkbox_values 819 || field.is( 'textarea' ) ) // Include Textarea 820 && 'coupon_code' != field_name ) { // Don't include discount field 821 // $( this ).rules( 'add', { 822 // alphanumericOnly: true 823 // } ); 824 } 825 } ); 826 827 $( 'input[name="tc_cart_required[]"]' ).each( function() { 828 let field = $( this ).closest( 'div' ).find( '.tickera-input-field:not( input[type="checkbox"] ):not( input[type="radio"] )' ); 829 field.rules( 'add', { 830 required: { 831 depends: function() { 832 833 let trimmedValue = $( this ).val().trim(); 834 835 if ( ! trimmedValue ) { 836 $( this ).val( $.trim( $( this ).val() ) ); 837 return true; 838 839 } else { 840 return false; 841 } 842 } 843 }, 844 messages: { 845 required: tc_jquery_validate_library_translation.required 846 } 847 } ); 848 } ); 849 850 $( '.tc_validate_field_type_email' ).each( function() { 851 $( this ).rules( 'add', { 852 email: true, 853 messages: { 854 email: tc_jquery_validate_library_translation.email 855 } 856 } ); 857 } ); 858 859 $( '.tc_validate_field_type_confirm_email' ).each( function() { 860 $( this ).rules( 'add', { 861 email: true, 862 equalTo: '.tc_validate_field_type_email', 863 messages: { 864 email: tc_jquery_validate_library_translation.email, 865 equalTo: tc_jquery_validate_library_translation.equalTo 866 } 867 } ); 868 } ); 869 870 $( '.tc_owner_email' ).each( function() { 871 $( this ).rules( 'add', { 872 email: true, 873 messages: { 874 email: tc_jquery_validate_library_translation.email 875 } 876 } ); 877 } ); 878 879 $( '.tc_owner_confirm_email' ).each( function() { 880 881 let owner_email_name = $( this ).attr( 'name' ); 882 owner_email_name = owner_email_name.replace( '_confirm', '' ); 883 884 $( this ).rules( 'add', { 885 email: true, 886 equalTo: 'input[name="' + owner_email_name + '"]', 887 messages: { 888 email: tc_jquery_validate_library_translation.email, 889 equalTo: tc_jquery_validate_library_translation.equalTo 890 } 891 } ); 892 } ); 893 894 /** 895 * ======================================================================= 896 * Update checkbox values on field change. 897 * ======================================================================= 898 */ 899 $( document ).on( 'change', '.buyer-field-checkbox, .owner-field-checkbox', function( e ) { 900 901 var field_values = $( this ).closest( 'div' ).find( '.checkbox_values' ), 902 values = field_values.val().split( ',' ); 903 904 if ( $( this ).is( ':checked' ) ) { 905 values[ values.length ] = $( this ).val(); 906 field_values.removeClass( 'has-error' ).addClass( 'valid' ); 907 908 } else { 909 var toRemove = $( this ).val(); 910 values = $.grep( values, function( value ) { 911 return value != toRemove; 912 } ) 913 } 914 915 field_values.val( values.filter( e => e ).join() ).focus().blur(); 916 } ); 917 918 /** 919 * ======================================================================= 920 * Update radio validation field 921 * ======================================================================= 922 */ 923 $( document ).on( 'change', '.buyer-field-radio, .owner-field-radio', function( e ) { 924 925 var fieldWrapper = $( this ).closest( 'div' ), 926 validationField = fieldWrapper.find( '.validation' ); 927
928 if ( fieldWrapper.find( 'input[type="radio"]:checked' ).length > 0 ) { 929 validationField.val( true ); 930 validationField.removeClass( 'has-error' ).addClass( 'valid' ); 931 validationField.next( '.has-error' ).remove(); 932 } 933 } ); 934 } 935 } ); 936} )( jQuery );
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.