1class WEBBA5_Form { 2 constructor(container) { 3 const get_this = () => { 4 return this 5 } 6 7 this.container = container 8 get_this().init_nice_select() 9 10 var screen_count = container.find( 11 '.appointment-content-screen-w' 12 ).length 13 14 // wbk_hidden wbk_service_checkbox_holder 15 if (this.container.find('[data-slug="link_payment"]').length > 0) { 16 get_this().initiaize_payments() 17 } 18 jQuery('.wbk_service_description_switcher').click(function (e) { 19 e.preventDefault() 20 jQuery(this).toggleClass('wbk_rotate_90') 21 jQuery(this) 22 .closest('li') 23 .find('.wbk_service_description_holder') 24 .toggleClass('wbk_hidden') 25 }) 26 var i = 1 27 28 if (container.find('.wbk_service_categories').length == 0) { 29 get_this() 30 .container.find('.wbk_service_label') 31 .removeClass('wbk_hidden') 32 33 get_this() 34 .container.find('.wbk_service_item') 35 .removeClass('wbk_hidden') 36 } 37 38 container.find('.wbk_service_categories').change(function () { 39 container.find('.wbk_services').prop('checked', false) 40 41 container.find('.wbk_services').trigger('change') 42 if (jQuery(this).val() == 0) { 43 get_this() 44 .container.find('.wbk_service_label') 45 .addClass('wbk_hidden') 46 47 get_this() 48 .container.find('.wbk_service_item') 49 .addClass('wbk_hidden') 50 51 return 52 } 53 var services_opt = jQuery(this) 54 .find('option:selected') 55 .attr('data-services') 56 .split('-') 57 58 get_this() 59 .container.find('.wbk_service_item') 60 .addClass('wbk_hidden') 61 62 jQuery.each(services_opt, function (index, value) { 63 container 64 .find('.wbk_service_item[data-servicei_id="' + value + '"]') 65 .removeClass('wbk_hidden') 66 }) 67 }) 68 69 container.find('.appointment-content-screen-w').each(function () { 70 if (i == screen_count) { 71 return 72 } 73 74 if (jQuery(this).attr('data-slug') == 'payment_optional') { 75 i++ 76 return 77 } 78 get_this().add_status_bar_item( 79 i, 80 jQuery(this).attr('data-title'), 81 jQuery(this).attr('data-slug') 82 ) 83 i++ 84 }) 85 86 container 87 .find('.appointment-content-screen-active-w') 88 .find('.wbk-input') 89 .addClass('linear-animation-w') 90 container 91 .find('.appointment-status-list-w > li') 92 .first() 93 .addClass('active-w') 94 95 container.find('.button-next-w').click(function () { 96 get_this().next_step() 97 return false 98 }) 99 container.find('.button-prev-w').click(function () { 100 get_this().prev_step() 101 return false 102 }) 103 104 jQuery(document).on( 105 'wbk_after_screen_rendered', 106 function (event, response) { 107 get_this().after_screen_rendered(response) 108 } 109 ) 110 this.container.attr('data-step', '1') 111 this.validate_prev_next_buttons() 112 this.validate_form() 113 this.set_input_events() 114 115 if (jQuery('.appointment-content-payment-optional').length > 0) { 116 container.find('.wbk_services').change(function () { 117 var payable = false 118 119 if (!get_this().is_multi_service()) { 120 if ( 121 container 122 .find('.wbk_services:checked') 123 .attr('data-payable') == 'true' 124 ) { 125 payable = true 126 } 127 } else { 128 get_this() 129 .container.find('.wbk_service_checkbox:checked') 130 .each(function () { 131 if (jQuery(this).attr('data-payable') == 'true') { 132 payable = true 133 } 134 }) 135 } 136 if (payable) { 137 container 138 .find('[data-slug="payment_optional"]') 139 .not('li') 140 .addClass('appointment-content-screen-w') 141 container 142 .find('[data-slug="payment_optional"]') 143 .not('li') 144 .removeClass(' appointment-content-payment-optional') 145 container 146 .find('[data-slug="final_screen"]') 147 .attr('data-request', 'wbk_approve_payment') 148 149 if ( 150 get_this().container.find( 151 '.appointment-status-list-w > li[data-slug="payment_optional"]' 152 ).length == 0 153 ) { 154 get_this().add_status_bar_item( 155 i, 156 container 157 .find('[data-slug="payment_optional"]') 158 .attr('data-title'), 159 container 160 .find('[data-slug="payment_optional"]') 161 .attr('data-slug') 162 ) 163 } 164 } else { 165 container 166 .find('[data-slug="payment_optional"]') 167 .not('li') 168 .removeClass('appointment-content-screen-w') 169 container 170 .find('[data-slug="payment_optional"]') 171 .not('li') 172 .addClass(' appointment-content-payment-optional') 173 container 174 .find('[data-slug="final_screen"]') 175 .attr('data-request', 'wbk_book') 176 177 container 178 .find('li.appointment-content-payment-optional') 179 .remove() 180 get_this().remove_status_bar_item('payment_optional') 181 } 182 get_this().update_mobile_step() 183 }) 184 } 185 186 this.circle_chart() 187 188 this.update_mobile_step() 189 get_this().init_scroll_bars() 190 if (this.container.find('.wbk_services_hidden').length > 0) { 191 this.get_service_data() 192 } 193 194 jQuery('.wbk-addgg-link').click(function () { 195 window.location.href = jQuery(this).attr('data-link') 196 }) 197 198 this.container.find('form').on('submit', function (e) { 199 e.preventDefault() 200 }) 201 } 202 async get_service_data() { 203 this.container 204 .find('.appointment-content-scroll-w') 205 .append('<div class="wbk-loading"></div>') 206 var response = await this.do_request('wbk_prepare_service_data') 207 response = jQuery.parseJSON(response) 208 this.prepare_service_data_init(response) 209 this.container.find('.wbk-loading').remove() 210 this.container.find('.wbk_date_picked_row').removeClass('wbk_hidden') 211 } 212 213 is_multi_service() { 214 return this.container.find('.wbk_service_checkbox').length > 0 215 } 216 circle_chart() { 217 var color = this.container 218 .find('.circle-chart-wb') 219 .attr('data-circle-color') 220 this.container.find('.circle-chart-wb').easyPieChart({ 221 animate: false, 222 barColor: '#ffffff', 223 trackColor: color, 224 scaleColor: false, 225 lineWidth: 6, 226 }) 227 } 228 229 validate_stripe_input(card_maintained) { 230 const get_this = () => { 231 return this 232 } 233 if (!card_maintained) { 234 this.container 235 .find('.button-approve-stripe-payment') 236 .prop('disabled', true) 237 return false 238 } else { 239 this.container 240 .find('.button-approve-stripe-payment') 241 .prop('disabled', false) 242 return true 243 } 244 } 245 246 process_conditional(elem) { 247 const get_this = () => { 248 return this 249 } 250 if (this.container.find('[name="_wpcf7cf_options"]').length == 0) { 251 return 252 } 253 var condition = jQuery.parseJSON( 254 this.container.find('[name="_wpcf7cf_options"]').val() 255 ) 256 257 jQuery.each(condition.conditions, function (i, data) { 258 var and_rules = data.and_rules 259 var then_field = data.then_field 260 261 jQuery.each(and_rules, function (k, rule) { 262 if ( 263 rule.if_field == elem.attr('name') && 264 rule.operator == 'equals' 265 ) { 266 if (rule.if_value == elem.val()) { 267 jQuery('[data-id="' + then_field + '"]').css( 268 'display', 269 'block' 270 ) 271 } else { 272 jQuery('[data-id="' + then_field + '"]').css( 273 'display', 274 'none' 275 ) 276 } 277 } 278 if ( 279 rule.if_field == elem.attr('name') && 280 rule.operator == 'not equals' 281 ) { 282 if (rule.if_value != elem.val()) { 283 jQuery('[data-id="' + then_field + '"]').css( 284 'display', 285 'block' 286 ) 287 } else { 288 jQuery('[data-id="' + then_field + '"]').css( 289 'display', 290 'none' 291 ) 292 } 293 } 294 }) 295 }) 296 } 297 298 set_input_events() { 299 const get_this = () => { 300 return this 301 } 302 this.container.find('.wbk-input').on('input', function () { 303 get_this().process_conditional(jQuery(this)) 304 get_this().validate_form() 305 }) 306 this.container.find('.wbk-file').on('input', function () { 307 get_this().validate_form() 308 }) 309 this.container.find('.wbk-book-quantity').change(function () { 310 get_this().set_multiple_data() 311 }) 312 313 this.container.find('[name="quantity"]').trigger('change') 314 this.container.find('.wbk-input').change(function () { 315 get_this().process_conditional(jQuery(this)) 316 get_this().validate_form() 317 }) 318 } 319 320 get_multi_service_name_by_id(service_id) { 321 return this.container 322 .find('.wbk_service_checkbox[value="' + service_id + '"]') 323 .closest('.wbk_service_item') 324 .find('.wbk_single_service_title') 325 .html() 326 } 327 328 after_screen_rendered(response) { 329 const get_this = () => { 330 return this 331 } 332 var request = this.container 333 .find('.appointment-content-screen-active-w') 334 .attr('data-request') 335 336 switch (request) { 337 case 'wbk_prepare_service_data': 338 get_this().prepare_service_data_init(response) 339 var value = '' 340 if (get_this().is_multi_service()) { 341 value = [] 342 get_this() 343 .container.find('.wbk_service_checkbox:checked') 344 .each(function () { 345 value.push( 346 jQuery(this) 347 .closest('.wbk_service_checkbox_holder') 348 .find('.wbk_single_service_title') 349 .html() 350 ) 351 }) 352 } else { 353 value = get_this() 354 .container.find('.wbk_services:checked') 355 .closest('.custom-radiobutton-w') 356 .find('.wbk_single_service_title') 357 .text() 358 value = [value] 359 } 360 361 get_this().set_step_subtitle('services', value) 362 363 break 364 case 'wbk_render_booking_form': 365 var value = [] 366 const checked = get_this() 367 .container.find('.wbk_local_time_checkbox') 368 .is(':checked') 369 get_this() 370 .container.find('.wbk_times > option:selected') 371 .each(function () { 372 var date_time_string = '' 373 if (checked) { 374 date_time_string = jQuery(this).attr( 375 'data-time_string_local' 376 ) 377 } else { 378 date_time_string = 379 jQuery(this).attr('data-time_string') 380 } 381 value.push(date_time_string) 382 }) 383 get_this().set_step_subtitle('date_time', value) 384 this.container 385 .find('.appointment-content-screen-active-w') 386 .html( 387 '<div style="display:none" class="hider-w">' + 388 response + 389 '</div>' 390 ) 391 392 this.init_nice_select() 393 get_this().init_scroll_bars() 394 this.container 395 .find('.appointment-content-screen-active-w') 396 .find('.hider-w') 397 .fadeIn('slow', function () {}) 398 399 this.container.find('.wbk-checkbox-custom').each(function () { 400 var exculsive = jQuery(this).hasClass( 401 'wpcf7-exclusive-checkbox' 402 ) 403 var chk_id = jQuery(this).attr('id') 404 var chk_label = jQuery("label[for='" + chk_id + "']").html() 405 var new_checkbox_html = 406 '<div class="wbk_checkbox_container"><label class="wbk-input-label" for="' + 407 chk_id + 408 '" >' + 409 chk_label + 410 '</label>' 411 var checkbox_data_validation = '' 412 if (jQuery(this).hasClass('wpcf7-validates-as-required')) { 413 checkbox_data_validation = 414 ' data-validation="not_empty" ' 415 } 416 new_checkbox_html += 417 '<input type="text" ' + 418 checkbox_data_validation + 419 ' class="wbk-input wbk_chk_proxy wbk-custom-field wbk_hidden" name="' + 420 chk_id + 421 '">' 422 423 var i = 0 424 jQuery(this) 425 .find('input[type="checkbox"]') 426 .each(function () { 427 i++ 428 var chk_val = jQuery(this).attr('value') 429 430 new_checkbox_html += 431 '<label for="' + 432 chk_id + 433 '_' + 434 i + 435 '" class="checkbox-row-w one-row-w">' 436 new_checkbox_html += 437
437 '<span class="checkbox-custom-w">' + 438 '<input type="checkbox" ' + 439 checkbox_data_validation + 440 ' data-exclusive="' + 441 exculsive + 442 '" data-id="' + 443 chk_id + 444 '" class="wbk_input_checkbox_option"' + 445 'name="' + 446 chk_id + 447 '" id="' + 448 chk_id + 449 '_' + 450 i + 451 '" value="' + 452 chk_val + 453 '">' + 454 '<span class="checkmark-w"></span>' + 455 '</span>' + 456 '<span class="checkbox-text-w">' + 457 '<span class="checkbox-title-w">' + 458 chk_val + 459 '</span>' + 460 '</span>' + 461 '</label>' 462 }) 463 new_checkbox_html += 464 '</div><div style="display:block;width:100%;height:50px"></div>' 465 get_this() 466 .container.find("label[for='" + chk_id + "']") 467 .replaceWith(new_checkbox_html) 468 jQuery(this).remove() 469 }) 470 get_this() 471 .container.find('.appointment-content-screen-active-w') 472 .find('[name="wbk-name"]') 473 .attr('name', 'custname') 474 get_this() 475 .container.find('.appointment-content-screen-active-w') 476 .find('[name="wbk-email"]') 477 .attr('name', 'email') 478 get_this() 479 .container.find('.appointment-content-screen-active-w') 480 .find('[name="wbk-phone"]') 481 .attr('name', 'phone') 482 483 get_this() 484 .container.find('.appointment-content-screen-active-w') 485 .find( 486 '.wbk-text:not([name="custname"]):not([name="email"]):not([name="phone"]), .wbk-textarea:not([name="wbk-comment"]), .wbk-select:not(.nice-select):not(.wbk-book-quantity)' 487 ) 488 .addClass('wbk-custom-field') 489 .removeAttr('id') 490 491 get_this() 492 .container.find('.appointment-content-screen-active-w') 493 .find('.wbk-text , .wbk-textarea, .wbk-select') 494 .addClass('wbk-input') 495 496 get_this() 497 .container.find('.appointment-content-screen-active-w') 498 .find('.wbk-file') 499 .each(function () { 500 if (jQuery(this).attr('aria-required') == 'true') { 501 jQuery(this).attr( 502 'data-validation', 503 'file_required' 504 ) 505 } 506 }) 507 508 get_this() 509 .container.find('.appointment-content-screen-active-w') 510 .find('.wbk-input') 511 .each(function () { 512 if (jQuery(this).attr('aria-required') == 'true') { 513 jQuery(this).attr('data-validation', 'not_empty') 514 } 515 }) 516 get_this() 517 .container.find('[name="email"]') 518 .attr('data-validation', 'email') 519 get_this() 520 .container.find('[name="phone"]') 521 .attr('data-validation', 'phone') 522 523 // custom checkbox processing 524 jQuery('.wbk_input_checkbox_option').change(function () { 525 var check_id = jQuery(this).attr('data-id') 526 if (jQuery(this).attr('data-exclusive') == 'true') {
527 jQuery('input[data-id="' + check_id + '"]') 528 .not(this) 529 .prop('checked', false) 530 } 531 var values = [] 532 jQuery('input[data-id="' + check_id + '"]').each( 533 function () { 534 if (jQuery(this).is(':checked')) { 535 values.push(jQuery(this).attr('value')) 536 } 537 } 538 ) 539 values = values.join() 540 jQuery(this) 541 .closest('.wbk_checkbox_container') 542 .find('.wbk_chk_proxy') 543 .val(values) 544 jQuery(this) 545 .closest('.wbk_checkbox_container') 546 .find('.wbk_chk_proxy') 547 .trigger('change') 548 }) 549 550 jQuery(document).trigger('wbk_form_rendered') 551 552 this.set_input_events() 553 554 // custom data processing 555 get_this() 556 .container.find('[name="wbk-comment"]') 557 .attr('name', 'comment') 558 get_this() 559 .container.find('.wbk-custom-field') 560 .change(function () { 561 var custom_data = [] 562 get_this() 563 .container.find('.wbk-custom-field') 564 .each(function () { 565 if ( 566 jQuery(this).closest( 567 '[data-class="wpcf7cf_group"]' 568 ).length > 0 569 ) { 570 if ( 571 jQuery(this) 572 .closest( 573 '[data-class="wpcf7cf_group"]' 574 ) 575 .attr('style') == 'display: none;' 576 ) { 577 return 578 } 579 } 580 var id = wbk_strip_html( 581 jQuery(this).attr('name') 582 ) 583 var val = '' 584 var title = '' 585 586 var val = wbk_strip_html(jQuery(this).val()) 587 588 title = wbk_strip_html( 589 get_this() 590 .container.find( 591 'label[for="' + id + '"]' 592 ) 593 .html() 594 ) 595 custom_data.push([id, title, val]) 596 }) 597 custom_data = JSON.stringify(custom_data) 598 get_this() 599 .container.find('.wbk-extra') 600 .html(custom_data) 601 }) 602 603 this.container 604 .find('.wbk-input') 605 .not('[name="custname"]') 606 .not('[name="email"]') 607 .not('[name="phone"]') 608 .not('.wbk_not_change_amount') 609 .change(function () { 610 get_this().update_amount() 611 }) 612 613 get_this().container.find('.wbk-custom-field').trigger('change') 614 615 get_this().set_multiple_data() 616 617 if (wbkl10n.phoneformat.trim() != '') { 618 get_this() 619 .container.find('[name="phone"]') 620 .mask(wbkl10n.phoneformat) 621 } 622 623 get_this().validate_form() 624 return 625 break 626 case 'wbk_book': 627 if ( 628 this.container 629 .find('.appointment-content-screen-active-w')
630 .attr('data-slug') == 'payment_optional' || 631 this.container 632 .find('.appointment-content-screen-active-w') 633 .attr('data-slug') == 'payment' 634 ) { 635 this.container 636 .find('.appointment-content-screen-active-w') 637 .append(response.thanks_message) 638 get_this().initiaize_payments() 639 } 640 break 641 } 642 this.validate_form() 643 } 644 645 initiaize_payments() { 646 const get_this = () => { 647 return this 648 } 649 650 this.container.find('.button-prev-w').remove() 651 this.container 652 .find('.button-next-w') 653 .html( 654 wbkl10n.continue + 655 '<span class="btn-ring-wb" style="opacity: 0;"></span>' 656 ) 657 this.container 658 .find('.button-next-w') 659 .after( 660 '<button type="button" style="display:none" class="button-w button-approve-stripe-payment" disabled>' + 661 wbkl10n.approve_payment_text + 662 '<span class="btn-ring-wb" style="opacity: 0;"></span></button>' 663 ) 664 this.container.find('.button-next-w').prop('disabled', true) 665 get_this().init_scroll_bars() 666 this.init_nice_select() 667 668 get_this() 669 .container.find('.wbk_coupon_input') 670 .on('input', function () { 671 if (jQuery(this).val().trim() == '') { 672 get_this() 673 .container.find('.wbk_apply_coupon') 674 .attr('disabled', true) 675 } else { 676 get_this() 677 .container.find('.wbk_apply_coupon') 678 .attr('disabled', false) 679 } 680 }) 681 get_this() 682 .container.find('.wbk_apply_coupon') 683 .click(function () { 684 get_this().apply_coupon() 685 }) 686 687 get_this() 688 .container.find('[name="payment-method"') 689 .change(function () { 690 var method = jQuery(this).val() 691 get_this() 692 .container.find('.wbk_payment_method_desc') 693 .toggle(false) 694 695 get_this() 696 .container.find('[value="' + method + '"]') 697 .parent() 698 .siblings('.wbk_payment_method_desc') 699 .slideToggle() 700 701 if (method == 'stripe') { 702 get_this().container.find('.button-next-w').toggle(false) 703 get_this() 704 .container.find('.button-approve-stripe-payment') 705 .toggle(true) 706 707 if ( 708 get_this().container.find('.StripeElement').length == 0 709 ) { 710 var style = { 711 base: { 712 lineHeight: '50px', 713 color: '#000', 714 fontSize: '16px', 715 }, 716 } 717 var locale = jQuery('html').attr('lang') 718 if ( 719 locale.length == '' || 720 locale.length == 'undefined' 721 ) { 722 locale = 'en' 723 } 724 if (locale.length > 2) { 725 locale = locale.slice(0, 2) 726 } 727 get_this().stripe = Stripe(wbkl10n.stripe_public_key) 728 var elements = get_this().stripe.elements() 729 var stripe_hide_postal = 730 wbkl10n.stripe_hide_postal == 'true' 731 get_this().card = elements.create('card', { 732 style: style, 733 hidePostalCode: stripe_hide_postal, 734 }) 735 get_this().card.mount('#card-element') 736 get_this().card.addEventListener( 737 'change', 738 function (event) { 739 if (event.error) { 740 get_this() 741 .container.find('#card-errors') 742 .html(event.error.message) 743 } else { 744 get_this() 745 .container.find('#card-errors') 746 .html('') 747 } 748 if (event.complete) { 749 get_this().validate_stripe_input(true) 750 } else { 751 get_this().validate_stripe_input(false) 752 } 753 } 754 ) 755 get_this().container.find('') 756 } 757 } else { 758 get_this().container.find('.button-next-w').toggle(true) 759 get_this() 760 .container.find('.button-approve-stripe-payment') 761 .toggle(false) 762 } 763 }) 764 765 get_this() 766 .container.find('.button-approve-stripe-payment') 767 .click(function () {
768 var valid = true 769 var wbk_stripe_fields = {} 770 var wbk_stripe_address = {} 771 var details_provided = false 772 jQuery('.wbk-stripe-additional-field') 773 .not('.nice-select') 774 .each(function () { 775 if (jQuery(this).val().trim() == '') { 776 jQuery(this).prev('label').addClass('input-error-w') 777 778 valid = false 779 } 780 var current_field = jQuery(this).attr('data-field') 781 if (current_field == 'name') { 782 wbk_stripe_fields[current_field] = 783 jQuery(this).val() 784 } else { 785 details_provided = true 786 wbk_stripe_address[current_field] = 787 jQuery(this).val() 788 } 789 }) 790 if (!valid) { 791 return false 792 } 793 if (details_provided) { 794 wbk_stripe_fields['address'] = wbk_stripe_address 795 } 796 get_this().change_button_status(jQuery(this), 'loading') 797 get_this() 798 .stripe.createPaymentMethod('card', get_this().card, { 799 billing_details: wbk_stripe_fields, 800 }) 801 .then(function (result) { 802 if (result.error) { 803 get_this().change_button_status( 804 get_this().container.find( 805 '.button-approve-stripe-payment' 806 ), 807 'regular' 808 ) 809 get_this().show_error(result.error.message) 810 } else { 811 get_this() 812 .container.find('.wbk_stripe_payment_method_id') 813 .val(result.paymentMethod.id) 814 815 get_this().stripe_process_payment() 816 } 817 }) 818 819 return false 820 }) 821 822 if (get_this().container.find('[name="payment-method"').length == 0) { 823 jQuery('.button-next-w').remove() 824 return 825 } 826 827 this.set_input_events() 828 get_this().validate_form() 829 } 830 831 async apply_coupon() { 832 var btn = this.container.find('.wbk_apply_coupon') 833 this.change_button_status(btn, 'loading') 834 835 var response = await this.do_request('wbk_apply_coupon') 836 if (response == false) { 837 this.show_error('An unexpected error occoured.') 838 return 839 } 840 response = jQuery.parseJSON(response) 841 if (response.status == 'fail') { 842 this.show_error(response.description) 843 return 844 } 845 if (response.status == 'payment_complete') { 846 this.finalize(response) 847 } 848 this.change_button_status(btn, 'regular') 849 if (response.status == 'applied') { 850 this.container 851 .find('.payment-details-wrapper-w') 852 .replaceWith(response.payment_card) 853 } 854 } 855 856 async update_amount() { 857 if (this.container.find('.wbk_quantities option').length == 0) { 858 return 859 } 860 var valid = true 861 this.container.find('.wbk_quantities option').each(function () { 862 if (jQuery(this).val() == 0) { 863 valid = false 864 } 865 }) 866 if (!valid) { 867 return 868 } 869 if (this.container.find('.payment-details-wrapper-w').length == 0) { 870 if (this.container.find('.wbk_dynamic_total').length == 0) { 871 this.set_step_subtitle('payment_optional', [ 872 '<span class="wbk_loader_s"></span>', 873 ]) 874 this.set_step_subtitle('payment', [ 875 '<span class="wbk_loader_s"></span>', 876 ]) 877 } else { 878 this.container 879 .find('.wbk_dynamic_total') 880 .replaceWith('<span class="wbk_loader_s"></span>') 881 } 882 var response = await this.do_request('wbk_calculate_amounts') 883 if (response == false) { 884 this.show_error('An unexpected error occoured.') 885 return 886 } 887 response = jQuery.parseJSON(response) 888 if (response.status == 'fail') { 889 this.show_error(response.description) 890 return 891 } 892 this.container 893 .find('.wbk_loader_s') 894 .replaceWith( 895 '<span class="wbk_dynamic_total">
895' + 896 response.total_formated + 897 '</span>' 898 ) 899 this.container 900 .find('.wbk_form_label_total') 901 .html(response.total_formated) 902 } else { 903 this.remove_step_subtitle('payment_optional') 904 this.remove_step_subtitle('payment') 905 } 906 } 907 908 async stripe_process_payment() { 909 const get_this = () => { 910 return this 911 } 912 var response = await this.do_request('wbk_approve_payment') 913 if (response == false) { 914 get_this().change_button_status( 915 get_this().container.find('.button-approve-stripe-payment'), 916 'regular' 917 ) 918 this.show_error('An unexpected error occoured.') 919 return 920 } 921 response = jQuery.parseJSON(response) 922 if (response.status == 'fail') { 923 get_this().change_button_status( 924 get_this().container.find('.button-approve-stripe-payment'), 925 'regular' 926 ) 927 this.show_error(response.description) 928 return 929 } 930 if (response.status == 'success') { 931 if (parseInt(response.result[0]) == 1) { 932 if (response.result.thanks_message != '') { 933 this.finalize(response.result) 934 } 935 if (response.result.url != '') { 936 window.location.href = response.result.url 937 } 938 } else { 939 this.stripe 940 .handleCardAction(response.result[1]) 941 .then((result) => { 942 if (result.error) { 943 this.show_error(result.error) 944 get_this().change_button_status( 945 get_this().container.find( 946 '.button-approve-stripe-payment' 947 ), 948 'regular' 949 ) 950 } else { 951 get_this() 952 .container.find('.wbk_stripe_payment_intent_id') 953 .val(result.paymentIntent.id) 954 955 get_this() 956 .container.find('.wbk_stripe_payment_method_id') 957 .val('') 958 this.stripe_process_payment() 959 } 960 }) 961 } 962 } 963 if (response.status == 'fail') { 964 get_this().change_button_status( 965 get_this().container.find('.button-approve-stripe-payment'), 966 'regular' 967 ) 968 this.show_error(response.result[1]) 969 } 970 } 971 972 remove_step_subtitle(slug) { 973 this.container 974 .find(".appointment-status-list-w li[data-slug='" + slug + "']") 975 .find('.subtitle-list-w') 976 .remove() 977 } 978 979 set_step_subtitle(slug, list) { 980 this.remove_step_subtitle(slug) 981 var html = '<ul class="subtitle-list-w" style="display:none;">' 982 jQuery.each(list, function (index, value) { 983 html += '<li>' + value + '</li>' 984 }) 985 html += '</ul>' 986 this.container 987 .find(".appointment-status-list-w li[data-slug='" + slug + "']") 988 .find('.text-w') 989 .append(html) 990 this.container 991 .find(".appointment-status-list-w li[data-slug='" + slug + "']") 992 .find('.text-w') 993 .find('ul') 994 .slideToggle() 995 } 996 997 init_scroll_bars() { 998 if ( 999 this.container 1000 .find('.appointment-content-screen-active-w') 1001 .attr('data-request') == 'wbk_render_booking_form' 1002 ) { 1003 if ( 1004 this.container 1005 .find('.appointment-content-screen-active-w') 1006 .find('.nice-select').length > 0 1007 ) { 1008 jQuery('.appointment-content-scroll-w').css('height', 'auto') 1009 if (jQuery('.wbk_custom_form_spacer').length == 0) { 1010 jQuery('.appointment-content-scroll-w').append( 1011 '<div class="wbk_custom_form_spacer"></div>' 1012 ) 1013 } 1014 return 1015 } 1016 } 1017 jQuery('.appointment-content-scroll-w').css('height', '555px') 1018 Scrollbar.initAll({ alwaysShowTracks: true, damping: 0.5 }) 1019 } 1020 1021 async search_time_slots() { 1022 const get_this = () => { 1023 return this 1024 } 1025 if (wbkl10n.multi_booking != 'enabled') { 1026 this.deselect_all_slots() 1027 } 1028 this.container.find('.dynamic-slots-w').remove() 1029 this.container 1030 .find('.appointment-content-scroll-w') 1031 .append('<div class="wbk-loading"></div>') 1032 var response = await this.do_request('wbk_search_time') 1033 if (response == false) { 1034 this.show_error('An unexpected error occoured.') 1035 return 1036 } 1037 if (response.status == 'fail') { 1038 this.show_error(response.description) 1039 return 1040 } 1041 response = jQuery.parseJSON(response) 1042 this.container.find('.wbk-loading').remove() 1043 Scrollbar.destroyAll() 1044 this.container 1045 .find('.appointment-content-screen-active-w') 1046 .append( 1047 '<div class="dynamic-slots-w dynamic-content-w">' + 1048 response.data + 1049 '</div>' 1050 ) 1051 get_this().init_scroll_bars() 1052 this.container.find('.timeslot_radio-w').click(function () { 1053 var time = jQuery(this) 1054 .closest('label') 1055 .find('.time-w') 1056 .attr('data-start') 1057 var service_id = jQuery(this) 1058 .closest('label') 1059 .find('.time-w') 1060 .attr('data-service') 1061 var time_string = 1062 jQuery(this) 1063 .closest('label') 1064 .find('.time-w') 1065 .attr('data-server-date') + 1066 ' ' + 1067 jQuery(this) 1068 .closest('label') 1069 .find('.time-w') 1070 .attr('data-server-time') 1071 var time_string_local = 1072 jQuery(this) 1073 .closest('label') 1074 .find('.time-w') 1075 .attr('data-local-date') + 1076 ' ' + 1077 jQuery(this) 1078 .closest('label') 1079 .find('.time-w') 1080 .attr('data-local-time') 1081 get_this().select_time_slot( 1082 time, 1083 time_string, 1084 time_string_local, 1085 service_id 1086 ) 1087 }) 1088 this.container.find('.appointment-content-screen-active-w') 1089 if (this.container.find('.time-w').length > 0) { 1090 if ( 1091 this.container 1092 .find('.time-w') 1093 .first() 1094 .attr('data-server-time') != 1095 this.container.find('.time-w').first().attr('data-local-time') 1096 ) { 1097 this.container 1098 .find('.wbl_local_time_switcher') 1099 .removeClass('wbk_hidden') 1100 } 1101 this.container.find('.wbk_local_time_checkbox').change(function () { 1102 const checked = jQuery(this).is(':checked') 1103 get_this().switch_local_time(checked) 1104 get_this().render_selected_time_slots_list() 1105 }) 1106 const checked = get_this() 1107 .container.find('.wbk_local_time_checkbox') 1108 .is(':checked') 1109 if (!checked) { 1110 this.container.find('.wbk_local_time_checkbox').trigger('click') 1111 } 1112 } 1113 } 1114 switch_local_time(state) { 1115 if (state) { 1116 this.container.find('.time-w').each(function () { 1117 jQuery(this).html(jQuery(this).attr('data-local-time')) 1118 }) 1119 } else { 1120 this.container.find('.time-w').each(function () { 1121 jQuery(this).html(jQuery(this).attr('data-server-time')) 1122 }) 1123 } 1124 } 1125 1126 deselect_all_slots() { 1127 this.container.find('.wbk_times > option').remove() 1128 this.container.find('.wbk_services_final > option').remove() 1129 this.render_selected_time_slots_list() 1130 } 1131 1132 deselect_time_slot(timestamp, service_id) { 1133 this.container.find('.wbk_times > option').each(function () { 1134 if ( 1135 jQuery(this).attr('value') == timestamp && 1136 jQuery(this).attr('data-service') == service_id 1137 ) { 1138 jQuery(this).remove() 1139 } 1140 }) 1141 this.container.find('.wbk_services_final > option').each(function () { 1142 if ( 1143 jQuery(this).attr('value') == service_id && 1144 jQuery(this).attr('data-time') == timestamp 1145 ) { 1146 jQuery(this).remove() 1147 } 1148 }) 1149 this.container.find('.time-w').each(function () { 1150 if ( 1151 jQuery(this).attr('data-start') == timestamp && 1152 jQuery(this).attr('data-service') == service_id 1153 ) { 1154 jQuery(this) 1155 .closest('label') 1156 .find('.timeslot_radio-w') 1157 .prop('checked', false) 1158 } 1159 }) 1160 1161 this.render_selected_time_slots_list() 1162 } 1163 1164 select_time_slot(timestamp, time_string, time_string_local, service_id) { 1165 const get_this = () => { 1166 return this 1167 } 1168 var exit = false 1169 this.container.find('.wbk_times option').each(function () { 1170 if (
1171 parseInt(jQuery(this).attr('value')) == parseInt(timestamp) && 1172 parseInt(jQuery(this).attr('data-service')) == 1173 parseInt(service_id) 1174 ) { 1175 exit = true 1176 return 1177 } 1178 }) 1179 if (exit) { 1180 return 1181 } 1182 1183 if (wbkl10n.multi_booking != 'enabled') { 1184 this.deselect_all_slots() 1185 } 1186 this.container 1187 .find('.wbk_times') 1188 .append( 1189 '<option data-time_string_local="' + 1190 time_string_local + 1191 '" data-time_string="' + 1192 time_string + 1193 '" data-service="' + 1194 service_id + 1195 '" value="' + 1196 timestamp + 1197 '" >' + 1198 time_string + 1199 '</option>' 1200 ) 1201 this.container 1202 .find('.wbk_services_final') 1203 .append( 1204 '<option data-time="' + 1205 timestamp + 1206 '" value="' + 1207 service_id + 1208 '" >' + 1209 service_id + 1210 '</option>' 1211 ) 1212 this.container.find('.wbk_times option').prop('selected', true) 1213 this.container.find('.wbk_times').trigger('change') 1214 1215 this.container.find('.wbk_services_final option').prop('selected', true) 1216 this.container.find('.wbk_services_final').trigger('change') 1217 1218 this.render_selected_time_slots_list() 1219 if (wbkl10n.auto_next == 'enabled') { 1220 this.container.find('.button-next-w').trigger('click') 1221 } 1222 } 1223 add_class_for_seleced_slots() { 1224 this.container.find('.timeslot_radio-w').each(function () { 1225 if (jQuery(this).is(':checked')) { 1226 jQuery(this) 1227 .siblings('.radio-time-block-w') 1228 .addClass('wb_slot_checked') 1229 } else { 1230 jQuery(this) 1231 .siblings('.radio-time-block-w') 1232 .removeClass('wb_slot_checked') 1233 } 1234 }) 1235 } 1236 1237 render_selected_time_slots_list() { 1238 const get_this = () => { 1239 return this 1240 } 1241 this.container.find('.details-list-w > li').remove() 1242 this.container 1243 .find('.wbk_times > option') 1244 .not('.nice-select > option') 1245 .each(function () { 1246 var service_id = jQuery(this).attr('data-service') 1247 var time = jQuery(this).attr('value') 1248 1249 const checked = get_this() 1250 .container.find('.wbk_local_time_checkbox') 1251 .is(':checked') 1252 var date_time_string = '' 1253 if (checked) { 1254 date_time_string = jQuery(this).attr( 1255 'data-time_string_local' 1256 ) 1257 } else { 1258 date_time_string = jQuery(this).attr('data-time_string') 1259 } 1260 var service_name = '' 1261 if (get_this().is_multi_service()) { 1262 service_name = 1263 get_this().get_multi_service_name_by_id(service_id) + 1264 ' ' 1265 } 1266 1267 get_this() 1268 .container.find('.details-list-w') 1269 .append( 1270 '<li><span class="details-item-text-w">' + 1271 service_name + 1272 date_time_string + 1273 '</span><span data-service="' + 1274 service_id + 1275 '" data-time="' + 1276 time + 1277 '" class="block-close-wb"></span></li>' 1278 ) 1279 get_this() 1280 .container.find('.block-close-wb') 1281 .last() 1282 .unbind('click') 1283 get_this() 1284 .container.find('.block-close-wb') 1285 .last() 1286 .click(function () { 1287 get_this().deselect_time_slot(time, service_id) 1288 }) 1289 }) 1290 this.add_class_for_seleced_slots() 1291 this.validate_form() 1292 } 1293 set_multiple_data() { 1294 const get_this = () => { 1295 return this 1296 } 1297 this.container.find('.wbk_quantities option').remove() 1298 this.container.find('.wbk_services_per_slot option').remove() 1299 1300 var qty_html = '' 1301 var services_html = '' 1302 this.container.find('.wbk_times option').each(function () { 1303 var service_id = jQuery(this).attr('data-service') 1304 var timestamp = jQuery(this).attr('value') 1305 var quantity_for_service = get_this() 1306 .container.find( 1307 '.wbk-book-quantity[data-service=' + service_id + ']' 1308 ) 1309 .val() 1310 1311 qty_html += 1312 '<option value="' + 1313 quantity_for_service + 1314 '">' + 1315 quantity_for_service + 1316 '</option>' 1317 services_html += 1318 '<option value="' + service_id + '">' + service_id + '</option>' 1319 }) 1320 1321 this.container.find('.wbk_quantities').html(qty_html) 1322 this.container.find('.wbk_services_per_slot').html(services_html) 1323 this.container.find('.wbk_quantities option').prop('selected', true) 1324 this.container 1325 .find('.wbk_services_per_slot option') 1326 .prop('selected', true) 1327 } 1328 prepare_service_data_init(response) { 1329 const get_this = () => { 1330 return this 1331 } 1332 1333 var disability_result = [] 1334 disability_result.push(true) 1335 var range_min = undefined 1336 var range_max = undefined 1337 var initial_date = undefined 1338 var allowed_timestamps = [] 1339 1340 this.disabled_dates = response.disabilities.split(';') 1341 this.disabled_days_of_week = response.week_disabilities 1342 1343 this.disabled_dates_horizontal = [] 1344 var last_date = new Date() 1345 last_date.setDate(last_date.getDate() + 360) 1346 1347 for (var d = new Date(); d <= last_date; d.setDate(d.getDate() + 1)) { 1348 var date_string = 1349 d.getFullYear() + ',' + d.getMonth() + ',' + d.getDate() 1350 if (!this.disabled_dates.includes(date_string)) { 1351 this.disabled_dates_horizontal.push( 1352 d.getFullYear() + 1353 '/' + 1354 ('0' + (d.getMonth() + 1)).slice(-2) + 1355 '/' + 1356 ('0' + d.getDate()).slice(-2) 1357 ) 1358 } 1359 } 1360 1361 if (response.disabilities != '') { 1362 var day_disabilities_all = response.disabilities.split(';') 1363 var index 1364 for (index = 0; index < day_disabilities_all.length; index++) { 1365 var disablity_current_day = 1366 day_disabilities_all[index].split(',') 1367 disability_result.push(disablity_current_day) 1368 var converte_date = new Date( 1369 disablity_current_day[0], 1370 disablity_current_day[1], 1371 disablity_current_day[2], 1372 0, 1373 0, 1374 0 1375 ) 1376 allowed_timestamps.push(converte_date.getTime()) 1377 } 1378 if (disability_result.length > 1) { 1379 initial_date = disability_result[1] 1380 } 1381 } 1382 1383 if (response.limits != '') { 1384 var date_range = response.limits.split('-') 1385 1386 range_min = date_range[0].split(',') 1387 range_min[0] = parseInt(range_min[0]) 1388 range_min[1] = parseInt(range_min[1]) - 1 1389 range_min[2] = parseInt(range_min[2]) 1390 1391 range_max = date_range[1].split(',') 1392 range_max[0] = parseInt(range_max[0]) 1393 range_max[1] = parseInt(range_max[1]) - 1 1394 range_max[2] = parseInt(range_max[2]) 1395 1396 var range_start = new Date(range_min[0], range_min[1], range_min[2]) 1397 var range_end = new Date(range_max[0], range_max[1], range_max[2]) 1398 var now = new Date() 1399 1400 if (range_start < now) { 1401 range_min[0] = now.getFullYear() 1402 range_min[1] = now.getMonth() 1403 range_min[2] = now.getDate() 1404 } 1405 } 1406 if (this.is_ios()) { 1407 disability_result = response.week_disabilities 1408 } 1409 1410 var date_html = this.container.find('.wbk_date').prop('outerHTML') 1411 1412 this.container.find('.wbk_date').replaceWith(date_html) 1413 this.container.find('[name="date"]').remove() 1414 var fixed_startofweek = 0 1415 if (!this.is_ios()) { 1416 fixed_startofweek = wbkl10n.startofweek 1417 } 1418 1419 this.date_input = this.container.find('.wbk_date').pickadate({ 1420 min: true, 1421 monthsFull: [ 1422 wbkl10n.january, 1423 wbkl10n.february, 1424 wbkl10n.march, 1425 wbkl10n.april, 1426 wbkl10n.may, 1427 wbkl10n.june, 1428 wbkl10n.july, 1429 wbkl10n.august, 1430 wbkl10n.september, 1431 wbkl10n.october, 1432 wbkl10n.november, 1433 wbkl10n.december, 1434 ], 1435 monthsShort: [ 1436 wbkl10n.jan, 1437 wbkl10n.feb, 1438 wbkl10n.mar, 1439 wbkl10n.apr, 1440 wbkl10n.mays, 1441 wbkl10n.jun, 1442 wbkl10n.jul, 1443 wbkl10n.aug, 1444 wbkl10n.sep, 1445 wbkl10n.oct, 1446 wbkl10n.nov, 1447 wbkl10n.dec, 1448 ], 1449 weekdaysFull: [ 1450 wbkl10n.sunday, 1451 wbkl10n.monday, 1452 wbkl10n.tuesday, 1453 wbkl10n.wednesday, 1454 wbkl10n.thursday, 1455 wbkl10n.friday, 1456 wbkl10n.saturday, 1457 ], 1458 weekdaysShort: [ 1459 wbkl10n.sun, 1460 wbkl10n.mon, 1461 wbkl10n.tue, 1462 wbkl10n.wed, 1463 wbkl10n.thu, 1464 wbkl10n.fri, 1465 wbkl10n.sat, 1466 ], 1467 today: wbkl10n.today, 1468 clear: wbkl10n.clear, 1469 close: wbkl10n.close, 1470 firstDay: parseInt(fixed_startofweek), 1471 format: wbkl10n.picker_format, 1472 disable: disability_result, 1473 labelMonthNext: wbkl10n.nextmonth, 1474 labelMonthPrev: wbkl10n.prevmonth, 1475 formatSubmit: 'yyyy/mm/dd', 1476 hiddenPrefix: 'wbk-date', 1477 onOpen: function () { 1478 jQuery('.wbk_date').removeClass('linear-animation-w') 1479 if (range_min != undefined) { 1480 this.set('highlight', range_min) 1481 } else { 1482 if (initial_date != undefined) { 1483 this.set('highlight', initial_date) 1484 } 1485 } 1486 }, 1487 onRender: function () { 1488 jQuery('.picker__day').addClass('picker__day--disabled') 1489 jQuery('.picker__day').each(function () { 1490 var current_pick = jQuery(this).attr('data-pick') 1491 var elem = jQuery(this) 1492 jQuery.each(allowed_timestamps, function (key, value) { 1493 if (value == current_pick) { 1494 elem.removeClass('picker__day--disabled') 1495 } 1496 }) 1497 }) 1498 jQuery(document).trigger('wbk_picker_on_render', [response]) 1499 }, 1500 onClose: function () { 1501 jQuery(document.activeElement).blur() 1502 }, 1503 onSet: function (thingSet) { 1504 if (typeof thingSet.select != 'undefined') {
1505 get_this().add_horizontal_calendar() 1506 get_this().search_time_slots() 1507 } else { 1508 if ( 1509 get_this() 1510 .container.find('[name="date_formated"]') 1511 .val() == '' 1512 ) { 1513 get_this().hide_horizontal_calendar() 1514 } 1515 } 1516 }, 1517 }) 1518 1519 jQuery('input[name="wbk-datedate_formated_submit"]').addClass( 1520 'wbk-input' 1521 ) 1522 jQuery('input[name="wbk-datedate_formated_submit"]').attr( 1523 'name', 1524 'date' 1525 ) 1526 jQuery('input[name="date"]').attr('data-validation', 'not_empty') 1527 1528 var open_calendar = true 1529 if (range_min != undefined) { 1530 var picker = this.date_input.pickadate('picker') 1531 picker.set('min', range_min) 1532 picker.set('max', range_max) 1533 1534 if ( 1535 range_min[0] == range_max[0] && 1536 range_min[1] == range_max[1] && 1537 range_min[2] == range_max[2] 1538 ) { 1539 picker.set('select', range_min) 1540 open_calendar = false 1541 } 1542 } 1543 if (open_calendar) { 1544 this.container.find('.wbk_date').trigger('click') 1545 } 1546 1547 jQuery('#calendar-horizontal-w button').click(function (e) { 1548 e.preventDefault() 1549 }) 1550 } 1551 1552 is_ios() { 1553 return ( 1554 [ 1555 'iPad Simulator', 1556 'iPhone Simulator', 1557 'iPod Simulator', 1558 'iPad', 1559 'iPhone', 1560 'iPod', 1561 ].includes(navigator.platform) || 1562 (navigator.userAgent.includes('Mac') && 'ontouchend' in document) 1563 ) 1564 } 1565 1566 remove_status_bar_item(slug) { 1567 this.container 1568 .find('.appointment-status-list-w') 1569 .find('[data-slug="' + slug + '"]') 1570 .remove() 1571 } 1572 1573 add_horizontal_calendar() { 1574 const get_this = () => { 1575 return this 1576 } 1577 this.container.find('.wbk_horizontal_calendar_container').html('') 1578 var id = 1579 'horizontal_calendar_' + 1580 (Math.random() + 1).toString(36).substring(7) 1581 this.container 1582 .find('.wbk_horizontal_calendar_container') 1583 .append('<div class="calendar-horizontal-w" id="' + id + '"></div>') 1584 var locale = jQuery('html').attr('lang') 1585 if (locale.length == '' || locale.length == 'undefined') { 1586 locale = 'en' 1587 } 1588 if (locale.length > 2) { 1589 locale = locale.slice(0, 2) 1590 } 1591 this.container.find('#' + id).rescalendar({ 1592 id: id, 1593 format: 'YYYY/MM/DD', 1594 refDate: get_this().container.find('[name="date"]').val(), 1595 calSize: 5, 1596 jumpSize: 0, 1597 disabledDays: this.disabled_dates_horizontal, 1598 dataKeyField: 'name', 1599 dataKeyValues: ['item1'], 1600 locale: locale, 1601 }) 1602 this.container 1603 .find('.wbk_horizontal_calendar_container') 1604 .removeClass('wbk_fade_out') 1605 this.container 1606 .find('.wbk_horizontal_calendar_container') 1607 .addClass('wbk_fade_in') 1608 this.container.find('.move_to_yesterday').attr('type', 'button') 1609 this.container.find('.move_to_tomorrow').attr('type', 'button') 1610 this.container.find('.move_to_tomorrow').click(function () { 1611 get_this().set_horizontal_calendar_event() 1612 }) 1613 this.container.find('.move_to_yesterday').click(function () { 1614 get_this().set_horizontal_calendar_event() 1615 }) 1616 this.set_horizontal_calendar_event() 1617 } 1618 set_horizontal_calendar_event() { 1619 const get_this = () => { 1620 return this 1621 } 1622 this.container.find('.day_cell').click(function (e) { 1623 if (jQuery(this).hasClass('disabledDay')) { 1624 e.preventDefault() 1625 return 1626 } 1627 get_this().set_horizontal_calendar_event() 1628 var horizontal_value = jQuery(this) 1629 .closest('.day_cell') 1630 .attr('data-celldate') 1631 horizontal_value = horizontal_value.split('/') 1632 var new_date = new Date( 1633 horizontal_value[0], 1634 horizontal_value[1] - 1, 1635 horizontal_value[2] 1636 ) 1637 var picker = get_this().date_input.pickadate('picker') 1638 picker.set('select', new_date) 1639 }) 1640 } 1641
1642 hide_horizontal_calendar() { 1643 this.container 1644 .find('.wbk_horizontal_calendar_container') 1645 .addClass('wbk_fade_out') 1646 this.container 1647 .find('.wbk_horizontal_calendar_container') 1648 .removeClass('wbk_fade_in') 1649 } 1650 1651 add_status_bar_item(num, title, slug) { 1652 var html = 1653 '<li data-slug=' + 1654 slug + 1655 '>\ 1656 <div class="circle__box-w">\ 1657 <div class="circle__wrapper-w circle__wrapper--right-w">\ 1658 <div class="circle__whole-w circle__right-w"></div>\ 1659 </div><div class="circle__wrapper-w circle__wrapper--left-w">\ 1660 <div class="circle__whole-w circle__left-w"></div>\ 1661 </div><div class="circle-digit-w"> ' + 1662 num + 1663 '</div>\ 1664 </div>\ 1665 <div class="text-w">\ 1666 <div class="text-title-w">' + 1667 title + 1668 '</div>\ 1669 </div>\ 1670 </li>' 1671 this.container.find('.appointment-status-list-w').append(html) 1672 } 1673 1674 change_button_status(elem, status) { 1675 if (status == 'loading') { 1676 elem.addClass('loading-btn-wb') 1677 elem.find('.btn-ring-wb').css('opacity', '1') 1678 elem.attr('disabled', true) 1679 } 1680 if (status == 'regular') { 1681 elem.removeClass('loading-btn-wb') 1682 elem.find('.btn-ring-wb').css('opacity', '0') 1683 elem.attr('disabled', false) 1684 } 1685 } 1686 1687 init_nice_select() { 1688 jQuery('.wbk-select').niceSelect('destroy') 1689 jQuery('.wbk-select').niceSelect() 1690 jQuery('.nice-select').click(function () { 1691 // Scrollbar.destroyAll(); 1692 // jQuery('.appointment-content-scroll-w').css('overflow', 'hidden'); 1693 // jQuery('.appointment-content-scroll-w').css('height', 'auto'); 1694 }) 1695 1696 jQuery('.wbk-select').on('change', function () { 1697 // Scrollbar.initAll({ alwaysShowTracks: true, damping: 0.5 }); 1698 // jQuery('.appointment-content-scroll-w').css('height', '555px'); 1699 }) 1700 jQuery(document).on('nice-select-close', function () { 1701 // Scrollbar.initAll({ alwaysShowTracks: true, damping: 0.5 }); 1702 // jQuery('.appointment-content-scroll-w').css('height', '555px'); 1703 }) 1704 } 1705 1706 get_next_screen() { 1707 return this.container 1708 .find('.appointment-content-screen-active-w') 1709 .nextAll('.appointment-content-screen-w') 1710 .first() 1711 } 1712 get_prev_screen() { 1713 return this.container 1714 .find('.appointment-content-screen-active-w') 1715 .prevAll('.appointment-content-screen-w') 1716 .first() 1717 } 1718 1719 do_request(action) { 1720 return new Promise((resolve) => { 1721 var form_data = new FormData(this.container.find('form')[0]) 1722 var offset = new Date().getTimezoneOffset() 1723 var time_zone_client = 1724 Intl.DateTimeFormat().resolvedOptions().timeZone 1725 if (typeof time_zone_client == 'undefined') { 1726 time_zone_client = '' 1727 } 1728 form_data.append('nonce', wbkl10n.wbkf_nonce) 1729 form_data.append('offset', offset) 1730 form_data.append('time_zone_client', time_zone_client) 1731 form_data.append('action', action) 1732 1733 const result = jQuery.ajax({ 1734 url: wbkl10n.ajaxurl, 1735 type: 'POST', 1736 data: form_data, 1737 cache: false, 1738 processData: false, 1739 contentType: false, 1740 success: function (response) { 1741 resolve(response) 1742 }, 1743 error: function () { 1744 resolve(false) 1745 }, 1746 complete: function () {}, 1747 }) 1748 }) 1749 } 1750 1751 mark_checked_services() { 1752 this.container 1753 .find('.wbk_service_item') 1754 .removeClass('wbk_service_item_active') 1755 1756 this.container.find('.wbk_services').each(function () { 1757 if (jQuery(this).is(':checked')) { 1758 jQuery(this) 1759 .closest('.wbk_service_item') 1760 .addClass('wbk_service_item_active') 1761 } 1762 }) 1763 } 1764 1765 validate_form() { 1766 const get_this = () => { 1767 return this 1768 } 1769 this.mark_checked_services() 1770 let passed = false 1771 1772 this.container 1773 .find('.appointment-content-screen-active-w') 1774 .find('.wbk-input, .wbk-file') 1775 .not('.nice-select') 1776 .not('[type="radio"]') 1777 .each(function () { 1778 if ( 1779 jQuery(this).closest('[data-class="wpcf7cf_group"]') 1780 .length > 0 1781 ) { 1782 if ( 1783 jQuery(this) 1784 .closest('[data-class="wpcf7cf_group"]') 1785 .attr('style') == 'display: none;' 1786 ) { 1787 return 1788 } 1789 } 1790 const elem = jQuery(this) 1791 const value = jQuery(this).val() 1792 const field_name = jQuery(this).attr('data-validationmsg') 1793 switch (jQuery(this).attr('data-validation')) { 1794 case 'file_required': 1795 if (jQuery(this).get(0).files.length == 0) { 1796 passed = false 1797 } else { 1798 passed = true 1799 } 1800 break 1801 case 'positive': 1802 passed = wbk_check_integer_min_max(value, 1, 99999999) 1803 break 1804 case 'not_empty': 1805 var min = 1 1806 var max = 16384 1807 var attr = jQuery(this).attr('minlength') 1808 if (typeof attr !== 'undefined' && attr !== false) { 1809 min = attr 1810 } 1811 attr = jQuery(this).attr('maxnlength') 1812 if (typeof attr !== 'undefined' && attr !== false) { 1813 max = attr 1814 } 1815 1816 passed = wbk_check_string(value, min, max) 1817 break 1818 case 'must_have_items': 1819 passed = false 1820 if (jQuery(this).is('select')) { 1821 elem.find('option').each(function () { 1822 if (jQuery(this).prop('selected')) { 1823 passed = true 1824 } 1825 }) 1826 } 1827 if (jQuery(this).is(':checkbox')) { 1828 var checkbox_name = jQuery(this).attr('name') 1829 var val = jQuery( 1830 '[name="' + checkbox_name + '"]' 1831 ).each(function () { 1832 if (jQuery(this).is(':checked')) { 1833 passed = true 1834 } 1835 }) 1836 } 1837 break 1838 case 'email': 1839 passed = wbk_check_email(value) 1840 break 1841 case 'phone': 1842 passed = wbk_check_string( 1843 value, 1844 wbkl10n.phone_required, 1845 30 1846 ) 1847 break 1848 default: 1849 passed = true 1850 } 1851 1852 if ( 1853 jQuery(this).val() != '' && 1854 passed == false && 1855 !jQuery(this).is(':focus') 1856 ) { 1857 jQuery(this).addClass('input-error-w') 1858 } 1859 if (jQuery(this).val() != '' && passed == true) { 1860 jQuery(this).removeClass('input-error-w') 1861 } 1862 1863 if (!passed) { 1864 get_this() 1865 .container.find('.button-next-w') 1866 .prop('disabled', true) 1867 return passed 1868 } 1869 }) 1870 1871 // check if service radio button is present and checked 1872 if ( 1873 this.container 1874 .find('.appointment-content-screen-active-w') 1875 .find('.wbk_services[type="radio"]').length > 0 1876 ) { 1877 var radio_val = this.container 1878 .find('.appointment-content-screen-active-w') 1879 .find('.wbk_services[type="radio"]:checked') 1880 .val() 1881 1882 if (radio_val == undefined) { 1883 passed = false 1884 } else { 1885 passed = true 1886 } 1887 } 1888 1889 // check if payment method radio button is present and checked 1890 if ( 1891 this.container 1892 .find('.appointment-content-screen-active-w') 1893 .find('.payment-method-list-w').length > 0 1894 ) { 1895 var radio_val = this.container 1896 .find('.appointment-content-screen-active-w') 1897 .find('input[type="radio"]:checked') 1898 .val() 1899 1900 if (radio_val == undefined) { 1901 passed = false 1902 } else { 1903 passed = true 1904 } 1905 } 1906 1907 if (!passed) { 1908 get_this().container.find('.button-next-w').prop('disabled', true) 1909 } else { 1910 get_this().container.find('.button-next-w').prop('disabled', false) 1911 } 1912 1913 return passed 1914 } 1915 1916 clear_fields(element, clear_slots = true) { 1917 if (clear_slots) { 1918 element.find('.dynamic-content-w').remove() 1919 1920 element.find('.wbk_times > option').remove() 1921 element.find('.wbk_services_final > option').remove() 1922 this.render_selected_time_slots_list() 1923 element 1924 .find('.wbk-input') 1925 .not('.wbk_service_checkbox') 1926 .not('.wbk_service_radio') 1927 .val('') 1928 } 1929 element.find('select.wbk-input').not('.wbk_services_hidden').val(0) 1930 element.find('select.wbk-input').trigger('change') 1931 element.find('.wbk-input').niceSelect('update') 1932 element.attr('style', '') 1933 element.find('.wbk_quantities > option').remove() 1934 element.find('.wbk-book-quantity').remove() 1935 } 1936 1937 validate_prev_next_buttons() { 1938 const get_this = () => { 1939 return this 1940 } 1941 var step = parseInt(get_this().container.attr('data-step')) 1942 if (step == 1) { 1943 get_this() 1944 .container.find('.button-prev-w') 1945 .addClass('wbk_invisible') 1946 } else { 1947 get_this() 1948 .container.find('.button-prev-w') 1949 .removeClass('wbk_invisible') 1950 } 1951 } 1952 1953 finalize(response) { 1954 const get_this = () => { 1955 return this 1956 } 1957 this.container.find('.appointment-status-wrapper-w').fadeOut('fast') 1958 this.container 1959 .find('.appointment-content-w') 1960 .fadeOut('fast', function () { 1961 if (typeof response !== 'object') { 1962 response = jQuery.parseJSON(response) 1963 } 1964 get_this().container.append(response.thanks_message) 1965 }) 1966 1967 jQuery(document).trigger('webba_booking_finalize', [response, this]) 1968 } 1969 1970 prev_step() { 1971 const get_this = () => { 1972 return this 1973 } 1974 this.container.find('.wbk_quantities option').remove() 1975 var prev_screen = get_this().get_prev_screen() 1976 var step = parseInt(get_this().container.attr('data-step')) 1977 get_this() 1978 .container.find( 1979 '.appointment-status-list-w li:nth-child(' + step + ')' 1980 ) 1981 .removeClass('active-w') 1982 step-- 1983 get_this().container.attr('data-step', step) 1984 get_this() 1985 .container.find( 1986 '.appointment-status-list-w li:nth-child(' + step + ')' 1987 ) 1988 .addClass('active-w') 1989 get_this() 1990 .container.find( 1991 '.appointment-status-list-w li:nth-child(' + step + ')' 1992 ) 1993 .removeClass('completed-w') 1994 1995 Scrollbar.destroyAll() 1996 get_this().change_button_status( 1997 get_this().container.find('.button-next-w'), 1998 'regular' 1999 ) 2000 2001 this.clear_fields( 2002 get_this().container.find('.appointment-content-screen-active-w') 2003 ) 2004 2005 get_this() 2006 .container.find('.appointment-content-screen-active-w') 2007 .removeClass('appointment-content-screen-active-w') 2008 prev_screen.addClass('appointment-content-screen-active-w') 2009 var slug = prev_screen.attr('data-slug') 2010 this.remove_step_subtitle(slug) 2011 this.remove_step_subtitle('payment_optional') 2012 this.clear_fields(prev_screen, false) 2013 this.init_scroll_bars() 2014 this.validate_prev_next_buttons() 2015 2016 this.container.find('.wbk_times option').prop('selected', true) 2017 this.container.find('.wbk_services_final option').prop('selected', true) 2018 2019 this.validate_form() 2020 2021 get_this().update_mobile_step() 2022 jQuery(document).trigger('wbk_after_prev', [this]) 2023 } 2024 is_last_step() { 2025 var elements = this.container 2026 .find('.appointment-content-screen-active-w') 2027 .nextAll('.appointment-content-screen-w') 2028 if (elements.length == 1) { 2029 return true 2030 } 2031 return false 2032 } 2033 update_mobile_step() { 2034 var total_steps = parseInt( 2035 this.container.find('.appointment-status-list-w > li').length 2036 ) 2037 if (total_steps == 0) { 2038 return 2039 } 2040 var step = parseInt(this.container.attr('data-step')) 2041 this.container 2042 .find('.circle-chart-text-wb') 2043 .html(step + ' ' + wbkl10n.of + ' ' + total_steps) 2044 2045 var acive_step_title = this.container 2046 .find('.appointment-status-list-w > li.active-w') 2047 .find('.text-title-w') 2048 .html() 2049 2050 this.container.find('.current-step-w').html(acive_step_title) 2051 var next_li = this.container 2052 .find('.appointment-status-list-w > li.active-w') 2053 .nextAll('li') 2054 2055 if (next_li.length > 0) { 2056 var next_text = this.container.find('.button-next-w').html() 2057 this.container 2058 .find('.next-step-w') 2059 .html(next_text + ': ' + next_li.find('.text-title-w').html()) 2060 } 2061 var progress = parseInt((100 * step) / total_steps) 2062 this.container 2063 .find('.circle-chart-wb') 2064 .data('easyPieChart') 2065 .update(progress) 2066 } 2067 async next_step() { 2068 const get_this = () => { 2069 return this 2070 } 2071 this.container 2072 .find('.wbk_service_item') 2073 .removeClass('timeslot-animation-w') 2074 2075 // validation 2076 if (!this.validate_form()) { 2077 return 2078 } 2079 var next_screen = get_this().get_next_screen() 2080 if (next_screen.length == 0) { 2081 get_this().change_button_status( 2082 get_this().container.find('.button-next-w'), 2083 'loading' 2084 ) 2085 2086 return 2087 } 2088 this.clear_fields(next_screen) 2089 var can_proceed = false 2090 var response = null 2091
2091 if (next_screen.attr('data-request') != '') { 2092 get_this().change_button_status( 2093 get_this().container.find('.button-next-w'), 2094 'loading' 2095 ) 2096 response = await this.do_request(next_screen.attr('data-request')) 2097 if (response == false) { 2098 get_this().show_error('An unexpected error occoured.') 2099 return 2100 } 2101 2102 try { 2103 response = jQuery.parseJSON(response) 2104 if (response.status == 'fail') { 2105 get_this().change_button_status( 2106 get_this().container.find('.button-next-w'), 2107 'regular' 2108 ) 2109 this.show_error(response.description) 2110 return 2111 } 2112 if ((response.url != undefined && response.url) != '') { 2113 window.location.href = response.url 2114 return 2115 } 2116 } catch (e) {} 2117 if (get_this().is_last_step()) { 2118 get_this().finalize(response) 2119 return 2120 } 2121 if (response != false) { 2122 if (typeof response.webba5_html !== 'undefined') { 2123 this.container.find('.appointment-content-screen-active-w') 2124 .response.webba5_html 2125 } 2126 } 2127 if (response != false) { 2128 can_proceed = true 2129 } 2130 } else { 2131 can_proceed = true 2132 } 2133 if (can_proceed) { 2134 var step = parseInt(get_this().container.attr('data-step')) 2135 get_this() 2136 .container.find('.input-error-w') 2137 .removeClass('input-error-w') 2138 get_this().container.find('.form-error-w').toggle(false) 2139 get_this() 2140 .container.find( 2141 '.appointment-status-list-w li:nth-child(' + step + ')' 2142 ) 2143 .removeClass('active-w') 2144 get_this() 2145 .container.find( 2146 '.appointment-status-list-w li:nth-child(' + step + ')' 2147 ) 2148 .addClass('completed-w') 2149 2150 step++ 2151 get_this().container.attr('data-step', step) 2152 get_this() 2153 .container.find( 2154 '.appointment-status-list-w li:nth-child(' + step + ')' 2155 ) 2156 .addClass('active-w') 2157 Scrollbar.destroyAll() 2158 get_this() 2159 .container.find('.appointment-content-screen-active-w') 2160 .fadeOut('fast', function () { 2161 get_this().change_button_status( 2162 get_this().container.find('.button-next-w'), 2163 'regular' 2164 ) 2165 get_this() 2166 .container.find('.appointment-content-screen-active-w') 2167 .removeClass('appointment-content-screen-active-w') 2168 next_screen.addClass('appointment-content-screen-active-w') 2169 next_screen 2170 .find('.wbk-input') 2171 .addClass('linear-animation-w') 2172 2173 jQuery(document).trigger('wbk_after_screen_rendered', [ 2174 response, 2175 ]) 2176 jQuery(document).trigger('wbk_after_next', [this, response]) 2177 }) 2178 get_this().validate_prev_next_buttons() 2179 get_this().update_mobile_step() 2180 } 2181 } 2182 show_error(message) { 2183 this.container.find('.form-error-message-w').html(message) 2184 this.container.find('.form-error-w').toggle(true) 2185 } 2186} 2187 2188let webba_forms = [] 2189jQuery(function ($) { 2190 jQuery('.appointment-box-w').each(function () { 2191 var form = new WEBBA5_Form(jQuery(this)) 2192 webba_forms.push(form) 2193 }) 2194 if (jQuery('#grve-safebutton-area').length > 0) { 2195 jQuery('#grve-safebutton-area').find('.main-block-w').remove() 2196 } else { 2197 if (jQuery('.main-block-w').length > 1) { 2198 jQuery('.main-block-w').not(':last').remove() 2199 } 2200 } 2201}) 2202 2203function wbk_strip_html(html) { 2204 let tmp = document.createElement('DIV') 2205 tmp.innerHTML = html 2206 return tmp.textContent || tmp.innerText || '' 2207}
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.