Changeset 3237969
- Timestamp:
- 02/10/2025 01:47:37 PM (14 months ago)
- Location:
- orderable
- Files:
-
- 4 added
- 2 deleted
- 12 edited
- 1 copied
-
tags/1.17.1 (copied) (copied from orderable/trunk)
-
tags/1.17.1/.nvmrc (added)
-
tags/1.17.1/.wp-env.json (added)
-
tags/1.17.1/assets/frontend/js/main.js (modified) (2 diffs)
-
tags/1.17.1/assets/frontend/js/main.min.js (modified) (1 diff)
-
tags/1.17.1/bin (deleted)
-
tags/1.17.1/docs/filters.json (modified) (2 diffs)
-
tags/1.17.1/languages/orderable.pot (modified) (2 diffs)
-
tags/1.17.1/orderable.php (modified) (2 diffs)
-
tags/1.17.1/readme.txt (modified) (2 diffs)
-
trunk/.nvmrc (added)
-
trunk/.wp-env.json (added)
-
trunk/assets/frontend/js/main.js (modified) (2 diffs)
-
trunk/assets/frontend/js/main.min.js (modified) (1 diff)
-
trunk/bin (deleted)
-
trunk/docs/filters.json (modified) (2 diffs)
-
trunk/languages/orderable.pot (modified) (2 diffs)
-
trunk/orderable.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
orderable/tags/1.17.1/assets/frontend/js/main.js
r3192586 r3237969 1 1 2 (function ($, document) { 3 'use strict'; 4 5 var orderable_accordion = { 6 /** 7 * On doc ready. 8 */ 9 on_ready() { 10 orderable_accordion.cache(); 11 orderable_accordion.watch(); 12 }, 13 /** 14 * Cache. 15 */ 16 cache() { 17 orderable_accordion.vars = { 18 classes: { 19 parent: 'orderable-accordion', 20 link: 'orderable-accordion__item-link', 21 content: 'orderable-accordion__item-content', 22 link_active: 'orderable-accordion__item-link--active', 23 content_active: 'orderable-accordion__item-content--active' 24 } 25 }; 26 }, 27 /** 28 * Watch. 29 */ 30 watch() { 31 /** 32 * When click accordion link. 33 */ 34 $(document.body).on('click', '.' + orderable_accordion.vars.classes.link, function (e) { 35 e.preventDefault(); 36 const $link = $(this), 37 $parent = $link.closest('.' + orderable_accordion.vars.classes.parent), 38 content_id = $link.attr('href'), 39 $content = $(content_id), 40 is_active = $link.hasClass(orderable_accordion.vars.classes.link_active); 41 $parent.find('.' + orderable_accordion.vars.classes.link).removeClass(orderable_accordion.vars.classes.link_active); 42 $parent.find('.' + orderable_accordion.vars.classes.content).removeClass(orderable_accordion.vars.classes.content_active); 43 if (!is_active) { 44 $link.addClass(orderable_accordion.vars.classes.link_active); 45 $content.addClass(orderable_accordion.vars.classes.content_active); 46 } 47 $(document.body).trigger('orderable-accordion.toggled', { 48 link: $link, 49 content: $content 50 }); 51 }); 52 53 /** 54 * When drawer is opened. 55 */ 56 $(document.body).on('orderable-scrollbar.created', function (e, args) { 57 const $active_accordion = $('.orderable-drawer .' + orderable_accordion.vars.classes.link_active); 58 if ($active_accordion.length <= 0) { 59 return; 60 } 61 const $scroll_content = args.content, 62 scroll_position = $scroll_content.scrollTop() - $scroll_content.offset().top + $active_accordion.offset().top; 63 $scroll_content.scrollTop(scroll_position); 64 }); 65 } 66 }; 67 $(document).ready(orderable_accordion.on_ready); 68 })(jQuery, document); 69 (function ($, document) { 70 'use strict'; 71 72 var orderable_drawer = { 73 /** 74 * Delays invoking function 75 * 76 * @param {Function} func The function to debounce. 77 * @param {number} timeout The number of milliseconds to delay. 78 * @return {Function} Returns the new debounced function. 79 */ 80 debounce(func, timeout = 700) { 81 let timer; 82 return (...args) => { 83 clearTimeout(timer); 84 timer = setTimeout(() => { 85 func.apply(this, args); 86 }, timeout); 87 }; 88 }, 89 /** 90 * Allow only number for events like keypress 91 * 92 * @param {Event} event 93 */ 94 allow_only_numbers(event) { 95 const value = String.fromCharCode(event.which); 96 if (!/^\d+$/.test(value)) { 97 event.preventDefault(); 98 } 99 }, 100 /** 101 * Send a request to change the quantity. 102 * 103 * @param {Event} event 104 */ 105 on_change_quantity(event) { 106 const quantityElement = $(event.currentTarget); 107 const product_id = quantityElement.data('orderable-product-id'); 108 const cart_item_key = quantityElement.data('orderable-cart-item-key'); 109 const quantity = parseInt(quantityElement.text()); 110 const data = { 111 action: 'orderable_cart_quantity', 112 cart_item_key, 113 product_id, 114 quantity 115 }; 116 jQuery.post(orderable_vars.ajax_url, data, function (response) { 117 if (!response) { 118 return; 119 } 120 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, quantityElement]); 121 $(document.body).trigger('orderable-drawer.quantity-updated'); 122 }); 123 }, 124 /** 125 * On doc ready. 126 */ 127 on_ready() { 128 orderable_drawer.cache(); 129 orderable_drawer.watch(); 130 131 /** 132 * Handle manually changing the quantity of a product. 133 */ 134 $(document.body).on('keypress', '.orderable-quantity-roller__quantity', orderable_drawer.allow_only_numbers); 135 $('.orderable-drawer__cart, .orderable-product--add-to-cart, .orderable-products-list').on('input', '.orderable-quantity-roller__quantity', orderable_drawer.debounce(orderable_drawer.on_change_quantity)); 136 $(document.body).on('click', '.orderable-quantity-roller__quantity', function (event) { 137 event.stopPropagation(); 138 }); 139 140 /** 141 * We turn off the click event for .add_to_cart_button elements 142 * to keep the AJAX behaviour only on Mini cart when the option 143 * "Enable AJAX add to cart buttons on archives" is disabled. 144 */ 145 if (orderable_vars && !orderable_vars.woocommerce_enable_ajax_add_to_cart) { 146 $(document.body).off('click', '.add_to_cart_button'); 147 } 148 }, 149 /** 150 * Cache. 151 */ 152 cache() { 153 orderable_drawer.vars = { 154 classes: { 155 overlay: 'orderable-drawer-overlay', 156 drawer: 'orderable-drawer', 157 drawer_cart: 'orderable-drawer__cart', 158 drawer_html: 'orderable-drawer__html', 159 overlay_open: 'orderable-drawer-overlay--open', 160 drawer_open: 'orderable-drawer--open', 161 drawer_open_body: 'orderable-drawer-open' 162 } 163 }; 164 orderable_drawer.elements = { 165 body: $('body'), 166 overlay: $('.' + orderable_drawer.vars.classes.overlay), 167 drawer: $('.' + orderable_drawer.vars.classes.drawer), 168 drawer_cart: $('.' + orderable_drawer.vars.classes.drawer_cart), 169 drawer_html: $('.' + orderable_drawer.vars.classes.drawer_html), 170 floating_cart_button_class: '.orderable-floating-cart__button' 171 }; 172 }, 173 /** 174 * Watch for trigger events. 175 */ 176 watch() { 177 if (typeof orderable_drawer.elements.drawer === 'undefined') { 178 return; 179 } 180 $(document.body).on('orderable-drawer.open', orderable_drawer.open); 181 $(document.body).on('orderable-drawer.close', orderable_drawer.close); 182 $(document.body).on('click', orderable_drawer.elements.floating_cart_button_class, function () { 183 $(document.body).trigger('orderable-drawer.open', { 184 show_cart: true 185 }); 186 }); 187 $(document.body).on('orderable-increase-quantity', orderable_drawer.cart.handle_quantity_change_by_button); 188 $(document.body).on('orderable-decrease-quantity', orderable_drawer.cart.handle_quantity_change_by_button); 189 const updateQuantityRequest = orderable_drawer.debounce(orderable_drawer.cart.click_increase_decrease_quantity); 190 $(document.body).on('orderable-increase-quantity', updateQuantityRequest); 191 $(document.body).on('orderable-decrease-quantity', updateQuantityRequest); 192 const drawer = document.querySelector('body:not( .rtl ) .orderable-drawer'); 193 const drawer_rtl = document.querySelector('body.rtl .orderable-drawer'); 194 if (drawer) { 195 drawer.addEventListener('swiped-right', function (e) { 196 orderable_drawer.close(); 197 }); 198 } 199 if (drawer_rtl) { 200 drawer_rtl.addEventListener('swiped-left', function (e) { 201 orderable_drawer.close(); 202 }); 203 } 204 }, 205 /** 206 * Open the drawer. 207 * @param event 208 * @param args 209 */ 210 open(event, args) { 211 args.html = args.html || false; 212 args.show_cart = args.show_cart || false; 213 orderable_drawer.elements.drawer_html.hide(); 214 orderable_drawer.elements.drawer_cart.hide(); 215 if (args.html) { 216 orderable_drawer.elements.drawer_html.html(args.html); 217 orderable_drawer.elements.drawer_html.show(); 218 } 219 if (args.show_cart) { 220 // Empty drawer HTML before showing cart. Prevents options 221 // interfering with subsequent cart additions. 222 orderable_drawer.elements.drawer_html.html(''); 223 orderable_drawer.elements.drawer_cart.show(); 224 } 225 orderable_drawer.elements.overlay.addClass(orderable_drawer.vars.classes.overlay_open); 226 orderable_drawer.elements.drawer.addClass(orderable_drawer.vars.classes.drawer_open); 227 orderable_drawer.elements.body.addClass(orderable_drawer.vars.classes.drawer_open_body); 228 $(document.body).trigger('orderable-drawer.opened', args); 229 }, 230 /** 231 * Close the drawer. 232 */ 233 close() { 234 orderable_drawer.elements.overlay.removeClass(orderable_drawer.vars.classes.overlay_open); 235 orderable_drawer.elements.drawer.removeClass(orderable_drawer.vars.classes.drawer_open); 236 orderable_drawer.elements.body.removeClass(orderable_drawer.vars.classes.drawer_open_body); 237 orderable_drawer.elements.drawer_html.html(''); 238 $(document.body).trigger('orderable-drawer.closed'); 239 }, 240 /** 241 * Mini cart related functions. 242 */ 243 cart: { 244 /** 245 * When increase qty is clicked. 246 * 247 * @param e 248 * @param $button 249 */ 250 click_increase_decrease_quantity(e, $button) { 251 const direction = $button.data('orderable-trigger'); 252 const product_id = $button.attr('data-orderable-product-id'), 253 cart_item_key = $button.attr('data-orderable-cart-item-key'), 254 quantity = $button.attr('data-orderable-quantity'); 255 const siblingButtonName = 'increase-quantity' === direction ? 'decrease' : 'increase'; 256 const $siblingButton = $button.siblings(`.orderable-quantity-roller__button--${siblingButtonName}`); 257 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity'); 258 const data = { 259 action: 'orderable_cart_quantity', 260 cart_item_key, 261 product_id, 262 quantity 263 }; 264 if (this.currentRequest) { 265 this.currentRequest.abort(); 266 this.currentRequest = undefined; 267 } 268 $button.addClass('orderable-button--loading'); 269 $button.attr('disabled', true); 270 $siblingButton.attr('disabled', true); 271 $quantityElement.attr('contenteditable', false); 272 this.currentRequest = jQuery.post(orderable_vars.ajax_url, data, function (response) { 273 if (!response) { 274 return; 275 } 276 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity'); 277 if (response && response.fragments && response.fragments['.orderable-mini-cart__notices']) { 278 $(document.body).trigger('orderable-drawer.open', { 279 show_cart: true 280 }); 281 } 282 switch (data.quantity) { 283 case '0': 284 $(document.body).trigger('removed_from_cart', [response.fragments, response.cart_hash, $button]); 285 break; 286 case $quantityElement.attr('data-orderable-updating-quantity'): 287 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $button]); 288 $(document.body).trigger('orderable-drawer.quantity-updated'); 289 break; 290 default: 291 break; 292 } 293 }.bind(this)).always(function () { 294 this.currentRequest = undefined; 295 $button.removeClass('orderable-button--loading'); 296 $button.attr('disabled', false); 297 $siblingButton.attr('disabled', false); 298 $quantityElement.attr('contenteditable', true); 299 }.bind(this)); 300 }, 301 handle_quantity_change_by_button(e, $button) { 302 const direction = $button.data('orderable-trigger'); 303 const quantity = parseInt($button.attr('data-orderable-quantity')); 304 const siblingButtonName = 'increase-quantity' === direction ? 'decrease' : 'increase'; 305 const $siblingButton = $button.siblings(`.orderable-quantity-roller__button--${siblingButtonName}`); 306 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity'); 307 const newQuantity = 'increase-quantity' === direction ? quantity + 1 : Math.max(0, quantity - 1); 308 const $parent = $button.parents('.orderable-product__actions-button'); 309 if (0 === newQuantity && $parent.length) { 310 const $addToCartButton = $parent.find('button.orderable-button[data-orderable-trigger]'); 311 const $quantityRoller = $parent.find('.orderable-quantity-roller'); 312 if ($quantityRoller.length) { 313 $addToCartButton.removeClass('orderable-button--product-in-the-cart'); 314 $quantityRoller.removeClass('orderable-quantity-roller--is-active'); 315 } 316 } 317 $button.attr('data-orderable-quantity', newQuantity); 318 $siblingButton.attr('data-orderable-quantity', newQuantity); 319 $quantityElement.attr('data-orderable-updating-quantity', newQuantity); 320 $quantityElement.text(newQuantity); 321 $quantityElement.attr('contenteditable', false); 322 } 323 } 324 }; 325 $(document).ready(orderable_drawer.on_ready); 326 })(jQuery, document); 327 (function ($, document) { 328 'use strict'; 329 330 var orderable_products = { 331 /** 332 * On doc ready. 333 */ 334 on_ready() { 335 orderable_products.cache(); 336 orderable_products.watch(); 337 }, 338 /** 339 * Cache. 340 */ 341 cache() { 342 orderable_products.vars = { 343 classes: { 344 clickable_product: 'orderable-product--add-to-cart ', 345 add_to_order_button: 'orderable-product__add-to-order', 346 product_messages: 'orderable-product__messages', 347 product_price: 'orderable-product__actions-price', 348 invalid_field: 'orderable-field--invalid', 349 option_select_td: 'orderable-product__option-select', 350 button_loading: 'orderable-button--loading', 351 out_of_stock: 'orderable-button--out-of-stock' 352 }, 353 parent_price: null, 354 variable_product_types: ['variable', 'variable-subscription'] 355 }; 356 orderable_products.elements = {}; 357 }, 358 /** 359 * Watch for trigger events. 360 */ 361 watch() { 362 $(document.body).on('orderable-drawer.opened', orderable_products.init_product_options); 363 $(document.body).on('orderable-add-to-cart', orderable_products.click_add_to_order); 364 $(document.body).on('orderable-product-options', orderable_products.click_add_to_order); 365 $(document.body).on('orderable-view-product', orderable_products.view_product); 366 $(document.body).on('mouseenter mouseleave', '.' + orderable_products.vars.classes.clickable_product, orderable_products.simulate_add_to_order_hover); 367 $(document.body).on('orderable-edit-cart-item', orderable_products.edit_cart_item); 368 $(document.body).on('orderable-update-cart-item', orderable_products.update_cart_item); 369 $(document.body).on('orderable-show-cart', orderable_products.show_cart); 370 $(document.body).on('orderable-add-to-cart-without-side-drawer', orderable_products.click_add_to_order); 371 $(document.body).on('added_to_cart', orderable_products.remove_fragments); 372 $(document.body).on('added_to_cart', orderable_products.remove_animation); 373 $(document.body).on('added_to_cart', orderable_products.shake_floating_cart); 374 $(document.body).on('removed_from_cart', orderable_products.hide_quantity_roller); 375 $(document.body).on('wc_cart_button_updated', orderable_products.remove_view_cart_link); 376 }, 377 /** 378 * Simulate hover on add to order button. 379 * 380 * @param event 381 */ 382 simulate_add_to_order_hover(event) { 383 const $element = $(this), 384 $button = $element.find('.' + orderable_products.vars.classes.add_to_order_button); 385 $button.toggleClass('orderable-button--hover', 'mouseenter' === event.type); 386 }, 387 /** 388 * Add to order click event. 389 * 390 * This event accounts for button clicks or card clicks. 391 * @param event 392 * @param $element 393 */ 394 click_add_to_order(event, $element) { 395 // If undefined, it means it was triggered by a click 396 // event and not the `orderable-add-to-cart` trigger. 397 $element = typeof $element !== 'undefined' ? $element : $(this); 398 399 // The button is either the clicked element, or the 400 // add to order button within the clicked element. 401 const $button = $element.is('button') ? $element : $element.find('.' + orderable_products.vars.classes.add_to_order_button), 402 action = $button.data('orderable-trigger'), 403 product_id = $button.data('orderable-product-id'), 404 variation_id = $button.data('orderable-variation-id'), 405 attributes = $button.data('orderable-variation-attributes'), 406 args = { 407 action 408 }; 409 if ($button.hasClass(orderable_products.vars.classes.button_loading) || $button.hasClass(orderable_products.vars.classes.out_of_stock)) { 410 return; 411 } 412 $button.addClass(orderable_products.vars.classes.button_loading); 413 switch (action) { 414 case 'add-to-cart': 415 orderable_products.add_to_cart({ 416 product_id, 417 variation_id, 418 attributes, 419 thisbutton: $element 420 }, function (response) { 421 args.show_cart = true; 422 args.response = response; 423 $(document.body).trigger('orderable-drawer.open', args); 424 $button.removeClass(orderable_products.vars.classes.button_loading); 425 const $addToCartButtonOutsideDrawer = $('.orderable-product .orderable-product__actions-button button.orderable-product__add-to-order[data-orderable-product-id=' + product_id + ']'); 426 if ($addToCartButtonOutsideDrawer.siblings('.orderable-quantity-roller').length) { 427 $addToCartButtonOutsideDrawer.addClass('orderable-button--product-in-the-cart'); 428 } 429 }); 430 break; 431 case 'add-to-cart-without-side-drawer': 432 orderable_products.add_to_cart({ 433 product_id, 434 variation_id, 435 attributes 436 }, function (response) { 437 args.response = response; 438 $button.addClass('orderable-button--product-in-the-cart'); 439 $button.removeClass(orderable_products.vars.classes.button_loading); 440 }); 441 break; 442 case 'product-options': 443 orderable_products.get_product_options({ 444 product_id, 445 focus: $button.data('orderable-focus') 446 }, function (response) { 447 args.html = response.html; 448 $(document.body).trigger('orderable-drawer.open', args); 449 $button.removeClass(orderable_products.vars.classes.button_loading); 450 }); 451 break; 452 default: 453 break; 454 } 455 }, 456 /** 457 * Show the cart. 458 */ 459 show_cart() { 460 $(document.body).trigger('orderable-drawer.open', { 461 show_cart: true 462 }); 463 }, 464 /** 465 * View product. 466 * 467 * @param event 468 * @param $element 469 */ 470 view_product(event, $element) { 471 const product_id = $element.data('orderable-product-id'), 472 args = { 473 action: 'product-options' 474 }; 475 orderable_products.get_product_options({ 476 product_id, 477 focus: $element.data('orderable-focus') 478 }, function (response) { 479 args.html = response.html; 480 $(document.body).trigger('orderable-drawer.open', args); 481 }); 482 }, 483 /** 484 * Ajax add to cart. 485 * @param args 486 * @param callback 487 */ 488 add_to_cart(args, callback) { 489 if (typeof args.product_id === 'undefined') { 490 return; 491 } 492 let data = { 493 action: 'orderable_add_to_cart', 494 product_id: args.product_id, 495 variation_id: args.variation_id || false, 496 attributes: args.attributes || false 497 }; 498 499 // Prepare addons data. 500 if ($('.orderable-product-fields-group').length) { 501 let inputs = jQuery('.orderable-product-fields-group :input').serializeArray(); 502 inputs = orderable_products.add_unchecked_checkbox_fields(inputs); 503 const addons_data = orderable_products.convert_to_flat_object(inputs); 504 if (!jQuery.isEmptyObject(addons_data)) { 505 data = Object.assign(data, addons_data); // Merge objects. 506 } 507 } 508 jQuery.post(orderable_vars.ajax_url, data, function (response) { 509 if (!response) { 510 return; 511 } 512 513 // Trigger event so themes can refresh other areas. 514 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, args.thisbutton]); 515 if (typeof callback === 'function') { 516 callback(response); 517 } 518 }); 519 }, 520 /** 521 * Edit cart item. 522 * 523 * @param event 524 * @param $element 525 */ 526 edit_cart_item(event, $element) { 527 const cart_item_key = $element.data('orderable-cart-item-key'); 528 $element.addClass(orderable_products.vars.classes.button_loading); 529 orderable_products.get_cart_item_options({ 530 cart_item_key 531 }, function (response) { 532 const args = { 533 html: response.html, 534 action: 'update-cart-item' 535 }; 536 $(document.body).trigger('orderable-drawer.open', args); 537 $element.removeClass(orderable_products.vars.classes.button_loading); 538 }); 539 }, 540 /** 541 * Update cart item. 542 * 543 * @param event 544 * @param $element 545 */ 546 update_cart_item(event, $element) { 547 const cart_item_key = $element.data('orderable-cart-item-key'); 548 const product_id = $element.data('orderable-product-id'); 549 const variation_id = $element.data('orderable-variation-id'); 550 const attributes = $element.data('orderable-variation-attributes'); 551 $element.addClass(orderable_products.vars.classes.button_loading); 552 orderable_products.update_cart_item_options({ 553 cart_item_key, 554 product_id, 555 variation_id, 556 attributes 557 }, function (response) { 558 const args = { 559 show_cart: true, 560 response 561 }; 562 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $element]); 563 $(document.body).trigger('orderable-drawer.open', args); 564 $element.removeClass(orderable_products.vars.classes.button_loading); 565 }); 566 }, 567 /** 568 * Convert [{name:x, value:y }] to {x:y} format. 569 * @param inputs 570 */ 571 convert_to_flat_object(inputs) { 572 const data = {}; 573 inputs.forEach(function (input) { 574 const is_array = '[]' === input.name.substr(-2) || Array.isArray(input.name); 575 // If last 2 chars are '[]', remove them. 576 const key = is_array ? input.name.substr(0, input.name.length - 2) : input.name; 577 if (is_array) { 578 data[key] = typeof data[key] === 'undefined' ? [] : data[key]; 579 data[key].push(input.value); 580 } else { 581 data[key] = input.value; 582 } 583 }); 584 return data; 585 }, 586 /** 587 * Get variable product options. 588 * 589 * @param args 590 * @param callback 591 */ 592 get_product_options(args, callback) { 593 if (typeof args.product_id === 'undefined') { 594 return; 595 } 596 args.action = 'orderable_get_product_options'; 597 jQuery.post(orderable_vars.ajax_url, args, function (response) { 598 if (!response.success) { 599 return; 600 } 601 if (typeof callback === 'function') { 602 callback(response.data); 603 } 604 }); 605 }, 606 /** 607 * Get variable product options. 608 * 609 * @param args 610 * @param callback 611 */ 612 get_cart_item_options(args, callback) { 613 if (typeof args.cart_item_key === 'undefined') { 614 return; 615 } 616 args.action = 'orderable_get_cart_item_options'; 617 jQuery.post(orderable_vars.ajax_url, args, function (response) { 618 if (!response.success) { 619 return; 620 } 621 if (typeof callback === 'function') { 622 callback(response.data); 623 } 624 }); 625 }, 626 /** 627 * Update variable product options. 628 * 629 * @param args 630 * @param callback 631 */ 632 update_cart_item_options(args, callback) { 633 if (typeof args.cart_item_key === 'undefined') { 634 return; 635 } 636 args.action = 'orderable_update_cart_item_options'; 637 638 // Prepare addons data. 639 if ($('.orderable-product-fields-group').length) { 640 let inputs = jQuery('.orderable-product-fields-group :input').serializeArray(); 641 inputs = orderable_products.add_unchecked_checkbox_fields(inputs); 642 const addons_data = orderable_products.convert_to_flat_object(inputs); 643 if (!jQuery.isEmptyObject(addons_data)) { 644 args = Object.assign(args, addons_data); // Merge objects. 645 } 646 } 647 jQuery.post(orderable_vars.ajax_url, args, function (response) { 648 if (!response) { 649 return; 650 } 651 if (typeof callback === 'function') { 652 callback(response); 653 } 654 }); 655 }, 656 /** 657 * Init drawer product options. 658 * 659 * @param event 660 * @param args 661 */ 662 init_product_options(event, args) { 663 if (typeof args.action === 'undefined' || 'product-options' !== args.action && 'update-cart-item' !== args.action) { 664 return; 665 } 666 const selectors = '.orderable-drawer .orderable-product__options input, .orderable-drawer .orderable-product__options select, .orderable-product__options textarea'; 667 const $options = $(selectors); 668 orderable_products.vars.parent_price = $('.orderable-drawer .orderable-product__actions-price').html(); 669 orderable_products.product_options_change($options); 670 orderable_products.update_button_state(); 671 const debounced_update_button_state = orderable_products.debounce(orderable_products.update_button_state, 500); 672 const debounced_product_options_change = orderable_products.debounce(orderable_products.product_options_change, 500); 673 $(document).on('change keyup', selectors, function () { 674 debounced_product_options_change($options); 675 debounced_update_button_state(); 676 }); 677 }, 678 /** 679 * On product options change. 680 * 681 * @param $options 682 */ 683 product_options_change($options) { 684 const $add_to_order_button = $('.orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item'), 685 options_set = orderable_products.check_options($options), 686 product_type = $add_to_order_button.data('orderable-product-type'); 687 if ('product-options' === $add_to_order_button.attr('data-orderable-trigger')) { 688 $add_to_order_button.attr('data-orderable-trigger', 'add-to-cart'); 689 } 690 $('.' + orderable_products.vars.classes.product_messages).html(''); 691 if (!orderable_products.vars.variable_product_types.includes(product_type)) { 692 return; 693 } 694 if (!options_set) { 695 orderable_products.clear_variation($add_to_order_button); 696 return; 697 } 698 const variation = orderable_products.check_variation($options); 699 orderable_products.set_variation($add_to_order_button, variation); 700 }, 701 /** 702 * Check if all product options are set. 703 * 704 * @param $options 705 * @return {boolean} 706 */ 707 check_options($options) { 708 if ($options.length <= 0) { 709 return false; 710 } 711 let all_set = true; 712 $options.each(function (index, option) { 713 // Only check attribute fields. 714 if (!$(option).hasClass('orderable-input--validate')) { 715 return; 716 } 717 if ('' === $(option).val()) { 718 $(option).addClass(orderable_products.vars.classes.invalid_field); 719 all_set = false; 720 } else { 721 $(option).removeClass(orderable_products.vars.classes.invalid_field); 722 } 723 }); 724 return all_set; 725 }, 726 /** 727 * Check if variation has been selected. 728 * @param $options 729 */ 730 check_variation($options) { 731 const $product = $options.closest('.orderable-drawer'); 732 let variations = $product.find('.orderable-product__variations').text(); 733 variations = variations ? JSON.parse(variations) : ''; 734 const selected_options = orderable_products.serialize_object($options), 735 matching_variations = orderable_products.find_matching_variations(variations, selected_options); 736 if (orderable_products.is_empty(matching_variations)) { 737 return false; 738 } 739 const variation = matching_variations.shift(); 740 variation.attributes = selected_options; 741 variation.attributes_json = JSON.stringify(selected_options); 742 return typeof variation !== 'undefined' ? variation : false; 743 }, 744 /** 745 * Set variation for add to cart button. 746 * @param $button 747 * @param variation 748 */ 749 set_variation($button, variation) { 750 let variation_id = variation.variation_id || '', 751 attributes = variation.attributes_json || '', 752 price = variation.price_html || orderable_products.vars.parent_price, 753 message = ''; 754 if (variation && '' !== variation.availability_html) { 755 message = variation.availability_html; 756 } 757 if (variation && !variation.is_in_stock) { 758 message = '<p>' + orderable_vars.i18n.out_of_stock + '</p>'; 759 } 760 if (variation && !variation.is_purchasable) { 761 message = '<p>' + orderable_vars.i18n.unavailable + '</p>'; 762 } 763 if (false === variation) { 764 message = '<p>' + orderable_vars.i18n.no_exist + '</p>'; 765 } 766 if (variation && (!variation.is_purchasable || !variation.is_in_stock)) { 767 variation_id = ''; 768 attributes = ''; 769 } 770 if ('' !== message) { 771 $('.' + orderable_products.vars.classes.product_messages).html(message); 772 } 773 $button.data('orderable-variation-id', variation_id); 774 $button.data('orderable-variation-attributes', attributes); 775 $('.orderable-drawer .orderable-product__actions-price').html(price); 776 $button.trigger('orderable_variation_set', { 777 variation, 778 variation_id, 779 attributes, 780 price 781 }); 782 }, 783 /** 784 * Clear variation and disable add to order. 785 * 786 * @param $button 787 */ 788 clear_variation($button) { 789 orderable_products.set_variation($button, ''); 790 if (orderable_products.vars.parent_price) { 791 $('.orderable-drawer .orderable-product__actions-price').html(orderable_products.vars.parent_price); 792 } 793 }, 794 /** 795 * Find matching variations for attributes. 796 * @param variations 797 * @param attributes 798 */ 799 find_matching_variations(variations, attributes) { 800 const matching = []; 801 for (let i = 0; i < variations.length; i++) { 802 const variation = variations[i]; 803 if (orderable_products.is_matching_variation(variation.attributes, attributes)) { 804 matching.push(variation); 805 } 806 } 807 return matching; 808 }, 809 /** 810 * See if attributes match. 811 * @param variation_attributes 812 * @param attributes 813 * @return {boolean} 814 */ 815 is_matching_variation(variation_attributes, attributes) { 816 let match = true; 817 for (const attr_name in variation_attributes) { 818 if (variation_attributes.hasOwnProperty(attr_name)) { 819 const val1 = variation_attributes[attr_name]; 820 const val2 = attributes[attr_name]; 821 if (val1 !== undefined && val2 !== undefined && val1.length !== 0 && val2.length !== 0 && val1 !== val2) { 822 match = false; 823 } 824 } 825 } 826 return match; 827 }, 828 /** 829 * Is value empty? 830 * 831 * @param value 832 * @return {boolean} 833 */ 834 is_empty(value) { 835 return typeof value === 'undefined' || false === value || value.length <= 0 || !value; 836 }, 837 /** 838 * Serialize into a key/value object. 839 * 840 * @param $elements 841 * @return {{}} 842 */ 843 serialize_object: function objectifyForm($elements) { 844 const serialized = $elements.serializeArray(), 845 return_object = {}; 846 for (let i = 0; i < serialized.length; i++) { 847 return_object[serialized[i].name] = serialized[i].value; 848 } 849 return return_object; 850 }, 851 /** 852 * Disable/Enable the 'Add to cart' button based on the presence of orderable-field--invalid class. 853 */ 854 update_button_state() { 855 // Add delay to ensure invalid class has been assigned to inputs. 856 setTimeout(function () { 857 let $button = $('.orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item'), 858 invalid_fields_count = $('.orderable-drawer__html .' + orderable_products.vars.classes.invalid_field).length, 859 product_type = $button.data('orderable-product-type'), 860 has_variation_id = true; 861 if ('variable' === product_type) { 862 has_variation_id = '' !== $button.data('orderable-variation-id'); 863 } 864 $button.prop('disabled', invalid_fields_count || !has_variation_id); 865 }, 50); 866 }, 867 /** 868 * Debounce function. 869 * 870 * @param func Function to debounce. 871 * @param wait Time to wait in milliseconds. 872 * @param immediate Trigger the function on the leading edge, instead of the trailing. 873 * 874 * @return 875 */ 876 debounce(func, wait, immediate) { 877 let timeout; 878 return function () { 879 const context = this, 880 args = arguments; 881 const later = function () { 882 timeout = null; 883 if (!immediate) { 884 func.apply(context, args); 885 } 886 }; 887 const callNow = immediate && !timeout; 888 clearTimeout(timeout); 889 timeout = setTimeout(later, wait); 890 if (callNow) { 891 func.apply(context, args); 892 } 893 }; 894 }, 895 /** 896 * Remove the quantity roller fragments 897 * 898 * @param {Event} e 899 * @param {Object} fragments 900 * @return void 901 */ 902 remove_fragments(e, fragments) { 903 if (!fragments || 'undefined' === typeof wc_cart_fragments_params || !wc_cart_fragments_params.fragment_name) { 904 return; 905 } 906 const regex_quantity_roller = /\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-quantity-roller/; 907 const regex_product_in_the_cart_counter = /\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-product__actions-counter/; 908 for (const key in fragments) { 909 if (!regex_quantity_roller.test(key) && !regex_product_in_the_cart_counter.test(key)) { 910 continue; 911 } 912 fragments[key] = undefined; 913 } 914 sessionStorage.setItem(wc_cart_fragments_params.fragment_name, JSON.stringify(fragments)); 915 }, 916 /** 917 * Remove animation. 918 */ 919 remove_animation() { 920 setTimeout(function () { 921 $('.orderable-product__actions-counter').css('animation', ''); 922 }, 1000); 923 }, 924 /** 925 * Hide quantity roller element and show the Add to Cart button. 926 * 927 * @param {Event} e 928 * @param {Object} fragments 929 * @param {string} cart_hash 930 * @param {Element} $button 931 * @return 932 */ 933 hide_quantity_roller(e, fragments, cart_hash, $button) { 934 const product_id = $button.attr('data-product_id') || $button.attr('data-orderable-product-id'); 935 if (!product_id) { 936 return; 937 } 938 const $actions_button = $('.orderable-product[data-orderable-product-id=' + product_id + '] .orderable-product__actions-button'); 939 if (!$actions_button.length) { 940 return; 941 } 942 const $quantity_roller = $actions_button.find('.orderable-quantity-roller'); 943 if ($quantity_roller.length) { 944 $actions_button.find('button.orderable-product__add-to-order[data-orderable-trigger]').removeClass('orderable-button--product-in-the-cart'); 945 $quantity_roller.addClass('orderable-button--hide'); 946 } 947 }, 948 /** 949 * Add unchecked checkboxs to the list of inputs 950 * sent to the request to add/update an item 951 * 952 * @param {Object} inputs 953 * @return {Object} 954 */ 955 add_unchecked_checkbox_fields(inputs) { 956 jQuery('.orderable-product-fields-group :input[type="checkbox"]:not(:checked)').each(function (index, element) { 957 inputs.push({ 958 name: element.getAttribute('name'), 959 value: '' 960 }); 961 }); 962 return inputs; 963 }, 964 /** 965 * Shake the floating cart button. 966 * 967 * @return void 968 */ 969 shake_floating_cart() { 970 $('.orderable-floating-cart__button').css('animation', 'wobble-hor-bottom .8s both'); 971 }, 972 /** 973 * Remove the view cart link. 974 * 975 * @param event 976 * @param $button 977 */ 978 remove_view_cart_link(event, $button) { 979 if (!$button?.hasClass('orderable-product__add-to-order')) { 980 return; 981 } 982 $button?.siblings('.added_to_cart.wc-forward').remove(); 983 } 984 }; 985 $(document).ready(orderable_products.on_ready); 986 })(jQuery, document); 987 (function ($, document) { 988 'use strict'; 989 990 var orderable_scrollbar = { 991 /** 992 * On doc ready. 993 */ 994 on_ready() { 995 orderable_scrollbar.cache(); 996 orderable_scrollbar.watch(); 997 }, 998 /** 999 * Cache. 1000 */ 1001 cache() { 1002 orderable_scrollbar.vars = { 1003 top: {} 1004 }; 1005 orderable_scrollbar.elements = {}; 1006 }, 1007 /** 1008 * Watch. 1009 */ 1010 watch() { 1011 $(document.body).on('orderable-drawer.opened', orderable_scrollbar.trigger); 1012 $(document.body).on('orderable-tabs.changed', orderable_scrollbar.trigger); 1013 $(document.body).on('orderable-accordion.toggled', orderable_scrollbar.trigger); 1014 $(document.body).on('wc_fragments_loaded', orderable_scrollbar.trigger); 1015 }, 1016 /** 1017 * Init or retrigger scrollbars. 1018 */ 1019 trigger() { 1020 $('.orderable-sb-container').each(function (index, element) { 1021 const $element = $(element), 1022 scroll_id = $element.data('orderable-scroll-id'); 1023 if (!orderable_scrollbar.has_scrollbar($element)) { 1024 $element.scrollBox({ 1025 containerClass: 'orderable-sb-container', 1026 containerNoScrollClass: 'orderable-sb-container-noscroll', 1027 contentClass: 'orderable-sb-content', 1028 scrollbarContainerClass: 'orderable-sb-scrollbar-container', 1029 scrollBarClass: 'orderable-sb-scrollbar' 1030 }); 1031 const $content = $element.find('.orderable-sb-content'); 1032 if ($content.length > 0) { 1033 $content.on('scroll.scrollBox', orderable_scrollbar.log_top_position); 1034 1035 // Set scroll position. 1036 if (typeof orderable_scrollbar.vars.top[scroll_id] !== 'undefined') { 1037 $content.scrollTop(orderable_scrollbar.vars.top[scroll_id]); 1038 } 1039 } 1040 $(document.body).trigger('orderable-scrollbar.created', { 1041 element: $element, 1042 content: $content 1043 }); 1044 } 1045 }); 1046 $(window).trigger('resize.scrollBox'); 1047 }, 1048 /** 1049 * Has scrollbar already? 1050 * 1051 * @param $element 1052 * @return {boolean} 1053 */ 1054 has_scrollbar($element) { 1055 return $element.find('.orderable-sb-content').length > 0; 1056 }, 1057 /** 1058 * Set scrolltop position. 1059 * 1060 * @param e 1061 */ 1062 log_top_position(e) { 1063 const $element = $(e.currentTarget), 1064 $container = $element.closest('.orderable-sb-container'), 1065 scroll_id = $container.data('orderable-scroll-id'); 1066 orderable_scrollbar.vars.top[scroll_id] = $(e.currentTarget).scrollTop(); 1067 } 1068 }; 1069 $(document).ready(orderable_scrollbar.on_ready); 1070 })(jQuery, document); 1071 (function ($, document) { 1072 'use strict'; 1073 1074 var orderable_tabs = { 1075 /** 1076 * On doc ready. 1077 */ 1078 on_ready() { 1079 orderable_tabs.cache(); 1080 orderable_tabs.watch(); 1081 orderable_tabs.toggle_scroll(); 1082 }, 1083 /** 1084 * On resize. 1085 */ 1086 on_resize() { 1087 if (typeof orderable_tabs.vars === 'undefined') { 1088 orderable_tabs.cache(); 1089 } 1090 orderable_tabs.toggle_scroll(); 1091 }, 1092 /** 1093 * Cache. 1094 */ 1095 cache() { 1096 orderable_tabs.vars = { 1097 classes: { 1098 tabs: 'orderable-tabs', 1099 tabs_list: 'orderable-tabs__list', 1100 tab_items: 'orderable-tabs__item', 1101 tab_item_active: 'orderable-tabs__item--active', 1102 tab_links: 'orderable-tabs__link', 1103 tab_arrow_right: 'orderable-tabs__arrow-right', 1104 tab_arrow_left: 'orderable-tabs__arrow-left' 1105 }, 1106 dragging: false 1107 }; 1108 orderable_tabs.elements = {}; 1109 }, 1110 /** 1111 * Watch. 1112 */ 1113 watch() { 1114 $('body').on('touchstart', function () { 1115 orderable_tabs.vars.dragging = false; 1116 }).on('touchmove', function () { 1117 orderable_tabs.vars.dragging = true; 1118 }); 1119 $(document.body).on('click mouseup touchend', '.' + orderable_tabs.vars.classes.tab_links, function (e) { 1120 if (orderable_tabs.vars.dragging) { 1121 return; 1122 } 1123 e.preventDefault(); 1124 const $link = $(this), 1125 section_id = $link.attr('href'), 1126 $tab = $link.closest('.' + orderable_tabs.vars.classes.tab_items), 1127 $tabs = $link.closest('.' + orderable_tabs.vars.classes.tabs), 1128 $tabs_list = $tabs.find('.' + orderable_tabs.vars.classes.tabs_list), 1129 $tab_items = $tabs.find('.' + orderable_tabs.vars.classes.tab_items), 1130 tabs_args = $tabs.data('orderable-tabs'), 1131 $wrapper = $link.closest(tabs_args.wrapper), 1132 $sections = $wrapper.find(tabs_args.sections), 1133 $section = $wrapper.find(section_id); 1134 $sections.hide(); 1135 $section.show(); 1136 $tab_items.removeClass(orderable_tabs.vars.classes.tab_item_active); 1137 $tab.addClass(orderable_tabs.vars.classes.tab_item_active); 1138 $tabs_list.animate({ 1139 scrollLeft: $tabs_list.scrollLeft() + $tab.position().left 1140 }); 1141 $(document.body).trigger('orderable-tabs.changed', { 1142 tab: $tab 1143 }); 1144 }); 1145 1146 /** 1147 * Watch scroll position of tabs. 1148 */ 1149 $('.' + orderable_tabs.vars.classes.tabs_list).on('scroll', function (e) { 1150 const $list = $(this), 1151 $wrapper = $list.parent('.' + orderable_tabs.vars.classes.tabs), 1152 $arrow_right = $list.siblings('.' + orderable_tabs.vars.classes.tab_arrow_right), 1153 $arrow_left = $list.siblings('.' + orderable_tabs.vars.classes.tab_arrow_left); 1154 if ($list[0].scrollWidth <= $wrapper.width() + $list.scrollLeft()) { 1155 $arrow_right.fadeOut(); 1156 } else { 1157 $arrow_right.fadeIn(); 1158 } 1159 if (0 >= $list.scrollLeft() - $arrow_left.width()) { 1160 $arrow_left.fadeOut(); 1161 } else { 1162 $arrow_left.fadeIn(); 1163 } 1164 }); 1165 1166 /** 1167 * Stop animated scroll if user manually scrolls. 1168 */ 1169 $('.' + orderable_tabs.vars.classes.tabs_list).on('wheel DOMMouseScroll mousewheel touchmove', function () { 1170 $(this).stop(); 1171 }); 1172 1173 /** 1174 * Click tab arrow right. 1175 */ 1176 $(document).on('click', '.' + orderable_tabs.vars.classes.tab_arrow_right, function (e) { 1177 e.preventDefault(); 1178 const $arrow = $(this), 1179 $wrapper = $arrow.parent(), 1180 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list); 1181 $list.animate({ 1182 scrollLeft: $list.scrollLeft() + $wrapper.width() * 0.5 1183 }); 1184 }); 1185 1186 /** 1187 * Click tab arrow left. 1188 */ 1189 $(document).on('click', '.' + orderable_tabs.vars.classes.tab_arrow_left, function (e) { 1190 e.preventDefault(); 1191 const $arrow = $(this), 1192 $wrapper = $arrow.parent(), 1193 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list); 1194 $list.animate({ 1195 scrollLeft: $list.scrollLeft() - $wrapper.width() * 0.5 1196 }); 1197 }); 1198 }, 1199 /** 1200 * Toggle scroll arrow. 1201 */ 1202 toggle_scroll() { 1203 $('.' + orderable_tabs.vars.classes.tabs).each(function (index, wrapper) { 1204 const $tabs = $(this), 1205 tabs_args = $tabs.data('orderable-tabs'), 1206 $wrapper = $tabs.closest(tabs_args.wrapper), 1207 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list), 1208 $arrow_right = $wrapper.find('.' + orderable_tabs.vars.classes.tab_arrow_right), 1209 wrapper_width = $wrapper.outerWidth(), 1210 list_width = $list[0].scrollWidth; 1211 if (list_width > wrapper_width) { 1212 $arrow_right.show(); 1213 } else { 1214 $arrow_right.hide(); 1215 } 1216 }); 1217 } 1218 }; 1219 $(document).ready(orderable_tabs.on_ready); 1220 $(window).on('resize', orderable_tabs.on_resize); 1221 })(jQuery, document); 1222 let orderable_timings = {}; // Make this global so pro modules can access it. 1223 1224 (function ($, document) { 1225 'use strict'; 1226 1227 orderable_timings = { 1228 /** 1229 * On doc ready. 1230 */ 1231 on_ready() { 1232 orderable_timings.watch(); 1233 }, 1234 /** 1235 * Restore current timings. 1236 */ 1237 restore() { 1238 const timings = orderable_timings.get_timings(); 1239 if (!timings || !timings.date) { 1240 return; 1241 } 1242 const dateSelect = $('.orderable-order-timings__date'); 1243 if (dateSelect.find('option[value="' + timings.date + '"]').length > 0) { 1244 dateSelect.val(timings.date); 1245 dateSelect.change(); 1246 } 1247 if (!timings.time) { 1248 return; 1249 } 1250 const timeSelect = $('.orderable-order-timings__time'); 1251 if (timeSelect.find('option[value="' + timings.time + '"]').length > 0) { 1252 timeSelect.val(timings.time); 1253 timeSelect.change(); 1254 } 1255 }, 1256 /** 1257 * Watch for trigger events. 1258 */ 1259 watch() { 1260 $(document.body).on('wc_fragments_refreshed', function () { 1261 orderable_timings.restore(); 1262 }); 1263 $(document.body).on('updated_checkout', function () { 1264 orderable_timings.restore(); 1265 }); 1266 $(document.body).on('change', '.orderable-order-timings__date', function (event) { 1267 const $date_field = $(this), 1268 $selected = $date_field.find('option:selected'), 1269 slots = $selected.data('orderable-slots'), 1270 $time_field_wrap = $('.orderable-order-timings--time'), 1271 $time_field = $('.orderable-order-timings__time'), 1272 $first_option = $time_field.find('option').first(), 1273 $asap_option = $time_field.find('option[value="asap"]').first(); 1274 const timings = orderable_timings.get_timings(); 1275 timings.date = $('.orderable-order-timings__date').val(); 1276 window.localStorage.setItem('orderable_timings', JSON.stringify(timings)); 1277 $time_field.html($first_option); 1278 if ($asap_option) { 1279 $time_field.append($asap_option); 1280 } 1281 if (!slots) { 1282 $time_field.prop('disabled', true); 1283 $time_field_wrap.hide(); 1284 return; 1285 } 1286 if ('all-day' === slots[0].value) { 1287 $time_field_wrap.hide(); 1288 $time_field.prop('disabled', true); 1289 } else { 1290 $time_field.prop('disabled', false); 1291 $time_field_wrap.show(); 1292 $.each(slots, function (index, slot) { 1293 $time_field.append($('<option />').attr('value', slot.value).attr('data-orderable-time-slot-id', slot?.setting_row?.time_slot_id).text(slot.formatted)); 1294 }); 1295 } 1296 }); 1297 $(document.body).on('change', '.orderable-order-timings__time', function (event) { 1298 const timings = orderable_timings.get_timings(); 1299 timings.time = $('.orderable-order-timings__time').val(); 1300 window.localStorage.setItem('orderable_timings', JSON.stringify(timings)); 1301 $(this).siblings('input[name="orderable_order_time_slot_id"]').val($(this).find(':selected').attr('data-orderable-time-slot-id')); 1302 }); 1303 }, 1304 get_timings() { 1305 return JSON.parse(window.localStorage.getItem('orderable_timings')) || {}; 1306 } 1307 }; 1308 $(document).ready(orderable_timings.on_ready); 1309 })(jQuery, document); 1310 (function ($, document) { 1311 'use strict'; 1312 1313 var orderable_triggers = { 1314 /** 1315 * On doc ready. 1316 */ 1317 on_ready() { 1318 orderable_triggers.watch(); 1319 }, 1320 /** 1321 * Watch for trigger events. 1322 */ 1323 watch() { 1324 if ('undefined' !== typeof window.orderable_triggers_admin) { 1325 return; 1326 } 1327 $(document.body).on('click', '[data-orderable-trigger]', orderable_triggers.trigger); 1328 }, 1329 /** 1330 * Fire trigger. 1331 * @param e 1332 */ 1333 trigger(e) { 1334 // Prevent even bubbling up. 1335 e.stopImmediatePropagation(); 1336 const $trigger_element = $(this), 1337 trigger = $trigger_element.data('orderable-trigger'); 1338 if ($trigger_element.is('button') || $trigger_element.is('a')) { 1339 e.preventDefault(); 1340 } 1341 $(document.body).trigger('orderable-' + trigger, [$trigger_element]); 1342 } 1343 }; 1344 $(document).ready(orderable_triggers.on_ready); 1345 })(jQuery, document); 2 1346 /** 3 1347 * jQiery scrollBar Plugin … … 177 1521 } 178 1522 }(window, document); 179 (function ($, document) {180 'use strict';181 182 var orderable_accordion = {183 /**184 * On doc ready.185 */186 on_ready() {187 orderable_accordion.cache();188 orderable_accordion.watch();189 },190 /**191 * Cache.192 */193 cache() {194 orderable_accordion.vars = {195 classes: {196 parent: 'orderable-accordion',197 link: 'orderable-accordion__item-link',198 content: 'orderable-accordion__item-content',199 link_active: 'orderable-accordion__item-link--active',200 content_active: 'orderable-accordion__item-content--active'201 }202 };203 },204 /**205 * Watch.206 */207 watch() {208 /**209 * When click accordion link.210 */211 $(document.body).on('click', '.' + orderable_accordion.vars.classes.link, function (e) {212 e.preventDefault();213 const $link = $(this),214 $parent = $link.closest('.' + orderable_accordion.vars.classes.parent),215 content_id = $link.attr('href'),216 $content = $(content_id),217 is_active = $link.hasClass(orderable_accordion.vars.classes.link_active);218 $parent.find('.' + orderable_accordion.vars.classes.link).removeClass(orderable_accordion.vars.classes.link_active);219 $parent.find('.' + orderable_accordion.vars.classes.content).removeClass(orderable_accordion.vars.classes.content_active);220 if (!is_active) {221 $link.addClass(orderable_accordion.vars.classes.link_active);222 $content.addClass(orderable_accordion.vars.classes.content_active);223 }224 $(document.body).trigger('orderable-accordion.toggled', {225 link: $link,226 content: $content227 });228 });229 230 /**231 * When drawer is opened.232 */233 $(document.body).on('orderable-scrollbar.created', function (e, args) {234 const $active_accordion = $('.orderable-drawer .' + orderable_accordion.vars.classes.link_active);235 if ($active_accordion.length <= 0) {236 return;237 }238 const $scroll_content = args.content,239 scroll_position = $scroll_content.scrollTop() - $scroll_content.offset().top + $active_accordion.offset().top;240 $scroll_content.scrollTop(scroll_position);241 });242 }243 };244 $(document).ready(orderable_accordion.on_ready);245 })(jQuery, document);246 (function ($, document) {247 'use strict';248 249 var orderable_drawer = {250 /**251 * Delays invoking function252 *253 * @param {Function} func The function to debounce.254 * @param {number} timeout The number of milliseconds to delay.255 * @return {Function} Returns the new debounced function.256 */257 debounce(func, timeout = 700) {258 let timer;259 return (...args) => {260 clearTimeout(timer);261 timer = setTimeout(() => {262 func.apply(this, args);263 }, timeout);264 };265 },266 /**267 * Allow only number for events like keypress268 *269 * @param {Event} event270 */271 allow_only_numbers(event) {272 const value = String.fromCharCode(event.which);273 if (!/^\d+$/.test(value)) {274 event.preventDefault();275 }276 },277 /**278 * Send a request to change the quantity.279 *280 * @param {Event} event281 */282 on_change_quantity(event) {283 const quantityElement = $(event.currentTarget);284 const product_id = quantityElement.data('orderable-product-id');285 const cart_item_key = quantityElement.data('orderable-cart-item-key');286 const quantity = parseInt(quantityElement.text());287 const data = {288 action: 'orderable_cart_quantity',289 cart_item_key,290 product_id,291 quantity292 };293 jQuery.post(orderable_vars.ajax_url, data, function (response) {294 if (!response) {295 return;296 }297 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, quantityElement]);298 $(document.body).trigger('orderable-drawer.quantity-updated');299 });300 },301 /**302 * On doc ready.303 */304 on_ready() {305 orderable_drawer.cache();306 orderable_drawer.watch();307 308 /**309 * Handle manually changing the quantity of a product.310 */311 $(document.body).on('keypress', '.orderable-quantity-roller__quantity', orderable_drawer.allow_only_numbers);312 $('.orderable-drawer__cart, .orderable-product--add-to-cart, .orderable-products-list').on('input', '.orderable-quantity-roller__quantity', orderable_drawer.debounce(orderable_drawer.on_change_quantity));313 $(document.body).on('click', '.orderable-quantity-roller__quantity', function (event) {314 event.stopPropagation();315 });316 317 /**318 * We turn off the click event for .add_to_cart_button elements319 * to keep the AJAX behaviour only on Mini cart when the option320 * "Enable AJAX add to cart buttons on archives" is disabled.321 */322 if (orderable_vars && !orderable_vars.woocommerce_enable_ajax_add_to_cart) {323 $(document.body).off('click', '.add_to_cart_button');324 }325 },326 /**327 * Cache.328 */329 cache() {330 orderable_drawer.vars = {331 classes: {332 overlay: 'orderable-drawer-overlay',333 drawer: 'orderable-drawer',334 drawer_cart: 'orderable-drawer__cart',335 drawer_html: 'orderable-drawer__html',336 overlay_open: 'orderable-drawer-overlay--open',337 drawer_open: 'orderable-drawer--open',338 drawer_open_body: 'orderable-drawer-open'339 }340 };341 orderable_drawer.elements = {342 body: $('body'),343 overlay: $('.' + orderable_drawer.vars.classes.overlay),344 drawer: $('.' + orderable_drawer.vars.classes.drawer),345 drawer_cart: $('.' + orderable_drawer.vars.classes.drawer_cart),346 drawer_html: $('.' + orderable_drawer.vars.classes.drawer_html),347 floating_cart_button_class: '.orderable-floating-cart__button'348 };349 },350 /**351 * Watch for trigger events.352 */353 watch() {354 if (typeof orderable_drawer.elements.drawer === 'undefined') {355 return;356 }357 $(document.body).on('orderable-drawer.open', orderable_drawer.open);358 $(document.body).on('orderable-drawer.close', orderable_drawer.close);359 $(document.body).on('click', orderable_drawer.elements.floating_cart_button_class, function () {360 $(document.body).trigger('orderable-drawer.open', {361 show_cart: true362 });363 });364 $(document.body).on('orderable-increase-quantity', orderable_drawer.cart.handle_quantity_change_by_button);365 $(document.body).on('orderable-decrease-quantity', orderable_drawer.cart.handle_quantity_change_by_button);366 const updateQuantityRequest = orderable_drawer.debounce(orderable_drawer.cart.click_increase_decrease_quantity);367 $(document.body).on('orderable-increase-quantity', updateQuantityRequest);368 $(document.body).on('orderable-decrease-quantity', updateQuantityRequest);369 const drawer = document.querySelector('body:not( .rtl ) .orderable-drawer');370 const drawer_rtl = document.querySelector('body.rtl .orderable-drawer');371 if (drawer) {372 drawer.addEventListener('swiped-right', function (e) {373 orderable_drawer.close();374 });375 }376 if (drawer_rtl) {377 drawer_rtl.addEventListener('swiped-left', function (e) {378 orderable_drawer.close();379 });380 }381 },382 /**383 * Open the drawer.384 * @param event385 * @param args386 */387 open(event, args) {388 args.html = args.html || false;389 args.show_cart = args.show_cart || false;390 orderable_drawer.elements.drawer_html.hide();391 orderable_drawer.elements.drawer_cart.hide();392 if (args.html) {393 orderable_drawer.elements.drawer_html.html(args.html);394 orderable_drawer.elements.drawer_html.show();395 }396 if (args.show_cart) {397 // Empty drawer HTML before showing cart. Prevents options398 // interfering with subsequent cart additions.399 orderable_drawer.elements.drawer_html.html('');400 orderable_drawer.elements.drawer_cart.show();401 }402 orderable_drawer.elements.overlay.addClass(orderable_drawer.vars.classes.overlay_open);403 orderable_drawer.elements.drawer.addClass(orderable_drawer.vars.classes.drawer_open);404 orderable_drawer.elements.body.addClass(orderable_drawer.vars.classes.drawer_open_body);405 $(document.body).trigger('orderable-drawer.opened', args);406 },407 /**408 * Close the drawer.409 */410 close() {411 orderable_drawer.elements.overlay.removeClass(orderable_drawer.vars.classes.overlay_open);412 orderable_drawer.elements.drawer.removeClass(orderable_drawer.vars.classes.drawer_open);413 orderable_drawer.elements.body.removeClass(orderable_drawer.vars.classes.drawer_open_body);414 orderable_drawer.elements.drawer_html.html('');415 $(document.body).trigger('orderable-drawer.closed');416 },417 /**418 * Mini cart related functions.419 */420 cart: {421 /**422 * When increase qty is clicked.423 *424 * @param e425 * @param $button426 */427 click_increase_decrease_quantity(e, $button) {428 const direction = $button.data('orderable-trigger');429 const product_id = $button.attr('data-orderable-product-id'),430 cart_item_key = $button.attr('data-orderable-cart-item-key'),431 quantity = $button.attr('data-orderable-quantity');432 const siblingButtonName = 'increase-quantity' === direction ? 'decrease' : 'increase';433 const $siblingButton = $button.siblings(`.orderable-quantity-roller__button--${siblingButtonName}`);434 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity');435 const data = {436 action: 'orderable_cart_quantity',437 cart_item_key,438 product_id,439 quantity440 };441 if (this.currentRequest) {442 this.currentRequest.abort();443 this.currentRequest = undefined;444 }445 $button.addClass('orderable-button--loading');446 $button.attr('disabled', true);447 $siblingButton.attr('disabled', true);448 $quantityElement.attr('contenteditable', false);449 this.currentRequest = jQuery.post(orderable_vars.ajax_url, data, function (response) {450 if (!response) {451 return;452 }453 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity');454 if (response && response.fragments && response.fragments['.orderable-mini-cart__notices']) {455 $(document.body).trigger('orderable-drawer.open', {456 show_cart: true457 });458 }459 switch (data.quantity) {460 case '0':461 $(document.body).trigger('removed_from_cart', [response.fragments, response.cart_hash, $button]);462 break;463 case $quantityElement.attr('data-orderable-updating-quantity'):464 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $button]);465 $(document.body).trigger('orderable-drawer.quantity-updated');466 break;467 default:468 break;469 }470 }.bind(this)).always(function () {471 this.currentRequest = undefined;472 $button.removeClass('orderable-button--loading');473 $button.attr('disabled', false);474 $siblingButton.attr('disabled', false);475 $quantityElement.attr('contenteditable', true);476 }.bind(this));477 },478 handle_quantity_change_by_button(e, $button) {479 const direction = $button.data('orderable-trigger');480 const quantity = parseInt($button.attr('data-orderable-quantity'));481 const siblingButtonName = 'increase-quantity' === direction ? 'decrease' : 'increase';482 const $siblingButton = $button.siblings(`.orderable-quantity-roller__button--${siblingButtonName}`);483 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity');484 const newQuantity = 'increase-quantity' === direction ? quantity + 1 : Math.max(0, quantity - 1);485 const $parent = $button.parents('.orderable-product__actions-button');486 if (0 === newQuantity && $parent.length) {487 const $addToCartButton = $parent.find('button.orderable-button[data-orderable-trigger]');488 const $quantityRoller = $parent.find('.orderable-quantity-roller');489 if ($quantityRoller.length) {490 $addToCartButton.removeClass('orderable-button--product-in-the-cart');491 $quantityRoller.removeClass('orderable-quantity-roller--is-active');492 }493 }494 $button.attr('data-orderable-quantity', newQuantity);495 $siblingButton.attr('data-orderable-quantity', newQuantity);496 $quantityElement.attr('data-orderable-updating-quantity', newQuantity);497 $quantityElement.text(newQuantity);498 $quantityElement.attr('contenteditable', false);499 }500 }501 };502 $(document).ready(orderable_drawer.on_ready);503 })(jQuery, document);504 (function ($, document) {505 'use strict';506 507 var orderable_products = {508 /**509 * On doc ready.510 */511 on_ready() {512 orderable_products.cache();513 orderable_products.watch();514 },515 /**516 * Cache.517 */518 cache() {519 orderable_products.vars = {520 classes: {521 clickable_product: 'orderable-product--add-to-cart ',522 add_to_order_button: 'orderable-product__add-to-order',523 product_messages: 'orderable-product__messages',524 product_price: 'orderable-product__actions-price',525 invalid_field: 'orderable-field--invalid',526 option_select_td: 'orderable-product__option-select',527 button_loading: 'orderable-button--loading',528 out_of_stock: 'orderable-button--out-of-stock'529 },530 parent_price: null,531 variable_product_types: ['variable', 'variable-subscription']532 };533 orderable_products.elements = {};534 },535 /**536 * Watch for trigger events.537 */538 watch() {539 $(document.body).on('orderable-drawer.opened', orderable_products.init_product_options);540 $(document.body).on('orderable-add-to-cart', orderable_products.click_add_to_order);541 $(document.body).on('orderable-product-options', orderable_products.click_add_to_order);542 $(document.body).on('orderable-view-product', orderable_products.view_product);543 $(document.body).on('mouseenter mouseleave', '.' + orderable_products.vars.classes.clickable_product, orderable_products.simulate_add_to_order_hover);544 $(document.body).on('orderable-edit-cart-item', orderable_products.edit_cart_item);545 $(document.body).on('orderable-update-cart-item', orderable_products.update_cart_item);546 $(document.body).on('orderable-show-cart', orderable_products.show_cart);547 $(document.body).on('orderable-add-to-cart-without-side-drawer', orderable_products.click_add_to_order);548 $(document.body).on('added_to_cart', orderable_products.remove_fragments);549 $(document.body).on('added_to_cart', orderable_products.remove_animation);550 $(document.body).on('added_to_cart', orderable_products.shake_floating_cart);551 $(document.body).on('removed_from_cart', orderable_products.hide_quantity_roller);552 $(document.body).on('wc_cart_button_updated', orderable_products.remove_view_cart_link);553 },554 /**555 * Simulate hover on add to order button.556 *557 * @param event558 */559 simulate_add_to_order_hover(event) {560 const $element = $(this),561 $button = $element.find('.' + orderable_products.vars.classes.add_to_order_button);562 $button.toggleClass('orderable-button--hover', 'mouseenter' === event.type);563 },564 /**565 * Add to order click event.566 *567 * This event accounts for button clicks or card clicks.568 * @param event569 * @param $element570 */571 click_add_to_order(event, $element) {572 // If undefined, it means it was triggered by a click573 // event and not the `orderable-add-to-cart` trigger.574 $element = typeof $element !== 'undefined' ? $element : $(this);575 576 // The button is either the clicked element, or the577 // add to order button within the clicked element.578 const $button = $element.is('button') ? $element : $element.find('.' + orderable_products.vars.classes.add_to_order_button),579 action = $button.data('orderable-trigger'),580 product_id = $button.data('orderable-product-id'),581 variation_id = $button.data('orderable-variation-id'),582 attributes = $button.data('orderable-variation-attributes'),583 args = {584 action585 };586 if ($button.hasClass(orderable_products.vars.classes.button_loading) || $button.hasClass(orderable_products.vars.classes.out_of_stock)) {587 return;588 }589 $button.addClass(orderable_products.vars.classes.button_loading);590 switch (action) {591 case 'add-to-cart':592 orderable_products.add_to_cart({593 product_id,594 variation_id,595 attributes,596 thisbutton: $element597 }, function (response) {598 args.show_cart = true;599 args.response = response;600 $(document.body).trigger('orderable-drawer.open', args);601 $button.removeClass(orderable_products.vars.classes.button_loading);602 const $addToCartButtonOutsideDrawer = $('.orderable-product .orderable-product__actions-button button.orderable-product__add-to-order[data-orderable-product-id=' + product_id + ']');603 if ($addToCartButtonOutsideDrawer.siblings('.orderable-quantity-roller').length) {604 $addToCartButtonOutsideDrawer.addClass('orderable-button--product-in-the-cart');605 }606 });607 break;608 case 'add-to-cart-without-side-drawer':609 orderable_products.add_to_cart({610 product_id,611 variation_id,612 attributes613 }, function (response) {614 args.response = response;615 $button.addClass('orderable-button--product-in-the-cart');616 $button.removeClass(orderable_products.vars.classes.button_loading);617 });618 break;619 case 'product-options':620 orderable_products.get_product_options({621 product_id,622 focus: $button.data('orderable-focus')623 }, function (response) {624 args.html = response.html;625 $(document.body).trigger('orderable-drawer.open', args);626 $button.removeClass(orderable_products.vars.classes.button_loading);627 });628 break;629 default:630 break;631 }632 },633 /**634 * Show the cart.635 */636 show_cart() {637 $(document.body).trigger('orderable-drawer.open', {638 show_cart: true639 });640 },641 /**642 * View product.643 *644 * @param event645 * @param $element646 */647 view_product(event, $element) {648 const product_id = $element.data('orderable-product-id'),649 args = {650 action: 'product-options'651 };652 orderable_products.get_product_options({653 product_id,654 focus: $element.data('orderable-focus')655 }, function (response) {656 args.html = response.html;657 $(document.body).trigger('orderable-drawer.open', args);658 });659 },660 /**661 * Ajax add to cart.662 * @param args663 * @param callback664 */665 add_to_cart(args, callback) {666 if (typeof args.product_id === 'undefined') {667 return;668 }669 let data = {670 action: 'orderable_add_to_cart',671 product_id: args.product_id,672 variation_id: args.variation_id || false,673 attributes: args.attributes || false674 };675 676 // Prepare addons data.677 if ($('.orderable-product-fields-group').length) {678 let inputs = jQuery('.orderable-product-fields-group :input').serializeArray();679 inputs = orderable_products.add_unchecked_checkbox_fields(inputs);680 const addons_data = orderable_products.convert_to_flat_object(inputs);681 if (!jQuery.isEmptyObject(addons_data)) {682 data = Object.assign(data, addons_data); // Merge objects.683 }684 }685 jQuery.post(orderable_vars.ajax_url, data, function (response) {686 if (!response) {687 return;688 }689 690 // Trigger event so themes can refresh other areas.691 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, args.thisbutton]);692 if (typeof callback === 'function') {693 callback(response);694 }695 });696 },697 /**698 * Edit cart item.699 *700 * @param event701 * @param $element702 */703 edit_cart_item(event, $element) {704 const cart_item_key = $element.data('orderable-cart-item-key');705 $element.addClass(orderable_products.vars.classes.button_loading);706 orderable_products.get_cart_item_options({707 cart_item_key708 }, function (response) {709 const args = {710 html: response.html,711 action: 'update-cart-item'712 };713 $(document.body).trigger('orderable-drawer.open', args);714 $element.removeClass(orderable_products.vars.classes.button_loading);715 });716 },717 /**718 * Update cart item.719 *720 * @param event721 * @param $element722 */723 update_cart_item(event, $element) {724 const cart_item_key = $element.data('orderable-cart-item-key');725 const product_id = $element.data('orderable-product-id');726 const variation_id = $element.data('orderable-variation-id');727 const attributes = $element.data('orderable-variation-attributes');728 $element.addClass(orderable_products.vars.classes.button_loading);729 orderable_products.update_cart_item_options({730 cart_item_key,731 product_id,732 variation_id,733 attributes734 }, function (response) {735 const args = {736 show_cart: true,737 response738 };739 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash]);740 $(document.body).trigger('orderable-drawer.open', args);741 $element.removeClass(orderable_products.vars.classes.button_loading);742 });743 },744 /**745 * Convert [{name:x, value:y }] to {x:y} format.746 * @param inputs747 */748 convert_to_flat_object(inputs) {749 const data = {};750 inputs.forEach(function (input) {751 const is_array = '[]' === input.name.substr(-2) || Array.isArray(input.name);752 // If last 2 chars are '[]', remove them.753 const key = is_array ? input.name.substr(0, input.name.length - 2) : input.name;754 if (is_array) {755 data[key] = typeof data[key] === 'undefined' ? [] : data[key];756 data[key].push(input.value);757 } else {758 data[key] = input.value;759 }760 });761 return data;762 },763 /**764 * Get variable product options.765 *766 * @param args767 * @param callback768 */769 get_product_options(args, callback) {770 if (typeof args.product_id === 'undefined') {771 return;772 }773 args.action = 'orderable_get_product_options';774 jQuery.post(orderable_vars.ajax_url, args, function (response) {775 if (!response.success) {776 return;777 }778 if (typeof callback === 'function') {779 callback(response.data);780 }781 });782 },783 /**784 * Get variable product options.785 *786 * @param args787 * @param callback788 */789 get_cart_item_options(args, callback) {790 if (typeof args.cart_item_key === 'undefined') {791 return;792 }793 args.action = 'orderable_get_cart_item_options';794 jQuery.post(orderable_vars.ajax_url, args, function (response) {795 if (!response.success) {796 return;797 }798 if (typeof callback === 'function') {799 callback(response.data);800 }801 });802 },803 /**804 * Update variable product options.805 *806 * @param args807 * @param callback808 */809 update_cart_item_options(args, callback) {810 if (typeof args.cart_item_key === 'undefined') {811 return;812 }813 args.action = 'orderable_update_cart_item_options';814 815 // Prepare addons data.816 if ($('.orderable-product-fields-group').length) {817 let inputs = jQuery('.orderable-product-fields-group :input').serializeArray();818 inputs = orderable_products.add_unchecked_checkbox_fields(inputs);819 const addons_data = orderable_products.convert_to_flat_object(inputs);820 if (!jQuery.isEmptyObject(addons_data)) {821 args = Object.assign(args, addons_data); // Merge objects.822 }823 }824 jQuery.post(orderable_vars.ajax_url, args, function (response) {825 if (!response) {826 return;827 }828 if (typeof callback === 'function') {829 callback(response);830 }831 });832 },833 /**834 * Init drawer product options.835 *836 * @param event837 * @param args838 */839 init_product_options(event, args) {840 if (typeof args.action === 'undefined' || 'product-options' !== args.action && 'update-cart-item' !== args.action) {841 return;842 }843 const selectors = '.orderable-drawer .orderable-product__options input, .orderable-drawer .orderable-product__options select, .orderable-product__options textarea';844 const $options = $(selectors);845 orderable_products.vars.parent_price = $('.orderable-drawer .orderable-product__actions-price').html();846 orderable_products.product_options_change($options);847 orderable_products.update_button_state();848 const debounced_update_button_state = orderable_products.debounce(orderable_products.update_button_state, 500);849 const debounced_product_options_change = orderable_products.debounce(orderable_products.product_options_change, 500);850 $(document).on('change keyup', selectors, function () {851 debounced_product_options_change($options);852 debounced_update_button_state();853 });854 },855 /**856 * On product options change.857 *858 * @param $options859 */860 product_options_change($options) {861 const $add_to_order_button = $('.orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item'),862 options_set = orderable_products.check_options($options),863 product_type = $add_to_order_button.data('orderable-product-type');864 if ('product-options' === $add_to_order_button.attr('data-orderable-trigger')) {865 $add_to_order_button.attr('data-orderable-trigger', 'add-to-cart');866 }867 $('.' + orderable_products.vars.classes.product_messages).html('');868 if (!orderable_products.vars.variable_product_types.includes(product_type)) {869 return;870 }871 if (!options_set) {872 orderable_products.clear_variation($add_to_order_button);873 return;874 }875 const variation = orderable_products.check_variation($options);876 orderable_products.set_variation($add_to_order_button, variation);877 },878 /**879 * Check if all product options are set.880 *881 * @param $options882 * @return {boolean}883 */884 check_options($options) {885 if ($options.length <= 0) {886 return false;887 }888 let all_set = true;889 $options.each(function (index, option) {890 // Only check attribute fields.891 if (!$(option).hasClass('orderable-input--validate')) {892 return;893 }894 if ('' === $(option).val()) {895 $(option).addClass(orderable_products.vars.classes.invalid_field);896 all_set = false;897 } else {898 $(option).removeClass(orderable_products.vars.classes.invalid_field);899 }900 });901 return all_set;902 },903 /**904 * Check if variation has been selected.905 * @param $options906 */907 check_variation($options) {908 const $product = $options.closest('.orderable-drawer');909 let variations = $product.find('.orderable-product__variations').text();910 variations = variations ? JSON.parse(variations) : '';911 const selected_options = orderable_products.serialize_object($options),912 matching_variations = orderable_products.find_matching_variations(variations, selected_options);913 if (orderable_products.is_empty(matching_variations)) {914 return false;915 }916 const variation = matching_variations.shift();917 variation.attributes = selected_options;918 variation.attributes_json = JSON.stringify(selected_options);919 return typeof variation !== 'undefined' ? variation : false;920 },921 /**922 * Set variation for add to cart button.923 * @param $button924 * @param variation925 */926 set_variation($button, variation) {927 let variation_id = variation.variation_id || '',928 attributes = variation.attributes_json || '',929 price = variation.price_html || orderable_products.vars.parent_price,930 message = '';931 if (variation && '' !== variation.availability_html) {932 message = variation.availability_html;933 }934 if (variation && !variation.is_in_stock) {935 message = '<p>' + orderable_vars.i18n.out_of_stock + '</p>';936 }937 if (variation && !variation.is_purchasable) {938 message = '<p>' + orderable_vars.i18n.unavailable + '</p>';939 }940 if (false === variation) {941 message = '<p>' + orderable_vars.i18n.no_exist + '</p>';942 }943 if (variation && (!variation.is_purchasable || !variation.is_in_stock)) {944 variation_id = '';945 attributes = '';946 }947 if ('' !== message) {948 $('.' + orderable_products.vars.classes.product_messages).html(message);949 }950 $button.data('orderable-variation-id', variation_id);951 $button.data('orderable-variation-attributes', attributes);952 $('.orderable-drawer .orderable-product__actions-price').html(price);953 $button.trigger('orderable_variation_set', {954 variation,955 variation_id,956 attributes,957 price958 });959 },960 /**961 * Clear variation and disable add to order.962 *963 * @param $button964 */965 clear_variation($button) {966 orderable_products.set_variation($button, '');967 if (orderable_products.vars.parent_price) {968 $('.orderable-drawer .orderable-product__actions-price').html(orderable_products.vars.parent_price);969 }970 },971 /**972 * Find matching variations for attributes.973 * @param variations974 * @param attributes975 */976 find_matching_variations(variations, attributes) {977 const matching = [];978 for (let i = 0; i < variations.length; i++) {979 const variation = variations[i];980 if (orderable_products.is_matching_variation(variation.attributes, attributes)) {981 matching.push(variation);982 }983 }984 return matching;985 },986 /**987 * See if attributes match.988 * @param variation_attributes989 * @param attributes990 * @return {boolean}991 */992 is_matching_variation(variation_attributes, attributes) {993 let match = true;994 for (const attr_name in variation_attributes) {995 if (variation_attributes.hasOwnProperty(attr_name)) {996 const val1 = variation_attributes[attr_name];997 const val2 = attributes[attr_name];998 if (val1 !== undefined && val2 !== undefined && val1.length !== 0 && val2.length !== 0 && val1 !== val2) {999 match = false;1000 }1001 }1002 }1003 return match;1004 },1005 /**1006 * Is value empty?1007 *1008 * @param value1009 * @return {boolean}1010 */1011 is_empty(value) {1012 return typeof value === 'undefined' || false === value || value.length <= 0 || !value;1013 },1014 /**1015 * Serialize into a key/value object.1016 *1017 * @param $elements1018 * @return {{}}1019 */1020 serialize_object: function objectifyForm($elements) {1021 const serialized = $elements.serializeArray(),1022 return_object = {};1023 for (let i = 0; i < serialized.length; i++) {1024 return_object[serialized[i].name] = serialized[i].value;1025 }1026 return return_object;1027 },1028 /**1029 * Disable/Enable the 'Add to cart' button based on the presence of orderable-field--invalid class.1030 */1031 update_button_state() {1032 // Add delay to ensure invalid class has been assigned to inputs.1033 setTimeout(function () {1034 let $button = $('.orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item'),1035 invalid_fields_count = $('.orderable-drawer__html .' + orderable_products.vars.classes.invalid_field).length,1036 product_type = $button.data('orderable-product-type'),1037 has_variation_id = true;1038 if ('variable' === product_type) {1039 has_variation_id = '' !== $button.data('orderable-variation-id');1040 }1041 $button.prop('disabled', invalid_fields_count || !has_variation_id);1042 }, 50);1043 },1044 /**1045 * Debounce function.1046 *1047 * @param func Function to debounce.1048 * @param wait Time to wait in milliseconds.1049 * @param immediate Trigger the function on the leading edge, instead of the trailing.1050 *1051 * @return1052 */1053 debounce(func, wait, immediate) {1054 let timeout;1055 return function () {1056 const context = this,1057 args = arguments;1058 const later = function () {1059 timeout = null;1060 if (!immediate) {1061 func.apply(context, args);1062 }1063 };1064 const callNow = immediate && !timeout;1065 clearTimeout(timeout);1066 timeout = setTimeout(later, wait);1067 if (callNow) {1068 func.apply(context, args);1069 }1070 };1071 },1072 /**1073 * Remove the quantity roller fragments1074 *1075 * @param {Event} e1076 * @param {Object} fragments1077 * @return void1078 */1079 remove_fragments(e, fragments) {1080 if (!fragments || 'undefined' === typeof wc_cart_fragments_params || !wc_cart_fragments_params.fragment_name) {1081 return;1082 }1083 const regex_quantity_roller = /\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-quantity-roller/;1084 const regex_product_in_the_cart_counter = /\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-product__actions-counter/;1085 for (const key in fragments) {1086 if (!regex_quantity_roller.test(key) && !regex_product_in_the_cart_counter.test(key)) {1087 continue;1088 }1089 fragments[key] = undefined;1090 }1091 sessionStorage.setItem(wc_cart_fragments_params.fragment_name, JSON.stringify(fragments));1092 },1093 /**1094 * Remove animation.1095 */1096 remove_animation() {1097 setTimeout(function () {1098 $('.orderable-product__actions-counter').css('animation', '');1099 }, 1000);1100 },1101 /**1102 * Hide quantity roller element and show the Add to Cart button.1103 *1104 * @param {Event} e1105 * @param {Object} fragments1106 * @param {string} cart_hash1107 * @param {Element} $button1108 * @return1109 */1110 hide_quantity_roller(e, fragments, cart_hash, $button) {1111 const product_id = $button.attr('data-product_id') || $button.attr('data-orderable-product-id');1112 if (!product_id) {1113 return;1114 }1115 const $actions_button = $('.orderable-product[data-orderable-product-id=' + product_id + '] .orderable-product__actions-button');1116 if (!$actions_button.length) {1117 return;1118 }1119 const $quantity_roller = $actions_button.find('.orderable-quantity-roller');1120 if ($quantity_roller.length) {1121 $actions_button.find('button.orderable-product__add-to-order[data-orderable-trigger]').removeClass('orderable-button--product-in-the-cart');1122 $quantity_roller.addClass('orderable-button--hide');1123 }1124 },1125 /**1126 * Add unchecked checkboxs to the list of inputs1127 * sent to the request to add/update an item1128 *1129 * @param {Object} inputs1130 * @return {Object}1131 */1132 add_unchecked_checkbox_fields(inputs) {1133 jQuery('.orderable-product-fields-group :input[type="checkbox"]:not(:checked)').each(function (index, element) {1134 inputs.push({1135 name: element.getAttribute('name'),1136 value: ''1137 });1138 });1139 return inputs;1140 },1141 /**1142 * Shake the floating cart button.1143 *1144 * @return void1145 */1146 shake_floating_cart() {1147 $('.orderable-floating-cart__button').css('animation', 'wobble-hor-bottom .8s both');1148 },1149 /**1150 * Remove the view cart link.1151 *1152 * @param event1153 * @param $button1154 */1155 remove_view_cart_link(event, $button) {1156 if (!$button?.hasClass('orderable-product__add-to-order')) {1157 return;1158 }1159 $button?.siblings('.added_to_cart.wc-forward').remove();1160 }1161 };1162 $(document).ready(orderable_products.on_ready);1163 })(jQuery, document);1164 (function ($, document) {1165 'use strict';1166 1167 var orderable_scrollbar = {1168 /**1169 * On doc ready.1170 */1171 on_ready() {1172 orderable_scrollbar.cache();1173 orderable_scrollbar.watch();1174 },1175 /**1176 * Cache.1177 */1178 cache() {1179 orderable_scrollbar.vars = {1180 top: {}1181 };1182 orderable_scrollbar.elements = {};1183 },1184 /**1185 * Watch.1186 */1187 watch() {1188 $(document.body).on('orderable-drawer.opened', orderable_scrollbar.trigger);1189 $(document.body).on('orderable-tabs.changed', orderable_scrollbar.trigger);1190 $(document.body).on('orderable-accordion.toggled', orderable_scrollbar.trigger);1191 $(document.body).on('wc_fragments_loaded', orderable_scrollbar.trigger);1192 },1193 /**1194 * Init or retrigger scrollbars.1195 */1196 trigger() {1197 $('.orderable-sb-container').each(function (index, element) {1198 const $element = $(element),1199 scroll_id = $element.data('orderable-scroll-id');1200 if (!orderable_scrollbar.has_scrollbar($element)) {1201 $element.scrollBox({1202 containerClass: 'orderable-sb-container',1203 containerNoScrollClass: 'orderable-sb-container-noscroll',1204 contentClass: 'orderable-sb-content',1205 scrollbarContainerClass: 'orderable-sb-scrollbar-container',1206 scrollBarClass: 'orderable-sb-scrollbar'1207 });1208 const $content = $element.find('.orderable-sb-content');1209 if ($content.length > 0) {1210 $content.on('scroll.scrollBox', orderable_scrollbar.log_top_position);1211 1212 // Set scroll position.1213 if (typeof orderable_scrollbar.vars.top[scroll_id] !== 'undefined') {1214 $content.scrollTop(orderable_scrollbar.vars.top[scroll_id]);1215 }1216 }1217 $(document.body).trigger('orderable-scrollbar.created', {1218 element: $element,1219 content: $content1220 });1221 }1222 });1223 $(window).trigger('resize.scrollBox');1224 },1225 /**1226 * Has scrollbar already?1227 *1228 * @param $element1229 * @return {boolean}1230 */1231 has_scrollbar($element) {1232 return $element.find('.orderable-sb-content').length > 0;1233 },1234 /**1235 * Set scrolltop position.1236 *1237 * @param e1238 */1239 log_top_position(e) {1240 const $element = $(e.currentTarget),1241 $container = $element.closest('.orderable-sb-container'),1242 scroll_id = $container.data('orderable-scroll-id');1243 orderable_scrollbar.vars.top[scroll_id] = $(e.currentTarget).scrollTop();1244 }1245 };1246 $(document).ready(orderable_scrollbar.on_ready);1247 })(jQuery, document);1248 (function ($, document) {1249 'use strict';1250 1251 var orderable_tabs = {1252 /**1253 * On doc ready.1254 */1255 on_ready() {1256 orderable_tabs.cache();1257 orderable_tabs.watch();1258 orderable_tabs.toggle_scroll();1259 },1260 /**1261 * On resize.1262 */1263 on_resize() {1264 orderable_tabs.toggle_scroll();1265 },1266 /**1267 * Cache.1268 */1269 cache() {1270 orderable_tabs.vars = {1271 classes: {1272 tabs: 'orderable-tabs',1273 tabs_list: 'orderable-tabs__list',1274 tab_items: 'orderable-tabs__item',1275 tab_item_active: 'orderable-tabs__item--active',1276 tab_links: 'orderable-tabs__link',1277 tab_arrow_right: 'orderable-tabs__arrow-right',1278 tab_arrow_left: 'orderable-tabs__arrow-left'1279 },1280 dragging: false1281 };1282 orderable_tabs.elements = {};1283 },1284 /**1285 * Watch.1286 */1287 watch() {1288 $('body').on('touchstart', function () {1289 orderable_tabs.vars.dragging = false;1290 }).on('touchmove', function () {1291 orderable_tabs.vars.dragging = true;1292 });1293 $(document.body).on('click mouseup touchend', '.' + orderable_tabs.vars.classes.tab_links, function (e) {1294 if (orderable_tabs.vars.dragging) {1295 return;1296 }1297 e.preventDefault();1298 const $link = $(this),1299 section_id = $link.attr('href'),1300 $tab = $link.closest('.' + orderable_tabs.vars.classes.tab_items),1301 $tabs = $link.closest('.' + orderable_tabs.vars.classes.tabs),1302 $tabs_list = $tabs.find('.' + orderable_tabs.vars.classes.tabs_list),1303 $tab_items = $tabs.find('.' + orderable_tabs.vars.classes.tab_items),1304 tabs_args = $tabs.data('orderable-tabs'),1305 $wrapper = $link.closest(tabs_args.wrapper),1306 $sections = $wrapper.find(tabs_args.sections),1307 $section = $wrapper.find(section_id);1308 $sections.hide();1309 $section.show();1310 $tab_items.removeClass(orderable_tabs.vars.classes.tab_item_active);1311 $tab.addClass(orderable_tabs.vars.classes.tab_item_active);1312 $tabs_list.animate({1313 scrollLeft: $tabs_list.scrollLeft() + $tab.position().left1314 });1315 $(document.body).trigger('orderable-tabs.changed', {1316 tab: $tab1317 });1318 });1319 1320 /**1321 * Watch scroll position of tabs.1322 */1323 $('.' + orderable_tabs.vars.classes.tabs_list).on('scroll', function (e) {1324 const $list = $(this),1325 $wrapper = $list.parent('.' + orderable_tabs.vars.classes.tabs),1326 $arrow_right = $list.siblings('.' + orderable_tabs.vars.classes.tab_arrow_right),1327 $arrow_left = $list.siblings('.' + orderable_tabs.vars.classes.tab_arrow_left);1328 if ($list[0].scrollWidth <= $wrapper.width() + $list.scrollLeft()) {1329 $arrow_right.fadeOut();1330 } else {1331 $arrow_right.fadeIn();1332 }1333 if (0 >= $list.scrollLeft() - $arrow_left.width()) {1334 $arrow_left.fadeOut();1335 } else {1336 $arrow_left.fadeIn();1337 }1338 });1339 1340 /**1341 * Stop animated scroll if user manually scrolls.1342 */1343 $('.' + orderable_tabs.vars.classes.tabs_list).on('wheel DOMMouseScroll mousewheel touchmove', function () {1344 $(this).stop();1345 });1346 1347 /**1348 * Click tab arrow right.1349 */1350 $(document).on('click', '.' + orderable_tabs.vars.classes.tab_arrow_right, function (e) {1351 e.preventDefault();1352 const $arrow = $(this),1353 $wrapper = $arrow.parent(),1354 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list);1355 $list.animate({1356 scrollLeft: $list.scrollLeft() + $wrapper.width() * 0.51357 });1358 });1359 1360 /**1361 * Click tab arrow left.1362 */1363 $(document).on('click', '.' + orderable_tabs.vars.classes.tab_arrow_left, function (e) {1364 e.preventDefault();1365 const $arrow = $(this),1366 $wrapper = $arrow.parent(),1367 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list);1368 $list.animate({1369 scrollLeft: $list.scrollLeft() - $wrapper.width() * 0.51370 });1371 });1372 },1373 /**1374 * Toggle scroll arrow.1375 */1376 toggle_scroll() {1377 $('.' + orderable_tabs.vars.classes.tabs).each(function (index, wrapper) {1378 const $tabs = $(this),1379 tabs_args = $tabs.data('orderable-tabs'),1380 $wrapper = $tabs.closest(tabs_args.wrapper),1381 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list),1382 $arrow_right = $wrapper.find('.' + orderable_tabs.vars.classes.tab_arrow_right),1383 wrapper_width = $wrapper.outerWidth(),1384 list_width = $list[0].scrollWidth;1385 if (list_width > wrapper_width) {1386 $arrow_right.show();1387 } else {1388 $arrow_right.hide();1389 }1390 });1391 }1392 };1393 $(document).ready(orderable_tabs.on_ready);1394 $(window).on('resize', orderable_tabs.on_resize);1395 })(jQuery, document);1396 let orderable_timings = {}; // Make this global so pro modules can access it.1397 1398 (function ($, document) {1399 'use strict';1400 1401 orderable_timings = {1402 /**1403 * On doc ready.1404 */1405 on_ready() {1406 orderable_timings.watch();1407 },1408 /**1409 * Restore current timings.1410 */1411 restore() {1412 const timings = orderable_timings.get_timings();1413 if (!timings || !timings.date) {1414 return;1415 }1416 const dateSelect = $('.orderable-order-timings__date');1417 if (dateSelect.find('option[value="' + timings.date + '"]').length > 0) {1418 dateSelect.val(timings.date);1419 dateSelect.change();1420 }1421 if (!timings.time) {1422 return;1423 }1424 const timeSelect = $('.orderable-order-timings__time');1425 if (timeSelect.find('option[value="' + timings.time + '"]').length > 0) {1426 timeSelect.val(timings.time);1427 timeSelect.change();1428 }1429 },1430 /**1431 * Watch for trigger events.1432 */1433 watch() {1434 $(document.body).on('wc_fragments_refreshed', function () {1435 orderable_timings.restore();1436 });1437 $(document.body).on('updated_checkout', function () {1438 orderable_timings.restore();1439 });1440 $(document.body).on('change', '.orderable-order-timings__date', function (event) {1441 const $date_field = $(this),1442 $selected = $date_field.find('option:selected'),1443 slots = $selected.data('orderable-slots'),1444 $time_field_wrap = $('.orderable-order-timings--time'),1445 $time_field = $('.orderable-order-timings__time'),1446 $first_option = $time_field.find('option').first(),1447 $asap_option = $time_field.find('option[value="asap"]').first();1448 const timings = orderable_timings.get_timings();1449 timings.date = $('.orderable-order-timings__date').val();1450 window.localStorage.setItem('orderable_timings', JSON.stringify(timings));1451 $time_field.html($first_option);1452 if ($asap_option) {1453 $time_field.append($asap_option);1454 }1455 if (!slots) {1456 $time_field.prop('disabled', true);1457 $time_field_wrap.hide();1458 return;1459 }1460 if ('all-day' === slots[0].value) {1461 $time_field_wrap.hide();1462 $time_field.prop('disabled', true);1463 } else {1464 $time_field.prop('disabled', false);1465 $time_field_wrap.show();1466 $.each(slots, function (index, slot) {1467 $time_field.append($('<option />').attr('value', slot.value).attr('data-orderable-time-slot-id', slot?.setting_row?.time_slot_id).text(slot.formatted));1468 });1469 }1470 });1471 $(document.body).on('change', '.orderable-order-timings__time', function (event) {1472 const timings = orderable_timings.get_timings();1473 timings.time = $('.orderable-order-timings__time').val();1474 window.localStorage.setItem('orderable_timings', JSON.stringify(timings));1475 $(this).siblings('input[name="orderable_order_time_slot_id"]').val($(this).find(':selected').attr('data-orderable-time-slot-id'));1476 });1477 },1478 get_timings() {1479 return JSON.parse(window.localStorage.getItem('orderable_timings')) || {};1480 }1481 };1482 $(document).ready(orderable_timings.on_ready);1483 })(jQuery, document);1484 (function ($, document) {1485 'use strict';1486 1487 var orderable_triggers = {1488 /**1489 * On doc ready.1490 */1491 on_ready() {1492 orderable_triggers.watch();1493 },1494 /**1495 * Watch for trigger events.1496 */1497 watch() {1498 if ('undefined' !== typeof window.orderable_triggers_admin) {1499 return;1500 }1501 $(document.body).on('click', '[data-orderable-trigger]', orderable_triggers.trigger);1502 },1503 /**1504 * Fire trigger.1505 * @param e1506 */1507 trigger(e) {1508 // Prevent even bubbling up.1509 e.stopImmediatePropagation();1510 const $trigger_element = $(this),1511 trigger = $trigger_element.data('orderable-trigger');1512 if ($trigger_element.is('button') || $trigger_element.is('a')) {1513 e.preventDefault();1514 }1515 $(document.body).trigger('orderable-' + trigger, [$trigger_element]);1516 }1517 };1518 $(document).ready(orderable_triggers.on_ready);1519 })(jQuery, document); -
orderable/tags/1.17.1/assets/frontend/js/main.min.js
r3192586 r3237969 1 !function(o,e,s){"use strict";var n="scrollBox",r={containerClass:"sb-container",containerNoScrollClass:"sb-container-noscroll",contentClass:"sb-content",scrollbarContainerClass:"sb-scrollbar-container",scrollBarClass:"sb-scrollbar"};function t(e,t){this.element=e,this.settings=o.extend({},r,t),this._defaults=r,this._name=n,this.init()}o.extend(t.prototype,{init:function(){this.addScrollbar(),this.addEvents(),this.onResize()},addScrollbar:function(){o(this.element).addClass(this.settings.containerClass),this.wrapper=o("<div class='"+this.settings.contentClass+"' />"),this.wrapper.append(o(this.element).contents()),o(this.element).append(this.wrapper),this.scollbarContainer=o("<div class='"+this.settings.scrollbarContainerClass+"' />"),this.scrollBar=o("<div class='"+this.settings.scrollBarClass+"' />"),this.scollbarContainer.append(this.scrollBar),o(this.element).prepend(this.scollbarContainer)},addEvents:function(){this.wrapper.on("scroll."+n,o.proxy(this.onScroll,this)),o(e).on("resize."+n,o.proxy(this.onResize,this)),this.scrollBar.on("mousedown."+n,o.proxy(this.onMousedown,this)),this.scrollBar.on("touchstart."+n,o.proxy(this.onTouchstart,this))},onTouchstart:function(t){var r=this,a=(t.preventDefault(),r.scrollBar[0].offsetTop);o(s).on("touchmove."+n,function(e){e=e.touches[0].pageY-t.touches[0].pageY;r.scrollBar[0].style.top=Math.min(r.scollbarContainer[0].clientHeight-r.scrollBar[0].clientHeight,Math.max(0,a+e))+"px",r.wrapper[0].scrollTop=r.wrapper[0].scrollHeight*r.scrollBar[0].offsetTop/r.scollbarContainer[0].clientHeight}),o(s).on("touchend."+n,function(){o(s).off("touchmove."+n),o(s).off("touchend."+n)})},onMousedown:function(t){var r=this,a=(t.preventDefault(),r.scrollBar[0].offsetTop);o(s).on("mousemove."+n,function(e){e=e.pageY-t.pageY;r.scrollBar[0].style.top=Math.min(r.scollbarContainer[0].clientHeight-r.scrollBar[0].clientHeight,Math.max(0,a+e))+"px",r.wrapper[0].scrollTop=r.wrapper[0].scrollHeight*r.scrollBar[0].offsetTop/r.scollbarContainer[0].clientHeight}),o(s).on("mouseup."+n,function(){o(s).off("mousemove."+n),o(s).off("mouseup."+n)})},onResize:function(){this.wrapper.css("max-height",o(this.element).height());var e=this.wrapper[0].clientHeight;this.scrollBar.css("height",this.scollbarContainer[0].clientHeight*e/this.wrapper[0].scrollHeight+"px"),this.scollbarContainer[0].clientHeight<=this.scrollBar[0].clientHeight?o(this.element).addClass(this.settings.containerNoScrollClass):o(this.element).removeClass(this.settings.containerNoScrollClass),this.onScroll()},onScroll:function(){this.scrollBar.css("top",Math.min(this.scollbarContainer[0].clientHeight-this.scrollBar[0].clientHeight,this.scollbarContainer[0].clientHeight*this.wrapper[0].scrollTop/this.wrapper[0].scrollHeight)+"px")}}),o.fn[n]=function(e){return this.each(function(){o.data(this,"plugin_"+n)||o.data(this,"plugin_"+n,new t(this,e))})}}(jQuery,window,document),function(e,o){"use strict";"function"!=typeof e.CustomEvent&&(e.CustomEvent=function(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var r=o.createEvent("CustomEvent");return r.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),r},e.CustomEvent.prototype=e.Event.prototype),o.addEventListener("touchstart",function(e){"true"!==e.target.getAttribute("data-swipe-ignore")&&(c=e.target,l=Date.now(),s=e.touches[0].clientX,n=e.touches[0].clientY,d=i=0)},!1),o.addEventListener("touchmove",function(e){var t;s&&n&&(t=e.touches[0].clientX,e=e.touches[0].clientY,i=s-t,d=n-e)},!1),o.addEventListener("touchend",function(e){var t,r,a,o;c===e.target&&(o=parseInt(_(c,"data-swipe-threshold","20"),10),t=parseInt(_(c,"data-swipe-timeout","500"),10),r=Date.now()-l,a="",e=e.changedTouches||e.touches||[],Math.abs(i)>Math.abs(d)?Math.abs(i)>o&&r<t&&(a=0<i?"swiped-left":"swiped-right"):Math.abs(d)>o&&r<t&&(a=0<d?"swiped-up":"swiped-down"),""!==a&&(o={dir:a.replace(/swiped-/,""),touchType:(e[0]||{}).touchType||"direct",xStart:parseInt(s,10),xEnd:parseInt((e[0]||{}).clientX||-1,10),yStart:parseInt(n,10),yEnd:parseInt((e[0]||{}).clientY||-1,10)},c.dispatchEvent(new CustomEvent("swiped",{bubbles:!0,cancelable:!0,detail:o})),c.dispatchEvent(new CustomEvent(a,{bubbles:!0,cancelable:!0,detail:o}))),l=n=s=null)},!1);var s=null,n=null,i=null,d=null,l=null,c=null;function _(e,t,r){for(;e&&e!==o.documentElement;){var a=e.getAttribute(t);if(a)return a;e=e.parentNode}return r}}(window,document),function(o,s){"use strict";var n={on_ready(){n.cache(),n.watch()},cache(){n.vars={classes:{parent:"orderable-accordion",link:"orderable-accordion__item-link",content:"orderable-accordion__item-content",link_active:"orderable-accordion__item-link--active",content_active:"orderable-accordion__item-content--active"}}},watch(){o(s.body).on("click","."+n.vars.classes.link,function(e){e.preventDefault();var e=o(this),t=e.closest("."+n.vars.classes.parent),r=e.attr("href"),r=o(r),a=e.hasClass(n.vars.classes.link_active);t.find("."+n.vars.classes.link).removeClass(n.vars.classes.link_active),t.find("."+n.vars.classes.content).removeClass(n.vars.classes.content_active),a||(e.addClass(n.vars.classes.link_active),r.addClass(n.vars.classes.content_active)),o(s.body).trigger("orderable-accordion.toggled",{link:e,content:r})}),o(s.body).on("orderable-scrollbar.created",function(e,t){var r=o(".orderable-drawer ."+n.vars.classes.link_active);r.length<=0||(r=(t=t.content).scrollTop()-t.offset().top+r.offset().top,t.scrollTop(r))})}};o(s).ready(n.on_ready)}(jQuery,document),function(l,c){"use strict";var r={debounce(t,r=700){let a;return(...e)=>{clearTimeout(a),a=setTimeout(()=>{t.apply(this,e)},r)}},allow_only_numbers(e){var t=String.fromCharCode(e.which);/^\d+$/.test(t)||e.preventDefault()},on_change_quantity(e){const t=l(e.currentTarget);var e=t.data("orderable-product-id"),r=t.data("orderable-cart-item-key"),a=parseInt(t.text());jQuery.post(orderable_vars.ajax_url,{action:"orderable_cart_quantity",cart_item_key:r,product_id:e,quantity:a},function(e){e&&(l(c.body).trigger("added_to_cart",[e.fragments,e.cart_hash,t]),l(c.body).trigger("orderable-drawer.quantity-updated"))})},on_ready(){r.cache(),r.watch(),l(c.body).on("keypress",".orderable-quantity-roller__quantity",r.allow_only_numbers),l(".orderable-drawer__cart, .orderable-product--add-to-cart, .orderable-products-list").on("input",".orderable-quantity-roller__quantity",r.debounce(r.on_change_quantity)),l(c.body).on("click",".orderable-quantity-roller__quantity",function(e){e.stopPropagation()}),orderable_vars&&!orderable_vars.woocommerce_enable_ajax_add_to_cart&&l(c.body).off("click",".add_to_cart_button")},cache(){r.vars={classes:{overlay:"orderable-drawer-overlay",drawer:"orderable-drawer",drawer_cart:"orderable-drawer__cart",drawer_html:"orderable-drawer__html",overlay_open:"orderable-drawer-overlay--open",drawer_open:"orderable-drawer--open",drawer_open_body:"orderable-drawer-open"}},r.elements={body:l("body"),overlay:l("."+r.vars.classes.overlay),drawer:l("."+r.vars.classes.drawer),drawer_cart:l("."+r.vars.classes.drawer_cart),drawer_html:l("."+r.vars.classes.drawer_html),floating_cart_button_class:".orderable-floating-cart__button"}},watch(){var e,t;void 0!==r.elements.drawer&&(l(c.body).on("orderable-drawer.open",r.open),l(c.body).on("orderable-drawer.close",r.close),l(c.body).on("click",r.elements.floating_cart_button_class,function(){l(c.body).trigger("orderable-drawer.open",{show_cart:!0})}),l(c.body).on("orderable-increase-quantity",r.cart.handle_quantity_change_by_button),l(c.body).on("orderable-decrease-quantity",r.cart.handle_quantity_change_by_button),e=r.debounce(r.cart.click_increase_decrease_quantity),l(c.body).on("orderable-increase-quantity",e),l(c.body).on("orderable-decrease-quantity",e),e=c.querySelector("body:not( .rtl ) .orderable-drawer"),t=c.querySelector("body.rtl .orderable-drawer"),e&&e.addEventListener("swiped-right",function(e){r.close()}),t)&&t.addEventListener("swiped-left",function(e){r.close()})},open(e,t){t.html=t.html||!1,t.show_cart=t.show_cart||!1,r.elements.drawer_html.hide(),r.elements.drawer_cart.hide(),t.html&&(r.elements.drawer_html.html(t.html),r.elements.drawer_html.show()),t.show_cart&&(r.elements.drawer_html.html(""),r.elements.drawer_cart.show()),r.elements.overlay.addClass(r.vars.classes.overlay_open),r.elements.drawer.addClass(r.vars.classes.drawer_open),r.elements.body.addClass(r.vars.classes.drawer_open_body),l(c.body).trigger("orderable-drawer.opened",t)},close(){r.elements.overlay.removeClass(r.vars.classes.overlay_open),r.elements.drawer.removeClass(r.vars.classes.drawer_open),r.elements.body.removeClass(r.vars.classes.drawer_open_body),r.elements.drawer_html.html(""),l(c.body).trigger("orderable-drawer.closed")},cart:{click_increase_decrease_quantity(e,r){var t=r.data("orderable-trigger"),a=r.attr("data-orderable-product-id"),o=r.attr("data-orderable-cart-item-key"),s=r.attr("data-orderable-quantity");const n=r.siblings(".orderable-quantity-roller__button--"+("increase-quantity"===t?"decrease":"increase")),i=r.siblings(".orderable-quantity-roller__quantity"),d={action:"orderable_cart_quantity",cart_item_key:o,product_id:a,quantity:s};this.currentRequest&&(this.currentRequest.abort(),this.currentRequest=void 0),r.addClass("orderable-button--loading"),r.attr("disabled",!0),n.attr("disabled",!0),i.attr("contenteditable",!1),this.currentRequest=jQuery.post(orderable_vars.ajax_url,d,function(e){if(e){var t=r.siblings(".orderable-quantity-roller__quantity");switch(e&&e.fragments&&e.fragments[".orderable-mini-cart__notices"]&&l(c.body).trigger("orderable-drawer.open",{show_cart:!0}),d.quantity){case"0":l(c.body).trigger("removed_from_cart",[e.fragments,e.cart_hash,r]);break;case t.attr("data-orderable-updating-quantity"):l(c.body).trigger("added_to_cart",[e.fragments,e.cart_hash,r]),l(c.body).trigger("orderable-drawer.quantity-updated")}}}.bind(this)).always(function(){this.currentRequest=void 0,r.removeClass("orderable-button--loading"),r.attr("disabled",!1),n.attr("disabled",!1),i.attr("contenteditable",!0)}.bind(this))},handle_quantity_change_by_button(e,t){var r,a=t.data("orderable-trigger"),o=parseInt(t.attr("data-orderable-quantity")),s=t.siblings(".orderable-quantity-roller__button--"+("increase-quantity"===a?"decrease":"increase")),n=t.siblings(".orderable-quantity-roller__quantity"),a="increase-quantity"===a?o+1:Math.max(0,o-1),o=t.parents(".orderable-product__actions-button");0===a&&o.length&&(r=o.find("button.orderable-button[data-orderable-trigger]"),(o=o.find(".orderable-quantity-roller")).length)&&(r.removeClass("orderable-button--product-in-the-cart"),o.removeClass("orderable-quantity-roller--is-active")),t.attr("data-orderable-quantity",a),s.attr("data-orderable-quantity",a),n.attr("data-orderable-updating-quantity",a),n.text(a),n.attr("contenteditable",!1)}}};l(c).ready(r.on_ready)}(jQuery,document),function(d,l){"use strict";var c={on_ready(){c.cache(),c.watch()},cache(){c.vars={classes:{clickable_product:"orderable-product--add-to-cart ",add_to_order_button:"orderable-product__add-to-order",product_messages:"orderable-product__messages",product_price:"orderable-product__actions-price",invalid_field:"orderable-field--invalid",option_select_td:"orderable-product__option-select",button_loading:"orderable-button--loading",out_of_stock:"orderable-button--out-of-stock"},parent_price:null,variable_product_types:["variable","variable-subscription"]},c.elements={}},watch(){d(l.body).on("orderable-drawer.opened",c.init_product_options),d(l.body).on("orderable-add-to-cart",c.click_add_to_order),d(l.body).on("orderable-product-options",c.click_add_to_order),d(l.body).on("orderable-view-product",c.view_product),d(l.body).on("mouseenter mouseleave","."+c.vars.classes.clickable_product,c.simulate_add_to_order_hover),d(l.body).on("orderable-edit-cart-item",c.edit_cart_item),d(l.body).on("orderable-update-cart-item",c.update_cart_item),d(l.body).on("orderable-show-cart",c.show_cart),d(l.body).on("orderable-add-to-cart-without-side-drawer",c.click_add_to_order),d(l.body).on("added_to_cart",c.remove_fragments),d(l.body).on("added_to_cart",c.remove_animation),d(l.body).on("added_to_cart",c.shake_floating_cart),d(l.body).on("removed_from_cart",c.hide_quantity_roller),d(l.body).on("wc_cart_button_updated",c.remove_view_cart_link)},simulate_add_to_order_hover(e){d(this).find("."+c.vars.classes.add_to_order_button).toggleClass("orderable-button--hover","mouseenter"===e.type)},click_add_to_order(e,t){const r=(t=void 0!==t?t:d(this)).is("button")?t:t.find("."+c.vars.classes.add_to_order_button),a=r.data("orderable-trigger"),o=r.data("orderable-product-id"),s=r.data("orderable-variation-id"),n=r.data("orderable-variation-attributes"),i={action:a};if(!r.hasClass(c.vars.classes.button_loading)&&!r.hasClass(c.vars.classes.out_of_stock))switch(r.addClass(c.vars.classes.button_loading),a){case"add-to-cart":c.add_to_cart({product_id:o,variation_id:s,attributes:n,thisbutton:t},function(e){i.show_cart=!0,i.response=e,d(l.body).trigger("orderable-drawer.open",i),r.removeClass(c.vars.classes.button_loading);e=d(".orderable-product .orderable-product__actions-button button.orderable-product__add-to-order[data-orderable-product-id="+o+"]");e.siblings(".orderable-quantity-roller").length&&e.addClass("orderable-button--product-in-the-cart")});break;case"add-to-cart-without-side-drawer":c.add_to_cart({product_id:o,variation_id:s,attributes:n},function(e){i.response=e,r.addClass("orderable-button--product-in-the-cart"),r.removeClass(c.vars.classes.button_loading)});break;case"product-options":c.get_product_options({product_id:o,focus:r.data("orderable-focus")},function(e){i.html=e.html,d(l.body).trigger("orderable-drawer.open",i),r.removeClass(c.vars.classes.button_loading)})}},show_cart(){d(l.body).trigger("orderable-drawer.open",{show_cart:!0})},view_product(e,t){const r=t.data("orderable-product-id"),a={action:"product-options"};c.get_product_options({product_id:r,focus:t.data("orderable-focus")},function(e){a.html=e.html,d(l.body).trigger("orderable-drawer.open",a)})},add_to_cart(t,r){if(void 0!==t.product_id){let e={action:"orderable_add_to_cart",product_id:t.product_id,variation_id:t.variation_id||!1,attributes:t.attributes||!1};var a;d(".orderable-product-fields-group").length&&(a=jQuery(".orderable-product-fields-group :input").serializeArray(),a=c.add_unchecked_checkbox_fields(a),a=c.convert_to_flat_object(a),jQuery.isEmptyObject(a)||(e=Object.assign(e,a))),jQuery.post(orderable_vars.ajax_url,e,function(e){e&&(d(l.body).trigger("added_to_cart",[e.fragments,e.cart_hash,t.thisbutton]),"function"==typeof r)&&r(e)})}},edit_cart_item(e,t){var r=t.data("orderable-cart-item-key");t.addClass(c.vars.classes.button_loading),c.get_cart_item_options({cart_item_key:r},function(e){e={html:e.html,action:"update-cart-item"};d(l.body).trigger("orderable-drawer.open",e),t.removeClass(c.vars.classes.button_loading)})},update_cart_item(e,r){var t=r.data("orderable-cart-item-key"),a=r.data("orderable-product-id"),o=r.data("orderable-variation-id"),s=r.data("orderable-variation-attributes");r.addClass(c.vars.classes.button_loading),c.update_cart_item_options({cart_item_key:t,product_id:a,variation_id:o,attributes:s},function(e){var t={show_cart:!0,response:e};d(l.body).trigger("added_to_cart",[e.fragments,e.cart_hash]),d(l.body).trigger("orderable-drawer.open",t),r.removeClass(c.vars.classes.button_loading)})},convert_to_flat_object(e){const a={};return e.forEach(function(e){var t="[]"===e.name.substr(-2)||Array.isArray(e.name),r=t?e.name.substr(0,e.name.length-2):e.name;t?(a[r]=void 0===a[r]?[]:a[r],a[r].push(e.value)):a[r]=e.value}),a},get_product_options(e,t){void 0!==e.product_id&&(e.action="orderable_get_product_options",jQuery.post(orderable_vars.ajax_url,e,function(e){e.success&&"function"==typeof t&&t(e.data)}))},get_cart_item_options(e,t){void 0!==e.cart_item_key&&(e.action="orderable_get_cart_item_options",jQuery.post(orderable_vars.ajax_url,e,function(e){e.success&&"function"==typeof t&&t(e.data)}))},update_cart_item_options(e,t){var r;void 0!==e.cart_item_key&&(e.action="orderable_update_cart_item_options",d(".orderable-product-fields-group").length&&(r=jQuery(".orderable-product-fields-group :input").serializeArray(),r=c.add_unchecked_checkbox_fields(r),r=c.convert_to_flat_object(r),jQuery.isEmptyObject(r)||(e=Object.assign(e,r))),jQuery.post(orderable_vars.ajax_url,e,function(e){e&&"function"==typeof t&&t(e)}))},init_product_options(e,t){if(void 0!==t.action&&("product-options"===t.action||"update-cart-item"===t.action)){t=".orderable-drawer .orderable-product__options input, .orderable-drawer .orderable-product__options select, .orderable-product__options textarea";const r=d(t),a=(c.vars.parent_price=d(".orderable-drawer .orderable-product__actions-price").html(),c.product_options_change(r),c.update_button_state(),c.debounce(c.update_button_state,500)),o=c.debounce(c.product_options_change,500);d(l).on("change keyup",t,function(){o(r),a()})}},product_options_change(e){var t=d(".orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item"),r=c.check_options(e),a=t.data("orderable-product-type");"product-options"===t.attr("data-orderable-trigger")&&t.attr("data-orderable-trigger","add-to-cart"),d("."+c.vars.classes.product_messages).html(""),c.vars.variable_product_types.includes(a)&&(r?(a=c.check_variation(e),c.set_variation(t,a)):c.clear_variation(t))},check_options(e){if(e.length<=0)return!1;let r=!0;return e.each(function(e,t){d(t).hasClass("orderable-input--validate")&&(""===d(t).val()?(d(t).addClass(c.vars.classes.invalid_field),r=!1):d(t).removeClass(c.vars.classes.invalid_field))}),r},check_variation(e){var t=(t=e.closest(".orderable-drawer").find(".orderable-product__variations").text())?JSON.parse(t):"",e=c.serialize_object(e),t=c.find_matching_variations(t,e);return!c.is_empty(t)&&((t=t.shift()).attributes=e,t.attributes_json=JSON.stringify(e),void 0!==t)&&t},set_variation(e,t){let r=t.variation_id||"",a=t.attributes_json||"",o=t.price_html||c.vars.parent_price,s="";t&&""!==t.availability_html&&(s=t.availability_html),t&&!t.is_in_stock&&(s="<p>"+orderable_vars.i18n.out_of_stock+"</p>"),t&&!t.is_purchasable&&(s="<p>"+orderable_vars.i18n.unavailable+"</p>"),!1===t&&(s="<p>"+orderable_vars.i18n.no_exist+"</p>"),!t||t.is_purchasable&&t.is_in_stock||(r="",a=""),""!==s&&d("."+c.vars.classes.product_messages).html(s),e.data("orderable-variation-id",r),e.data("orderable-variation-attributes",a),d(".orderable-drawer .orderable-product__actions-price").html(o),e.trigger("orderable_variation_set",{variation:t,variation_id:r,attributes:a,price:o})},clear_variation(e){c.set_variation(e,""),c.vars.parent_price&&d(".orderable-drawer .orderable-product__actions-price").html(c.vars.parent_price)},find_matching_variations(t,r){var a=[];for(let e=0;e<t.length;e++){var o=t[e];c.is_matching_variation(o.attributes,r)&&a.push(o)}return a},is_matching_variation(e,t){let r=!0;for(const s in e){var a,o;e.hasOwnProperty(s)&&(a=e[s],o=t[s],void 0!==a)&&void 0!==o&&0!==a.length&&0!==o.length&&a!==o&&(r=!1)}return r},is_empty(e){return void 0===e||!1===e||e.length<=0||!e},serialize_object:function(e){var t=e.serializeArray(),r={};for(let e=0;e<t.length;e++)r[t[e].name]=t[e].value;return r},update_button_state(){setTimeout(function(){let e=d(".orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item"),t=d(".orderable-drawer__html ."+c.vars.classes.invalid_field).length,r=e.data("orderable-product-type"),a=!0;"variable"===r&&(a=""!==e.data("orderable-variation-id")),e.prop("disabled",t||!a)},50)},debounce(a,o,s){let n;return function(){const e=this,t=arguments;var r=s&&!n;clearTimeout(n),n=setTimeout(function(){n=null,s||a.apply(e,t)},o),r&&a.apply(e,t)}},remove_fragments(e,t){if(t&&"undefined"!=typeof wc_cart_fragments_params&&wc_cart_fragments_params.fragment_name){var r=/\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-quantity-roller/,a=/\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-product__actions-counter/;for(const o in t)(r.test(o)||a.test(o))&&(t[o]=void 0);sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(t))}},remove_animation(){setTimeout(function(){d(".orderable-product__actions-counter").css("animation","")},1e3)},hide_quantity_roller(e,t,r,a){var o,a=a.attr("data-product_id")||a.attr("data-orderable-product-id");a&&(a=d(".orderable-product[data-orderable-product-id="+a+"] .orderable-product__actions-button")).length&&(o=a.find(".orderable-quantity-roller")).length&&(a.find("button.orderable-product__add-to-order[data-orderable-trigger]").removeClass("orderable-button--product-in-the-cart"),o.addClass("orderable-button--hide"))},add_unchecked_checkbox_fields(r){return jQuery('.orderable-product-fields-group :input[type="checkbox"]:not(:checked)').each(function(e,t){r.push({name:t.getAttribute("name"),value:""})}),r},shake_floating_cart(){d(".orderable-floating-cart__button").css("animation","wobble-hor-bottom .8s both")},remove_view_cart_link(e,t){t?.hasClass("orderable-product__add-to-order")&&t?.siblings(".added_to_cart.wc-forward").remove()}};d(l).ready(c.on_ready)}(jQuery,document),function(o,s){"use strict";var n={on_ready(){n.cache(),n.watch()},cache(){n.vars={top:{}},n.elements={}},watch(){o(s.body).on("orderable-drawer.opened",n.trigger),o(s.body).on("orderable-tabs.changed",n.trigger),o(s.body).on("orderable-accordion.toggled",n.trigger),o(s.body).on("wc_fragments_loaded",n.trigger)},trigger(){o(".orderable-sb-container").each(function(e,t){var r,t=o(t),a=t.data("orderable-scroll-id");n.has_scrollbar(t)||(t.scrollBox({containerClass:"orderable-sb-container",containerNoScrollClass:"orderable-sb-container-noscroll",contentClass:"orderable-sb-content",scrollbarContainerClass:"orderable-sb-scrollbar-container",scrollBarClass:"orderable-sb-scrollbar"}),0<(r=t.find(".orderable-sb-content")).length&&(r.on("scroll.scrollBox",n.log_top_position),void 0!==n.vars.top[a])&&r.scrollTop(n.vars.top[a]),o(s.body).trigger("orderable-scrollbar.created",{element:t,content:r}))}),o(window).trigger("resize.scrollBox")},has_scrollbar(e){return 0<e.find(".orderable-sb-content").length},log_top_position(e){var t=o(e.currentTarget).closest(".orderable-sb-container").data("orderable-scroll-id");n.vars.top[t]=o(e.currentTarget).scrollTop()}};o(s).ready(n.on_ready)}(jQuery,document),function(n,i){"use strict";var d={on_ready(){d.cache(),d.watch(),d.toggle_scroll()},on_resize(){d.toggle_scroll()},cache(){d.vars={classes:{tabs:"orderable-tabs",tabs_list:"orderable-tabs__list",tab_items:"orderable-tabs__item",tab_item_active:"orderable-tabs__item--active",tab_links:"orderable-tabs__link",tab_arrow_right:"orderable-tabs__arrow-right",tab_arrow_left:"orderable-tabs__arrow-left"},dragging:!1},d.elements={}},watch(){n("body").on("touchstart",function(){d.vars.dragging=!1}).on("touchmove",function(){d.vars.dragging=!0}),n(i.body).on("click mouseup touchend","."+d.vars.classes.tab_links,function(e){var t,r,a,o,s;d.vars.dragging||(e.preventDefault(),t=(e=n(this)).attr("href"),r=e.closest("."+d.vars.classes.tab_items),a=(s=e.closest("."+d.vars.classes.tabs)).find("."+d.vars.classes.tabs_list),o=s.find("."+d.vars.classes.tab_items),s=s.data("orderable-tabs"),s=(e=e.closest(s.wrapper)).find(s.sections),e=e.find(t),s.hide(),e.show(),o.removeClass(d.vars.classes.tab_item_active),r.addClass(d.vars.classes.tab_item_active),a.animate({scrollLeft:a.scrollLeft()+r.position().left}),n(i.body).trigger("orderable-tabs.changed",{tab:r}))}),n("."+d.vars.classes.tabs_list).on("scroll",function(e){var t=n(this),r=t.parent("."+d.vars.classes.tabs),a=t.siblings("."+d.vars.classes.tab_arrow_right),o=t.siblings("."+d.vars.classes.tab_arrow_left);t[0].scrollWidth<=r.width()+t.scrollLeft()?a.fadeOut():a.fadeIn(),t.scrollLeft()-o.width()<=0?o.fadeOut():o.fadeIn()}),n("."+d.vars.classes.tabs_list).on("wheel DOMMouseScroll mousewheel touchmove",function(){n(this).stop()}),n(i).on("click","."+d.vars.classes.tab_arrow_right,function(e){e.preventDefault();var e=n(this).parent(),t=e.find("."+d.vars.classes.tabs_list);t.animate({scrollLeft:t.scrollLeft()+.5*e.width()})}),n(i).on("click","."+d.vars.classes.tab_arrow_left,function(e){e.preventDefault();var e=n(this).parent(),t=e.find("."+d.vars.classes.tabs_list);t.animate({scrollLeft:t.scrollLeft()-.5*e.width()})})},toggle_scroll(){n("."+d.vars.classes.tabs).each(function(e,t){var r=n(this),a=r.data("orderable-tabs"),r=r.closest(a.wrapper),a=r.find("."+d.vars.classes.tabs_list),o=r.find("."+d.vars.classes.tab_arrow_right);r.outerWidth()<a[0].scrollWidth?o.show():o.hide()})}};n(i).ready(d.on_ready),n(window).on("resize",d.on_resize)}(jQuery,document);let orderable_timings={};!function(l,e){"use strict";orderable_timings={on_ready(){orderable_timings.watch()},restore(){var e,t=orderable_timings.get_timings();t&&t.date&&(0<(e=l(".orderable-order-timings__date")).find('option[value="'+t.date+'"]').length&&(e.val(t.date),e.change()),t.time)&&0<(e=l(".orderable-order-timings__time")).find('option[value="'+t.time+'"]').length&&(e.val(t.time),e.change())},watch(){l(e.body).on("wc_fragments_refreshed",function(){orderable_timings.restore()}),l(e.body).on("updated_checkout",function(){orderable_timings.restore()}),l(e.body).on("change",".orderable-order-timings__date",function(e){const t=l(this),r=t.find("option:selected"),a=r.data("orderable-slots"),o=l(".orderable-order-timings--time"),s=l(".orderable-order-timings__time"),n=s.find("option").first(),i=s.find('option[value="asap"]').first();var d=orderable_timings.get_timings();d.date=l(".orderable-order-timings__date").val(),window.localStorage.setItem("orderable_timings",JSON.stringify(d)),s.html(n),i&&s.append(i),a?"all-day"===a[0].value?(o.hide(),s.prop("disabled",!0)):(s.prop("disabled",!1),o.show(),l.each(a,function(e,t){s.append(l("<option />").attr("value",t.value).attr("data-orderable-time-slot-id",t?.setting_row?.time_slot_id).text(t.formatted))})):(s.prop("disabled",!0),o.hide())}),l(e.body).on("change",".orderable-order-timings__time",function(e){var t=orderable_timings.get_timings();t.time=l(".orderable-order-timings__time").val(),window.localStorage.setItem("orderable_timings",JSON.stringify(t)),l(this).siblings('input[name="orderable_order_time_slot_id"]').val(l(this).find(":selected").attr("data-orderable-time-slot-id"))})},get_timings(){return JSON.parse(window.localStorage.getItem("orderable_timings"))||{}}},l(e).ready(orderable_timings.on_ready)}(jQuery,document),function(a,o){"use strict";var e={on_ready(){e.watch()},watch(){void 0===window.orderable_triggers_admin&&a(o.body).on("click","[data-orderable-trigger]",e.trigger)},trigger(e){e.stopImmediatePropagation();var t=a(this),r=t.data("orderable-trigger");(t.is("button")||t.is("a"))&&e.preventDefault(),a(o.body).trigger("orderable-"+r,[t])}};a(o).ready(e.on_ready)}(jQuery,document);1 ((o,s)=>{var i={on_ready(){i.cache(),i.watch()},cache(){i.vars={classes:{parent:"orderable-accordion",link:"orderable-accordion__item-link",content:"orderable-accordion__item-content",link_active:"orderable-accordion__item-link--active",content_active:"orderable-accordion__item-content--active"}}},watch(){o(s.body).on("click","."+i.vars.classes.link,function(e){e.preventDefault();var e=o(this),t=e.closest("."+i.vars.classes.parent),r=e.attr("href"),r=o(r),a=e.hasClass(i.vars.classes.link_active);t.find("."+i.vars.classes.link).removeClass(i.vars.classes.link_active),t.find("."+i.vars.classes.content).removeClass(i.vars.classes.content_active),a||(e.addClass(i.vars.classes.link_active),r.addClass(i.vars.classes.content_active)),o(s.body).trigger("orderable-accordion.toggled",{link:e,content:r})}),o(s.body).on("orderable-scrollbar.created",function(e,t){var r=o(".orderable-drawer ."+i.vars.classes.link_active);r.length<=0||(r=(t=t.content).scrollTop()-t.offset().top+r.offset().top,t.scrollTop(r))})}};o(s).ready(i.on_ready)})(jQuery,document),((l,c)=>{var r={debounce(t,r=700){let a;return(...e)=>{clearTimeout(a),a=setTimeout(()=>{t.apply(this,e)},r)}},allow_only_numbers(e){var t=String.fromCharCode(e.which);/^\d+$/.test(t)||e.preventDefault()},on_change_quantity(e){let t=l(e.currentTarget);var e=t.data("orderable-product-id"),r=t.data("orderable-cart-item-key"),a=parseInt(t.text());jQuery.post(orderable_vars.ajax_url,{action:"orderable_cart_quantity",cart_item_key:r,product_id:e,quantity:a},function(e){e&&(l(c.body).trigger("added_to_cart",[e.fragments,e.cart_hash,t]),l(c.body).trigger("orderable-drawer.quantity-updated"))})},on_ready(){r.cache(),r.watch(),l(c.body).on("keypress",".orderable-quantity-roller__quantity",r.allow_only_numbers),l(".orderable-drawer__cart, .orderable-product--add-to-cart, .orderable-products-list").on("input",".orderable-quantity-roller__quantity",r.debounce(r.on_change_quantity)),l(c.body).on("click",".orderable-quantity-roller__quantity",function(e){e.stopPropagation()}),orderable_vars&&!orderable_vars.woocommerce_enable_ajax_add_to_cart&&l(c.body).off("click",".add_to_cart_button")},cache(){r.vars={classes:{overlay:"orderable-drawer-overlay",drawer:"orderable-drawer",drawer_cart:"orderable-drawer__cart",drawer_html:"orderable-drawer__html",overlay_open:"orderable-drawer-overlay--open",drawer_open:"orderable-drawer--open",drawer_open_body:"orderable-drawer-open"}},r.elements={body:l("body"),overlay:l("."+r.vars.classes.overlay),drawer:l("."+r.vars.classes.drawer),drawer_cart:l("."+r.vars.classes.drawer_cart),drawer_html:l("."+r.vars.classes.drawer_html),floating_cart_button_class:".orderable-floating-cart__button"}},watch(){var e,t;void 0!==r.elements.drawer&&(l(c.body).on("orderable-drawer.open",r.open),l(c.body).on("orderable-drawer.close",r.close),l(c.body).on("click",r.elements.floating_cart_button_class,function(){l(c.body).trigger("orderable-drawer.open",{show_cart:!0})}),l(c.body).on("orderable-increase-quantity",r.cart.handle_quantity_change_by_button),l(c.body).on("orderable-decrease-quantity",r.cart.handle_quantity_change_by_button),e=r.debounce(r.cart.click_increase_decrease_quantity),l(c.body).on("orderable-increase-quantity",e),l(c.body).on("orderable-decrease-quantity",e),e=c.querySelector("body:not( .rtl ) .orderable-drawer"),t=c.querySelector("body.rtl .orderable-drawer"),e&&e.addEventListener("swiped-right",function(e){r.close()}),t)&&t.addEventListener("swiped-left",function(e){r.close()})},open(e,t){t.html=t.html||!1,t.show_cart=t.show_cart||!1,r.elements.drawer_html.hide(),r.elements.drawer_cart.hide(),t.html&&(r.elements.drawer_html.html(t.html),r.elements.drawer_html.show()),t.show_cart&&(r.elements.drawer_html.html(""),r.elements.drawer_cart.show()),r.elements.overlay.addClass(r.vars.classes.overlay_open),r.elements.drawer.addClass(r.vars.classes.drawer_open),r.elements.body.addClass(r.vars.classes.drawer_open_body),l(c.body).trigger("orderable-drawer.opened",t)},close(){r.elements.overlay.removeClass(r.vars.classes.overlay_open),r.elements.drawer.removeClass(r.vars.classes.drawer_open),r.elements.body.removeClass(r.vars.classes.drawer_open_body),r.elements.drawer_html.html(""),l(c.body).trigger("orderable-drawer.closed")},cart:{click_increase_decrease_quantity(e,r){var t=r.data("orderable-trigger"),a=r.attr("data-orderable-product-id"),o=r.attr("data-orderable-cart-item-key"),s=r.attr("data-orderable-quantity");let i=r.siblings(".orderable-quantity-roller__button--"+("increase-quantity"===t?"decrease":"increase")),n=r.siblings(".orderable-quantity-roller__quantity"),d={action:"orderable_cart_quantity",cart_item_key:o,product_id:a,quantity:s};this.currentRequest&&(this.currentRequest.abort(),this.currentRequest=void 0),r.addClass("orderable-button--loading"),r.attr("disabled",!0),i.attr("disabled",!0),n.attr("contenteditable",!1),this.currentRequest=jQuery.post(orderable_vars.ajax_url,d,function(e){if(e){var t=r.siblings(".orderable-quantity-roller__quantity");switch(e&&e.fragments&&e.fragments[".orderable-mini-cart__notices"]&&l(c.body).trigger("orderable-drawer.open",{show_cart:!0}),d.quantity){case"0":l(c.body).trigger("removed_from_cart",[e.fragments,e.cart_hash,r]);break;case t.attr("data-orderable-updating-quantity"):l(c.body).trigger("added_to_cart",[e.fragments,e.cart_hash,r]),l(c.body).trigger("orderable-drawer.quantity-updated")}}}.bind(this)).always(function(){this.currentRequest=void 0,r.removeClass("orderable-button--loading"),r.attr("disabled",!1),i.attr("disabled",!1),n.attr("contenteditable",!0)}.bind(this))},handle_quantity_change_by_button(e,t){var r,a=t.data("orderable-trigger"),o=parseInt(t.attr("data-orderable-quantity")),s=t.siblings(".orderable-quantity-roller__button--"+("increase-quantity"===a?"decrease":"increase")),i=t.siblings(".orderable-quantity-roller__quantity"),a="increase-quantity"===a?o+1:Math.max(0,o-1),o=t.parents(".orderable-product__actions-button");0===a&&o.length&&(r=o.find("button.orderable-button[data-orderable-trigger]"),(o=o.find(".orderable-quantity-roller")).length)&&(r.removeClass("orderable-button--product-in-the-cart"),o.removeClass("orderable-quantity-roller--is-active")),t.attr("data-orderable-quantity",a),s.attr("data-orderable-quantity",a),i.attr("data-orderable-updating-quantity",a),i.text(a),i.attr("contenteditable",!1)}}};l(c).ready(r.on_ready)})(jQuery,document),((d,l)=>{var c={on_ready(){c.cache(),c.watch()},cache(){c.vars={classes:{clickable_product:"orderable-product--add-to-cart ",add_to_order_button:"orderable-product__add-to-order",product_messages:"orderable-product__messages",product_price:"orderable-product__actions-price",invalid_field:"orderable-field--invalid",option_select_td:"orderable-product__option-select",button_loading:"orderable-button--loading",out_of_stock:"orderable-button--out-of-stock"},parent_price:null,variable_product_types:["variable","variable-subscription"]},c.elements={}},watch(){d(l.body).on("orderable-drawer.opened",c.init_product_options),d(l.body).on("orderable-add-to-cart",c.click_add_to_order),d(l.body).on("orderable-product-options",c.click_add_to_order),d(l.body).on("orderable-view-product",c.view_product),d(l.body).on("mouseenter mouseleave","."+c.vars.classes.clickable_product,c.simulate_add_to_order_hover),d(l.body).on("orderable-edit-cart-item",c.edit_cart_item),d(l.body).on("orderable-update-cart-item",c.update_cart_item),d(l.body).on("orderable-show-cart",c.show_cart),d(l.body).on("orderable-add-to-cart-without-side-drawer",c.click_add_to_order),d(l.body).on("added_to_cart",c.remove_fragments),d(l.body).on("added_to_cart",c.remove_animation),d(l.body).on("added_to_cart",c.shake_floating_cart),d(l.body).on("removed_from_cart",c.hide_quantity_roller),d(l.body).on("wc_cart_button_updated",c.remove_view_cart_link)},simulate_add_to_order_hover(e){d(this).find("."+c.vars.classes.add_to_order_button).toggleClass("orderable-button--hover","mouseenter"===e.type)},click_add_to_order(e,t){let r=(t=void 0!==t?t:d(this)).is("button")?t:t.find("."+c.vars.classes.add_to_order_button),a=r.data("orderable-trigger"),o=r.data("orderable-product-id"),s=r.data("orderable-variation-id"),i=r.data("orderable-variation-attributes"),n={action:a};if(!r.hasClass(c.vars.classes.button_loading)&&!r.hasClass(c.vars.classes.out_of_stock))switch(r.addClass(c.vars.classes.button_loading),a){case"add-to-cart":c.add_to_cart({product_id:o,variation_id:s,attributes:i,thisbutton:t},function(e){n.show_cart=!0,n.response=e,d(l.body).trigger("orderable-drawer.open",n),r.removeClass(c.vars.classes.button_loading);e=d(".orderable-product .orderable-product__actions-button button.orderable-product__add-to-order[data-orderable-product-id="+o+"]");e.siblings(".orderable-quantity-roller").length&&e.addClass("orderable-button--product-in-the-cart")});break;case"add-to-cart-without-side-drawer":c.add_to_cart({product_id:o,variation_id:s,attributes:i},function(e){n.response=e,r.addClass("orderable-button--product-in-the-cart"),r.removeClass(c.vars.classes.button_loading)});break;case"product-options":c.get_product_options({product_id:o,focus:r.data("orderable-focus")},function(e){n.html=e.html,d(l.body).trigger("orderable-drawer.open",n),r.removeClass(c.vars.classes.button_loading)})}},show_cart(){d(l.body).trigger("orderable-drawer.open",{show_cart:!0})},view_product(e,t){let r=t.data("orderable-product-id"),a={action:"product-options"};c.get_product_options({product_id:r,focus:t.data("orderable-focus")},function(e){a.html=e.html,d(l.body).trigger("orderable-drawer.open",a)})},add_to_cart(t,r){if(void 0!==t.product_id){let e={action:"orderable_add_to_cart",product_id:t.product_id,variation_id:t.variation_id||!1,attributes:t.attributes||!1};var a;d(".orderable-product-fields-group").length&&(a=jQuery(".orderable-product-fields-group :input").serializeArray(),a=c.add_unchecked_checkbox_fields(a),a=c.convert_to_flat_object(a),jQuery.isEmptyObject(a)||(e=Object.assign(e,a))),jQuery.post(orderable_vars.ajax_url,e,function(e){e&&(d(l.body).trigger("added_to_cart",[e.fragments,e.cart_hash,t.thisbutton]),"function"==typeof r)&&r(e)})}},edit_cart_item(e,t){var r=t.data("orderable-cart-item-key");t.addClass(c.vars.classes.button_loading),c.get_cart_item_options({cart_item_key:r},function(e){e={html:e.html,action:"update-cart-item"};d(l.body).trigger("orderable-drawer.open",e),t.removeClass(c.vars.classes.button_loading)})},update_cart_item(e,r){var t=r.data("orderable-cart-item-key"),a=r.data("orderable-product-id"),o=r.data("orderable-variation-id"),s=r.data("orderable-variation-attributes");r.addClass(c.vars.classes.button_loading),c.update_cart_item_options({cart_item_key:t,product_id:a,variation_id:o,attributes:s},function(e){var t={show_cart:!0,response:e};d(l.body).trigger("added_to_cart",[e.fragments,e.cart_hash,r]),d(l.body).trigger("orderable-drawer.open",t),r.removeClass(c.vars.classes.button_loading)})},convert_to_flat_object(e){let a={};return e.forEach(function(e){var t="[]"===e.name.substr(-2)||Array.isArray(e.name),r=t?e.name.substr(0,e.name.length-2):e.name;t?(a[r]=void 0===a[r]?[]:a[r],a[r].push(e.value)):a[r]=e.value}),a},get_product_options(e,t){void 0!==e.product_id&&(e.action="orderable_get_product_options",jQuery.post(orderable_vars.ajax_url,e,function(e){e.success&&"function"==typeof t&&t(e.data)}))},get_cart_item_options(e,t){void 0!==e.cart_item_key&&(e.action="orderable_get_cart_item_options",jQuery.post(orderable_vars.ajax_url,e,function(e){e.success&&"function"==typeof t&&t(e.data)}))},update_cart_item_options(e,t){var r;void 0!==e.cart_item_key&&(e.action="orderable_update_cart_item_options",d(".orderable-product-fields-group").length&&(r=jQuery(".orderable-product-fields-group :input").serializeArray(),r=c.add_unchecked_checkbox_fields(r),r=c.convert_to_flat_object(r),jQuery.isEmptyObject(r)||(e=Object.assign(e,r))),jQuery.post(orderable_vars.ajax_url,e,function(e){e&&"function"==typeof t&&t(e)}))},init_product_options(e,a){if(void 0!==a.action&&("product-options"===a.action||"update-cart-item"===a.action)){a=".orderable-drawer .orderable-product__options input, .orderable-drawer .orderable-product__options select, .orderable-product__options textarea";let e=d(a),t=(c.vars.parent_price=d(".orderable-drawer .orderable-product__actions-price").html(),c.product_options_change(e),c.update_button_state(),c.debounce(c.update_button_state,500)),r=c.debounce(c.product_options_change,500);d(l).on("change keyup",a,function(){r(e),t()})}},product_options_change(e){var t=d(".orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item"),r=c.check_options(e),a=t.data("orderable-product-type");"product-options"===t.attr("data-orderable-trigger")&&t.attr("data-orderable-trigger","add-to-cart"),d("."+c.vars.classes.product_messages).html(""),c.vars.variable_product_types.includes(a)&&(r?(a=c.check_variation(e),c.set_variation(t,a)):c.clear_variation(t))},check_options(e){if(e.length<=0)return!1;let r=!0;return e.each(function(e,t){d(t).hasClass("orderable-input--validate")&&(""===d(t).val()?(d(t).addClass(c.vars.classes.invalid_field),r=!1):d(t).removeClass(c.vars.classes.invalid_field))}),r},check_variation(e){var t=(t=e.closest(".orderable-drawer").find(".orderable-product__variations").text())?JSON.parse(t):"",e=c.serialize_object(e),t=c.find_matching_variations(t,e);return!c.is_empty(t)&&((t=t.shift()).attributes=e,t.attributes_json=JSON.stringify(e),void 0!==t)&&t},set_variation(e,t){let r=t.variation_id||"",a=t.attributes_json||"",o=t.price_html||c.vars.parent_price,s="";t&&""!==t.availability_html&&(s=t.availability_html),t&&!t.is_in_stock&&(s="<p>"+orderable_vars.i18n.out_of_stock+"</p>"),t&&!t.is_purchasable&&(s="<p>"+orderable_vars.i18n.unavailable+"</p>"),!1===t&&(s="<p>"+orderable_vars.i18n.no_exist+"</p>"),!t||t.is_purchasable&&t.is_in_stock||(r="",a=""),""!==s&&d("."+c.vars.classes.product_messages).html(s),e.data("orderable-variation-id",r),e.data("orderable-variation-attributes",a),d(".orderable-drawer .orderable-product__actions-price").html(o),e.trigger("orderable_variation_set",{variation:t,variation_id:r,attributes:a,price:o})},clear_variation(e){c.set_variation(e,""),c.vars.parent_price&&d(".orderable-drawer .orderable-product__actions-price").html(c.vars.parent_price)},find_matching_variations(t,r){var a=[];for(let e=0;e<t.length;e++){var o=t[e];c.is_matching_variation(o.attributes,r)&&a.push(o)}return a},is_matching_variation(e,t){let r=!0;for(var a in e){var o;e.hasOwnProperty(a)&&(o=e[a],a=t[a],void 0!==o)&&void 0!==a&&0!==o.length&&0!==a.length&&o!==a&&(r=!1)}return r},is_empty(e){return void 0===e||!1===e||e.length<=0||!e},serialize_object:function(e){var t=e.serializeArray(),r={};for(let e=0;e<t.length;e++)r[t[e].name]=t[e].value;return r},update_button_state(){setTimeout(function(){let e=d(".orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item"),t=d(".orderable-drawer__html ."+c.vars.classes.invalid_field).length,r=e.data("orderable-product-type"),a=!0;"variable"===r&&(a=""!==e.data("orderable-variation-id")),e.prop("disabled",t||!a)},50)},debounce(a,o,s){let i;return function(){let e=this,t=arguments;var r=s&&!i;clearTimeout(i),i=setTimeout(function(){i=null,s||a.apply(e,t)},o),r&&a.apply(e,t)}},remove_fragments(e,t){if(t&&"undefined"!=typeof wc_cart_fragments_params&&wc_cart_fragments_params.fragment_name){var r,a=/\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-quantity-roller/,o=/\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-product__actions-counter/;for(r in t)(a.test(r)||o.test(r))&&(t[r]=void 0);sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(t))}},remove_animation(){setTimeout(function(){d(".orderable-product__actions-counter").css("animation","")},1e3)},hide_quantity_roller(e,t,r,a){var o,a=a.attr("data-product_id")||a.attr("data-orderable-product-id");a&&(a=d(".orderable-product[data-orderable-product-id="+a+"] .orderable-product__actions-button")).length&&(o=a.find(".orderable-quantity-roller")).length&&(a.find("button.orderable-product__add-to-order[data-orderable-trigger]").removeClass("orderable-button--product-in-the-cart"),o.addClass("orderable-button--hide"))},add_unchecked_checkbox_fields(r){return jQuery('.orderable-product-fields-group :input[type="checkbox"]:not(:checked)').each(function(e,t){r.push({name:t.getAttribute("name"),value:""})}),r},shake_floating_cart(){d(".orderable-floating-cart__button").css("animation","wobble-hor-bottom .8s both")},remove_view_cart_link(e,t){t?.hasClass("orderable-product__add-to-order")&&t?.siblings(".added_to_cart.wc-forward").remove()}};d(l).ready(c.on_ready)})(jQuery,document),((o,s)=>{var i={on_ready(){i.cache(),i.watch()},cache(){i.vars={top:{}},i.elements={}},watch(){o(s.body).on("orderable-drawer.opened",i.trigger),o(s.body).on("orderable-tabs.changed",i.trigger),o(s.body).on("orderable-accordion.toggled",i.trigger),o(s.body).on("wc_fragments_loaded",i.trigger)},trigger(){o(".orderable-sb-container").each(function(e,t){var r,t=o(t),a=t.data("orderable-scroll-id");i.has_scrollbar(t)||(t.scrollBox({containerClass:"orderable-sb-container",containerNoScrollClass:"orderable-sb-container-noscroll",contentClass:"orderable-sb-content",scrollbarContainerClass:"orderable-sb-scrollbar-container",scrollBarClass:"orderable-sb-scrollbar"}),0<(r=t.find(".orderable-sb-content")).length&&(r.on("scroll.scrollBox",i.log_top_position),void 0!==i.vars.top[a])&&r.scrollTop(i.vars.top[a]),o(s.body).trigger("orderable-scrollbar.created",{element:t,content:r}))}),o(window).trigger("resize.scrollBox")},has_scrollbar(e){return 0<e.find(".orderable-sb-content").length},log_top_position(e){var t=o(e.currentTarget).closest(".orderable-sb-container").data("orderable-scroll-id");i.vars.top[t]=o(e.currentTarget).scrollTop()}};o(s).ready(i.on_ready)})(jQuery,document),((i,n)=>{var d={on_ready(){d.cache(),d.watch(),d.toggle_scroll()},on_resize(){void 0===d.vars&&d.cache(),d.toggle_scroll()},cache(){d.vars={classes:{tabs:"orderable-tabs",tabs_list:"orderable-tabs__list",tab_items:"orderable-tabs__item",tab_item_active:"orderable-tabs__item--active",tab_links:"orderable-tabs__link",tab_arrow_right:"orderable-tabs__arrow-right",tab_arrow_left:"orderable-tabs__arrow-left"},dragging:!1},d.elements={}},watch(){i("body").on("touchstart",function(){d.vars.dragging=!1}).on("touchmove",function(){d.vars.dragging=!0}),i(n.body).on("click mouseup touchend","."+d.vars.classes.tab_links,function(e){var t,r,a,o,s;d.vars.dragging||(e.preventDefault(),t=(e=i(this)).attr("href"),r=e.closest("."+d.vars.classes.tab_items),a=(s=e.closest("."+d.vars.classes.tabs)).find("."+d.vars.classes.tabs_list),o=s.find("."+d.vars.classes.tab_items),s=s.data("orderable-tabs"),s=(e=e.closest(s.wrapper)).find(s.sections),e=e.find(t),s.hide(),e.show(),o.removeClass(d.vars.classes.tab_item_active),r.addClass(d.vars.classes.tab_item_active),a.animate({scrollLeft:a.scrollLeft()+r.position().left}),i(n.body).trigger("orderable-tabs.changed",{tab:r}))}),i("."+d.vars.classes.tabs_list).on("scroll",function(e){var t=i(this),r=t.parent("."+d.vars.classes.tabs),a=t.siblings("."+d.vars.classes.tab_arrow_right),o=t.siblings("."+d.vars.classes.tab_arrow_left);t[0].scrollWidth<=r.width()+t.scrollLeft()?a.fadeOut():a.fadeIn(),t.scrollLeft()-o.width()<=0?o.fadeOut():o.fadeIn()}),i("."+d.vars.classes.tabs_list).on("wheel DOMMouseScroll mousewheel touchmove",function(){i(this).stop()}),i(n).on("click","."+d.vars.classes.tab_arrow_right,function(e){e.preventDefault();var e=i(this).parent(),t=e.find("."+d.vars.classes.tabs_list);t.animate({scrollLeft:t.scrollLeft()+.5*e.width()})}),i(n).on("click","."+d.vars.classes.tab_arrow_left,function(e){e.preventDefault();var e=i(this).parent(),t=e.find("."+d.vars.classes.tabs_list);t.animate({scrollLeft:t.scrollLeft()-.5*e.width()})})},toggle_scroll(){i("."+d.vars.classes.tabs).each(function(e,t){var r=i(this),a=r.data("orderable-tabs"),r=r.closest(a.wrapper),a=r.find("."+d.vars.classes.tabs_list),o=r.find("."+d.vars.classes.tab_arrow_right);r.outerWidth()<a[0].scrollWidth?o.show():o.hide()})}};i(n).ready(d.on_ready),i(window).on("resize",d.on_resize)})(jQuery,document);let orderable_timings={};((l,e)=>{orderable_timings={on_ready(){orderable_timings.watch()},restore(){var e,t=orderable_timings.get_timings();t&&t.date&&(0<(e=l(".orderable-order-timings__date")).find('option[value="'+t.date+'"]').length&&(e.val(t.date),e.change()),t.time)&&0<(e=l(".orderable-order-timings__time")).find('option[value="'+t.time+'"]').length&&(e.val(t.time),e.change())},watch(){l(e.body).on("wc_fragments_refreshed",function(){orderable_timings.restore()}),l(e.body).on("updated_checkout",function(){orderable_timings.restore()}),l(e.body).on("change",".orderable-order-timings__date",function(e){let t=l(this),r=t.find("option:selected"),a=r.data("orderable-slots"),o=l(".orderable-order-timings--time"),s=l(".orderable-order-timings__time"),i=s.find("option").first(),n=s.find('option[value="asap"]').first();var d=orderable_timings.get_timings();d.date=l(".orderable-order-timings__date").val(),window.localStorage.setItem("orderable_timings",JSON.stringify(d)),s.html(i),n&&s.append(n),a?"all-day"===a[0].value?(o.hide(),s.prop("disabled",!0)):(s.prop("disabled",!1),o.show(),l.each(a,function(e,t){s.append(l("<option />").attr("value",t.value).attr("data-orderable-time-slot-id",t?.setting_row?.time_slot_id).text(t.formatted))})):(s.prop("disabled",!0),o.hide())}),l(e.body).on("change",".orderable-order-timings__time",function(e){var t=orderable_timings.get_timings();t.time=l(".orderable-order-timings__time").val(),window.localStorage.setItem("orderable_timings",JSON.stringify(t)),l(this).siblings('input[name="orderable_order_time_slot_id"]').val(l(this).find(":selected").attr("data-orderable-time-slot-id"))})},get_timings(){return JSON.parse(window.localStorage.getItem("orderable_timings"))||{}}},l(e).ready(orderable_timings.on_ready)})(jQuery,document),((a,o)=>{var e={on_ready(){e.watch()},watch(){void 0===window.orderable_triggers_admin&&a(o.body).on("click","[data-orderable-trigger]",e.trigger)},trigger(e){e.stopImmediatePropagation();var t=a(this),r=t.data("orderable-trigger");(t.is("button")||t.is("a"))&&e.preventDefault(),a(o.body).trigger("orderable-"+r,[t])}};a(o).ready(e.on_ready)})(jQuery,document),((o,e,s)=>{var i="scrollBox",r={containerClass:"sb-container",containerNoScrollClass:"sb-container-noscroll",contentClass:"sb-content",scrollbarContainerClass:"sb-scrollbar-container",scrollBarClass:"sb-scrollbar"};function t(e,t){this.element=e,this.settings=o.extend({},r,t),this._defaults=r,this._name=i,this.init()}o.extend(t.prototype,{init:function(){this.addScrollbar(),this.addEvents(),this.onResize()},addScrollbar:function(){o(this.element).addClass(this.settings.containerClass),this.wrapper=o("<div class='"+this.settings.contentClass+"' />"),this.wrapper.append(o(this.element).contents()),o(this.element).append(this.wrapper),this.scollbarContainer=o("<div class='"+this.settings.scrollbarContainerClass+"' />"),this.scrollBar=o("<div class='"+this.settings.scrollBarClass+"' />"),this.scollbarContainer.append(this.scrollBar),o(this.element).prepend(this.scollbarContainer)},addEvents:function(){this.wrapper.on("scroll."+i,o.proxy(this.onScroll,this)),o(e).on("resize."+i,o.proxy(this.onResize,this)),this.scrollBar.on("mousedown."+i,o.proxy(this.onMousedown,this)),this.scrollBar.on("touchstart."+i,o.proxy(this.onTouchstart,this))},onTouchstart:function(t){var r=this,a=(t.preventDefault(),r.scrollBar[0].offsetTop);o(s).on("touchmove."+i,function(e){e=e.touches[0].pageY-t.touches[0].pageY;r.scrollBar[0].style.top=Math.min(r.scollbarContainer[0].clientHeight-r.scrollBar[0].clientHeight,Math.max(0,a+e))+"px",r.wrapper[0].scrollTop=r.wrapper[0].scrollHeight*r.scrollBar[0].offsetTop/r.scollbarContainer[0].clientHeight}),o(s).on("touchend."+i,function(){o(s).off("touchmove."+i),o(s).off("touchend."+i)})},onMousedown:function(t){var r=this,a=(t.preventDefault(),r.scrollBar[0].offsetTop);o(s).on("mousemove."+i,function(e){e=e.pageY-t.pageY;r.scrollBar[0].style.top=Math.min(r.scollbarContainer[0].clientHeight-r.scrollBar[0].clientHeight,Math.max(0,a+e))+"px",r.wrapper[0].scrollTop=r.wrapper[0].scrollHeight*r.scrollBar[0].offsetTop/r.scollbarContainer[0].clientHeight}),o(s).on("mouseup."+i,function(){o(s).off("mousemove."+i),o(s).off("mouseup."+i)})},onResize:function(){this.wrapper.css("max-height",o(this.element).height());var e=this.wrapper[0].clientHeight;this.scrollBar.css("height",this.scollbarContainer[0].clientHeight*e/this.wrapper[0].scrollHeight+"px"),this.scollbarContainer[0].clientHeight<=this.scrollBar[0].clientHeight?o(this.element).addClass(this.settings.containerNoScrollClass):o(this.element).removeClass(this.settings.containerNoScrollClass),this.onScroll()},onScroll:function(){this.scrollBar.css("top",Math.min(this.scollbarContainer[0].clientHeight-this.scrollBar[0].clientHeight,this.scollbarContainer[0].clientHeight*this.wrapper[0].scrollTop/this.wrapper[0].scrollHeight)+"px")}}),o.fn[i]=function(e){return this.each(function(){o.data(this,"plugin_"+i)||o.data(this,"plugin_"+i,new t(this,e))})}})(jQuery,window,document),((e,o)=>{"function"!=typeof e.CustomEvent&&(e.CustomEvent=function(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var r=o.createEvent("CustomEvent");return r.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),r},e.CustomEvent.prototype=e.Event.prototype),o.addEventListener("touchstart",function(e){"true"!==e.target.getAttribute("data-swipe-ignore")&&(c=e.target,l=Date.now(),s=e.touches[0].clientX,i=e.touches[0].clientY,d=n=0)},!1),o.addEventListener("touchmove",function(e){var t;s&&i&&(t=e.touches[0].clientX,e=e.touches[0].clientY,n=s-t,d=i-e)},!1),o.addEventListener("touchend",function(e){var t,r,a,o;c===e.target&&(o=parseInt(_(c,"data-swipe-threshold","20"),10),t=parseInt(_(c,"data-swipe-timeout","500"),10),r=Date.now()-l,a="",e=e.changedTouches||e.touches||[],Math.abs(n)>Math.abs(d)?Math.abs(n)>o&&r<t&&(a=0<n?"swiped-left":"swiped-right"):Math.abs(d)>o&&r<t&&(a=0<d?"swiped-up":"swiped-down"),""!==a&&(o={dir:a.replace(/swiped-/,""),touchType:(e[0]||{}).touchType||"direct",xStart:parseInt(s,10),xEnd:parseInt((e[0]||{}).clientX||-1,10),yStart:parseInt(i,10),yEnd:parseInt((e[0]||{}).clientY||-1,10)},c.dispatchEvent(new CustomEvent("swiped",{bubbles:!0,cancelable:!0,detail:o})),c.dispatchEvent(new CustomEvent(a,{bubbles:!0,cancelable:!0,detail:o}))),l=i=s=null)},!1);var s=null,i=null,n=null,d=null,l=null,c=null;function _(e,t,r){for(;e&&e!==o.documentElement;){var a=e.getAttribute(t);if(a)return a;e=e.parentNode}return r}})(window,document); -
orderable/tags/1.17.1/docs/filters.json
r3192586 r3237969 270 270 "type": "filter", 271 271 "doc": { 272 "description": "", 273 "long_description": "", 274 "tags": [], 275 "long_description_html": "" 276 }, 277 "args": 2 278 }, 279 { 280 "name": "orderable_get_accordion_data", 281 "file": "inc/class-products.php", 282 "type": "filter", 283 "doc": { 284 "description": "", 285 "long_description": "", 286 "tags": [], 287 "long_description_html": "" 288 }, 289 "args": 2 290 }, 291 { 292 "name": "orderable_get_accordion_data", 293 "file": "inc/class-products.php", 294 "type": "filter", 295 "doc": { 272 296 "description": "Filter product accordion data.", 273 297 "long_description": "", … … 288 312 ], 289 313 "variable": "$product" 314 }, 315 { 316 "name": "since", 317 "content": "1.0.0" 290 318 } 291 319 ], -
orderable/tags/1.17.1/languages/orderable.pot
r3192586 r3237969 1 # Copyright (C) 202 4orderable1 # Copyright (C) 2025 orderable 2 2 # This file is distributed under the same license as the orderable package. 3 3 msgid "" … … 7 7 "Content-Type: text/plain; charset=UTF-8\n" 8 8 "Content-Transfer-Encoding: 8bit\n" 9 "POT-Creation-Date: 202 4-11-19 18:56+0000\n"9 "POT-Creation-Date: 2025-02-10 13:33+0000\n" 10 10 "X-Poedit-Basepath: ..\n" 11 11 "X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n" -
orderable/tags/1.17.1/orderable.php
r3192586 r3237969 4 4 * Author URI: https://orderable.com 5 5 * Description: Take local online ordering to a whole new level with Orderable. 6 * Version: 1.17. 06 * Version: 1.17.1 7 7 * Author: Orderable 8 8 * Text Domain: orderable 9 9 * WC requires at least: 5.4.0 10 * WC tested up to: 9. 410 * WC tested up to: 9.6 11 11 */ 12 12 … … 20 20 * @var string Plugin version. 21 21 */ 22 public static $version = '1.17. 0';22 public static $version = '1.17.1'; 23 23 24 24 /** -
orderable/tags/1.17.1/readme.txt
r3192586 r3237969 5 5 Tested up to: 6.7 6 6 Requires PHP: 5.6 7 Stable tag: 1.17. 07 Stable tag: 1.17.1 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 186 186 187 187 == Changelog == 188 **v1.17.1** (10 Feb 2025) 189 [fix] Compatibility issue with Xstore theme 190 188 191 **v1.17.0** (19 Nov 2024) 189 192 [fix] Compatibility with Flux Checkout for WooCommerce plugin -
orderable/trunk/assets/frontend/js/main.js
r3192586 r3237969 1 1 2 (function ($, document) { 3 'use strict'; 4 5 var orderable_accordion = { 6 /** 7 * On doc ready. 8 */ 9 on_ready() { 10 orderable_accordion.cache(); 11 orderable_accordion.watch(); 12 }, 13 /** 14 * Cache. 15 */ 16 cache() { 17 orderable_accordion.vars = { 18 classes: { 19 parent: 'orderable-accordion', 20 link: 'orderable-accordion__item-link', 21 content: 'orderable-accordion__item-content', 22 link_active: 'orderable-accordion__item-link--active', 23 content_active: 'orderable-accordion__item-content--active' 24 } 25 }; 26 }, 27 /** 28 * Watch. 29 */ 30 watch() { 31 /** 32 * When click accordion link. 33 */ 34 $(document.body).on('click', '.' + orderable_accordion.vars.classes.link, function (e) { 35 e.preventDefault(); 36 const $link = $(this), 37 $parent = $link.closest('.' + orderable_accordion.vars.classes.parent), 38 content_id = $link.attr('href'), 39 $content = $(content_id), 40 is_active = $link.hasClass(orderable_accordion.vars.classes.link_active); 41 $parent.find('.' + orderable_accordion.vars.classes.link).removeClass(orderable_accordion.vars.classes.link_active); 42 $parent.find('.' + orderable_accordion.vars.classes.content).removeClass(orderable_accordion.vars.classes.content_active); 43 if (!is_active) { 44 $link.addClass(orderable_accordion.vars.classes.link_active); 45 $content.addClass(orderable_accordion.vars.classes.content_active); 46 } 47 $(document.body).trigger('orderable-accordion.toggled', { 48 link: $link, 49 content: $content 50 }); 51 }); 52 53 /** 54 * When drawer is opened. 55 */ 56 $(document.body).on('orderable-scrollbar.created', function (e, args) { 57 const $active_accordion = $('.orderable-drawer .' + orderable_accordion.vars.classes.link_active); 58 if ($active_accordion.length <= 0) { 59 return; 60 } 61 const $scroll_content = args.content, 62 scroll_position = $scroll_content.scrollTop() - $scroll_content.offset().top + $active_accordion.offset().top; 63 $scroll_content.scrollTop(scroll_position); 64 }); 65 } 66 }; 67 $(document).ready(orderable_accordion.on_ready); 68 })(jQuery, document); 69 (function ($, document) { 70 'use strict'; 71 72 var orderable_drawer = { 73 /** 74 * Delays invoking function 75 * 76 * @param {Function} func The function to debounce. 77 * @param {number} timeout The number of milliseconds to delay. 78 * @return {Function} Returns the new debounced function. 79 */ 80 debounce(func, timeout = 700) { 81 let timer; 82 return (...args) => { 83 clearTimeout(timer); 84 timer = setTimeout(() => { 85 func.apply(this, args); 86 }, timeout); 87 }; 88 }, 89 /** 90 * Allow only number for events like keypress 91 * 92 * @param {Event} event 93 */ 94 allow_only_numbers(event) { 95 const value = String.fromCharCode(event.which); 96 if (!/^\d+$/.test(value)) { 97 event.preventDefault(); 98 } 99 }, 100 /** 101 * Send a request to change the quantity. 102 * 103 * @param {Event} event 104 */ 105 on_change_quantity(event) { 106 const quantityElement = $(event.currentTarget); 107 const product_id = quantityElement.data('orderable-product-id'); 108 const cart_item_key = quantityElement.data('orderable-cart-item-key'); 109 const quantity = parseInt(quantityElement.text()); 110 const data = { 111 action: 'orderable_cart_quantity', 112 cart_item_key, 113 product_id, 114 quantity 115 }; 116 jQuery.post(orderable_vars.ajax_url, data, function (response) { 117 if (!response) { 118 return; 119 } 120 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, quantityElement]); 121 $(document.body).trigger('orderable-drawer.quantity-updated'); 122 }); 123 }, 124 /** 125 * On doc ready. 126 */ 127 on_ready() { 128 orderable_drawer.cache(); 129 orderable_drawer.watch(); 130 131 /** 132 * Handle manually changing the quantity of a product. 133 */ 134 $(document.body).on('keypress', '.orderable-quantity-roller__quantity', orderable_drawer.allow_only_numbers); 135 $('.orderable-drawer__cart, .orderable-product--add-to-cart, .orderable-products-list').on('input', '.orderable-quantity-roller__quantity', orderable_drawer.debounce(orderable_drawer.on_change_quantity)); 136 $(document.body).on('click', '.orderable-quantity-roller__quantity', function (event) { 137 event.stopPropagation(); 138 }); 139 140 /** 141 * We turn off the click event for .add_to_cart_button elements 142 * to keep the AJAX behaviour only on Mini cart when the option 143 * "Enable AJAX add to cart buttons on archives" is disabled. 144 */ 145 if (orderable_vars && !orderable_vars.woocommerce_enable_ajax_add_to_cart) { 146 $(document.body).off('click', '.add_to_cart_button'); 147 } 148 }, 149 /** 150 * Cache. 151 */ 152 cache() { 153 orderable_drawer.vars = { 154 classes: { 155 overlay: 'orderable-drawer-overlay', 156 drawer: 'orderable-drawer', 157 drawer_cart: 'orderable-drawer__cart', 158 drawer_html: 'orderable-drawer__html', 159 overlay_open: 'orderable-drawer-overlay--open', 160 drawer_open: 'orderable-drawer--open', 161 drawer_open_body: 'orderable-drawer-open' 162 } 163 }; 164 orderable_drawer.elements = { 165 body: $('body'), 166 overlay: $('.' + orderable_drawer.vars.classes.overlay), 167 drawer: $('.' + orderable_drawer.vars.classes.drawer), 168 drawer_cart: $('.' + orderable_drawer.vars.classes.drawer_cart), 169 drawer_html: $('.' + orderable_drawer.vars.classes.drawer_html), 170 floating_cart_button_class: '.orderable-floating-cart__button' 171 }; 172 }, 173 /** 174 * Watch for trigger events. 175 */ 176 watch() { 177 if (typeof orderable_drawer.elements.drawer === 'undefined') { 178 return; 179 } 180 $(document.body).on('orderable-drawer.open', orderable_drawer.open); 181 $(document.body).on('orderable-drawer.close', orderable_drawer.close); 182 $(document.body).on('click', orderable_drawer.elements.floating_cart_button_class, function () { 183 $(document.body).trigger('orderable-drawer.open', { 184 show_cart: true 185 }); 186 }); 187 $(document.body).on('orderable-increase-quantity', orderable_drawer.cart.handle_quantity_change_by_button); 188 $(document.body).on('orderable-decrease-quantity', orderable_drawer.cart.handle_quantity_change_by_button); 189 const updateQuantityRequest = orderable_drawer.debounce(orderable_drawer.cart.click_increase_decrease_quantity); 190 $(document.body).on('orderable-increase-quantity', updateQuantityRequest); 191 $(document.body).on('orderable-decrease-quantity', updateQuantityRequest); 192 const drawer = document.querySelector('body:not( .rtl ) .orderable-drawer'); 193 const drawer_rtl = document.querySelector('body.rtl .orderable-drawer'); 194 if (drawer) { 195 drawer.addEventListener('swiped-right', function (e) { 196 orderable_drawer.close(); 197 }); 198 } 199 if (drawer_rtl) { 200 drawer_rtl.addEventListener('swiped-left', function (e) { 201 orderable_drawer.close(); 202 }); 203 } 204 }, 205 /** 206 * Open the drawer. 207 * @param event 208 * @param args 209 */ 210 open(event, args) { 211 args.html = args.html || false; 212 args.show_cart = args.show_cart || false; 213 orderable_drawer.elements.drawer_html.hide(); 214 orderable_drawer.elements.drawer_cart.hide(); 215 if (args.html) { 216 orderable_drawer.elements.drawer_html.html(args.html); 217 orderable_drawer.elements.drawer_html.show(); 218 } 219 if (args.show_cart) { 220 // Empty drawer HTML before showing cart. Prevents options 221 // interfering with subsequent cart additions. 222 orderable_drawer.elements.drawer_html.html(''); 223 orderable_drawer.elements.drawer_cart.show(); 224 } 225 orderable_drawer.elements.overlay.addClass(orderable_drawer.vars.classes.overlay_open); 226 orderable_drawer.elements.drawer.addClass(orderable_drawer.vars.classes.drawer_open); 227 orderable_drawer.elements.body.addClass(orderable_drawer.vars.classes.drawer_open_body); 228 $(document.body).trigger('orderable-drawer.opened', args); 229 }, 230 /** 231 * Close the drawer. 232 */ 233 close() { 234 orderable_drawer.elements.overlay.removeClass(orderable_drawer.vars.classes.overlay_open); 235 orderable_drawer.elements.drawer.removeClass(orderable_drawer.vars.classes.drawer_open); 236 orderable_drawer.elements.body.removeClass(orderable_drawer.vars.classes.drawer_open_body); 237 orderable_drawer.elements.drawer_html.html(''); 238 $(document.body).trigger('orderable-drawer.closed'); 239 }, 240 /** 241 * Mini cart related functions. 242 */ 243 cart: { 244 /** 245 * When increase qty is clicked. 246 * 247 * @param e 248 * @param $button 249 */ 250 click_increase_decrease_quantity(e, $button) { 251 const direction = $button.data('orderable-trigger'); 252 const product_id = $button.attr('data-orderable-product-id'), 253 cart_item_key = $button.attr('data-orderable-cart-item-key'), 254 quantity = $button.attr('data-orderable-quantity'); 255 const siblingButtonName = 'increase-quantity' === direction ? 'decrease' : 'increase'; 256 const $siblingButton = $button.siblings(`.orderable-quantity-roller__button--${siblingButtonName}`); 257 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity'); 258 const data = { 259 action: 'orderable_cart_quantity', 260 cart_item_key, 261 product_id, 262 quantity 263 }; 264 if (this.currentRequest) { 265 this.currentRequest.abort(); 266 this.currentRequest = undefined; 267 } 268 $button.addClass('orderable-button--loading'); 269 $button.attr('disabled', true); 270 $siblingButton.attr('disabled', true); 271 $quantityElement.attr('contenteditable', false); 272 this.currentRequest = jQuery.post(orderable_vars.ajax_url, data, function (response) { 273 if (!response) { 274 return; 275 } 276 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity'); 277 if (response && response.fragments && response.fragments['.orderable-mini-cart__notices']) { 278 $(document.body).trigger('orderable-drawer.open', { 279 show_cart: true 280 }); 281 } 282 switch (data.quantity) { 283 case '0': 284 $(document.body).trigger('removed_from_cart', [response.fragments, response.cart_hash, $button]); 285 break; 286 case $quantityElement.attr('data-orderable-updating-quantity'): 287 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $button]); 288 $(document.body).trigger('orderable-drawer.quantity-updated'); 289 break; 290 default: 291 break; 292 } 293 }.bind(this)).always(function () { 294 this.currentRequest = undefined; 295 $button.removeClass('orderable-button--loading'); 296 $button.attr('disabled', false); 297 $siblingButton.attr('disabled', false); 298 $quantityElement.attr('contenteditable', true); 299 }.bind(this)); 300 }, 301 handle_quantity_change_by_button(e, $button) { 302 const direction = $button.data('orderable-trigger'); 303 const quantity = parseInt($button.attr('data-orderable-quantity')); 304 const siblingButtonName = 'increase-quantity' === direction ? 'decrease' : 'increase'; 305 const $siblingButton = $button.siblings(`.orderable-quantity-roller__button--${siblingButtonName}`); 306 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity'); 307 const newQuantity = 'increase-quantity' === direction ? quantity + 1 : Math.max(0, quantity - 1); 308 const $parent = $button.parents('.orderable-product__actions-button'); 309 if (0 === newQuantity && $parent.length) { 310 const $addToCartButton = $parent.find('button.orderable-button[data-orderable-trigger]'); 311 const $quantityRoller = $parent.find('.orderable-quantity-roller'); 312 if ($quantityRoller.length) { 313 $addToCartButton.removeClass('orderable-button--product-in-the-cart'); 314 $quantityRoller.removeClass('orderable-quantity-roller--is-active'); 315 } 316 } 317 $button.attr('data-orderable-quantity', newQuantity); 318 $siblingButton.attr('data-orderable-quantity', newQuantity); 319 $quantityElement.attr('data-orderable-updating-quantity', newQuantity); 320 $quantityElement.text(newQuantity); 321 $quantityElement.attr('contenteditable', false); 322 } 323 } 324 }; 325 $(document).ready(orderable_drawer.on_ready); 326 })(jQuery, document); 327 (function ($, document) { 328 'use strict'; 329 330 var orderable_products = { 331 /** 332 * On doc ready. 333 */ 334 on_ready() { 335 orderable_products.cache(); 336 orderable_products.watch(); 337 }, 338 /** 339 * Cache. 340 */ 341 cache() { 342 orderable_products.vars = { 343 classes: { 344 clickable_product: 'orderable-product--add-to-cart ', 345 add_to_order_button: 'orderable-product__add-to-order', 346 product_messages: 'orderable-product__messages', 347 product_price: 'orderable-product__actions-price', 348 invalid_field: 'orderable-field--invalid', 349 option_select_td: 'orderable-product__option-select', 350 button_loading: 'orderable-button--loading', 351 out_of_stock: 'orderable-button--out-of-stock' 352 }, 353 parent_price: null, 354 variable_product_types: ['variable', 'variable-subscription'] 355 }; 356 orderable_products.elements = {}; 357 }, 358 /** 359 * Watch for trigger events. 360 */ 361 watch() { 362 $(document.body).on('orderable-drawer.opened', orderable_products.init_product_options); 363 $(document.body).on('orderable-add-to-cart', orderable_products.click_add_to_order); 364 $(document.body).on('orderable-product-options', orderable_products.click_add_to_order); 365 $(document.body).on('orderable-view-product', orderable_products.view_product); 366 $(document.body).on('mouseenter mouseleave', '.' + orderable_products.vars.classes.clickable_product, orderable_products.simulate_add_to_order_hover); 367 $(document.body).on('orderable-edit-cart-item', orderable_products.edit_cart_item); 368 $(document.body).on('orderable-update-cart-item', orderable_products.update_cart_item); 369 $(document.body).on('orderable-show-cart', orderable_products.show_cart); 370 $(document.body).on('orderable-add-to-cart-without-side-drawer', orderable_products.click_add_to_order); 371 $(document.body).on('added_to_cart', orderable_products.remove_fragments); 372 $(document.body).on('added_to_cart', orderable_products.remove_animation); 373 $(document.body).on('added_to_cart', orderable_products.shake_floating_cart); 374 $(document.body).on('removed_from_cart', orderable_products.hide_quantity_roller); 375 $(document.body).on('wc_cart_button_updated', orderable_products.remove_view_cart_link); 376 }, 377 /** 378 * Simulate hover on add to order button. 379 * 380 * @param event 381 */ 382 simulate_add_to_order_hover(event) { 383 const $element = $(this), 384 $button = $element.find('.' + orderable_products.vars.classes.add_to_order_button); 385 $button.toggleClass('orderable-button--hover', 'mouseenter' === event.type); 386 }, 387 /** 388 * Add to order click event. 389 * 390 * This event accounts for button clicks or card clicks. 391 * @param event 392 * @param $element 393 */ 394 click_add_to_order(event, $element) { 395 // If undefined, it means it was triggered by a click 396 // event and not the `orderable-add-to-cart` trigger. 397 $element = typeof $element !== 'undefined' ? $element : $(this); 398 399 // The button is either the clicked element, or the 400 // add to order button within the clicked element. 401 const $button = $element.is('button') ? $element : $element.find('.' + orderable_products.vars.classes.add_to_order_button), 402 action = $button.data('orderable-trigger'), 403 product_id = $button.data('orderable-product-id'), 404 variation_id = $button.data('orderable-variation-id'), 405 attributes = $button.data('orderable-variation-attributes'), 406 args = { 407 action 408 }; 409 if ($button.hasClass(orderable_products.vars.classes.button_loading) || $button.hasClass(orderable_products.vars.classes.out_of_stock)) { 410 return; 411 } 412 $button.addClass(orderable_products.vars.classes.button_loading); 413 switch (action) { 414 case 'add-to-cart': 415 orderable_products.add_to_cart({ 416 product_id, 417 variation_id, 418 attributes, 419 thisbutton: $element 420 }, function (response) { 421 args.show_cart = true; 422 args.response = response; 423 $(document.body).trigger('orderable-drawer.open', args); 424 $button.removeClass(orderable_products.vars.classes.button_loading); 425 const $addToCartButtonOutsideDrawer = $('.orderable-product .orderable-product__actions-button button.orderable-product__add-to-order[data-orderable-product-id=' + product_id + ']'); 426 if ($addToCartButtonOutsideDrawer.siblings('.orderable-quantity-roller').length) { 427 $addToCartButtonOutsideDrawer.addClass('orderable-button--product-in-the-cart'); 428 } 429 }); 430 break; 431 case 'add-to-cart-without-side-drawer': 432 orderable_products.add_to_cart({ 433 product_id, 434 variation_id, 435 attributes 436 }, function (response) { 437 args.response = response; 438 $button.addClass('orderable-button--product-in-the-cart'); 439 $button.removeClass(orderable_products.vars.classes.button_loading); 440 }); 441 break; 442 case 'product-options': 443 orderable_products.get_product_options({ 444 product_id, 445 focus: $button.data('orderable-focus') 446 }, function (response) { 447 args.html = response.html; 448 $(document.body).trigger('orderable-drawer.open', args); 449 $button.removeClass(orderable_products.vars.classes.button_loading); 450 }); 451 break; 452 default: 453 break; 454 } 455 }, 456 /** 457 * Show the cart. 458 */ 459 show_cart() { 460 $(document.body).trigger('orderable-drawer.open', { 461 show_cart: true 462 }); 463 }, 464 /** 465 * View product. 466 * 467 * @param event 468 * @param $element 469 */ 470 view_product(event, $element) { 471 const product_id = $element.data('orderable-product-id'), 472 args = { 473 action: 'product-options' 474 }; 475 orderable_products.get_product_options({ 476 product_id, 477 focus: $element.data('orderable-focus') 478 }, function (response) { 479 args.html = response.html; 480 $(document.body).trigger('orderable-drawer.open', args); 481 }); 482 }, 483 /** 484 * Ajax add to cart. 485 * @param args 486 * @param callback 487 */ 488 add_to_cart(args, callback) { 489 if (typeof args.product_id === 'undefined') { 490 return; 491 } 492 let data = { 493 action: 'orderable_add_to_cart', 494 product_id: args.product_id, 495 variation_id: args.variation_id || false, 496 attributes: args.attributes || false 497 }; 498 499 // Prepare addons data. 500 if ($('.orderable-product-fields-group').length) { 501 let inputs = jQuery('.orderable-product-fields-group :input').serializeArray(); 502 inputs = orderable_products.add_unchecked_checkbox_fields(inputs); 503 const addons_data = orderable_products.convert_to_flat_object(inputs); 504 if (!jQuery.isEmptyObject(addons_data)) { 505 data = Object.assign(data, addons_data); // Merge objects. 506 } 507 } 508 jQuery.post(orderable_vars.ajax_url, data, function (response) { 509 if (!response) { 510 return; 511 } 512 513 // Trigger event so themes can refresh other areas. 514 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, args.thisbutton]); 515 if (typeof callback === 'function') { 516 callback(response); 517 } 518 }); 519 }, 520 /** 521 * Edit cart item. 522 * 523 * @param event 524 * @param $element 525 */ 526 edit_cart_item(event, $element) { 527 const cart_item_key = $element.data('orderable-cart-item-key'); 528 $element.addClass(orderable_products.vars.classes.button_loading); 529 orderable_products.get_cart_item_options({ 530 cart_item_key 531 }, function (response) { 532 const args = { 533 html: response.html, 534 action: 'update-cart-item' 535 }; 536 $(document.body).trigger('orderable-drawer.open', args); 537 $element.removeClass(orderable_products.vars.classes.button_loading); 538 }); 539 }, 540 /** 541 * Update cart item. 542 * 543 * @param event 544 * @param $element 545 */ 546 update_cart_item(event, $element) { 547 const cart_item_key = $element.data('orderable-cart-item-key'); 548 const product_id = $element.data('orderable-product-id'); 549 const variation_id = $element.data('orderable-variation-id'); 550 const attributes = $element.data('orderable-variation-attributes'); 551 $element.addClass(orderable_products.vars.classes.button_loading); 552 orderable_products.update_cart_item_options({ 553 cart_item_key, 554 product_id, 555 variation_id, 556 attributes 557 }, function (response) { 558 const args = { 559 show_cart: true, 560 response 561 }; 562 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $element]); 563 $(document.body).trigger('orderable-drawer.open', args); 564 $element.removeClass(orderable_products.vars.classes.button_loading); 565 }); 566 }, 567 /** 568 * Convert [{name:x, value:y }] to {x:y} format. 569 * @param inputs 570 */ 571 convert_to_flat_object(inputs) { 572 const data = {}; 573 inputs.forEach(function (input) { 574 const is_array = '[]' === input.name.substr(-2) || Array.isArray(input.name); 575 // If last 2 chars are '[]', remove them. 576 const key = is_array ? input.name.substr(0, input.name.length - 2) : input.name; 577 if (is_array) { 578 data[key] = typeof data[key] === 'undefined' ? [] : data[key]; 579 data[key].push(input.value); 580 } else { 581 data[key] = input.value; 582 } 583 }); 584 return data; 585 }, 586 /** 587 * Get variable product options. 588 * 589 * @param args 590 * @param callback 591 */ 592 get_product_options(args, callback) { 593 if (typeof args.product_id === 'undefined') { 594 return; 595 } 596 args.action = 'orderable_get_product_options'; 597 jQuery.post(orderable_vars.ajax_url, args, function (response) { 598 if (!response.success) { 599 return; 600 } 601 if (typeof callback === 'function') { 602 callback(response.data); 603 } 604 }); 605 }, 606 /** 607 * Get variable product options. 608 * 609 * @param args 610 * @param callback 611 */ 612 get_cart_item_options(args, callback) { 613 if (typeof args.cart_item_key === 'undefined') { 614 return; 615 } 616 args.action = 'orderable_get_cart_item_options'; 617 jQuery.post(orderable_vars.ajax_url, args, function (response) { 618 if (!response.success) { 619 return; 620 } 621 if (typeof callback === 'function') { 622 callback(response.data); 623 } 624 }); 625 }, 626 /** 627 * Update variable product options. 628 * 629 * @param args 630 * @param callback 631 */ 632 update_cart_item_options(args, callback) { 633 if (typeof args.cart_item_key === 'undefined') { 634 return; 635 } 636 args.action = 'orderable_update_cart_item_options'; 637 638 // Prepare addons data. 639 if ($('.orderable-product-fields-group').length) { 640 let inputs = jQuery('.orderable-product-fields-group :input').serializeArray(); 641 inputs = orderable_products.add_unchecked_checkbox_fields(inputs); 642 const addons_data = orderable_products.convert_to_flat_object(inputs); 643 if (!jQuery.isEmptyObject(addons_data)) { 644 args = Object.assign(args, addons_data); // Merge objects. 645 } 646 } 647 jQuery.post(orderable_vars.ajax_url, args, function (response) { 648 if (!response) { 649 return; 650 } 651 if (typeof callback === 'function') { 652 callback(response); 653 } 654 }); 655 }, 656 /** 657 * Init drawer product options. 658 * 659 * @param event 660 * @param args 661 */ 662 init_product_options(event, args) { 663 if (typeof args.action === 'undefined' || 'product-options' !== args.action && 'update-cart-item' !== args.action) { 664 return; 665 } 666 const selectors = '.orderable-drawer .orderable-product__options input, .orderable-drawer .orderable-product__options select, .orderable-product__options textarea'; 667 const $options = $(selectors); 668 orderable_products.vars.parent_price = $('.orderable-drawer .orderable-product__actions-price').html(); 669 orderable_products.product_options_change($options); 670 orderable_products.update_button_state(); 671 const debounced_update_button_state = orderable_products.debounce(orderable_products.update_button_state, 500); 672 const debounced_product_options_change = orderable_products.debounce(orderable_products.product_options_change, 500); 673 $(document).on('change keyup', selectors, function () { 674 debounced_product_options_change($options); 675 debounced_update_button_state(); 676 }); 677 }, 678 /** 679 * On product options change. 680 * 681 * @param $options 682 */ 683 product_options_change($options) { 684 const $add_to_order_button = $('.orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item'), 685 options_set = orderable_products.check_options($options), 686 product_type = $add_to_order_button.data('orderable-product-type'); 687 if ('product-options' === $add_to_order_button.attr('data-orderable-trigger')) { 688 $add_to_order_button.attr('data-orderable-trigger', 'add-to-cart'); 689 } 690 $('.' + orderable_products.vars.classes.product_messages).html(''); 691 if (!orderable_products.vars.variable_product_types.includes(product_type)) { 692 return; 693 } 694 if (!options_set) { 695 orderable_products.clear_variation($add_to_order_button); 696 return; 697 } 698 const variation = orderable_products.check_variation($options); 699 orderable_products.set_variation($add_to_order_button, variation); 700 }, 701 /** 702 * Check if all product options are set. 703 * 704 * @param $options 705 * @return {boolean} 706 */ 707 check_options($options) { 708 if ($options.length <= 0) { 709 return false; 710 } 711 let all_set = true; 712 $options.each(function (index, option) { 713 // Only check attribute fields. 714 if (!$(option).hasClass('orderable-input--validate')) { 715 return; 716 } 717 if ('' === $(option).val()) { 718 $(option).addClass(orderable_products.vars.classes.invalid_field); 719 all_set = false; 720 } else { 721 $(option).removeClass(orderable_products.vars.classes.invalid_field); 722 } 723 }); 724 return all_set; 725 }, 726 /** 727 * Check if variation has been selected. 728 * @param $options 729 */ 730 check_variation($options) { 731 const $product = $options.closest('.orderable-drawer'); 732 let variations = $product.find('.orderable-product__variations').text(); 733 variations = variations ? JSON.parse(variations) : ''; 734 const selected_options = orderable_products.serialize_object($options), 735 matching_variations = orderable_products.find_matching_variations(variations, selected_options); 736 if (orderable_products.is_empty(matching_variations)) { 737 return false; 738 } 739 const variation = matching_variations.shift(); 740 variation.attributes = selected_options; 741 variation.attributes_json = JSON.stringify(selected_options); 742 return typeof variation !== 'undefined' ? variation : false; 743 }, 744 /** 745 * Set variation for add to cart button. 746 * @param $button 747 * @param variation 748 */ 749 set_variation($button, variation) { 750 let variation_id = variation.variation_id || '', 751 attributes = variation.attributes_json || '', 752 price = variation.price_html || orderable_products.vars.parent_price, 753 message = ''; 754 if (variation && '' !== variation.availability_html) { 755 message = variation.availability_html; 756 } 757 if (variation && !variation.is_in_stock) { 758 message = '<p>' + orderable_vars.i18n.out_of_stock + '</p>'; 759 } 760 if (variation && !variation.is_purchasable) { 761 message = '<p>' + orderable_vars.i18n.unavailable + '</p>'; 762 } 763 if (false === variation) { 764 message = '<p>' + orderable_vars.i18n.no_exist + '</p>'; 765 } 766 if (variation && (!variation.is_purchasable || !variation.is_in_stock)) { 767 variation_id = ''; 768 attributes = ''; 769 } 770 if ('' !== message) { 771 $('.' + orderable_products.vars.classes.product_messages).html(message); 772 } 773 $button.data('orderable-variation-id', variation_id); 774 $button.data('orderable-variation-attributes', attributes); 775 $('.orderable-drawer .orderable-product__actions-price').html(price); 776 $button.trigger('orderable_variation_set', { 777 variation, 778 variation_id, 779 attributes, 780 price 781 }); 782 }, 783 /** 784 * Clear variation and disable add to order. 785 * 786 * @param $button 787 */ 788 clear_variation($button) { 789 orderable_products.set_variation($button, ''); 790 if (orderable_products.vars.parent_price) { 791 $('.orderable-drawer .orderable-product__actions-price').html(orderable_products.vars.parent_price); 792 } 793 }, 794 /** 795 * Find matching variations for attributes. 796 * @param variations 797 * @param attributes 798 */ 799 find_matching_variations(variations, attributes) { 800 const matching = []; 801 for (let i = 0; i < variations.length; i++) { 802 const variation = variations[i]; 803 if (orderable_products.is_matching_variation(variation.attributes, attributes)) { 804 matching.push(variation); 805 } 806 } 807 return matching; 808 }, 809 /** 810 * See if attributes match. 811 * @param variation_attributes 812 * @param attributes 813 * @return {boolean} 814 */ 815 is_matching_variation(variation_attributes, attributes) { 816 let match = true; 817 for (const attr_name in variation_attributes) { 818 if (variation_attributes.hasOwnProperty(attr_name)) { 819 const val1 = variation_attributes[attr_name]; 820 const val2 = attributes[attr_name]; 821 if (val1 !== undefined && val2 !== undefined && val1.length !== 0 && val2.length !== 0 && val1 !== val2) { 822 match = false; 823 } 824 } 825 } 826 return match; 827 }, 828 /** 829 * Is value empty? 830 * 831 * @param value 832 * @return {boolean} 833 */ 834 is_empty(value) { 835 return typeof value === 'undefined' || false === value || value.length <= 0 || !value; 836 }, 837 /** 838 * Serialize into a key/value object. 839 * 840 * @param $elements 841 * @return {{}} 842 */ 843 serialize_object: function objectifyForm($elements) { 844 const serialized = $elements.serializeArray(), 845 return_object = {}; 846 for (let i = 0; i < serialized.length; i++) { 847 return_object[serialized[i].name] = serialized[i].value; 848 } 849 return return_object; 850 }, 851 /** 852 * Disable/Enable the 'Add to cart' button based on the presence of orderable-field--invalid class. 853 */ 854 update_button_state() { 855 // Add delay to ensure invalid class has been assigned to inputs. 856 setTimeout(function () { 857 let $button = $('.orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item'), 858 invalid_fields_count = $('.orderable-drawer__html .' + orderable_products.vars.classes.invalid_field).length, 859 product_type = $button.data('orderable-product-type'), 860 has_variation_id = true; 861 if ('variable' === product_type) { 862 has_variation_id = '' !== $button.data('orderable-variation-id'); 863 } 864 $button.prop('disabled', invalid_fields_count || !has_variation_id); 865 }, 50); 866 }, 867 /** 868 * Debounce function. 869 * 870 * @param func Function to debounce. 871 * @param wait Time to wait in milliseconds. 872 * @param immediate Trigger the function on the leading edge, instead of the trailing. 873 * 874 * @return 875 */ 876 debounce(func, wait, immediate) { 877 let timeout; 878 return function () { 879 const context = this, 880 args = arguments; 881 const later = function () { 882 timeout = null; 883 if (!immediate) { 884 func.apply(context, args); 885 } 886 }; 887 const callNow = immediate && !timeout; 888 clearTimeout(timeout); 889 timeout = setTimeout(later, wait); 890 if (callNow) { 891 func.apply(context, args); 892 } 893 }; 894 }, 895 /** 896 * Remove the quantity roller fragments 897 * 898 * @param {Event} e 899 * @param {Object} fragments 900 * @return void 901 */ 902 remove_fragments(e, fragments) { 903 if (!fragments || 'undefined' === typeof wc_cart_fragments_params || !wc_cart_fragments_params.fragment_name) { 904 return; 905 } 906 const regex_quantity_roller = /\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-quantity-roller/; 907 const regex_product_in_the_cart_counter = /\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-product__actions-counter/; 908 for (const key in fragments) { 909 if (!regex_quantity_roller.test(key) && !regex_product_in_the_cart_counter.test(key)) { 910 continue; 911 } 912 fragments[key] = undefined; 913 } 914 sessionStorage.setItem(wc_cart_fragments_params.fragment_name, JSON.stringify(fragments)); 915 }, 916 /** 917 * Remove animation. 918 */ 919 remove_animation() { 920 setTimeout(function () { 921 $('.orderable-product__actions-counter').css('animation', ''); 922 }, 1000); 923 }, 924 /** 925 * Hide quantity roller element and show the Add to Cart button. 926 * 927 * @param {Event} e 928 * @param {Object} fragments 929 * @param {string} cart_hash 930 * @param {Element} $button 931 * @return 932 */ 933 hide_quantity_roller(e, fragments, cart_hash, $button) { 934 const product_id = $button.attr('data-product_id') || $button.attr('data-orderable-product-id'); 935 if (!product_id) { 936 return; 937 } 938 const $actions_button = $('.orderable-product[data-orderable-product-id=' + product_id + '] .orderable-product__actions-button'); 939 if (!$actions_button.length) { 940 return; 941 } 942 const $quantity_roller = $actions_button.find('.orderable-quantity-roller'); 943 if ($quantity_roller.length) { 944 $actions_button.find('button.orderable-product__add-to-order[data-orderable-trigger]').removeClass('orderable-button--product-in-the-cart'); 945 $quantity_roller.addClass('orderable-button--hide'); 946 } 947 }, 948 /** 949 * Add unchecked checkboxs to the list of inputs 950 * sent to the request to add/update an item 951 * 952 * @param {Object} inputs 953 * @return {Object} 954 */ 955 add_unchecked_checkbox_fields(inputs) { 956 jQuery('.orderable-product-fields-group :input[type="checkbox"]:not(:checked)').each(function (index, element) { 957 inputs.push({ 958 name: element.getAttribute('name'), 959 value: '' 960 }); 961 }); 962 return inputs; 963 }, 964 /** 965 * Shake the floating cart button. 966 * 967 * @return void 968 */ 969 shake_floating_cart() { 970 $('.orderable-floating-cart__button').css('animation', 'wobble-hor-bottom .8s both'); 971 }, 972 /** 973 * Remove the view cart link. 974 * 975 * @param event 976 * @param $button 977 */ 978 remove_view_cart_link(event, $button) { 979 if (!$button?.hasClass('orderable-product__add-to-order')) { 980 return; 981 } 982 $button?.siblings('.added_to_cart.wc-forward').remove(); 983 } 984 }; 985 $(document).ready(orderable_products.on_ready); 986 })(jQuery, document); 987 (function ($, document) { 988 'use strict'; 989 990 var orderable_scrollbar = { 991 /** 992 * On doc ready. 993 */ 994 on_ready() { 995 orderable_scrollbar.cache(); 996 orderable_scrollbar.watch(); 997 }, 998 /** 999 * Cache. 1000 */ 1001 cache() { 1002 orderable_scrollbar.vars = { 1003 top: {} 1004 }; 1005 orderable_scrollbar.elements = {}; 1006 }, 1007 /** 1008 * Watch. 1009 */ 1010 watch() { 1011 $(document.body).on('orderable-drawer.opened', orderable_scrollbar.trigger); 1012 $(document.body).on('orderable-tabs.changed', orderable_scrollbar.trigger); 1013 $(document.body).on('orderable-accordion.toggled', orderable_scrollbar.trigger); 1014 $(document.body).on('wc_fragments_loaded', orderable_scrollbar.trigger); 1015 }, 1016 /** 1017 * Init or retrigger scrollbars. 1018 */ 1019 trigger() { 1020 $('.orderable-sb-container').each(function (index, element) { 1021 const $element = $(element), 1022 scroll_id = $element.data('orderable-scroll-id'); 1023 if (!orderable_scrollbar.has_scrollbar($element)) { 1024 $element.scrollBox({ 1025 containerClass: 'orderable-sb-container', 1026 containerNoScrollClass: 'orderable-sb-container-noscroll', 1027 contentClass: 'orderable-sb-content', 1028 scrollbarContainerClass: 'orderable-sb-scrollbar-container', 1029 scrollBarClass: 'orderable-sb-scrollbar' 1030 }); 1031 const $content = $element.find('.orderable-sb-content'); 1032 if ($content.length > 0) { 1033 $content.on('scroll.scrollBox', orderable_scrollbar.log_top_position); 1034 1035 // Set scroll position. 1036 if (typeof orderable_scrollbar.vars.top[scroll_id] !== 'undefined') { 1037 $content.scrollTop(orderable_scrollbar.vars.top[scroll_id]); 1038 } 1039 } 1040 $(document.body).trigger('orderable-scrollbar.created', { 1041 element: $element, 1042 content: $content 1043 }); 1044 } 1045 }); 1046 $(window).trigger('resize.scrollBox'); 1047 }, 1048 /** 1049 * Has scrollbar already? 1050 * 1051 * @param $element 1052 * @return {boolean} 1053 */ 1054 has_scrollbar($element) { 1055 return $element.find('.orderable-sb-content').length > 0; 1056 }, 1057 /** 1058 * Set scrolltop position. 1059 * 1060 * @param e 1061 */ 1062 log_top_position(e) { 1063 const $element = $(e.currentTarget), 1064 $container = $element.closest('.orderable-sb-container'), 1065 scroll_id = $container.data('orderable-scroll-id'); 1066 orderable_scrollbar.vars.top[scroll_id] = $(e.currentTarget).scrollTop(); 1067 } 1068 }; 1069 $(document).ready(orderable_scrollbar.on_ready); 1070 })(jQuery, document); 1071 (function ($, document) { 1072 'use strict'; 1073 1074 var orderable_tabs = { 1075 /** 1076 * On doc ready. 1077 */ 1078 on_ready() { 1079 orderable_tabs.cache(); 1080 orderable_tabs.watch(); 1081 orderable_tabs.toggle_scroll(); 1082 }, 1083 /** 1084 * On resize. 1085 */ 1086 on_resize() { 1087 if (typeof orderable_tabs.vars === 'undefined') { 1088 orderable_tabs.cache(); 1089 } 1090 orderable_tabs.toggle_scroll(); 1091 }, 1092 /** 1093 * Cache. 1094 */ 1095 cache() { 1096 orderable_tabs.vars = { 1097 classes: { 1098 tabs: 'orderable-tabs', 1099 tabs_list: 'orderable-tabs__list', 1100 tab_items: 'orderable-tabs__item', 1101 tab_item_active: 'orderable-tabs__item--active', 1102 tab_links: 'orderable-tabs__link', 1103 tab_arrow_right: 'orderable-tabs__arrow-right', 1104 tab_arrow_left: 'orderable-tabs__arrow-left' 1105 }, 1106 dragging: false 1107 }; 1108 orderable_tabs.elements = {}; 1109 }, 1110 /** 1111 * Watch. 1112 */ 1113 watch() { 1114 $('body').on('touchstart', function () { 1115 orderable_tabs.vars.dragging = false; 1116 }).on('touchmove', function () { 1117 orderable_tabs.vars.dragging = true; 1118 }); 1119 $(document.body).on('click mouseup touchend', '.' + orderable_tabs.vars.classes.tab_links, function (e) { 1120 if (orderable_tabs.vars.dragging) { 1121 return; 1122 } 1123 e.preventDefault(); 1124 const $link = $(this), 1125 section_id = $link.attr('href'), 1126 $tab = $link.closest('.' + orderable_tabs.vars.classes.tab_items), 1127 $tabs = $link.closest('.' + orderable_tabs.vars.classes.tabs), 1128 $tabs_list = $tabs.find('.' + orderable_tabs.vars.classes.tabs_list), 1129 $tab_items = $tabs.find('.' + orderable_tabs.vars.classes.tab_items), 1130 tabs_args = $tabs.data('orderable-tabs'), 1131 $wrapper = $link.closest(tabs_args.wrapper), 1132 $sections = $wrapper.find(tabs_args.sections), 1133 $section = $wrapper.find(section_id); 1134 $sections.hide(); 1135 $section.show(); 1136 $tab_items.removeClass(orderable_tabs.vars.classes.tab_item_active); 1137 $tab.addClass(orderable_tabs.vars.classes.tab_item_active); 1138 $tabs_list.animate({ 1139 scrollLeft: $tabs_list.scrollLeft() + $tab.position().left 1140 }); 1141 $(document.body).trigger('orderable-tabs.changed', { 1142 tab: $tab 1143 }); 1144 }); 1145 1146 /** 1147 * Watch scroll position of tabs. 1148 */ 1149 $('.' + orderable_tabs.vars.classes.tabs_list).on('scroll', function (e) { 1150 const $list = $(this), 1151 $wrapper = $list.parent('.' + orderable_tabs.vars.classes.tabs), 1152 $arrow_right = $list.siblings('.' + orderable_tabs.vars.classes.tab_arrow_right), 1153 $arrow_left = $list.siblings('.' + orderable_tabs.vars.classes.tab_arrow_left); 1154 if ($list[0].scrollWidth <= $wrapper.width() + $list.scrollLeft()) { 1155 $arrow_right.fadeOut(); 1156 } else { 1157 $arrow_right.fadeIn(); 1158 } 1159 if (0 >= $list.scrollLeft() - $arrow_left.width()) { 1160 $arrow_left.fadeOut(); 1161 } else { 1162 $arrow_left.fadeIn(); 1163 } 1164 }); 1165 1166 /** 1167 * Stop animated scroll if user manually scrolls. 1168 */ 1169 $('.' + orderable_tabs.vars.classes.tabs_list).on('wheel DOMMouseScroll mousewheel touchmove', function () { 1170 $(this).stop(); 1171 }); 1172 1173 /** 1174 * Click tab arrow right. 1175 */ 1176 $(document).on('click', '.' + orderable_tabs.vars.classes.tab_arrow_right, function (e) { 1177 e.preventDefault(); 1178 const $arrow = $(this), 1179 $wrapper = $arrow.parent(), 1180 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list); 1181 $list.animate({ 1182 scrollLeft: $list.scrollLeft() + $wrapper.width() * 0.5 1183 }); 1184 }); 1185 1186 /** 1187 * Click tab arrow left. 1188 */ 1189 $(document).on('click', '.' + orderable_tabs.vars.classes.tab_arrow_left, function (e) { 1190 e.preventDefault(); 1191 const $arrow = $(this), 1192 $wrapper = $arrow.parent(), 1193 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list); 1194 $list.animate({ 1195 scrollLeft: $list.scrollLeft() - $wrapper.width() * 0.5 1196 }); 1197 }); 1198 }, 1199 /** 1200 * Toggle scroll arrow. 1201 */ 1202 toggle_scroll() { 1203 $('.' + orderable_tabs.vars.classes.tabs).each(function (index, wrapper) { 1204 const $tabs = $(this), 1205 tabs_args = $tabs.data('orderable-tabs'), 1206 $wrapper = $tabs.closest(tabs_args.wrapper), 1207 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list), 1208 $arrow_right = $wrapper.find('.' + orderable_tabs.vars.classes.tab_arrow_right), 1209 wrapper_width = $wrapper.outerWidth(), 1210 list_width = $list[0].scrollWidth; 1211 if (list_width > wrapper_width) { 1212 $arrow_right.show(); 1213 } else { 1214 $arrow_right.hide(); 1215 } 1216 }); 1217 } 1218 }; 1219 $(document).ready(orderable_tabs.on_ready); 1220 $(window).on('resize', orderable_tabs.on_resize); 1221 })(jQuery, document); 1222 let orderable_timings = {}; // Make this global so pro modules can access it. 1223 1224 (function ($, document) { 1225 'use strict'; 1226 1227 orderable_timings = { 1228 /** 1229 * On doc ready. 1230 */ 1231 on_ready() { 1232 orderable_timings.watch(); 1233 }, 1234 /** 1235 * Restore current timings. 1236 */ 1237 restore() { 1238 const timings = orderable_timings.get_timings(); 1239 if (!timings || !timings.date) { 1240 return; 1241 } 1242 const dateSelect = $('.orderable-order-timings__date'); 1243 if (dateSelect.find('option[value="' + timings.date + '"]').length > 0) { 1244 dateSelect.val(timings.date); 1245 dateSelect.change(); 1246 } 1247 if (!timings.time) { 1248 return; 1249 } 1250 const timeSelect = $('.orderable-order-timings__time'); 1251 if (timeSelect.find('option[value="' + timings.time + '"]').length > 0) { 1252 timeSelect.val(timings.time); 1253 timeSelect.change(); 1254 } 1255 }, 1256 /** 1257 * Watch for trigger events. 1258 */ 1259 watch() { 1260 $(document.body).on('wc_fragments_refreshed', function () { 1261 orderable_timings.restore(); 1262 }); 1263 $(document.body).on('updated_checkout', function () { 1264 orderable_timings.restore(); 1265 }); 1266 $(document.body).on('change', '.orderable-order-timings__date', function (event) { 1267 const $date_field = $(this), 1268 $selected = $date_field.find('option:selected'), 1269 slots = $selected.data('orderable-slots'), 1270 $time_field_wrap = $('.orderable-order-timings--time'), 1271 $time_field = $('.orderable-order-timings__time'), 1272 $first_option = $time_field.find('option').first(), 1273 $asap_option = $time_field.find('option[value="asap"]').first(); 1274 const timings = orderable_timings.get_timings(); 1275 timings.date = $('.orderable-order-timings__date').val(); 1276 window.localStorage.setItem('orderable_timings', JSON.stringify(timings)); 1277 $time_field.html($first_option); 1278 if ($asap_option) { 1279 $time_field.append($asap_option); 1280 } 1281 if (!slots) { 1282 $time_field.prop('disabled', true); 1283 $time_field_wrap.hide(); 1284 return; 1285 } 1286 if ('all-day' === slots[0].value) { 1287 $time_field_wrap.hide(); 1288 $time_field.prop('disabled', true); 1289 } else { 1290 $time_field.prop('disabled', false); 1291 $time_field_wrap.show(); 1292 $.each(slots, function (index, slot) { 1293 $time_field.append($('<option />').attr('value', slot.value).attr('data-orderable-time-slot-id', slot?.setting_row?.time_slot_id).text(slot.formatted)); 1294 }); 1295 } 1296 }); 1297 $(document.body).on('change', '.orderable-order-timings__time', function (event) { 1298 const timings = orderable_timings.get_timings(); 1299 timings.time = $('.orderable-order-timings__time').val(); 1300 window.localStorage.setItem('orderable_timings', JSON.stringify(timings)); 1301 $(this).siblings('input[name="orderable_order_time_slot_id"]').val($(this).find(':selected').attr('data-orderable-time-slot-id')); 1302 }); 1303 }, 1304 get_timings() { 1305 return JSON.parse(window.localStorage.getItem('orderable_timings')) || {}; 1306 } 1307 }; 1308 $(document).ready(orderable_timings.on_ready); 1309 })(jQuery, document); 1310 (function ($, document) { 1311 'use strict'; 1312 1313 var orderable_triggers = { 1314 /** 1315 * On doc ready. 1316 */ 1317 on_ready() { 1318 orderable_triggers.watch(); 1319 }, 1320 /** 1321 * Watch for trigger events. 1322 */ 1323 watch() { 1324 if ('undefined' !== typeof window.orderable_triggers_admin) { 1325 return; 1326 } 1327 $(document.body).on('click', '[data-orderable-trigger]', orderable_triggers.trigger); 1328 }, 1329 /** 1330 * Fire trigger. 1331 * @param e 1332 */ 1333 trigger(e) { 1334 // Prevent even bubbling up. 1335 e.stopImmediatePropagation(); 1336 const $trigger_element = $(this), 1337 trigger = $trigger_element.data('orderable-trigger'); 1338 if ($trigger_element.is('button') || $trigger_element.is('a')) { 1339 e.preventDefault(); 1340 } 1341 $(document.body).trigger('orderable-' + trigger, [$trigger_element]); 1342 } 1343 }; 1344 $(document).ready(orderable_triggers.on_ready); 1345 })(jQuery, document); 2 1346 /** 3 1347 * jQiery scrollBar Plugin … … 177 1521 } 178 1522 }(window, document); 179 (function ($, document) {180 'use strict';181 182 var orderable_accordion = {183 /**184 * On doc ready.185 */186 on_ready() {187 orderable_accordion.cache();188 orderable_accordion.watch();189 },190 /**191 * Cache.192 */193 cache() {194 orderable_accordion.vars = {195 classes: {196 parent: 'orderable-accordion',197 link: 'orderable-accordion__item-link',198 content: 'orderable-accordion__item-content',199 link_active: 'orderable-accordion__item-link--active',200 content_active: 'orderable-accordion__item-content--active'201 }202 };203 },204 /**205 * Watch.206 */207 watch() {208 /**209 * When click accordion link.210 */211 $(document.body).on('click', '.' + orderable_accordion.vars.classes.link, function (e) {212 e.preventDefault();213 const $link = $(this),214 $parent = $link.closest('.' + orderable_accordion.vars.classes.parent),215 content_id = $link.attr('href'),216 $content = $(content_id),217 is_active = $link.hasClass(orderable_accordion.vars.classes.link_active);218 $parent.find('.' + orderable_accordion.vars.classes.link).removeClass(orderable_accordion.vars.classes.link_active);219 $parent.find('.' + orderable_accordion.vars.classes.content).removeClass(orderable_accordion.vars.classes.content_active);220 if (!is_active) {221 $link.addClass(orderable_accordion.vars.classes.link_active);222 $content.addClass(orderable_accordion.vars.classes.content_active);223 }224 $(document.body).trigger('orderable-accordion.toggled', {225 link: $link,226 content: $content227 });228 });229 230 /**231 * When drawer is opened.232 */233 $(document.body).on('orderable-scrollbar.created', function (e, args) {234 const $active_accordion = $('.orderable-drawer .' + orderable_accordion.vars.classes.link_active);235 if ($active_accordion.length <= 0) {236 return;237 }238 const $scroll_content = args.content,239 scroll_position = $scroll_content.scrollTop() - $scroll_content.offset().top + $active_accordion.offset().top;240 $scroll_content.scrollTop(scroll_position);241 });242 }243 };244 $(document).ready(orderable_accordion.on_ready);245 })(jQuery, document);246 (function ($, document) {247 'use strict';248 249 var orderable_drawer = {250 /**251 * Delays invoking function252 *253 * @param {Function} func The function to debounce.254 * @param {number} timeout The number of milliseconds to delay.255 * @return {Function} Returns the new debounced function.256 */257 debounce(func, timeout = 700) {258 let timer;259 return (...args) => {260 clearTimeout(timer);261 timer = setTimeout(() => {262 func.apply(this, args);263 }, timeout);264 };265 },266 /**267 * Allow only number for events like keypress268 *269 * @param {Event} event270 */271 allow_only_numbers(event) {272 const value = String.fromCharCode(event.which);273 if (!/^\d+$/.test(value)) {274 event.preventDefault();275 }276 },277 /**278 * Send a request to change the quantity.279 *280 * @param {Event} event281 */282 on_change_quantity(event) {283 const quantityElement = $(event.currentTarget);284 const product_id = quantityElement.data('orderable-product-id');285 const cart_item_key = quantityElement.data('orderable-cart-item-key');286 const quantity = parseInt(quantityElement.text());287 const data = {288 action: 'orderable_cart_quantity',289 cart_item_key,290 product_id,291 quantity292 };293 jQuery.post(orderable_vars.ajax_url, data, function (response) {294 if (!response) {295 return;296 }297 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, quantityElement]);298 $(document.body).trigger('orderable-drawer.quantity-updated');299 });300 },301 /**302 * On doc ready.303 */304 on_ready() {305 orderable_drawer.cache();306 orderable_drawer.watch();307 308 /**309 * Handle manually changing the quantity of a product.310 */311 $(document.body).on('keypress', '.orderable-quantity-roller__quantity', orderable_drawer.allow_only_numbers);312 $('.orderable-drawer__cart, .orderable-product--add-to-cart, .orderable-products-list').on('input', '.orderable-quantity-roller__quantity', orderable_drawer.debounce(orderable_drawer.on_change_quantity));313 $(document.body).on('click', '.orderable-quantity-roller__quantity', function (event) {314 event.stopPropagation();315 });316 317 /**318 * We turn off the click event for .add_to_cart_button elements319 * to keep the AJAX behaviour only on Mini cart when the option320 * "Enable AJAX add to cart buttons on archives" is disabled.321 */322 if (orderable_vars && !orderable_vars.woocommerce_enable_ajax_add_to_cart) {323 $(document.body).off('click', '.add_to_cart_button');324 }325 },326 /**327 * Cache.328 */329 cache() {330 orderable_drawer.vars = {331 classes: {332 overlay: 'orderable-drawer-overlay',333 drawer: 'orderable-drawer',334 drawer_cart: 'orderable-drawer__cart',335 drawer_html: 'orderable-drawer__html',336 overlay_open: 'orderable-drawer-overlay--open',337 drawer_open: 'orderable-drawer--open',338 drawer_open_body: 'orderable-drawer-open'339 }340 };341 orderable_drawer.elements = {342 body: $('body'),343 overlay: $('.' + orderable_drawer.vars.classes.overlay),344 drawer: $('.' + orderable_drawer.vars.classes.drawer),345 drawer_cart: $('.' + orderable_drawer.vars.classes.drawer_cart),346 drawer_html: $('.' + orderable_drawer.vars.classes.drawer_html),347 floating_cart_button_class: '.orderable-floating-cart__button'348 };349 },350 /**351 * Watch for trigger events.352 */353 watch() {354 if (typeof orderable_drawer.elements.drawer === 'undefined') {355 return;356 }357 $(document.body).on('orderable-drawer.open', orderable_drawer.open);358 $(document.body).on('orderable-drawer.close', orderable_drawer.close);359 $(document.body).on('click', orderable_drawer.elements.floating_cart_button_class, function () {360 $(document.body).trigger('orderable-drawer.open', {361 show_cart: true362 });363 });364 $(document.body).on('orderable-increase-quantity', orderable_drawer.cart.handle_quantity_change_by_button);365 $(document.body).on('orderable-decrease-quantity', orderable_drawer.cart.handle_quantity_change_by_button);366 const updateQuantityRequest = orderable_drawer.debounce(orderable_drawer.cart.click_increase_decrease_quantity);367 $(document.body).on('orderable-increase-quantity', updateQuantityRequest);368 $(document.body).on('orderable-decrease-quantity', updateQuantityRequest);369 const drawer = document.querySelector('body:not( .rtl ) .orderable-drawer');370 const drawer_rtl = document.querySelector('body.rtl .orderable-drawer');371 if (drawer) {372 drawer.addEventListener('swiped-right', function (e) {373 orderable_drawer.close();374 });375 }376 if (drawer_rtl) {377 drawer_rtl.addEventListener('swiped-left', function (e) {378 orderable_drawer.close();379 });380 }381 },382 /**383 * Open the drawer.384 * @param event385 * @param args386 */387 open(event, args) {388 args.html = args.html || false;389 args.show_cart = args.show_cart || false;390 orderable_drawer.elements.drawer_html.hide();391 orderable_drawer.elements.drawer_cart.hide();392 if (args.html) {393 orderable_drawer.elements.drawer_html.html(args.html);394 orderable_drawer.elements.drawer_html.show();395 }396 if (args.show_cart) {397 // Empty drawer HTML before showing cart. Prevents options398 // interfering with subsequent cart additions.399 orderable_drawer.elements.drawer_html.html('');400 orderable_drawer.elements.drawer_cart.show();401 }402 orderable_drawer.elements.overlay.addClass(orderable_drawer.vars.classes.overlay_open);403 orderable_drawer.elements.drawer.addClass(orderable_drawer.vars.classes.drawer_open);404 orderable_drawer.elements.body.addClass(orderable_drawer.vars.classes.drawer_open_body);405 $(document.body).trigger('orderable-drawer.opened', args);406 },407 /**408 * Close the drawer.409 */410 close() {411 orderable_drawer.elements.overlay.removeClass(orderable_drawer.vars.classes.overlay_open);412 orderable_drawer.elements.drawer.removeClass(orderable_drawer.vars.classes.drawer_open);413 orderable_drawer.elements.body.removeClass(orderable_drawer.vars.classes.drawer_open_body);414 orderable_drawer.elements.drawer_html.html('');415 $(document.body).trigger('orderable-drawer.closed');416 },417 /**418 * Mini cart related functions.419 */420 cart: {421 /**422 * When increase qty is clicked.423 *424 * @param e425 * @param $button426 */427 click_increase_decrease_quantity(e, $button) {428 const direction = $button.data('orderable-trigger');429 const product_id = $button.attr('data-orderable-product-id'),430 cart_item_key = $button.attr('data-orderable-cart-item-key'),431 quantity = $button.attr('data-orderable-quantity');432 const siblingButtonName = 'increase-quantity' === direction ? 'decrease' : 'increase';433 const $siblingButton = $button.siblings(`.orderable-quantity-roller__button--${siblingButtonName}`);434 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity');435 const data = {436 action: 'orderable_cart_quantity',437 cart_item_key,438 product_id,439 quantity440 };441 if (this.currentRequest) {442 this.currentRequest.abort();443 this.currentRequest = undefined;444 }445 $button.addClass('orderable-button--loading');446 $button.attr('disabled', true);447 $siblingButton.attr('disabled', true);448 $quantityElement.attr('contenteditable', false);449 this.currentRequest = jQuery.post(orderable_vars.ajax_url, data, function (response) {450 if (!response) {451 return;452 }453 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity');454 if (response && response.fragments && response.fragments['.orderable-mini-cart__notices']) {455 $(document.body).trigger('orderable-drawer.open', {456 show_cart: true457 });458 }459 switch (data.quantity) {460 case '0':461 $(document.body).trigger('removed_from_cart', [response.fragments, response.cart_hash, $button]);462 break;463 case $quantityElement.attr('data-orderable-updating-quantity'):464 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $button]);465 $(document.body).trigger('orderable-drawer.quantity-updated');466 break;467 default:468 break;469 }470 }.bind(this)).always(function () {471 this.currentRequest = undefined;472 $button.removeClass('orderable-button--loading');473 $button.attr('disabled', false);474 $siblingButton.attr('disabled', false);475 $quantityElement.attr('contenteditable', true);476 }.bind(this));477 },478 handle_quantity_change_by_button(e, $button) {479 const direction = $button.data('orderable-trigger');480 const quantity = parseInt($button.attr('data-orderable-quantity'));481 const siblingButtonName = 'increase-quantity' === direction ? 'decrease' : 'increase';482 const $siblingButton = $button.siblings(`.orderable-quantity-roller__button--${siblingButtonName}`);483 const $quantityElement = $button.siblings('.orderable-quantity-roller__quantity');484 const newQuantity = 'increase-quantity' === direction ? quantity + 1 : Math.max(0, quantity - 1);485 const $parent = $button.parents('.orderable-product__actions-button');486 if (0 === newQuantity && $parent.length) {487 const $addToCartButton = $parent.find('button.orderable-button[data-orderable-trigger]');488 const $quantityRoller = $parent.find('.orderable-quantity-roller');489 if ($quantityRoller.length) {490 $addToCartButton.removeClass('orderable-button--product-in-the-cart');491 $quantityRoller.removeClass('orderable-quantity-roller--is-active');492 }493 }494 $button.attr('data-orderable-quantity', newQuantity);495 $siblingButton.attr('data-orderable-quantity', newQuantity);496 $quantityElement.attr('data-orderable-updating-quantity', newQuantity);497 $quantityElement.text(newQuantity);498 $quantityElement.attr('contenteditable', false);499 }500 }501 };502 $(document).ready(orderable_drawer.on_ready);503 })(jQuery, document);504 (function ($, document) {505 'use strict';506 507 var orderable_products = {508 /**509 * On doc ready.510 */511 on_ready() {512 orderable_products.cache();513 orderable_products.watch();514 },515 /**516 * Cache.517 */518 cache() {519 orderable_products.vars = {520 classes: {521 clickable_product: 'orderable-product--add-to-cart ',522 add_to_order_button: 'orderable-product__add-to-order',523 product_messages: 'orderable-product__messages',524 product_price: 'orderable-product__actions-price',525 invalid_field: 'orderable-field--invalid',526 option_select_td: 'orderable-product__option-select',527 button_loading: 'orderable-button--loading',528 out_of_stock: 'orderable-button--out-of-stock'529 },530 parent_price: null,531 variable_product_types: ['variable', 'variable-subscription']532 };533 orderable_products.elements = {};534 },535 /**536 * Watch for trigger events.537 */538 watch() {539 $(document.body).on('orderable-drawer.opened', orderable_products.init_product_options);540 $(document.body).on('orderable-add-to-cart', orderable_products.click_add_to_order);541 $(document.body).on('orderable-product-options', orderable_products.click_add_to_order);542 $(document.body).on('orderable-view-product', orderable_products.view_product);543 $(document.body).on('mouseenter mouseleave', '.' + orderable_products.vars.classes.clickable_product, orderable_products.simulate_add_to_order_hover);544 $(document.body).on('orderable-edit-cart-item', orderable_products.edit_cart_item);545 $(document.body).on('orderable-update-cart-item', orderable_products.update_cart_item);546 $(document.body).on('orderable-show-cart', orderable_products.show_cart);547 $(document.body).on('orderable-add-to-cart-without-side-drawer', orderable_products.click_add_to_order);548 $(document.body).on('added_to_cart', orderable_products.remove_fragments);549 $(document.body).on('added_to_cart', orderable_products.remove_animation);550 $(document.body).on('added_to_cart', orderable_products.shake_floating_cart);551 $(document.body).on('removed_from_cart', orderable_products.hide_quantity_roller);552 $(document.body).on('wc_cart_button_updated', orderable_products.remove_view_cart_link);553 },554 /**555 * Simulate hover on add to order button.556 *557 * @param event558 */559 simulate_add_to_order_hover(event) {560 const $element = $(this),561 $button = $element.find('.' + orderable_products.vars.classes.add_to_order_button);562 $button.toggleClass('orderable-button--hover', 'mouseenter' === event.type);563 },564 /**565 * Add to order click event.566 *567 * This event accounts for button clicks or card clicks.568 * @param event569 * @param $element570 */571 click_add_to_order(event, $element) {572 // If undefined, it means it was triggered by a click573 // event and not the `orderable-add-to-cart` trigger.574 $element = typeof $element !== 'undefined' ? $element : $(this);575 576 // The button is either the clicked element, or the577 // add to order button within the clicked element.578 const $button = $element.is('button') ? $element : $element.find('.' + orderable_products.vars.classes.add_to_order_button),579 action = $button.data('orderable-trigger'),580 product_id = $button.data('orderable-product-id'),581 variation_id = $button.data('orderable-variation-id'),582 attributes = $button.data('orderable-variation-attributes'),583 args = {584 action585 };586 if ($button.hasClass(orderable_products.vars.classes.button_loading) || $button.hasClass(orderable_products.vars.classes.out_of_stock)) {587 return;588 }589 $button.addClass(orderable_products.vars.classes.button_loading);590 switch (action) {591 case 'add-to-cart':592 orderable_products.add_to_cart({593 product_id,594 variation_id,595 attributes,596 thisbutton: $element597 }, function (response) {598 args.show_cart = true;599 args.response = response;600 $(document.body).trigger('orderable-drawer.open', args);601 $button.removeClass(orderable_products.vars.classes.button_loading);602 const $addToCartButtonOutsideDrawer = $('.orderable-product .orderable-product__actions-button button.orderable-product__add-to-order[data-orderable-product-id=' + product_id + ']');603 if ($addToCartButtonOutsideDrawer.siblings('.orderable-quantity-roller').length) {604 $addToCartButtonOutsideDrawer.addClass('orderable-button--product-in-the-cart');605 }606 });607 break;608 case 'add-to-cart-without-side-drawer':609 orderable_products.add_to_cart({610 product_id,611 variation_id,612 attributes613 }, function (response) {614 args.response = response;615 $button.addClass('orderable-button--product-in-the-cart');616 $button.removeClass(orderable_products.vars.classes.button_loading);617 });618 break;619 case 'product-options':620 orderable_products.get_product_options({621 product_id,622 focus: $button.data('orderable-focus')623 }, function (response) {624 args.html = response.html;625 $(document.body).trigger('orderable-drawer.open', args);626 $button.removeClass(orderable_products.vars.classes.button_loading);627 });628 break;629 default:630 break;631 }632 },633 /**634 * Show the cart.635 */636 show_cart() {637 $(document.body).trigger('orderable-drawer.open', {638 show_cart: true639 });640 },641 /**642 * View product.643 *644 * @param event645 * @param $element646 */647 view_product(event, $element) {648 const product_id = $element.data('orderable-product-id'),649 args = {650 action: 'product-options'651 };652 orderable_products.get_product_options({653 product_id,654 focus: $element.data('orderable-focus')655 }, function (response) {656 args.html = response.html;657 $(document.body).trigger('orderable-drawer.open', args);658 });659 },660 /**661 * Ajax add to cart.662 * @param args663 * @param callback664 */665 add_to_cart(args, callback) {666 if (typeof args.product_id === 'undefined') {667 return;668 }669 let data = {670 action: 'orderable_add_to_cart',671 product_id: args.product_id,672 variation_id: args.variation_id || false,673 attributes: args.attributes || false674 };675 676 // Prepare addons data.677 if ($('.orderable-product-fields-group').length) {678 let inputs = jQuery('.orderable-product-fields-group :input').serializeArray();679 inputs = orderable_products.add_unchecked_checkbox_fields(inputs);680 const addons_data = orderable_products.convert_to_flat_object(inputs);681 if (!jQuery.isEmptyObject(addons_data)) {682 data = Object.assign(data, addons_data); // Merge objects.683 }684 }685 jQuery.post(orderable_vars.ajax_url, data, function (response) {686 if (!response) {687 return;688 }689 690 // Trigger event so themes can refresh other areas.691 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, args.thisbutton]);692 if (typeof callback === 'function') {693 callback(response);694 }695 });696 },697 /**698 * Edit cart item.699 *700 * @param event701 * @param $element702 */703 edit_cart_item(event, $element) {704 const cart_item_key = $element.data('orderable-cart-item-key');705 $element.addClass(orderable_products.vars.classes.button_loading);706 orderable_products.get_cart_item_options({707 cart_item_key708 }, function (response) {709 const args = {710 html: response.html,711 action: 'update-cart-item'712 };713 $(document.body).trigger('orderable-drawer.open', args);714 $element.removeClass(orderable_products.vars.classes.button_loading);715 });716 },717 /**718 * Update cart item.719 *720 * @param event721 * @param $element722 */723 update_cart_item(event, $element) {724 const cart_item_key = $element.data('orderable-cart-item-key');725 const product_id = $element.data('orderable-product-id');726 const variation_id = $element.data('orderable-variation-id');727 const attributes = $element.data('orderable-variation-attributes');728 $element.addClass(orderable_products.vars.classes.button_loading);729 orderable_products.update_cart_item_options({730 cart_item_key,731 product_id,732 variation_id,733 attributes734 }, function (response) {735 const args = {736 show_cart: true,737 response738 };739 $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash]);740 $(document.body).trigger('orderable-drawer.open', args);741 $element.removeClass(orderable_products.vars.classes.button_loading);742 });743 },744 /**745 * Convert [{name:x, value:y }] to {x:y} format.746 * @param inputs747 */748 convert_to_flat_object(inputs) {749 const data = {};750 inputs.forEach(function (input) {751 const is_array = '[]' === input.name.substr(-2) || Array.isArray(input.name);752 // If last 2 chars are '[]', remove them.753 const key = is_array ? input.name.substr(0, input.name.length - 2) : input.name;754 if (is_array) {755 data[key] = typeof data[key] === 'undefined' ? [] : data[key];756 data[key].push(input.value);757 } else {758 data[key] = input.value;759 }760 });761 return data;762 },763 /**764 * Get variable product options.765 *766 * @param args767 * @param callback768 */769 get_product_options(args, callback) {770 if (typeof args.product_id === 'undefined') {771 return;772 }773 args.action = 'orderable_get_product_options';774 jQuery.post(orderable_vars.ajax_url, args, function (response) {775 if (!response.success) {776 return;777 }778 if (typeof callback === 'function') {779 callback(response.data);780 }781 });782 },783 /**784 * Get variable product options.785 *786 * @param args787 * @param callback788 */789 get_cart_item_options(args, callback) {790 if (typeof args.cart_item_key === 'undefined') {791 return;792 }793 args.action = 'orderable_get_cart_item_options';794 jQuery.post(orderable_vars.ajax_url, args, function (response) {795 if (!response.success) {796 return;797 }798 if (typeof callback === 'function') {799 callback(response.data);800 }801 });802 },803 /**804 * Update variable product options.805 *806 * @param args807 * @param callback808 */809 update_cart_item_options(args, callback) {810 if (typeof args.cart_item_key === 'undefined') {811 return;812 }813 args.action = 'orderable_update_cart_item_options';814 815 // Prepare addons data.816 if ($('.orderable-product-fields-group').length) {817 let inputs = jQuery('.orderable-product-fields-group :input').serializeArray();818 inputs = orderable_products.add_unchecked_checkbox_fields(inputs);819 const addons_data = orderable_products.convert_to_flat_object(inputs);820 if (!jQuery.isEmptyObject(addons_data)) {821 args = Object.assign(args, addons_data); // Merge objects.822 }823 }824 jQuery.post(orderable_vars.ajax_url, args, function (response) {825 if (!response) {826 return;827 }828 if (typeof callback === 'function') {829 callback(response);830 }831 });832 },833 /**834 * Init drawer product options.835 *836 * @param event837 * @param args838 */839 init_product_options(event, args) {840 if (typeof args.action === 'undefined' || 'product-options' !== args.action && 'update-cart-item' !== args.action) {841 return;842 }843 const selectors = '.orderable-drawer .orderable-product__options input, .orderable-drawer .orderable-product__options select, .orderable-product__options textarea';844 const $options = $(selectors);845 orderable_products.vars.parent_price = $('.orderable-drawer .orderable-product__actions-price').html();846 orderable_products.product_options_change($options);847 orderable_products.update_button_state();848 const debounced_update_button_state = orderable_products.debounce(orderable_products.update_button_state, 500);849 const debounced_product_options_change = orderable_products.debounce(orderable_products.product_options_change, 500);850 $(document).on('change keyup', selectors, function () {851 debounced_product_options_change($options);852 debounced_update_button_state();853 });854 },855 /**856 * On product options change.857 *858 * @param $options859 */860 product_options_change($options) {861 const $add_to_order_button = $('.orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item'),862 options_set = orderable_products.check_options($options),863 product_type = $add_to_order_button.data('orderable-product-type');864 if ('product-options' === $add_to_order_button.attr('data-orderable-trigger')) {865 $add_to_order_button.attr('data-orderable-trigger', 'add-to-cart');866 }867 $('.' + orderable_products.vars.classes.product_messages).html('');868 if (!orderable_products.vars.variable_product_types.includes(product_type)) {869 return;870 }871 if (!options_set) {872 orderable_products.clear_variation($add_to_order_button);873 return;874 }875 const variation = orderable_products.check_variation($options);876 orderable_products.set_variation($add_to_order_button, variation);877 },878 /**879 * Check if all product options are set.880 *881 * @param $options882 * @return {boolean}883 */884 check_options($options) {885 if ($options.length <= 0) {886 return false;887 }888 let all_set = true;889 $options.each(function (index, option) {890 // Only check attribute fields.891 if (!$(option).hasClass('orderable-input--validate')) {892 return;893 }894 if ('' === $(option).val()) {895 $(option).addClass(orderable_products.vars.classes.invalid_field);896 all_set = false;897 } else {898 $(option).removeClass(orderable_products.vars.classes.invalid_field);899 }900 });901 return all_set;902 },903 /**904 * Check if variation has been selected.905 * @param $options906 */907 check_variation($options) {908 const $product = $options.closest('.orderable-drawer');909 let variations = $product.find('.orderable-product__variations').text();910 variations = variations ? JSON.parse(variations) : '';911 const selected_options = orderable_products.serialize_object($options),912 matching_variations = orderable_products.find_matching_variations(variations, selected_options);913 if (orderable_products.is_empty(matching_variations)) {914 return false;915 }916 const variation = matching_variations.shift();917 variation.attributes = selected_options;918 variation.attributes_json = JSON.stringify(selected_options);919 return typeof variation !== 'undefined' ? variation : false;920 },921 /**922 * Set variation for add to cart button.923 * @param $button924 * @param variation925 */926 set_variation($button, variation) {927 let variation_id = variation.variation_id || '',928 attributes = variation.attributes_json || '',929 price = variation.price_html || orderable_products.vars.parent_price,930 message = '';931 if (variation && '' !== variation.availability_html) {932 message = variation.availability_html;933 }934 if (variation && !variation.is_in_stock) {935 message = '<p>' + orderable_vars.i18n.out_of_stock + '</p>';936 }937 if (variation && !variation.is_purchasable) {938 message = '<p>' + orderable_vars.i18n.unavailable + '</p>';939 }940 if (false === variation) {941 message = '<p>' + orderable_vars.i18n.no_exist + '</p>';942 }943 if (variation && (!variation.is_purchasable || !variation.is_in_stock)) {944 variation_id = '';945 attributes = '';946 }947 if ('' !== message) {948 $('.' + orderable_products.vars.classes.product_messages).html(message);949 }950 $button.data('orderable-variation-id', variation_id);951 $button.data('orderable-variation-attributes', attributes);952 $('.orderable-drawer .orderable-product__actions-price').html(price);953 $button.trigger('orderable_variation_set', {954 variation,955 variation_id,956 attributes,957 price958 });959 },960 /**961 * Clear variation and disable add to order.962 *963 * @param $button964 */965 clear_variation($button) {966 orderable_products.set_variation($button, '');967 if (orderable_products.vars.parent_price) {968 $('.orderable-drawer .orderable-product__actions-price').html(orderable_products.vars.parent_price);969 }970 },971 /**972 * Find matching variations for attributes.973 * @param variations974 * @param attributes975 */976 find_matching_variations(variations, attributes) {977 const matching = [];978 for (let i = 0; i < variations.length; i++) {979 const variation = variations[i];980 if (orderable_products.is_matching_variation(variation.attributes, attributes)) {981 matching.push(variation);982 }983 }984 return matching;985 },986 /**987 * See if attributes match.988 * @param variation_attributes989 * @param attributes990 * @return {boolean}991 */992 is_matching_variation(variation_attributes, attributes) {993 let match = true;994 for (const attr_name in variation_attributes) {995 if (variation_attributes.hasOwnProperty(attr_name)) {996 const val1 = variation_attributes[attr_name];997 const val2 = attributes[attr_name];998 if (val1 !== undefined && val2 !== undefined && val1.length !== 0 && val2.length !== 0 && val1 !== val2) {999 match = false;1000 }1001 }1002 }1003 return match;1004 },1005 /**1006 * Is value empty?1007 *1008 * @param value1009 * @return {boolean}1010 */1011 is_empty(value) {1012 return typeof value === 'undefined' || false === value || value.length <= 0 || !value;1013 },1014 /**1015 * Serialize into a key/value object.1016 *1017 * @param $elements1018 * @return {{}}1019 */1020 serialize_object: function objectifyForm($elements) {1021 const serialized = $elements.serializeArray(),1022 return_object = {};1023 for (let i = 0; i < serialized.length; i++) {1024 return_object[serialized[i].name] = serialized[i].value;1025 }1026 return return_object;1027 },1028 /**1029 * Disable/Enable the 'Add to cart' button based on the presence of orderable-field--invalid class.1030 */1031 update_button_state() {1032 // Add delay to ensure invalid class has been assigned to inputs.1033 setTimeout(function () {1034 let $button = $('.orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item'),1035 invalid_fields_count = $('.orderable-drawer__html .' + orderable_products.vars.classes.invalid_field).length,1036 product_type = $button.data('orderable-product-type'),1037 has_variation_id = true;1038 if ('variable' === product_type) {1039 has_variation_id = '' !== $button.data('orderable-variation-id');1040 }1041 $button.prop('disabled', invalid_fields_count || !has_variation_id);1042 }, 50);1043 },1044 /**1045 * Debounce function.1046 *1047 * @param func Function to debounce.1048 * @param wait Time to wait in milliseconds.1049 * @param immediate Trigger the function on the leading edge, instead of the trailing.1050 *1051 * @return1052 */1053 debounce(func, wait, immediate) {1054 let timeout;1055 return function () {1056 const context = this,1057 args = arguments;1058 const later = function () {1059 timeout = null;1060 if (!immediate) {1061 func.apply(context, args);1062 }1063 };1064 const callNow = immediate && !timeout;1065 clearTimeout(timeout);1066 timeout = setTimeout(later, wait);1067 if (callNow) {1068 func.apply(context, args);1069 }1070 };1071 },1072 /**1073 * Remove the quantity roller fragments1074 *1075 * @param {Event} e1076 * @param {Object} fragments1077 * @return void1078 */1079 remove_fragments(e, fragments) {1080 if (!fragments || 'undefined' === typeof wc_cart_fragments_params || !wc_cart_fragments_params.fragment_name) {1081 return;1082 }1083 const regex_quantity_roller = /\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-quantity-roller/;1084 const regex_product_in_the_cart_counter = /\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-product__actions-counter/;1085 for (const key in fragments) {1086 if (!regex_quantity_roller.test(key) && !regex_product_in_the_cart_counter.test(key)) {1087 continue;1088 }1089 fragments[key] = undefined;1090 }1091 sessionStorage.setItem(wc_cart_fragments_params.fragment_name, JSON.stringify(fragments));1092 },1093 /**1094 * Remove animation.1095 */1096 remove_animation() {1097 setTimeout(function () {1098 $('.orderable-product__actions-counter').css('animation', '');1099 }, 1000);1100 },1101 /**1102 * Hide quantity roller element and show the Add to Cart button.1103 *1104 * @param {Event} e1105 * @param {Object} fragments1106 * @param {string} cart_hash1107 * @param {Element} $button1108 * @return1109 */1110 hide_quantity_roller(e, fragments, cart_hash, $button) {1111 const product_id = $button.attr('data-product_id') || $button.attr('data-orderable-product-id');1112 if (!product_id) {1113 return;1114 }1115 const $actions_button = $('.orderable-product[data-orderable-product-id=' + product_id + '] .orderable-product__actions-button');1116 if (!$actions_button.length) {1117 return;1118 }1119 const $quantity_roller = $actions_button.find('.orderable-quantity-roller');1120 if ($quantity_roller.length) {1121 $actions_button.find('button.orderable-product__add-to-order[data-orderable-trigger]').removeClass('orderable-button--product-in-the-cart');1122 $quantity_roller.addClass('orderable-button--hide');1123 }1124 },1125 /**1126 * Add unchecked checkboxs to the list of inputs1127 * sent to the request to add/update an item1128 *1129 * @param {Object} inputs1130 * @return {Object}1131 */1132 add_unchecked_checkbox_fields(inputs) {1133 jQuery('.orderable-product-fields-group :input[type="checkbox"]:not(:checked)').each(function (index, element) {1134 inputs.push({1135 name: element.getAttribute('name'),1136 value: ''1137 });1138 });1139 return inputs;1140 },1141 /**1142 * Shake the floating cart button.1143 *1144 * @return void1145 */1146 shake_floating_cart() {1147 $('.orderable-floating-cart__button').css('animation', 'wobble-hor-bottom .8s both');1148 },1149 /**1150 * Remove the view cart link.1151 *1152 * @param event1153 * @param $button1154 */1155 remove_view_cart_link(event, $button) {1156 if (!$button?.hasClass('orderable-product__add-to-order')) {1157 return;1158 }1159 $button?.siblings('.added_to_cart.wc-forward').remove();1160 }1161 };1162 $(document).ready(orderable_products.on_ready);1163 })(jQuery, document);1164 (function ($, document) {1165 'use strict';1166 1167 var orderable_scrollbar = {1168 /**1169 * On doc ready.1170 */1171 on_ready() {1172 orderable_scrollbar.cache();1173 orderable_scrollbar.watch();1174 },1175 /**1176 * Cache.1177 */1178 cache() {1179 orderable_scrollbar.vars = {1180 top: {}1181 };1182 orderable_scrollbar.elements = {};1183 },1184 /**1185 * Watch.1186 */1187 watch() {1188 $(document.body).on('orderable-drawer.opened', orderable_scrollbar.trigger);1189 $(document.body).on('orderable-tabs.changed', orderable_scrollbar.trigger);1190 $(document.body).on('orderable-accordion.toggled', orderable_scrollbar.trigger);1191 $(document.body).on('wc_fragments_loaded', orderable_scrollbar.trigger);1192 },1193 /**1194 * Init or retrigger scrollbars.1195 */1196 trigger() {1197 $('.orderable-sb-container').each(function (index, element) {1198 const $element = $(element),1199 scroll_id = $element.data('orderable-scroll-id');1200 if (!orderable_scrollbar.has_scrollbar($element)) {1201 $element.scrollBox({1202 containerClass: 'orderable-sb-container',1203 containerNoScrollClass: 'orderable-sb-container-noscroll',1204 contentClass: 'orderable-sb-content',1205 scrollbarContainerClass: 'orderable-sb-scrollbar-container',1206 scrollBarClass: 'orderable-sb-scrollbar'1207 });1208 const $content = $element.find('.orderable-sb-content');1209 if ($content.length > 0) {1210 $content.on('scroll.scrollBox', orderable_scrollbar.log_top_position);1211 1212 // Set scroll position.1213 if (typeof orderable_scrollbar.vars.top[scroll_id] !== 'undefined') {1214 $content.scrollTop(orderable_scrollbar.vars.top[scroll_id]);1215 }1216 }1217 $(document.body).trigger('orderable-scrollbar.created', {1218 element: $element,1219 content: $content1220 });1221 }1222 });1223 $(window).trigger('resize.scrollBox');1224 },1225 /**1226 * Has scrollbar already?1227 *1228 * @param $element1229 * @return {boolean}1230 */1231 has_scrollbar($element) {1232 return $element.find('.orderable-sb-content').length > 0;1233 },1234 /**1235 * Set scrolltop position.1236 *1237 * @param e1238 */1239 log_top_position(e) {1240 const $element = $(e.currentTarget),1241 $container = $element.closest('.orderable-sb-container'),1242 scroll_id = $container.data('orderable-scroll-id');1243 orderable_scrollbar.vars.top[scroll_id] = $(e.currentTarget).scrollTop();1244 }1245 };1246 $(document).ready(orderable_scrollbar.on_ready);1247 })(jQuery, document);1248 (function ($, document) {1249 'use strict';1250 1251 var orderable_tabs = {1252 /**1253 * On doc ready.1254 */1255 on_ready() {1256 orderable_tabs.cache();1257 orderable_tabs.watch();1258 orderable_tabs.toggle_scroll();1259 },1260 /**1261 * On resize.1262 */1263 on_resize() {1264 orderable_tabs.toggle_scroll();1265 },1266 /**1267 * Cache.1268 */1269 cache() {1270 orderable_tabs.vars = {1271 classes: {1272 tabs: 'orderable-tabs',1273 tabs_list: 'orderable-tabs__list',1274 tab_items: 'orderable-tabs__item',1275 tab_item_active: 'orderable-tabs__item--active',1276 tab_links: 'orderable-tabs__link',1277 tab_arrow_right: 'orderable-tabs__arrow-right',1278 tab_arrow_left: 'orderable-tabs__arrow-left'1279 },1280 dragging: false1281 };1282 orderable_tabs.elements = {};1283 },1284 /**1285 * Watch.1286 */1287 watch() {1288 $('body').on('touchstart', function () {1289 orderable_tabs.vars.dragging = false;1290 }).on('touchmove', function () {1291 orderable_tabs.vars.dragging = true;1292 });1293 $(document.body).on('click mouseup touchend', '.' + orderable_tabs.vars.classes.tab_links, function (e) {1294 if (orderable_tabs.vars.dragging) {1295 return;1296 }1297 e.preventDefault();1298 const $link = $(this),1299 section_id = $link.attr('href'),1300 $tab = $link.closest('.' + orderable_tabs.vars.classes.tab_items),1301 $tabs = $link.closest('.' + orderable_tabs.vars.classes.tabs),1302 $tabs_list = $tabs.find('.' + orderable_tabs.vars.classes.tabs_list),1303 $tab_items = $tabs.find('.' + orderable_tabs.vars.classes.tab_items),1304 tabs_args = $tabs.data('orderable-tabs'),1305 $wrapper = $link.closest(tabs_args.wrapper),1306 $sections = $wrapper.find(tabs_args.sections),1307 $section = $wrapper.find(section_id);1308 $sections.hide();1309 $section.show();1310 $tab_items.removeClass(orderable_tabs.vars.classes.tab_item_active);1311 $tab.addClass(orderable_tabs.vars.classes.tab_item_active);1312 $tabs_list.animate({1313 scrollLeft: $tabs_list.scrollLeft() + $tab.position().left1314 });1315 $(document.body).trigger('orderable-tabs.changed', {1316 tab: $tab1317 });1318 });1319 1320 /**1321 * Watch scroll position of tabs.1322 */1323 $('.' + orderable_tabs.vars.classes.tabs_list).on('scroll', function (e) {1324 const $list = $(this),1325 $wrapper = $list.parent('.' + orderable_tabs.vars.classes.tabs),1326 $arrow_right = $list.siblings('.' + orderable_tabs.vars.classes.tab_arrow_right),1327 $arrow_left = $list.siblings('.' + orderable_tabs.vars.classes.tab_arrow_left);1328 if ($list[0].scrollWidth <= $wrapper.width() + $list.scrollLeft()) {1329 $arrow_right.fadeOut();1330 } else {1331 $arrow_right.fadeIn();1332 }1333 if (0 >= $list.scrollLeft() - $arrow_left.width()) {1334 $arrow_left.fadeOut();1335 } else {1336 $arrow_left.fadeIn();1337 }1338 });1339 1340 /**1341 * Stop animated scroll if user manually scrolls.1342 */1343 $('.' + orderable_tabs.vars.classes.tabs_list).on('wheel DOMMouseScroll mousewheel touchmove', function () {1344 $(this).stop();1345 });1346 1347 /**1348 * Click tab arrow right.1349 */1350 $(document).on('click', '.' + orderable_tabs.vars.classes.tab_arrow_right, function (e) {1351 e.preventDefault();1352 const $arrow = $(this),1353 $wrapper = $arrow.parent(),1354 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list);1355 $list.animate({1356 scrollLeft: $list.scrollLeft() + $wrapper.width() * 0.51357 });1358 });1359 1360 /**1361 * Click tab arrow left.1362 */1363 $(document).on('click', '.' + orderable_tabs.vars.classes.tab_arrow_left, function (e) {1364 e.preventDefault();1365 const $arrow = $(this),1366 $wrapper = $arrow.parent(),1367 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list);1368 $list.animate({1369 scrollLeft: $list.scrollLeft() - $wrapper.width() * 0.51370 });1371 });1372 },1373 /**1374 * Toggle scroll arrow.1375 */1376 toggle_scroll() {1377 $('.' + orderable_tabs.vars.classes.tabs).each(function (index, wrapper) {1378 const $tabs = $(this),1379 tabs_args = $tabs.data('orderable-tabs'),1380 $wrapper = $tabs.closest(tabs_args.wrapper),1381 $list = $wrapper.find('.' + orderable_tabs.vars.classes.tabs_list),1382 $arrow_right = $wrapper.find('.' + orderable_tabs.vars.classes.tab_arrow_right),1383 wrapper_width = $wrapper.outerWidth(),1384 list_width = $list[0].scrollWidth;1385 if (list_width > wrapper_width) {1386 $arrow_right.show();1387 } else {1388 $arrow_right.hide();1389 }1390 });1391 }1392 };1393 $(document).ready(orderable_tabs.on_ready);1394 $(window).on('resize', orderable_tabs.on_resize);1395 })(jQuery, document);1396 let orderable_timings = {}; // Make this global so pro modules can access it.1397 1398 (function ($, document) {1399 'use strict';1400 1401 orderable_timings = {1402 /**1403 * On doc ready.1404 */1405 on_ready() {1406 orderable_timings.watch();1407 },1408 /**1409 * Restore current timings.1410 */1411 restore() {1412 const timings = orderable_timings.get_timings();1413 if (!timings || !timings.date) {1414 return;1415 }1416 const dateSelect = $('.orderable-order-timings__date');1417 if (dateSelect.find('option[value="' + timings.date + '"]').length > 0) {1418 dateSelect.val(timings.date);1419 dateSelect.change();1420 }1421 if (!timings.time) {1422 return;1423 }1424 const timeSelect = $('.orderable-order-timings__time');1425 if (timeSelect.find('option[value="' + timings.time + '"]').length > 0) {1426 timeSelect.val(timings.time);1427 timeSelect.change();1428 }1429 },1430 /**1431 * Watch for trigger events.1432 */1433 watch() {1434 $(document.body).on('wc_fragments_refreshed', function () {1435 orderable_timings.restore();1436 });1437 $(document.body).on('updated_checkout', function () {1438 orderable_timings.restore();1439 });1440 $(document.body).on('change', '.orderable-order-timings__date', function (event) {1441 const $date_field = $(this),1442 $selected = $date_field.find('option:selected'),1443 slots = $selected.data('orderable-slots'),1444 $time_field_wrap = $('.orderable-order-timings--time'),1445 $time_field = $('.orderable-order-timings__time'),1446 $first_option = $time_field.find('option').first(),1447 $asap_option = $time_field.find('option[value="asap"]').first();1448 const timings = orderable_timings.get_timings();1449 timings.date = $('.orderable-order-timings__date').val();1450 window.localStorage.setItem('orderable_timings', JSON.stringify(timings));1451 $time_field.html($first_option);1452 if ($asap_option) {1453 $time_field.append($asap_option);1454 }1455 if (!slots) {1456 $time_field.prop('disabled', true);1457 $time_field_wrap.hide();1458 return;1459 }1460 if ('all-day' === slots[0].value) {1461 $time_field_wrap.hide();1462 $time_field.prop('disabled', true);1463 } else {1464 $time_field.prop('disabled', false);1465 $time_field_wrap.show();1466 $.each(slots, function (index, slot) {1467 $time_field.append($('<option />').attr('value', slot.value).attr('data-orderable-time-slot-id', slot?.setting_row?.time_slot_id).text(slot.formatted));1468 });1469 }1470 });1471 $(document.body).on('change', '.orderable-order-timings__time', function (event) {1472 const timings = orderable_timings.get_timings();1473 timings.time = $('.orderable-order-timings__time').val();1474 window.localStorage.setItem('orderable_timings', JSON.stringify(timings));1475 $(this).siblings('input[name="orderable_order_time_slot_id"]').val($(this).find(':selected').attr('data-orderable-time-slot-id'));1476 });1477 },1478 get_timings() {1479 return JSON.parse(window.localStorage.getItem('orderable_timings')) || {};1480 }1481 };1482 $(document).ready(orderable_timings.on_ready);1483 })(jQuery, document);1484 (function ($, document) {1485 'use strict';1486 1487 var orderable_triggers = {1488 /**1489 * On doc ready.1490 */1491 on_ready() {1492 orderable_triggers.watch();1493 },1494 /**1495 * Watch for trigger events.1496 */1497 watch() {1498 if ('undefined' !== typeof window.orderable_triggers_admin) {1499 return;1500 }1501 $(document.body).on('click', '[data-orderable-trigger]', orderable_triggers.trigger);1502 },1503 /**1504 * Fire trigger.1505 * @param e1506 */1507 trigger(e) {1508 // Prevent even bubbling up.1509 e.stopImmediatePropagation();1510 const $trigger_element = $(this),1511 trigger = $trigger_element.data('orderable-trigger');1512 if ($trigger_element.is('button') || $trigger_element.is('a')) {1513 e.preventDefault();1514 }1515 $(document.body).trigger('orderable-' + trigger, [$trigger_element]);1516 }1517 };1518 $(document).ready(orderable_triggers.on_ready);1519 })(jQuery, document); -
orderable/trunk/assets/frontend/js/main.min.js
r3192586 r3237969 1 !function(o,e,s){"use strict";var n="scrollBox",r={containerClass:"sb-container",containerNoScrollClass:"sb-container-noscroll",contentClass:"sb-content",scrollbarContainerClass:"sb-scrollbar-container",scrollBarClass:"sb-scrollbar"};function t(e,t){this.element=e,this.settings=o.extend({},r,t),this._defaults=r,this._name=n,this.init()}o.extend(t.prototype,{init:function(){this.addScrollbar(),this.addEvents(),this.onResize()},addScrollbar:function(){o(this.element).addClass(this.settings.containerClass),this.wrapper=o("<div class='"+this.settings.contentClass+"' />"),this.wrapper.append(o(this.element).contents()),o(this.element).append(this.wrapper),this.scollbarContainer=o("<div class='"+this.settings.scrollbarContainerClass+"' />"),this.scrollBar=o("<div class='"+this.settings.scrollBarClass+"' />"),this.scollbarContainer.append(this.scrollBar),o(this.element).prepend(this.scollbarContainer)},addEvents:function(){this.wrapper.on("scroll."+n,o.proxy(this.onScroll,this)),o(e).on("resize."+n,o.proxy(this.onResize,this)),this.scrollBar.on("mousedown."+n,o.proxy(this.onMousedown,this)),this.scrollBar.on("touchstart."+n,o.proxy(this.onTouchstart,this))},onTouchstart:function(t){var r=this,a=(t.preventDefault(),r.scrollBar[0].offsetTop);o(s).on("touchmove."+n,function(e){e=e.touches[0].pageY-t.touches[0].pageY;r.scrollBar[0].style.top=Math.min(r.scollbarContainer[0].clientHeight-r.scrollBar[0].clientHeight,Math.max(0,a+e))+"px",r.wrapper[0].scrollTop=r.wrapper[0].scrollHeight*r.scrollBar[0].offsetTop/r.scollbarContainer[0].clientHeight}),o(s).on("touchend."+n,function(){o(s).off("touchmove."+n),o(s).off("touchend."+n)})},onMousedown:function(t){var r=this,a=(t.preventDefault(),r.scrollBar[0].offsetTop);o(s).on("mousemove."+n,function(e){e=e.pageY-t.pageY;r.scrollBar[0].style.top=Math.min(r.scollbarContainer[0].clientHeight-r.scrollBar[0].clientHeight,Math.max(0,a+e))+"px",r.wrapper[0].scrollTop=r.wrapper[0].scrollHeight*r.scrollBar[0].offsetTop/r.scollbarContainer[0].clientHeight}),o(s).on("mouseup."+n,function(){o(s).off("mousemove."+n),o(s).off("mouseup."+n)})},onResize:function(){this.wrapper.css("max-height",o(this.element).height());var e=this.wrapper[0].clientHeight;this.scrollBar.css("height",this.scollbarContainer[0].clientHeight*e/this.wrapper[0].scrollHeight+"px"),this.scollbarContainer[0].clientHeight<=this.scrollBar[0].clientHeight?o(this.element).addClass(this.settings.containerNoScrollClass):o(this.element).removeClass(this.settings.containerNoScrollClass),this.onScroll()},onScroll:function(){this.scrollBar.css("top",Math.min(this.scollbarContainer[0].clientHeight-this.scrollBar[0].clientHeight,this.scollbarContainer[0].clientHeight*this.wrapper[0].scrollTop/this.wrapper[0].scrollHeight)+"px")}}),o.fn[n]=function(e){return this.each(function(){o.data(this,"plugin_"+n)||o.data(this,"plugin_"+n,new t(this,e))})}}(jQuery,window,document),function(e,o){"use strict";"function"!=typeof e.CustomEvent&&(e.CustomEvent=function(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var r=o.createEvent("CustomEvent");return r.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),r},e.CustomEvent.prototype=e.Event.prototype),o.addEventListener("touchstart",function(e){"true"!==e.target.getAttribute("data-swipe-ignore")&&(c=e.target,l=Date.now(),s=e.touches[0].clientX,n=e.touches[0].clientY,d=i=0)},!1),o.addEventListener("touchmove",function(e){var t;s&&n&&(t=e.touches[0].clientX,e=e.touches[0].clientY,i=s-t,d=n-e)},!1),o.addEventListener("touchend",function(e){var t,r,a,o;c===e.target&&(o=parseInt(_(c,"data-swipe-threshold","20"),10),t=parseInt(_(c,"data-swipe-timeout","500"),10),r=Date.now()-l,a="",e=e.changedTouches||e.touches||[],Math.abs(i)>Math.abs(d)?Math.abs(i)>o&&r<t&&(a=0<i?"swiped-left":"swiped-right"):Math.abs(d)>o&&r<t&&(a=0<d?"swiped-up":"swiped-down"),""!==a&&(o={dir:a.replace(/swiped-/,""),touchType:(e[0]||{}).touchType||"direct",xStart:parseInt(s,10),xEnd:parseInt((e[0]||{}).clientX||-1,10),yStart:parseInt(n,10),yEnd:parseInt((e[0]||{}).clientY||-1,10)},c.dispatchEvent(new CustomEvent("swiped",{bubbles:!0,cancelable:!0,detail:o})),c.dispatchEvent(new CustomEvent(a,{bubbles:!0,cancelable:!0,detail:o}))),l=n=s=null)},!1);var s=null,n=null,i=null,d=null,l=null,c=null;function _(e,t,r){for(;e&&e!==o.documentElement;){var a=e.getAttribute(t);if(a)return a;e=e.parentNode}return r}}(window,document),function(o,s){"use strict";var n={on_ready(){n.cache(),n.watch()},cache(){n.vars={classes:{parent:"orderable-accordion",link:"orderable-accordion__item-link",content:"orderable-accordion__item-content",link_active:"orderable-accordion__item-link--active",content_active:"orderable-accordion__item-content--active"}}},watch(){o(s.body).on("click","."+n.vars.classes.link,function(e){e.preventDefault();var e=o(this),t=e.closest("."+n.vars.classes.parent),r=e.attr("href"),r=o(r),a=e.hasClass(n.vars.classes.link_active);t.find("."+n.vars.classes.link).removeClass(n.vars.classes.link_active),t.find("."+n.vars.classes.content).removeClass(n.vars.classes.content_active),a||(e.addClass(n.vars.classes.link_active),r.addClass(n.vars.classes.content_active)),o(s.body).trigger("orderable-accordion.toggled",{link:e,content:r})}),o(s.body).on("orderable-scrollbar.created",function(e,t){var r=o(".orderable-drawer ."+n.vars.classes.link_active);r.length<=0||(r=(t=t.content).scrollTop()-t.offset().top+r.offset().top,t.scrollTop(r))})}};o(s).ready(n.on_ready)}(jQuery,document),function(l,c){"use strict";var r={debounce(t,r=700){let a;return(...e)=>{clearTimeout(a),a=setTimeout(()=>{t.apply(this,e)},r)}},allow_only_numbers(e){var t=String.fromCharCode(e.which);/^\d+$/.test(t)||e.preventDefault()},on_change_quantity(e){const t=l(e.currentTarget);var e=t.data("orderable-product-id"),r=t.data("orderable-cart-item-key"),a=parseInt(t.text());jQuery.post(orderable_vars.ajax_url,{action:"orderable_cart_quantity",cart_item_key:r,product_id:e,quantity:a},function(e){e&&(l(c.body).trigger("added_to_cart",[e.fragments,e.cart_hash,t]),l(c.body).trigger("orderable-drawer.quantity-updated"))})},on_ready(){r.cache(),r.watch(),l(c.body).on("keypress",".orderable-quantity-roller__quantity",r.allow_only_numbers),l(".orderable-drawer__cart, .orderable-product--add-to-cart, .orderable-products-list").on("input",".orderable-quantity-roller__quantity",r.debounce(r.on_change_quantity)),l(c.body).on("click",".orderable-quantity-roller__quantity",function(e){e.stopPropagation()}),orderable_vars&&!orderable_vars.woocommerce_enable_ajax_add_to_cart&&l(c.body).off("click",".add_to_cart_button")},cache(){r.vars={classes:{overlay:"orderable-drawer-overlay",drawer:"orderable-drawer",drawer_cart:"orderable-drawer__cart",drawer_html:"orderable-drawer__html",overlay_open:"orderable-drawer-overlay--open",drawer_open:"orderable-drawer--open",drawer_open_body:"orderable-drawer-open"}},r.elements={body:l("body"),overlay:l("."+r.vars.classes.overlay),drawer:l("."+r.vars.classes.drawer),drawer_cart:l("."+r.vars.classes.drawer_cart),drawer_html:l("."+r.vars.classes.drawer_html),floating_cart_button_class:".orderable-floating-cart__button"}},watch(){var e,t;void 0!==r.elements.drawer&&(l(c.body).on("orderable-drawer.open",r.open),l(c.body).on("orderable-drawer.close",r.close),l(c.body).on("click",r.elements.floating_cart_button_class,function(){l(c.body).trigger("orderable-drawer.open",{show_cart:!0})}),l(c.body).on("orderable-increase-quantity",r.cart.handle_quantity_change_by_button),l(c.body).on("orderable-decrease-quantity",r.cart.handle_quantity_change_by_button),e=r.debounce(r.cart.click_increase_decrease_quantity),l(c.body).on("orderable-increase-quantity",e),l(c.body).on("orderable-decrease-quantity",e),e=c.querySelector("body:not( .rtl ) .orderable-drawer"),t=c.querySelector("body.rtl .orderable-drawer"),e&&e.addEventListener("swiped-right",function(e){r.close()}),t)&&t.addEventListener("swiped-left",function(e){r.close()})},open(e,t){t.html=t.html||!1,t.show_cart=t.show_cart||!1,r.elements.drawer_html.hide(),r.elements.drawer_cart.hide(),t.html&&(r.elements.drawer_html.html(t.html),r.elements.drawer_html.show()),t.show_cart&&(r.elements.drawer_html.html(""),r.elements.drawer_cart.show()),r.elements.overlay.addClass(r.vars.classes.overlay_open),r.elements.drawer.addClass(r.vars.classes.drawer_open),r.elements.body.addClass(r.vars.classes.drawer_open_body),l(c.body).trigger("orderable-drawer.opened",t)},close(){r.elements.overlay.removeClass(r.vars.classes.overlay_open),r.elements.drawer.removeClass(r.vars.classes.drawer_open),r.elements.body.removeClass(r.vars.classes.drawer_open_body),r.elements.drawer_html.html(""),l(c.body).trigger("orderable-drawer.closed")},cart:{click_increase_decrease_quantity(e,r){var t=r.data("orderable-trigger"),a=r.attr("data-orderable-product-id"),o=r.attr("data-orderable-cart-item-key"),s=r.attr("data-orderable-quantity");const n=r.siblings(".orderable-quantity-roller__button--"+("increase-quantity"===t?"decrease":"increase")),i=r.siblings(".orderable-quantity-roller__quantity"),d={action:"orderable_cart_quantity",cart_item_key:o,product_id:a,quantity:s};this.currentRequest&&(this.currentRequest.abort(),this.currentRequest=void 0),r.addClass("orderable-button--loading"),r.attr("disabled",!0),n.attr("disabled",!0),i.attr("contenteditable",!1),this.currentRequest=jQuery.post(orderable_vars.ajax_url,d,function(e){if(e){var t=r.siblings(".orderable-quantity-roller__quantity");switch(e&&e.fragments&&e.fragments[".orderable-mini-cart__notices"]&&l(c.body).trigger("orderable-drawer.open",{show_cart:!0}),d.quantity){case"0":l(c.body).trigger("removed_from_cart",[e.fragments,e.cart_hash,r]);break;case t.attr("data-orderable-updating-quantity"):l(c.body).trigger("added_to_cart",[e.fragments,e.cart_hash,r]),l(c.body).trigger("orderable-drawer.quantity-updated")}}}.bind(this)).always(function(){this.currentRequest=void 0,r.removeClass("orderable-button--loading"),r.attr("disabled",!1),n.attr("disabled",!1),i.attr("contenteditable",!0)}.bind(this))},handle_quantity_change_by_button(e,t){var r,a=t.data("orderable-trigger"),o=parseInt(t.attr("data-orderable-quantity")),s=t.siblings(".orderable-quantity-roller__button--"+("increase-quantity"===a?"decrease":"increase")),n=t.siblings(".orderable-quantity-roller__quantity"),a="increase-quantity"===a?o+1:Math.max(0,o-1),o=t.parents(".orderable-product__actions-button");0===a&&o.length&&(r=o.find("button.orderable-button[data-orderable-trigger]"),(o=o.find(".orderable-quantity-roller")).length)&&(r.removeClass("orderable-button--product-in-the-cart"),o.removeClass("orderable-quantity-roller--is-active")),t.attr("data-orderable-quantity",a),s.attr("data-orderable-quantity",a),n.attr("data-orderable-updating-quantity",a),n.text(a),n.attr("contenteditable",!1)}}};l(c).ready(r.on_ready)}(jQuery,document),function(d,l){"use strict";var c={on_ready(){c.cache(),c.watch()},cache(){c.vars={classes:{clickable_product:"orderable-product--add-to-cart ",add_to_order_button:"orderable-product__add-to-order",product_messages:"orderable-product__messages",product_price:"orderable-product__actions-price",invalid_field:"orderable-field--invalid",option_select_td:"orderable-product__option-select",button_loading:"orderable-button--loading",out_of_stock:"orderable-button--out-of-stock"},parent_price:null,variable_product_types:["variable","variable-subscription"]},c.elements={}},watch(){d(l.body).on("orderable-drawer.opened",c.init_product_options),d(l.body).on("orderable-add-to-cart",c.click_add_to_order),d(l.body).on("orderable-product-options",c.click_add_to_order),d(l.body).on("orderable-view-product",c.view_product),d(l.body).on("mouseenter mouseleave","."+c.vars.classes.clickable_product,c.simulate_add_to_order_hover),d(l.body).on("orderable-edit-cart-item",c.edit_cart_item),d(l.body).on("orderable-update-cart-item",c.update_cart_item),d(l.body).on("orderable-show-cart",c.show_cart),d(l.body).on("orderable-add-to-cart-without-side-drawer",c.click_add_to_order),d(l.body).on("added_to_cart",c.remove_fragments),d(l.body).on("added_to_cart",c.remove_animation),d(l.body).on("added_to_cart",c.shake_floating_cart),d(l.body).on("removed_from_cart",c.hide_quantity_roller),d(l.body).on("wc_cart_button_updated",c.remove_view_cart_link)},simulate_add_to_order_hover(e){d(this).find("."+c.vars.classes.add_to_order_button).toggleClass("orderable-button--hover","mouseenter"===e.type)},click_add_to_order(e,t){const r=(t=void 0!==t?t:d(this)).is("button")?t:t.find("."+c.vars.classes.add_to_order_button),a=r.data("orderable-trigger"),o=r.data("orderable-product-id"),s=r.data("orderable-variation-id"),n=r.data("orderable-variation-attributes"),i={action:a};if(!r.hasClass(c.vars.classes.button_loading)&&!r.hasClass(c.vars.classes.out_of_stock))switch(r.addClass(c.vars.classes.button_loading),a){case"add-to-cart":c.add_to_cart({product_id:o,variation_id:s,attributes:n,thisbutton:t},function(e){i.show_cart=!0,i.response=e,d(l.body).trigger("orderable-drawer.open",i),r.removeClass(c.vars.classes.button_loading);e=d(".orderable-product .orderable-product__actions-button button.orderable-product__add-to-order[data-orderable-product-id="+o+"]");e.siblings(".orderable-quantity-roller").length&&e.addClass("orderable-button--product-in-the-cart")});break;case"add-to-cart-without-side-drawer":c.add_to_cart({product_id:o,variation_id:s,attributes:n},function(e){i.response=e,r.addClass("orderable-button--product-in-the-cart"),r.removeClass(c.vars.classes.button_loading)});break;case"product-options":c.get_product_options({product_id:o,focus:r.data("orderable-focus")},function(e){i.html=e.html,d(l.body).trigger("orderable-drawer.open",i),r.removeClass(c.vars.classes.button_loading)})}},show_cart(){d(l.body).trigger("orderable-drawer.open",{show_cart:!0})},view_product(e,t){const r=t.data("orderable-product-id"),a={action:"product-options"};c.get_product_options({product_id:r,focus:t.data("orderable-focus")},function(e){a.html=e.html,d(l.body).trigger("orderable-drawer.open",a)})},add_to_cart(t,r){if(void 0!==t.product_id){let e={action:"orderable_add_to_cart",product_id:t.product_id,variation_id:t.variation_id||!1,attributes:t.attributes||!1};var a;d(".orderable-product-fields-group").length&&(a=jQuery(".orderable-product-fields-group :input").serializeArray(),a=c.add_unchecked_checkbox_fields(a),a=c.convert_to_flat_object(a),jQuery.isEmptyObject(a)||(e=Object.assign(e,a))),jQuery.post(orderable_vars.ajax_url,e,function(e){e&&(d(l.body).trigger("added_to_cart",[e.fragments,e.cart_hash,t.thisbutton]),"function"==typeof r)&&r(e)})}},edit_cart_item(e,t){var r=t.data("orderable-cart-item-key");t.addClass(c.vars.classes.button_loading),c.get_cart_item_options({cart_item_key:r},function(e){e={html:e.html,action:"update-cart-item"};d(l.body).trigger("orderable-drawer.open",e),t.removeClass(c.vars.classes.button_loading)})},update_cart_item(e,r){var t=r.data("orderable-cart-item-key"),a=r.data("orderable-product-id"),o=r.data("orderable-variation-id"),s=r.data("orderable-variation-attributes");r.addClass(c.vars.classes.button_loading),c.update_cart_item_options({cart_item_key:t,product_id:a,variation_id:o,attributes:s},function(e){var t={show_cart:!0,response:e};d(l.body).trigger("added_to_cart",[e.fragments,e.cart_hash]),d(l.body).trigger("orderable-drawer.open",t),r.removeClass(c.vars.classes.button_loading)})},convert_to_flat_object(e){const a={};return e.forEach(function(e){var t="[]"===e.name.substr(-2)||Array.isArray(e.name),r=t?e.name.substr(0,e.name.length-2):e.name;t?(a[r]=void 0===a[r]?[]:a[r],a[r].push(e.value)):a[r]=e.value}),a},get_product_options(e,t){void 0!==e.product_id&&(e.action="orderable_get_product_options",jQuery.post(orderable_vars.ajax_url,e,function(e){e.success&&"function"==typeof t&&t(e.data)}))},get_cart_item_options(e,t){void 0!==e.cart_item_key&&(e.action="orderable_get_cart_item_options",jQuery.post(orderable_vars.ajax_url,e,function(e){e.success&&"function"==typeof t&&t(e.data)}))},update_cart_item_options(e,t){var r;void 0!==e.cart_item_key&&(e.action="orderable_update_cart_item_options",d(".orderable-product-fields-group").length&&(r=jQuery(".orderable-product-fields-group :input").serializeArray(),r=c.add_unchecked_checkbox_fields(r),r=c.convert_to_flat_object(r),jQuery.isEmptyObject(r)||(e=Object.assign(e,r))),jQuery.post(orderable_vars.ajax_url,e,function(e){e&&"function"==typeof t&&t(e)}))},init_product_options(e,t){if(void 0!==t.action&&("product-options"===t.action||"update-cart-item"===t.action)){t=".orderable-drawer .orderable-product__options input, .orderable-drawer .orderable-product__options select, .orderable-product__options textarea";const r=d(t),a=(c.vars.parent_price=d(".orderable-drawer .orderable-product__actions-price").html(),c.product_options_change(r),c.update_button_state(),c.debounce(c.update_button_state,500)),o=c.debounce(c.product_options_change,500);d(l).on("change keyup",t,function(){o(r),a()})}},product_options_change(e){var t=d(".orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item"),r=c.check_options(e),a=t.data("orderable-product-type");"product-options"===t.attr("data-orderable-trigger")&&t.attr("data-orderable-trigger","add-to-cart"),d("."+c.vars.classes.product_messages).html(""),c.vars.variable_product_types.includes(a)&&(r?(a=c.check_variation(e),c.set_variation(t,a)):c.clear_variation(t))},check_options(e){if(e.length<=0)return!1;let r=!0;return e.each(function(e,t){d(t).hasClass("orderable-input--validate")&&(""===d(t).val()?(d(t).addClass(c.vars.classes.invalid_field),r=!1):d(t).removeClass(c.vars.classes.invalid_field))}),r},check_variation(e){var t=(t=e.closest(".orderable-drawer").find(".orderable-product__variations").text())?JSON.parse(t):"",e=c.serialize_object(e),t=c.find_matching_variations(t,e);return!c.is_empty(t)&&((t=t.shift()).attributes=e,t.attributes_json=JSON.stringify(e),void 0!==t)&&t},set_variation(e,t){let r=t.variation_id||"",a=t.attributes_json||"",o=t.price_html||c.vars.parent_price,s="";t&&""!==t.availability_html&&(s=t.availability_html),t&&!t.is_in_stock&&(s="<p>"+orderable_vars.i18n.out_of_stock+"</p>"),t&&!t.is_purchasable&&(s="<p>"+orderable_vars.i18n.unavailable+"</p>"),!1===t&&(s="<p>"+orderable_vars.i18n.no_exist+"</p>"),!t||t.is_purchasable&&t.is_in_stock||(r="",a=""),""!==s&&d("."+c.vars.classes.product_messages).html(s),e.data("orderable-variation-id",r),e.data("orderable-variation-attributes",a),d(".orderable-drawer .orderable-product__actions-price").html(o),e.trigger("orderable_variation_set",{variation:t,variation_id:r,attributes:a,price:o})},clear_variation(e){c.set_variation(e,""),c.vars.parent_price&&d(".orderable-drawer .orderable-product__actions-price").html(c.vars.parent_price)},find_matching_variations(t,r){var a=[];for(let e=0;e<t.length;e++){var o=t[e];c.is_matching_variation(o.attributes,r)&&a.push(o)}return a},is_matching_variation(e,t){let r=!0;for(const s in e){var a,o;e.hasOwnProperty(s)&&(a=e[s],o=t[s],void 0!==a)&&void 0!==o&&0!==a.length&&0!==o.length&&a!==o&&(r=!1)}return r},is_empty(e){return void 0===e||!1===e||e.length<=0||!e},serialize_object:function(e){var t=e.serializeArray(),r={};for(let e=0;e<t.length;e++)r[t[e].name]=t[e].value;return r},update_button_state(){setTimeout(function(){let e=d(".orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item"),t=d(".orderable-drawer__html ."+c.vars.classes.invalid_field).length,r=e.data("orderable-product-type"),a=!0;"variable"===r&&(a=""!==e.data("orderable-variation-id")),e.prop("disabled",t||!a)},50)},debounce(a,o,s){let n;return function(){const e=this,t=arguments;var r=s&&!n;clearTimeout(n),n=setTimeout(function(){n=null,s||a.apply(e,t)},o),r&&a.apply(e,t)}},remove_fragments(e,t){if(t&&"undefined"!=typeof wc_cart_fragments_params&&wc_cart_fragments_params.fragment_name){var r=/\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-quantity-roller/,a=/\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-product__actions-counter/;for(const o in t)(r.test(o)||a.test(o))&&(t[o]=void 0);sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(t))}},remove_animation(){setTimeout(function(){d(".orderable-product__actions-counter").css("animation","")},1e3)},hide_quantity_roller(e,t,r,a){var o,a=a.attr("data-product_id")||a.attr("data-orderable-product-id");a&&(a=d(".orderable-product[data-orderable-product-id="+a+"] .orderable-product__actions-button")).length&&(o=a.find(".orderable-quantity-roller")).length&&(a.find("button.orderable-product__add-to-order[data-orderable-trigger]").removeClass("orderable-button--product-in-the-cart"),o.addClass("orderable-button--hide"))},add_unchecked_checkbox_fields(r){return jQuery('.orderable-product-fields-group :input[type="checkbox"]:not(:checked)').each(function(e,t){r.push({name:t.getAttribute("name"),value:""})}),r},shake_floating_cart(){d(".orderable-floating-cart__button").css("animation","wobble-hor-bottom .8s both")},remove_view_cart_link(e,t){t?.hasClass("orderable-product__add-to-order")&&t?.siblings(".added_to_cart.wc-forward").remove()}};d(l).ready(c.on_ready)}(jQuery,document),function(o,s){"use strict";var n={on_ready(){n.cache(),n.watch()},cache(){n.vars={top:{}},n.elements={}},watch(){o(s.body).on("orderable-drawer.opened",n.trigger),o(s.body).on("orderable-tabs.changed",n.trigger),o(s.body).on("orderable-accordion.toggled",n.trigger),o(s.body).on("wc_fragments_loaded",n.trigger)},trigger(){o(".orderable-sb-container").each(function(e,t){var r,t=o(t),a=t.data("orderable-scroll-id");n.has_scrollbar(t)||(t.scrollBox({containerClass:"orderable-sb-container",containerNoScrollClass:"orderable-sb-container-noscroll",contentClass:"orderable-sb-content",scrollbarContainerClass:"orderable-sb-scrollbar-container",scrollBarClass:"orderable-sb-scrollbar"}),0<(r=t.find(".orderable-sb-content")).length&&(r.on("scroll.scrollBox",n.log_top_position),void 0!==n.vars.top[a])&&r.scrollTop(n.vars.top[a]),o(s.body).trigger("orderable-scrollbar.created",{element:t,content:r}))}),o(window).trigger("resize.scrollBox")},has_scrollbar(e){return 0<e.find(".orderable-sb-content").length},log_top_position(e){var t=o(e.currentTarget).closest(".orderable-sb-container").data("orderable-scroll-id");n.vars.top[t]=o(e.currentTarget).scrollTop()}};o(s).ready(n.on_ready)}(jQuery,document),function(n,i){"use strict";var d={on_ready(){d.cache(),d.watch(),d.toggle_scroll()},on_resize(){d.toggle_scroll()},cache(){d.vars={classes:{tabs:"orderable-tabs",tabs_list:"orderable-tabs__list",tab_items:"orderable-tabs__item",tab_item_active:"orderable-tabs__item--active",tab_links:"orderable-tabs__link",tab_arrow_right:"orderable-tabs__arrow-right",tab_arrow_left:"orderable-tabs__arrow-left"},dragging:!1},d.elements={}},watch(){n("body").on("touchstart",function(){d.vars.dragging=!1}).on("touchmove",function(){d.vars.dragging=!0}),n(i.body).on("click mouseup touchend","."+d.vars.classes.tab_links,function(e){var t,r,a,o,s;d.vars.dragging||(e.preventDefault(),t=(e=n(this)).attr("href"),r=e.closest("."+d.vars.classes.tab_items),a=(s=e.closest("."+d.vars.classes.tabs)).find("."+d.vars.classes.tabs_list),o=s.find("."+d.vars.classes.tab_items),s=s.data("orderable-tabs"),s=(e=e.closest(s.wrapper)).find(s.sections),e=e.find(t),s.hide(),e.show(),o.removeClass(d.vars.classes.tab_item_active),r.addClass(d.vars.classes.tab_item_active),a.animate({scrollLeft:a.scrollLeft()+r.position().left}),n(i.body).trigger("orderable-tabs.changed",{tab:r}))}),n("."+d.vars.classes.tabs_list).on("scroll",function(e){var t=n(this),r=t.parent("."+d.vars.classes.tabs),a=t.siblings("."+d.vars.classes.tab_arrow_right),o=t.siblings("."+d.vars.classes.tab_arrow_left);t[0].scrollWidth<=r.width()+t.scrollLeft()?a.fadeOut():a.fadeIn(),t.scrollLeft()-o.width()<=0?o.fadeOut():o.fadeIn()}),n("."+d.vars.classes.tabs_list).on("wheel DOMMouseScroll mousewheel touchmove",function(){n(this).stop()}),n(i).on("click","."+d.vars.classes.tab_arrow_right,function(e){e.preventDefault();var e=n(this).parent(),t=e.find("."+d.vars.classes.tabs_list);t.animate({scrollLeft:t.scrollLeft()+.5*e.width()})}),n(i).on("click","."+d.vars.classes.tab_arrow_left,function(e){e.preventDefault();var e=n(this).parent(),t=e.find("."+d.vars.classes.tabs_list);t.animate({scrollLeft:t.scrollLeft()-.5*e.width()})})},toggle_scroll(){n("."+d.vars.classes.tabs).each(function(e,t){var r=n(this),a=r.data("orderable-tabs"),r=r.closest(a.wrapper),a=r.find("."+d.vars.classes.tabs_list),o=r.find("."+d.vars.classes.tab_arrow_right);r.outerWidth()<a[0].scrollWidth?o.show():o.hide()})}};n(i).ready(d.on_ready),n(window).on("resize",d.on_resize)}(jQuery,document);let orderable_timings={};!function(l,e){"use strict";orderable_timings={on_ready(){orderable_timings.watch()},restore(){var e,t=orderable_timings.get_timings();t&&t.date&&(0<(e=l(".orderable-order-timings__date")).find('option[value="'+t.date+'"]').length&&(e.val(t.date),e.change()),t.time)&&0<(e=l(".orderable-order-timings__time")).find('option[value="'+t.time+'"]').length&&(e.val(t.time),e.change())},watch(){l(e.body).on("wc_fragments_refreshed",function(){orderable_timings.restore()}),l(e.body).on("updated_checkout",function(){orderable_timings.restore()}),l(e.body).on("change",".orderable-order-timings__date",function(e){const t=l(this),r=t.find("option:selected"),a=r.data("orderable-slots"),o=l(".orderable-order-timings--time"),s=l(".orderable-order-timings__time"),n=s.find("option").first(),i=s.find('option[value="asap"]').first();var d=orderable_timings.get_timings();d.date=l(".orderable-order-timings__date").val(),window.localStorage.setItem("orderable_timings",JSON.stringify(d)),s.html(n),i&&s.append(i),a?"all-day"===a[0].value?(o.hide(),s.prop("disabled",!0)):(s.prop("disabled",!1),o.show(),l.each(a,function(e,t){s.append(l("<option />").attr("value",t.value).attr("data-orderable-time-slot-id",t?.setting_row?.time_slot_id).text(t.formatted))})):(s.prop("disabled",!0),o.hide())}),l(e.body).on("change",".orderable-order-timings__time",function(e){var t=orderable_timings.get_timings();t.time=l(".orderable-order-timings__time").val(),window.localStorage.setItem("orderable_timings",JSON.stringify(t)),l(this).siblings('input[name="orderable_order_time_slot_id"]').val(l(this).find(":selected").attr("data-orderable-time-slot-id"))})},get_timings(){return JSON.parse(window.localStorage.getItem("orderable_timings"))||{}}},l(e).ready(orderable_timings.on_ready)}(jQuery,document),function(a,o){"use strict";var e={on_ready(){e.watch()},watch(){void 0===window.orderable_triggers_admin&&a(o.body).on("click","[data-orderable-trigger]",e.trigger)},trigger(e){e.stopImmediatePropagation();var t=a(this),r=t.data("orderable-trigger");(t.is("button")||t.is("a"))&&e.preventDefault(),a(o.body).trigger("orderable-"+r,[t])}};a(o).ready(e.on_ready)}(jQuery,document);1 ((o,s)=>{var i={on_ready(){i.cache(),i.watch()},cache(){i.vars={classes:{parent:"orderable-accordion",link:"orderable-accordion__item-link",content:"orderable-accordion__item-content",link_active:"orderable-accordion__item-link--active",content_active:"orderable-accordion__item-content--active"}}},watch(){o(s.body).on("click","."+i.vars.classes.link,function(e){e.preventDefault();var e=o(this),t=e.closest("."+i.vars.classes.parent),r=e.attr("href"),r=o(r),a=e.hasClass(i.vars.classes.link_active);t.find("."+i.vars.classes.link).removeClass(i.vars.classes.link_active),t.find("."+i.vars.classes.content).removeClass(i.vars.classes.content_active),a||(e.addClass(i.vars.classes.link_active),r.addClass(i.vars.classes.content_active)),o(s.body).trigger("orderable-accordion.toggled",{link:e,content:r})}),o(s.body).on("orderable-scrollbar.created",function(e,t){var r=o(".orderable-drawer ."+i.vars.classes.link_active);r.length<=0||(r=(t=t.content).scrollTop()-t.offset().top+r.offset().top,t.scrollTop(r))})}};o(s).ready(i.on_ready)})(jQuery,document),((l,c)=>{var r={debounce(t,r=700){let a;return(...e)=>{clearTimeout(a),a=setTimeout(()=>{t.apply(this,e)},r)}},allow_only_numbers(e){var t=String.fromCharCode(e.which);/^\d+$/.test(t)||e.preventDefault()},on_change_quantity(e){let t=l(e.currentTarget);var e=t.data("orderable-product-id"),r=t.data("orderable-cart-item-key"),a=parseInt(t.text());jQuery.post(orderable_vars.ajax_url,{action:"orderable_cart_quantity",cart_item_key:r,product_id:e,quantity:a},function(e){e&&(l(c.body).trigger("added_to_cart",[e.fragments,e.cart_hash,t]),l(c.body).trigger("orderable-drawer.quantity-updated"))})},on_ready(){r.cache(),r.watch(),l(c.body).on("keypress",".orderable-quantity-roller__quantity",r.allow_only_numbers),l(".orderable-drawer__cart, .orderable-product--add-to-cart, .orderable-products-list").on("input",".orderable-quantity-roller__quantity",r.debounce(r.on_change_quantity)),l(c.body).on("click",".orderable-quantity-roller__quantity",function(e){e.stopPropagation()}),orderable_vars&&!orderable_vars.woocommerce_enable_ajax_add_to_cart&&l(c.body).off("click",".add_to_cart_button")},cache(){r.vars={classes:{overlay:"orderable-drawer-overlay",drawer:"orderable-drawer",drawer_cart:"orderable-drawer__cart",drawer_html:"orderable-drawer__html",overlay_open:"orderable-drawer-overlay--open",drawer_open:"orderable-drawer--open",drawer_open_body:"orderable-drawer-open"}},r.elements={body:l("body"),overlay:l("."+r.vars.classes.overlay),drawer:l("."+r.vars.classes.drawer),drawer_cart:l("."+r.vars.classes.drawer_cart),drawer_html:l("."+r.vars.classes.drawer_html),floating_cart_button_class:".orderable-floating-cart__button"}},watch(){var e,t;void 0!==r.elements.drawer&&(l(c.body).on("orderable-drawer.open",r.open),l(c.body).on("orderable-drawer.close",r.close),l(c.body).on("click",r.elements.floating_cart_button_class,function(){l(c.body).trigger("orderable-drawer.open",{show_cart:!0})}),l(c.body).on("orderable-increase-quantity",r.cart.handle_quantity_change_by_button),l(c.body).on("orderable-decrease-quantity",r.cart.handle_quantity_change_by_button),e=r.debounce(r.cart.click_increase_decrease_quantity),l(c.body).on("orderable-increase-quantity",e),l(c.body).on("orderable-decrease-quantity",e),e=c.querySelector("body:not( .rtl ) .orderable-drawer"),t=c.querySelector("body.rtl .orderable-drawer"),e&&e.addEventListener("swiped-right",function(e){r.close()}),t)&&t.addEventListener("swiped-left",function(e){r.close()})},open(e,t){t.html=t.html||!1,t.show_cart=t.show_cart||!1,r.elements.drawer_html.hide(),r.elements.drawer_cart.hide(),t.html&&(r.elements.drawer_html.html(t.html),r.elements.drawer_html.show()),t.show_cart&&(r.elements.drawer_html.html(""),r.elements.drawer_cart.show()),r.elements.overlay.addClass(r.vars.classes.overlay_open),r.elements.drawer.addClass(r.vars.classes.drawer_open),r.elements.body.addClass(r.vars.classes.drawer_open_body),l(c.body).trigger("orderable-drawer.opened",t)},close(){r.elements.overlay.removeClass(r.vars.classes.overlay_open),r.elements.drawer.removeClass(r.vars.classes.drawer_open),r.elements.body.removeClass(r.vars.classes.drawer_open_body),r.elements.drawer_html.html(""),l(c.body).trigger("orderable-drawer.closed")},cart:{click_increase_decrease_quantity(e,r){var t=r.data("orderable-trigger"),a=r.attr("data-orderable-product-id"),o=r.attr("data-orderable-cart-item-key"),s=r.attr("data-orderable-quantity");let i=r.siblings(".orderable-quantity-roller__button--"+("increase-quantity"===t?"decrease":"increase")),n=r.siblings(".orderable-quantity-roller__quantity"),d={action:"orderable_cart_quantity",cart_item_key:o,product_id:a,quantity:s};this.currentRequest&&(this.currentRequest.abort(),this.currentRequest=void 0),r.addClass("orderable-button--loading"),r.attr("disabled",!0),i.attr("disabled",!0),n.attr("contenteditable",!1),this.currentRequest=jQuery.post(orderable_vars.ajax_url,d,function(e){if(e){var t=r.siblings(".orderable-quantity-roller__quantity");switch(e&&e.fragments&&e.fragments[".orderable-mini-cart__notices"]&&l(c.body).trigger("orderable-drawer.open",{show_cart:!0}),d.quantity){case"0":l(c.body).trigger("removed_from_cart",[e.fragments,e.cart_hash,r]);break;case t.attr("data-orderable-updating-quantity"):l(c.body).trigger("added_to_cart",[e.fragments,e.cart_hash,r]),l(c.body).trigger("orderable-drawer.quantity-updated")}}}.bind(this)).always(function(){this.currentRequest=void 0,r.removeClass("orderable-button--loading"),r.attr("disabled",!1),i.attr("disabled",!1),n.attr("contenteditable",!0)}.bind(this))},handle_quantity_change_by_button(e,t){var r,a=t.data("orderable-trigger"),o=parseInt(t.attr("data-orderable-quantity")),s=t.siblings(".orderable-quantity-roller__button--"+("increase-quantity"===a?"decrease":"increase")),i=t.siblings(".orderable-quantity-roller__quantity"),a="increase-quantity"===a?o+1:Math.max(0,o-1),o=t.parents(".orderable-product__actions-button");0===a&&o.length&&(r=o.find("button.orderable-button[data-orderable-trigger]"),(o=o.find(".orderable-quantity-roller")).length)&&(r.removeClass("orderable-button--product-in-the-cart"),o.removeClass("orderable-quantity-roller--is-active")),t.attr("data-orderable-quantity",a),s.attr("data-orderable-quantity",a),i.attr("data-orderable-updating-quantity",a),i.text(a),i.attr("contenteditable",!1)}}};l(c).ready(r.on_ready)})(jQuery,document),((d,l)=>{var c={on_ready(){c.cache(),c.watch()},cache(){c.vars={classes:{clickable_product:"orderable-product--add-to-cart ",add_to_order_button:"orderable-product__add-to-order",product_messages:"orderable-product__messages",product_price:"orderable-product__actions-price",invalid_field:"orderable-field--invalid",option_select_td:"orderable-product__option-select",button_loading:"orderable-button--loading",out_of_stock:"orderable-button--out-of-stock"},parent_price:null,variable_product_types:["variable","variable-subscription"]},c.elements={}},watch(){d(l.body).on("orderable-drawer.opened",c.init_product_options),d(l.body).on("orderable-add-to-cart",c.click_add_to_order),d(l.body).on("orderable-product-options",c.click_add_to_order),d(l.body).on("orderable-view-product",c.view_product),d(l.body).on("mouseenter mouseleave","."+c.vars.classes.clickable_product,c.simulate_add_to_order_hover),d(l.body).on("orderable-edit-cart-item",c.edit_cart_item),d(l.body).on("orderable-update-cart-item",c.update_cart_item),d(l.body).on("orderable-show-cart",c.show_cart),d(l.body).on("orderable-add-to-cart-without-side-drawer",c.click_add_to_order),d(l.body).on("added_to_cart",c.remove_fragments),d(l.body).on("added_to_cart",c.remove_animation),d(l.body).on("added_to_cart",c.shake_floating_cart),d(l.body).on("removed_from_cart",c.hide_quantity_roller),d(l.body).on("wc_cart_button_updated",c.remove_view_cart_link)},simulate_add_to_order_hover(e){d(this).find("."+c.vars.classes.add_to_order_button).toggleClass("orderable-button--hover","mouseenter"===e.type)},click_add_to_order(e,t){let r=(t=void 0!==t?t:d(this)).is("button")?t:t.find("."+c.vars.classes.add_to_order_button),a=r.data("orderable-trigger"),o=r.data("orderable-product-id"),s=r.data("orderable-variation-id"),i=r.data("orderable-variation-attributes"),n={action:a};if(!r.hasClass(c.vars.classes.button_loading)&&!r.hasClass(c.vars.classes.out_of_stock))switch(r.addClass(c.vars.classes.button_loading),a){case"add-to-cart":c.add_to_cart({product_id:o,variation_id:s,attributes:i,thisbutton:t},function(e){n.show_cart=!0,n.response=e,d(l.body).trigger("orderable-drawer.open",n),r.removeClass(c.vars.classes.button_loading);e=d(".orderable-product .orderable-product__actions-button button.orderable-product__add-to-order[data-orderable-product-id="+o+"]");e.siblings(".orderable-quantity-roller").length&&e.addClass("orderable-button--product-in-the-cart")});break;case"add-to-cart-without-side-drawer":c.add_to_cart({product_id:o,variation_id:s,attributes:i},function(e){n.response=e,r.addClass("orderable-button--product-in-the-cart"),r.removeClass(c.vars.classes.button_loading)});break;case"product-options":c.get_product_options({product_id:o,focus:r.data("orderable-focus")},function(e){n.html=e.html,d(l.body).trigger("orderable-drawer.open",n),r.removeClass(c.vars.classes.button_loading)})}},show_cart(){d(l.body).trigger("orderable-drawer.open",{show_cart:!0})},view_product(e,t){let r=t.data("orderable-product-id"),a={action:"product-options"};c.get_product_options({product_id:r,focus:t.data("orderable-focus")},function(e){a.html=e.html,d(l.body).trigger("orderable-drawer.open",a)})},add_to_cart(t,r){if(void 0!==t.product_id){let e={action:"orderable_add_to_cart",product_id:t.product_id,variation_id:t.variation_id||!1,attributes:t.attributes||!1};var a;d(".orderable-product-fields-group").length&&(a=jQuery(".orderable-product-fields-group :input").serializeArray(),a=c.add_unchecked_checkbox_fields(a),a=c.convert_to_flat_object(a),jQuery.isEmptyObject(a)||(e=Object.assign(e,a))),jQuery.post(orderable_vars.ajax_url,e,function(e){e&&(d(l.body).trigger("added_to_cart",[e.fragments,e.cart_hash,t.thisbutton]),"function"==typeof r)&&r(e)})}},edit_cart_item(e,t){var r=t.data("orderable-cart-item-key");t.addClass(c.vars.classes.button_loading),c.get_cart_item_options({cart_item_key:r},function(e){e={html:e.html,action:"update-cart-item"};d(l.body).trigger("orderable-drawer.open",e),t.removeClass(c.vars.classes.button_loading)})},update_cart_item(e,r){var t=r.data("orderable-cart-item-key"),a=r.data("orderable-product-id"),o=r.data("orderable-variation-id"),s=r.data("orderable-variation-attributes");r.addClass(c.vars.classes.button_loading),c.update_cart_item_options({cart_item_key:t,product_id:a,variation_id:o,attributes:s},function(e){var t={show_cart:!0,response:e};d(l.body).trigger("added_to_cart",[e.fragments,e.cart_hash,r]),d(l.body).trigger("orderable-drawer.open",t),r.removeClass(c.vars.classes.button_loading)})},convert_to_flat_object(e){let a={};return e.forEach(function(e){var t="[]"===e.name.substr(-2)||Array.isArray(e.name),r=t?e.name.substr(0,e.name.length-2):e.name;t?(a[r]=void 0===a[r]?[]:a[r],a[r].push(e.value)):a[r]=e.value}),a},get_product_options(e,t){void 0!==e.product_id&&(e.action="orderable_get_product_options",jQuery.post(orderable_vars.ajax_url,e,function(e){e.success&&"function"==typeof t&&t(e.data)}))},get_cart_item_options(e,t){void 0!==e.cart_item_key&&(e.action="orderable_get_cart_item_options",jQuery.post(orderable_vars.ajax_url,e,function(e){e.success&&"function"==typeof t&&t(e.data)}))},update_cart_item_options(e,t){var r;void 0!==e.cart_item_key&&(e.action="orderable_update_cart_item_options",d(".orderable-product-fields-group").length&&(r=jQuery(".orderable-product-fields-group :input").serializeArray(),r=c.add_unchecked_checkbox_fields(r),r=c.convert_to_flat_object(r),jQuery.isEmptyObject(r)||(e=Object.assign(e,r))),jQuery.post(orderable_vars.ajax_url,e,function(e){e&&"function"==typeof t&&t(e)}))},init_product_options(e,a){if(void 0!==a.action&&("product-options"===a.action||"update-cart-item"===a.action)){a=".orderable-drawer .orderable-product__options input, .orderable-drawer .orderable-product__options select, .orderable-product__options textarea";let e=d(a),t=(c.vars.parent_price=d(".orderable-drawer .orderable-product__actions-price").html(),c.product_options_change(e),c.update_button_state(),c.debounce(c.update_button_state,500)),r=c.debounce(c.product_options_change,500);d(l).on("change keyup",a,function(){r(e),t()})}},product_options_change(e){var t=d(".orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item"),r=c.check_options(e),a=t.data("orderable-product-type");"product-options"===t.attr("data-orderable-trigger")&&t.attr("data-orderable-trigger","add-to-cart"),d("."+c.vars.classes.product_messages).html(""),c.vars.variable_product_types.includes(a)&&(r?(a=c.check_variation(e),c.set_variation(t,a)):c.clear_variation(t))},check_options(e){if(e.length<=0)return!1;let r=!0;return e.each(function(e,t){d(t).hasClass("orderable-input--validate")&&(""===d(t).val()?(d(t).addClass(c.vars.classes.invalid_field),r=!1):d(t).removeClass(c.vars.classes.invalid_field))}),r},check_variation(e){var t=(t=e.closest(".orderable-drawer").find(".orderable-product__variations").text())?JSON.parse(t):"",e=c.serialize_object(e),t=c.find_matching_variations(t,e);return!c.is_empty(t)&&((t=t.shift()).attributes=e,t.attributes_json=JSON.stringify(e),void 0!==t)&&t},set_variation(e,t){let r=t.variation_id||"",a=t.attributes_json||"",o=t.price_html||c.vars.parent_price,s="";t&&""!==t.availability_html&&(s=t.availability_html),t&&!t.is_in_stock&&(s="<p>"+orderable_vars.i18n.out_of_stock+"</p>"),t&&!t.is_purchasable&&(s="<p>"+orderable_vars.i18n.unavailable+"</p>"),!1===t&&(s="<p>"+orderable_vars.i18n.no_exist+"</p>"),!t||t.is_purchasable&&t.is_in_stock||(r="",a=""),""!==s&&d("."+c.vars.classes.product_messages).html(s),e.data("orderable-variation-id",r),e.data("orderable-variation-attributes",a),d(".orderable-drawer .orderable-product__actions-price").html(o),e.trigger("orderable_variation_set",{variation:t,variation_id:r,attributes:a,price:o})},clear_variation(e){c.set_variation(e,""),c.vars.parent_price&&d(".orderable-drawer .orderable-product__actions-price").html(c.vars.parent_price)},find_matching_variations(t,r){var a=[];for(let e=0;e<t.length;e++){var o=t[e];c.is_matching_variation(o.attributes,r)&&a.push(o)}return a},is_matching_variation(e,t){let r=!0;for(var a in e){var o;e.hasOwnProperty(a)&&(o=e[a],a=t[a],void 0!==o)&&void 0!==a&&0!==o.length&&0!==a.length&&o!==a&&(r=!1)}return r},is_empty(e){return void 0===e||!1===e||e.length<=0||!e},serialize_object:function(e){var t=e.serializeArray(),r={};for(let e=0;e<t.length;e++)r[t[e].name]=t[e].value;return r},update_button_state(){setTimeout(function(){let e=d(".orderable-drawer .orderable-product__add-to-order, .orderable-drawer .orderable-product__update-cart-item"),t=d(".orderable-drawer__html ."+c.vars.classes.invalid_field).length,r=e.data("orderable-product-type"),a=!0;"variable"===r&&(a=""!==e.data("orderable-variation-id")),e.prop("disabled",t||!a)},50)},debounce(a,o,s){let i;return function(){let e=this,t=arguments;var r=s&&!i;clearTimeout(i),i=setTimeout(function(){i=null,s||a.apply(e,t)},o),r&&a.apply(e,t)}},remove_fragments(e,t){if(t&&"undefined"!=typeof wc_cart_fragments_params&&wc_cart_fragments_params.fragment_name){var r,a=/\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-quantity-roller/,o=/\.orderable-product\[data-orderable-product-id='[1-9][0-9]*'\] \.orderable-product__actions-button \.orderable-product__actions-counter/;for(r in t)(a.test(r)||o.test(r))&&(t[r]=void 0);sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(t))}},remove_animation(){setTimeout(function(){d(".orderable-product__actions-counter").css("animation","")},1e3)},hide_quantity_roller(e,t,r,a){var o,a=a.attr("data-product_id")||a.attr("data-orderable-product-id");a&&(a=d(".orderable-product[data-orderable-product-id="+a+"] .orderable-product__actions-button")).length&&(o=a.find(".orderable-quantity-roller")).length&&(a.find("button.orderable-product__add-to-order[data-orderable-trigger]").removeClass("orderable-button--product-in-the-cart"),o.addClass("orderable-button--hide"))},add_unchecked_checkbox_fields(r){return jQuery('.orderable-product-fields-group :input[type="checkbox"]:not(:checked)').each(function(e,t){r.push({name:t.getAttribute("name"),value:""})}),r},shake_floating_cart(){d(".orderable-floating-cart__button").css("animation","wobble-hor-bottom .8s both")},remove_view_cart_link(e,t){t?.hasClass("orderable-product__add-to-order")&&t?.siblings(".added_to_cart.wc-forward").remove()}};d(l).ready(c.on_ready)})(jQuery,document),((o,s)=>{var i={on_ready(){i.cache(),i.watch()},cache(){i.vars={top:{}},i.elements={}},watch(){o(s.body).on("orderable-drawer.opened",i.trigger),o(s.body).on("orderable-tabs.changed",i.trigger),o(s.body).on("orderable-accordion.toggled",i.trigger),o(s.body).on("wc_fragments_loaded",i.trigger)},trigger(){o(".orderable-sb-container").each(function(e,t){var r,t=o(t),a=t.data("orderable-scroll-id");i.has_scrollbar(t)||(t.scrollBox({containerClass:"orderable-sb-container",containerNoScrollClass:"orderable-sb-container-noscroll",contentClass:"orderable-sb-content",scrollbarContainerClass:"orderable-sb-scrollbar-container",scrollBarClass:"orderable-sb-scrollbar"}),0<(r=t.find(".orderable-sb-content")).length&&(r.on("scroll.scrollBox",i.log_top_position),void 0!==i.vars.top[a])&&r.scrollTop(i.vars.top[a]),o(s.body).trigger("orderable-scrollbar.created",{element:t,content:r}))}),o(window).trigger("resize.scrollBox")},has_scrollbar(e){return 0<e.find(".orderable-sb-content").length},log_top_position(e){var t=o(e.currentTarget).closest(".orderable-sb-container").data("orderable-scroll-id");i.vars.top[t]=o(e.currentTarget).scrollTop()}};o(s).ready(i.on_ready)})(jQuery,document),((i,n)=>{var d={on_ready(){d.cache(),d.watch(),d.toggle_scroll()},on_resize(){void 0===d.vars&&d.cache(),d.toggle_scroll()},cache(){d.vars={classes:{tabs:"orderable-tabs",tabs_list:"orderable-tabs__list",tab_items:"orderable-tabs__item",tab_item_active:"orderable-tabs__item--active",tab_links:"orderable-tabs__link",tab_arrow_right:"orderable-tabs__arrow-right",tab_arrow_left:"orderable-tabs__arrow-left"},dragging:!1},d.elements={}},watch(){i("body").on("touchstart",function(){d.vars.dragging=!1}).on("touchmove",function(){d.vars.dragging=!0}),i(n.body).on("click mouseup touchend","."+d.vars.classes.tab_links,function(e){var t,r,a,o,s;d.vars.dragging||(e.preventDefault(),t=(e=i(this)).attr("href"),r=e.closest("."+d.vars.classes.tab_items),a=(s=e.closest("."+d.vars.classes.tabs)).find("."+d.vars.classes.tabs_list),o=s.find("."+d.vars.classes.tab_items),s=s.data("orderable-tabs"),s=(e=e.closest(s.wrapper)).find(s.sections),e=e.find(t),s.hide(),e.show(),o.removeClass(d.vars.classes.tab_item_active),r.addClass(d.vars.classes.tab_item_active),a.animate({scrollLeft:a.scrollLeft()+r.position().left}),i(n.body).trigger("orderable-tabs.changed",{tab:r}))}),i("."+d.vars.classes.tabs_list).on("scroll",function(e){var t=i(this),r=t.parent("."+d.vars.classes.tabs),a=t.siblings("."+d.vars.classes.tab_arrow_right),o=t.siblings("."+d.vars.classes.tab_arrow_left);t[0].scrollWidth<=r.width()+t.scrollLeft()?a.fadeOut():a.fadeIn(),t.scrollLeft()-o.width()<=0?o.fadeOut():o.fadeIn()}),i("."+d.vars.classes.tabs_list).on("wheel DOMMouseScroll mousewheel touchmove",function(){i(this).stop()}),i(n).on("click","."+d.vars.classes.tab_arrow_right,function(e){e.preventDefault();var e=i(this).parent(),t=e.find("."+d.vars.classes.tabs_list);t.animate({scrollLeft:t.scrollLeft()+.5*e.width()})}),i(n).on("click","."+d.vars.classes.tab_arrow_left,function(e){e.preventDefault();var e=i(this).parent(),t=e.find("."+d.vars.classes.tabs_list);t.animate({scrollLeft:t.scrollLeft()-.5*e.width()})})},toggle_scroll(){i("."+d.vars.classes.tabs).each(function(e,t){var r=i(this),a=r.data("orderable-tabs"),r=r.closest(a.wrapper),a=r.find("."+d.vars.classes.tabs_list),o=r.find("."+d.vars.classes.tab_arrow_right);r.outerWidth()<a[0].scrollWidth?o.show():o.hide()})}};i(n).ready(d.on_ready),i(window).on("resize",d.on_resize)})(jQuery,document);let orderable_timings={};((l,e)=>{orderable_timings={on_ready(){orderable_timings.watch()},restore(){var e,t=orderable_timings.get_timings();t&&t.date&&(0<(e=l(".orderable-order-timings__date")).find('option[value="'+t.date+'"]').length&&(e.val(t.date),e.change()),t.time)&&0<(e=l(".orderable-order-timings__time")).find('option[value="'+t.time+'"]').length&&(e.val(t.time),e.change())},watch(){l(e.body).on("wc_fragments_refreshed",function(){orderable_timings.restore()}),l(e.body).on("updated_checkout",function(){orderable_timings.restore()}),l(e.body).on("change",".orderable-order-timings__date",function(e){let t=l(this),r=t.find("option:selected"),a=r.data("orderable-slots"),o=l(".orderable-order-timings--time"),s=l(".orderable-order-timings__time"),i=s.find("option").first(),n=s.find('option[value="asap"]').first();var d=orderable_timings.get_timings();d.date=l(".orderable-order-timings__date").val(),window.localStorage.setItem("orderable_timings",JSON.stringify(d)),s.html(i),n&&s.append(n),a?"all-day"===a[0].value?(o.hide(),s.prop("disabled",!0)):(s.prop("disabled",!1),o.show(),l.each(a,function(e,t){s.append(l("<option />").attr("value",t.value).attr("data-orderable-time-slot-id",t?.setting_row?.time_slot_id).text(t.formatted))})):(s.prop("disabled",!0),o.hide())}),l(e.body).on("change",".orderable-order-timings__time",function(e){var t=orderable_timings.get_timings();t.time=l(".orderable-order-timings__time").val(),window.localStorage.setItem("orderable_timings",JSON.stringify(t)),l(this).siblings('input[name="orderable_order_time_slot_id"]').val(l(this).find(":selected").attr("data-orderable-time-slot-id"))})},get_timings(){return JSON.parse(window.localStorage.getItem("orderable_timings"))||{}}},l(e).ready(orderable_timings.on_ready)})(jQuery,document),((a,o)=>{var e={on_ready(){e.watch()},watch(){void 0===window.orderable_triggers_admin&&a(o.body).on("click","[data-orderable-trigger]",e.trigger)},trigger(e){e.stopImmediatePropagation();var t=a(this),r=t.data("orderable-trigger");(t.is("button")||t.is("a"))&&e.preventDefault(),a(o.body).trigger("orderable-"+r,[t])}};a(o).ready(e.on_ready)})(jQuery,document),((o,e,s)=>{var i="scrollBox",r={containerClass:"sb-container",containerNoScrollClass:"sb-container-noscroll",contentClass:"sb-content",scrollbarContainerClass:"sb-scrollbar-container",scrollBarClass:"sb-scrollbar"};function t(e,t){this.element=e,this.settings=o.extend({},r,t),this._defaults=r,this._name=i,this.init()}o.extend(t.prototype,{init:function(){this.addScrollbar(),this.addEvents(),this.onResize()},addScrollbar:function(){o(this.element).addClass(this.settings.containerClass),this.wrapper=o("<div class='"+this.settings.contentClass+"' />"),this.wrapper.append(o(this.element).contents()),o(this.element).append(this.wrapper),this.scollbarContainer=o("<div class='"+this.settings.scrollbarContainerClass+"' />"),this.scrollBar=o("<div class='"+this.settings.scrollBarClass+"' />"),this.scollbarContainer.append(this.scrollBar),o(this.element).prepend(this.scollbarContainer)},addEvents:function(){this.wrapper.on("scroll."+i,o.proxy(this.onScroll,this)),o(e).on("resize."+i,o.proxy(this.onResize,this)),this.scrollBar.on("mousedown."+i,o.proxy(this.onMousedown,this)),this.scrollBar.on("touchstart."+i,o.proxy(this.onTouchstart,this))},onTouchstart:function(t){var r=this,a=(t.preventDefault(),r.scrollBar[0].offsetTop);o(s).on("touchmove."+i,function(e){e=e.touches[0].pageY-t.touches[0].pageY;r.scrollBar[0].style.top=Math.min(r.scollbarContainer[0].clientHeight-r.scrollBar[0].clientHeight,Math.max(0,a+e))+"px",r.wrapper[0].scrollTop=r.wrapper[0].scrollHeight*r.scrollBar[0].offsetTop/r.scollbarContainer[0].clientHeight}),o(s).on("touchend."+i,function(){o(s).off("touchmove."+i),o(s).off("touchend."+i)})},onMousedown:function(t){var r=this,a=(t.preventDefault(),r.scrollBar[0].offsetTop);o(s).on("mousemove."+i,function(e){e=e.pageY-t.pageY;r.scrollBar[0].style.top=Math.min(r.scollbarContainer[0].clientHeight-r.scrollBar[0].clientHeight,Math.max(0,a+e))+"px",r.wrapper[0].scrollTop=r.wrapper[0].scrollHeight*r.scrollBar[0].offsetTop/r.scollbarContainer[0].clientHeight}),o(s).on("mouseup."+i,function(){o(s).off("mousemove."+i),o(s).off("mouseup."+i)})},onResize:function(){this.wrapper.css("max-height",o(this.element).height());var e=this.wrapper[0].clientHeight;this.scrollBar.css("height",this.scollbarContainer[0].clientHeight*e/this.wrapper[0].scrollHeight+"px"),this.scollbarContainer[0].clientHeight<=this.scrollBar[0].clientHeight?o(this.element).addClass(this.settings.containerNoScrollClass):o(this.element).removeClass(this.settings.containerNoScrollClass),this.onScroll()},onScroll:function(){this.scrollBar.css("top",Math.min(this.scollbarContainer[0].clientHeight-this.scrollBar[0].clientHeight,this.scollbarContainer[0].clientHeight*this.wrapper[0].scrollTop/this.wrapper[0].scrollHeight)+"px")}}),o.fn[i]=function(e){return this.each(function(){o.data(this,"plugin_"+i)||o.data(this,"plugin_"+i,new t(this,e))})}})(jQuery,window,document),((e,o)=>{"function"!=typeof e.CustomEvent&&(e.CustomEvent=function(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var r=o.createEvent("CustomEvent");return r.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),r},e.CustomEvent.prototype=e.Event.prototype),o.addEventListener("touchstart",function(e){"true"!==e.target.getAttribute("data-swipe-ignore")&&(c=e.target,l=Date.now(),s=e.touches[0].clientX,i=e.touches[0].clientY,d=n=0)},!1),o.addEventListener("touchmove",function(e){var t;s&&i&&(t=e.touches[0].clientX,e=e.touches[0].clientY,n=s-t,d=i-e)},!1),o.addEventListener("touchend",function(e){var t,r,a,o;c===e.target&&(o=parseInt(_(c,"data-swipe-threshold","20"),10),t=parseInt(_(c,"data-swipe-timeout","500"),10),r=Date.now()-l,a="",e=e.changedTouches||e.touches||[],Math.abs(n)>Math.abs(d)?Math.abs(n)>o&&r<t&&(a=0<n?"swiped-left":"swiped-right"):Math.abs(d)>o&&r<t&&(a=0<d?"swiped-up":"swiped-down"),""!==a&&(o={dir:a.replace(/swiped-/,""),touchType:(e[0]||{}).touchType||"direct",xStart:parseInt(s,10),xEnd:parseInt((e[0]||{}).clientX||-1,10),yStart:parseInt(i,10),yEnd:parseInt((e[0]||{}).clientY||-1,10)},c.dispatchEvent(new CustomEvent("swiped",{bubbles:!0,cancelable:!0,detail:o})),c.dispatchEvent(new CustomEvent(a,{bubbles:!0,cancelable:!0,detail:o}))),l=i=s=null)},!1);var s=null,i=null,n=null,d=null,l=null,c=null;function _(e,t,r){for(;e&&e!==o.documentElement;){var a=e.getAttribute(t);if(a)return a;e=e.parentNode}return r}})(window,document); -
orderable/trunk/docs/filters.json
r3192586 r3237969 270 270 "type": "filter", 271 271 "doc": { 272 "description": "", 273 "long_description": "", 274 "tags": [], 275 "long_description_html": "" 276 }, 277 "args": 2 278 }, 279 { 280 "name": "orderable_get_accordion_data", 281 "file": "inc/class-products.php", 282 "type": "filter", 283 "doc": { 284 "description": "", 285 "long_description": "", 286 "tags": [], 287 "long_description_html": "" 288 }, 289 "args": 2 290 }, 291 { 292 "name": "orderable_get_accordion_data", 293 "file": "inc/class-products.php", 294 "type": "filter", 295 "doc": { 272 296 "description": "Filter product accordion data.", 273 297 "long_description": "", … … 288 312 ], 289 313 "variable": "$product" 314 }, 315 { 316 "name": "since", 317 "content": "1.0.0" 290 318 } 291 319 ], -
orderable/trunk/languages/orderable.pot
r3192586 r3237969 1 # Copyright (C) 202 4orderable1 # Copyright (C) 2025 orderable 2 2 # This file is distributed under the same license as the orderable package. 3 3 msgid "" … … 7 7 "Content-Type: text/plain; charset=UTF-8\n" 8 8 "Content-Transfer-Encoding: 8bit\n" 9 "POT-Creation-Date: 202 4-11-19 18:56+0000\n"9 "POT-Creation-Date: 2025-02-10 13:33+0000\n" 10 10 "X-Poedit-Basepath: ..\n" 11 11 "X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n" -
orderable/trunk/orderable.php
r3192586 r3237969 4 4 * Author URI: https://orderable.com 5 5 * Description: Take local online ordering to a whole new level with Orderable. 6 * Version: 1.17. 06 * Version: 1.17.1 7 7 * Author: Orderable 8 8 * Text Domain: orderable 9 9 * WC requires at least: 5.4.0 10 * WC tested up to: 9. 410 * WC tested up to: 9.6 11 11 */ 12 12 … … 20 20 * @var string Plugin version. 21 21 */ 22 public static $version = '1.17. 0';22 public static $version = '1.17.1'; 23 23 24 24 /** -
orderable/trunk/readme.txt
r3192586 r3237969 5 5 Tested up to: 6.7 6 6 Requires PHP: 5.6 7 Stable tag: 1.17. 07 Stable tag: 1.17.1 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 186 186 187 187 == Changelog == 188 **v1.17.1** (10 Feb 2025) 189 [fix] Compatibility issue with Xstore theme 190 188 191 **v1.17.0** (19 Nov 2024) 189 192 [fix] Compatibility with Flux Checkout for WooCommerce plugin
Note: See TracChangeset
for help on using the changeset viewer.