1'use strict'; 2 3(function ($) { 4 var $gallery = null; 5 var gallery_loading = false; 6 7 $(function () { 8 if ($('.wooco-wrap').length) { 9 wooco_init_selector(); 10 11 $('.wooco-wrap').each(function () { 12 wooco_init($(this), 'loaded'); 13 }); 14 } 15 }); 16 17 $(document).on('woosq_loaded', function () { 18 // composite products in quick view popup 19 if ($('#woosq-popup .wooco-wrap').length) { 20 wooco_init_selector(); 21 wooco_init($('#woosq-popup .wooco-wrap'), 'woosq_loaded'); 22 } 23 }); 24 25 $(document).on('wooco_save_ids', function (e, ids, $wrap, context, $selected) { 26 const block_ui_params = { 27 message: null, overlayCSS: { 28 background: '#fff', opacity: 0.6, 29 }, 30 }; 31 32 if ((wooco_vars.change_image === 'yes') && (context === 'loaded' || context === 'on_select' || context === 'on_click')) { 33 var product_id = $wrap.data('id'); 34 var $all_gallery = $(wooco_vars.gallery_selector); 35 var $main_gallery = $(wooco_vars.main_gallery_selector); 36 37 if ($all_gallery.length && $main_gallery.length) { 38 if (!ids.length) { 39 $(document).find('.woocommerce-product-gallery--wooco').unblock().hide(); 40 $main_gallery.unblock().show(); 41 } else { 42 var key = btoa(ids.toString()).replace(/[^a-zA-Z0-9]/g, ''); 43 var $key_gallery = $('.woocommerce-product-gallery--wooco-' + key); 44 45 if ($key_gallery.length) { 46 $all_gallery.unblock().hide(); 47 $key_gallery.unblock().show(); 48 49 // scroll to selected image 50 if ($selected) { 51 var selected_image = $selected.data('image_gallery'); 52 var $gallery_nav = $key_gallery.find('.flex-control-nav'); 53 54 if ($gallery_nav.length && (selected_image !== undefined) && (selected_image !== '')) { 55 var $scroll_image = $gallery_nav.find('li img[src="' + selected_image + '"]'); 56 57 if ($scroll_image.length) { 58 window.setTimeout(function () { 59 $scroll_image.trigger('click'); 60 $(window).trigger('resize'); 61 }, 100); 62 } 63 } 64 } 65 } else { 66 $all_gallery.block(block_ui_params); 67 68 if (gallery_loading && ($gallery != null)) { 69 $gallery.abort(); 70 } 71 72 var data = { 73 action: 'wooco_load_gallery', 74 nonce: wooco_vars.nonce, 75 product_id: product_id, 76 key: key, 77 ids: ids, 78 }; 79 80 gallery_loading = true; 81 82 $gallery = $.post(wooco_vars.wc_ajax_url.toString().replace('%%endpoint%%', 'wooco_load_gallery'), data, function (response) { 83 if (response.gallery) { 84 var $wooco_gallery = $(response.gallery); 85 86 $all_gallery.unblock().hide(); 87 $wooco_gallery.insertAfter($main_gallery); 88 $(document).trigger('wooco_gallery_loaded', product_id, key, ids); 89 90 $wooco_gallery.imagesLoaded(function () { 91 $wooco_gallery.wc_product_gallery(); 92 93 // scroll to selected image 94 if ($selected) { 95 var selected_image = $selected.data('image_gallery'); 96 var $gallery_nav = $wooco_gallery.find('.flex-control-nav'); 97 98 if ($gallery_nav.length && (selected_image !== undefined) && (selected_image !== '')) { 99 var $scroll_image = $gallery_nav.find('li img[src="' + selected_image + '"]'); 100 101 if ($scroll_image.length) { 102 window.setTimeout(function () { 103 $scroll_image.trigger('click'); 104 $(window).trigger('resize'); 105 }, 100); 106 } 107 } 108 } 109 110 $(document).trigger('wooco_gallery_images_loaded', product_id, key, ids); 111 }); 112 } else { 113 $all_gallery.unblock(); 114 } 115 116 gallery_loading = false;
117 }); 118 } 119 } 120 } 121 } 122 }); 123 124 $(document).on('click touch', '.single_add_to_cart_button', function (e) { 125 if ($(this).hasClass('wooco-disabled')) { 126 if (wooco_vars.show_alert === 'change') { 127 wooco_show_alert($(this).closest('.wooco-wrap')); 128 } 129 130 e.preventDefault(); 131 } 132 }); 133 134 $(document).on('click touch', '.wooco-plus, .wooco-minus', function () { 135 // get values 136 var $qty = $(this).closest('.wooco-qty-wrap').find('.wooco_qty').length ? $(this).closest('.wooco-qty-wrap').find('.wooco_qty') : $(this).closest('.wooco-qty-wrap').find('.qty'), 137 val = parseFloat($qty.val()), max = parseFloat($qty.attr('max')), min = parseFloat($qty.attr('min')), 138 step = $qty.attr('step'); 139 140 // format values 141 if (!val || val === '' || val === 'NaN') { 142 val = 0; 143 } 144 145 if (max === '' || max === 'NaN') { 146 max = ''; 147 } 148 149 if (min === '' || min === 'NaN') { 150 min = 0; 151 } 152 153 if (step === 'any' || step === '' || step === undefined || parseFloat(step) === 'NaN') { 154 step = 1; 155 } else { 156 step = parseFloat(step); 157 } 158 159 // change the value 160 if ($(this).is('.wooco-plus')) { 161 if (max && (val >= max)) { 162 $qty.val(max); 163 } else { 164 $qty.val((val + step).toFixed(wooco_decimal_places(step))); 165 } 166 } else { 167 if (min && (val <= min)) { 168 $qty.val(min); 169 } else if (val > 0) { 170 $qty.val((val - step).toFixed(wooco_decimal_places(step))); 171 } 172 } 173 174 // trigger change event 175 $qty.trigger('change'); 176 }); 177 178 $(document).on('keyup change', '.wooco_qty', function () { 179 var $this = $(this); 180 var $wrap = $this.closest('.wooco-wrap'); 181 var val = parseFloat($this.val()); 182 var min = parseFloat($this.attr('min')); 183 var max = parseFloat($this.attr('max')); 184 185 if ((val < min) || isNaN(val)) { 186 val = min; 187 $this.val(val); 188 } 189 190 if (val > max) { 191 val = max; 192 $this.val(val); 193 } 194 195 $this.closest('.wooco_component_product_selection_item').attr('data-qty', val); 196 $this.closest('.wooco_component_product').attr('data-qty', val); 197 198 wooco_init($wrap, 'update_qty'); 199 }); 200 201 $(document).on('change', '.wooco-checkbox', function () { 202 var $wrap = $(this).closest('.wooco-wrap'); 203 204 wooco_init($wrap, 'checked'); 205 }); 206 207 $(document).on('change', '.wooco_component_product_select', function () { 208 // check on select 209 var $this = $(this); 210 var $selection = $this.closest('.wooco_component_product_selection'); 211 var $component = $this.closest('.wooco_component_product'); 212 var $wrap = $this.closest('.wooco-wrap'); 213 var $selected = $('option:selected', this); 214 215 wooco_selected($selected, $selection, $component); 216 wooco_init($wrap, 'on_select', $selected); 217 }); 218 219 $(document).on('click touch', '.wooco_component_product_selection_item', function (e) { 220 if ($(e.target).closest('.wooco_component_product_selection_item_qty').length === 0 && !$(e.target).is('a, a *')) { 221 // check on select 222 var $this = $(this); 223 var $selection = $this.closest('.wooco_component_product_selection'); 224 var $component = $this.closest('.wooco_component_product'); 225 var $wrap = $this.closest('.wooco-wrap'); 226 227 if ($component.attr('data-multiple') === 'yes') { 228 // multiple selection 229 if ($this.hasClass('wooco_item_selected')) { 230 $this.removeClass('wooco_item_selected'); 231 wooco_deselect($this, $selection, $component); 232 } else { 233 $this.addClass('wooco_item_selected'); 234 wooco_selected($this, $selection, $component); 235 } 236 } else { 237 // single selection 238 if ($this.hasClass('wooco_item_selected')) { 239 // remove 240 $component.attr('data-id', '-1'); 241 $component.attr('data-price', ''); 242 $component.attr('data-price-html', ''); 243 $component.attr('data-regular-price', ''); 244 $this.removeClass('wooco_item_selected'); 245 wooco_deselect($this, $selection, $component); 246 } else { 247 $selection.find('.wooco_component_product_selection_item').removeClass('wooco_item_selected'); 248 $this.addClass('wooco_item_selected'); 249 wooco_selected($this, $selection, $component); 250 } 251 } 252 253 wooco_init($wrap, 'on_click', $this); 254 } 255 }); 256 257 $(document).on('select2:select', '.wooco_component_product_select', function (e) { 258 var $this = $(this); 259 var $selection = $this.closest('.wooco_component_product_selection'); 260 var $component = $this.closest('.wooco_component_product'); 261 var $wrap = $this.closest('.wooco-wrap'); 262 var $selected = $(e.params.data.element); 263 264 wooco_selected($selected, $selection, $component); 265 wooco_init($wrap, 'on_select', $selected); 266 }); 267})(jQuery); 268 269function wooco_init($wrap, context = null, $selected = null) { 270 if (context === 'loaded' || context === 'woosq_loaded') { 271 // update qty 272 if ($wrap.find('.wooco_qty').length) { 273 $wrap.find('.wooco_qty').trigger('change'); 274 } else { 275 $wrap.find('.qty').trigger('change'); 276 } 277 } 278 279 wooco_check_ready($wrap, context, $selected); 280 wooco_save_ids($wrap, context, $selected); 281 282 if (context === null || context === 'on_select' || context === wooco_vars.show_alert) { 283 wooco_show_alert($wrap, context, $selected); 284 } 285 286 // Update selected products summary when setting is enabled 287 if ((context === 'on_select' || context === 'on_click' || context === 'update_qty') && wooco_vars.show_selected === 'yes') { 288 wooco_step_update_selected($wrap); 289 } 290 291 // Refresh selected summary on initial load too 292 if ((context === 'loaded' || context === 'woosq_loaded' || context === 'selected') && wooco_vars.show_selected === 'yes') { 293 wooco_step_update_selected($wrap); 294 } 295 296 jQuery(document).trigger('wooco_init', [$wrap, context, $selected]); 297} 298 299function wooco_check_ready($wrap, context = null, $selected = null) { 300 var wid = $wrap.attr('data-id'); 301 var $components = $wrap.find('.wooco-components'); 302 var $ids = jQuery('.wooco-ids-' + wid); 303 var $btn = $ids.closest('form.cart').find('.single_add_to_cart_button'); 304 var $alert = $wrap.find('.wooco-alert'); 305 var is_selection = false;
306 var c_name = ''; 307 var is_min = false; 308 var is_max = false; 309 var is_m_min = false; 310 var is_m_max = false; 311 var is_same = false; 312 var is_total_min = false; 313 var is_total_max = false; 314 var is_count = false; 315 var selected_products = []; 316 var allow_same = $components.attr('data-same'); 317 var qty = 0; 318 var m_min = 0; 319 var m_max = 10000; 320 var qty_min = parseFloat($components.attr('data-min')); 321 var qty_max = parseFloat($components.attr('data-max')); 322 var total_min = parseFloat($components.attr('data-total-min')); 323 var total_max = parseFloat($components.attr('data-total-max')); 324 var $total = $wrap.find('.wooco-total'); 325 var $count = $wrap.find('.wooco-count'); 326 var $price = jQuery('.wooco-price-' + wid); 327 var $woobt = jQuery('.woobt-wrap-' + wid); 328 var pricing = $components.attr('data-pricing'); 329 var price = wooco_format_number($components.attr('data-price')); 330 var regular_price = wooco_format_number($components.attr('data-regular-price')); 331 var percent = wooco_format_number($components.attr('data-percent')); 332 var total = 0; 333 var total_regular = 0; 334 335 if (!$components.length || !$components.find('.wooco_component_product').length) { 336 return; 337 } 338 339 // calculate price 340 341 if (pricing === 'only') { 342 total = price; 343 total_regular = regular_price; 344 } else { 345 // calc price 346 $components.find('.wooco_component_product').each(function () { 347 var $this = jQuery(this); 348 var $checkbox = $this.find('.wooco-checkbox'); 349 var _price = wooco_format_number($this.attr('data-price')); 350 var _regular_price = wooco_format_number($this.attr('data-regular-price')); 351 var _qty = wooco_format_number($this.attr('data-qty')); 352 var _multiple = $this.attr('data-multiple'); 353 354 if ($checkbox.length && !$checkbox.prop('checked')) { 355 return; 356 } 357 358 if (_multiple === 'yes') { 359 // multiple selection 360 361 $this.find('.wooco_item_selected').each(function () { 362 var $_this = jQuery(this); 363 var __price = wooco_format_number($_this.attr('data-price')); 364 var __regular_price = wooco_format_number($_this.attr('data-regular-price')); 365 var __qty = wooco_format_number($_this.attr('data-qty')); 366 367 if ((__price > 0) && (__qty > 0)) { 368 total += __price * __qty; 369 } 370 371 if ((__regular_price > 0) && (__qty > 0)) { 372 total_regular += __regular_price * __qty; 373 } 374 }); 375 } else { 376 // single selection 377 378 if ((_price > 0) && (_qty > 0)) { 379 total += _price * _qty; 380 } 381 382 if ((_regular_price > 0) && (_qty > 0)) { 383 total_regular += _regular_price * _qty; 384 } 385 } 386 }); 387 388 // discount 389 if ((percent > 0) && (percent < 100)) { 390 total = total * (100 - percent) / 100; 391 } 392 393 if (pricing === 'include') { 394 total += price; 395 total_regular += regular_price; 396 } 397 } 398 399 var total_html = wooco_price_html(total_regular, total); 400 401 if ((pricing !== 'only') && (percent > 0) && (percent < 100)) { 402 total_html += ' <small class="woocommerce-price-suffix">' + wooco_vars.saved_text.replace('[d]', percent + '%') + '</small>'; 403 } 404 405 $total.html(wooco_vars.total_text + ' ' + total_html).slideDown(); 406 407 if ((wooco_vars.change_price !== 'no') && (pricing !== 'only')) { 408 if ((wooco_vars.change_price === 'yes_custom') && (wooco_vars.price_selector !== null) && (wooco_vars.price_selector !== '')) { 409 $price = jQuery(wooco_vars.price_selector); 410 } 411 412 $price.html(total_html); 413 } 414 415 if ($woobt.length) { 416 $woobt.find('.woobt-products').attr('data-product-price-html', total_html); 417 $woobt.find('.woobt-product-this').attr('data-price', total).attr('data-regular-price', total_regular); 418 419 woobt_init($woobt); 420 } 421 422 jQuery(document).trigger('wooco_calc_price', [total, total_regular, total_html, $wrap, context, $selected]); 423 424 // check ready 425 426 $components.find('.wooco_component_product').each(function () { 427 var $this = jQuery(this); 428 var $checkbox = $this.find('.wooco-checkbox'); 429 var _selected = false;
430 var _name = $this.attr('data-name'); 431 var _id = parseInt($this.attr('data-id')); 432 var _qty = parseFloat($this.attr('data-qty')); 433 var _required = $this.attr('data-required'); 434 var _multiple = $this.attr('data-multiple'); 435 var _custom_qty = $this.attr('data-custom-qty'); 436 437 if ($checkbox.length && !$checkbox.prop('checked')) { 438 return; 439 } 440 441 if (_custom_qty === 'yes' || _multiple === 'yes') { 442 is_count = true; 443 } 444 445 if (_multiple === 'yes') { 446 // multiple selection 447 var _m_qty = 0; 448 var _m_min = parseFloat($this.attr('data-m-min')); 449 var _m_max = parseFloat($this.attr('data-m-max')); 450 451 $this.find('.wooco_item_selected').each(function () { 452 var $_this = jQuery(this); 453 var __id = parseInt($_this.attr('data-id')); 454 var __qty = parseFloat($_this.attr('data-qty')); 455 456 if (__id > 0) { 457 qty += __qty; 458 _m_qty += __qty; 459 _selected = true; 460 } 461 462 if (allow_same === 'no') { 463 if (selected_products.includes(__id)) { 464 is_same = true; 465 } else { 466 if (__id > 0) { 467 selected_products.push(__id); 468 } 469 } 470 } 471 }); 472 473 if (_m_qty < _m_min) { 474 is_m_min = true; 475 m_min = _m_min; 476 477 if (c_name === '') { 478 c_name = _name; 479 } 480 } 481 482 if (_m_qty > _m_max) { 483 is_m_max = true; 484 m_max = _m_max; 485 486 if (c_name === '') { 487 c_name = _name; 488 } 489 } 490 } else { 491 // single selection 492 493 if (_id > 0) { 494 qty += _qty; 495 _selected = true; 496 } 497 498 if (allow_same === 'no') { 499 if (selected_products.includes(_id)) { 500 is_same = true; 501 } else { 502 if (_id > 0) { 503 selected_products.push(_id); 504 } 505 } 506 } 507 } 508 509 if (!_selected && (_required === 'yes')) { 510 is_selection = true; 511 512 if (c_name === '') { 513 c_name = _name; 514 } 515 } 516 }); 517 518 if (is_count) { 519 $count.html('<span class="wooco-count-label">' + wooco_vars.selected_text + '</span> <span class="wooco-count-value">' + qty + '</span>').slideDown(); 520 jQuery(document).trigger('wooco_change_count', [$count, qty, qty_min, qty_max]); 521 } 522 523 if (qty < qty_min) { 524 is_min = true; 525 } 526 527 if (qty > qty_max) { 528 is_max = true; 529 } 530 531 if ((pricing !== 'only')) { 532 // check total min 533 if (total_min > 0 && total < total_min) { 534 is_total_min = true; 535 } 536 537 // check total max 538 if (total_max > 0 && total > total_max) { 539 is_total_max = true; 540 } 541 } 542 543 if (is_selection || is_min || is_max || is_m_min || is_m_max || is_same || is_total_min || is_total_max) { 544 $btn.addClass('wooco-disabled'); 545 $alert.addClass('alert-active'); 546 547 if (is_selection) { 548 $alert.addClass('alert-selection').html(wooco_vars.alert_selection.replace('[name]', '<strong>' + c_name + '</strong>')); 549 } else if (is_m_min) { 550 $alert.addClass('alert-min').html(wooco_vars.alert_m_min.replace('[min]', m_min).replace('[name]', '<strong>' + c_name + '</strong>')); 551 } else if (is_m_max) { 552 $alert.addClass('alert-max').html(wooco_vars.alert_m_max.replace('[max]', m_max).replace('[name]', '<strong>' + c_name + '</strong>')); 553 } else if (is_min) { 554 $alert.addClass('alert-min').html(wooco_vars.alert_min.replace('[min]', qty_min)); 555 } else if (is_max) { 556 $alert.addClass('alert-max').html(wooco_vars.alert_max.replace('[max]', qty_max)); 557 } else if (is_same) { 558 $alert.addClass('alert-same').html(wooco_vars.alert_same); 559 } else if (is_total_min) { 560 $alert.addClass('alert-total-min').html(wooco_vars.alert_total_min.replace('[min]', wooco_format_price(total_min)).replace('[total]', wo
560oco_format_price(total))); 561 } else if (is_total_max) { 562 $alert.addClass('alert-total-max').html(wooco_vars.alert_total_max.replace('[max]', wooco_format_price(total_max)).replace('[total]', wooco_format_price(total))); 563 } 564 565 $alert.slideDown(); 566 567 jQuery(document).trigger('wooco_check_ready', [false, is_selection, is_same, is_min, is_max, $wrap, context, $selected]); 568 } else { 569 $alert.removeClass('alert-active alert-selection alert-min alert-max alert-total-min alert-total-max').slideUp(300, function () { 570 $alert.html(''); 571 }); 572 $btn.removeClass('wooco-disabled'); 573 574 // ready 575 jQuery(document).trigger('wooco_check_ready', [true, is_selection, is_same, is_min, is_max, $wrap, context, $selected]); 576 } 577} 578 579function wooco_save_ids($wrap, context = null, $selected = null) { 580 var wid = $wrap.attr('data-id'); 581 var $components = $wrap.find('.wooco-components'); 582 var $ids = jQuery('.wooco-ids-' + wid); 583 var ids = Array(); 584 585 $components.find('.wooco_component_product').each(function () { 586 var $this = jQuery(this); 587 var $checkbox = $this.find('.wooco-checkbox'); 588 var key = $this.data('key'); 589 590 if ($checkbox.length && !$checkbox.prop('checked')) { 591 return; 592 } 593 594 if ($this.attr('data-multiple') === 'yes') { 595 // multiple selection 596 $this.find('.wooco_item_selected').each(function () { 597 var $_this = jQuery(this); 598 599 if (($_this.attr('data-id') > 0) && ($_this.attr('data-qty') > 0)) { 600 ids.push($_this.attr('data-id') + '/' + $_this.attr('data-qty') + '/' + key); 601 } 602 }); 603 } else { 604 // single selection 605 606 if (($this.attr('data-id') > 0) && ($this.attr('data-qty') > 0)) { 607 ids.push($this.attr('data-id') + '/' + $this.attr('data-qty') + '/' + key); 608 } 609 } 610 }); 611 612 $ids.val(ids.join(',')); 613 jQuery(document).trigger('wooco_save_ids', [ids, $wrap, context, $selected]); 614} 615 616function wooco_show_alert($wrap, context = null, $selected = null) { 617 var $alert = $wrap.find('.wooco-alert'); 618 619 if ($alert.hasClass('alert-active')) { 620 $alert.slideDown(); 621 } else { 622 $alert.slideUp(); 623 } 624 625 jQuery(document).trigger('wooco_show_alert', [$wrap, context, $selected]); 626} 627 628function wooco_init_selector() { 629 if (wooco_vars.selector === 'ddslick') { 630 jQuery('.wooco_component_product_select').each(function () { 631 var $this = jQuery(this); 632 var $selection = $this.closest('.wooco_component_product_selection'); 633 var $component = $this.closest('.wooco_component_product'); 634 var $wrap = $this.closest('.wooco-wrap'); 635 636 $selection.data('select', 0); 637 638 $this.ddslick({ 639 width: '100%', onSelected: function (data) { 640 var _select = $selection.data('select'); 641 var $selected = jQuery(data.original[0].children[data.selectedIndex]); 642 643 if (data.selectedData.value == '-1') { 644 if (!$selection.find('.dd-selected .dd-desc').length) { 645 $selection.find('.dd-selected').addClass('dd-option-without-desc'); 646 $selection.find('.dd-option-selected').addClass('dd-option-without-desc'); 647 } else { 648 $selection.find('.dd-selected').removeClass('dd-option-without-desc'); 649 $selection.find('.dd-option-selected').removeClass('dd-option-without-desc'); 650 } 651 } 652 653 // check empty desc 654 if (!$selection.hasClass('wooco-ddslick-checked-desc')) { 655 $selection.find('.dd-selected, .dd-option').each(function () { 656 if (!jQuery(this).find('.dd-desc').length) { 657 jQuery(this).addClass('dd-option-without-desc'); 658 } else { 659 jQuery(this).removeClass('dd-option-without-desc'); 660 } 661 }); 662 663 $selection.addClass('wooco-ddslick-checked-desc'); 664 } 665 666 // check disabled 667 if (!$selection.hasClass('wooco-ddslick-checked-disabled')) { 668 $selection.find('.dd-selected, .dd-option').each(function () {
669 if (parseInt(jQuery(this).find('.dd-option-value').val()) === 0) { 670 jQuery(this).addClass('dd-option-disabled'); 671 } else { 672 jQuery(this).removeClass('dd-option-disabled'); 673 } 674 }); 675 676 $selection.addClass('wooco-ddslick-checked-disabled'); 677 } 678 679 wooco_selected($selected, $selection, $component); 680 681 if (_select > 0) { 682 wooco_init($wrap, 'on_select', $selected); 683 } else { 684 // selected on init_selector 685 wooco_init($wrap, 'selected', $selected); 686 } 687 688 $selection.data('select', _select + 1); 689 }, 690 }); 691 }); 692 } else if (wooco_vars.selector === 'select2') { 693 jQuery('.wooco_component_product_select').each(function () { 694 var $this = jQuery(this); 695 var $selection = $this.closest('.wooco_component_product_selection'); 696 var $component = $this.closest('.wooco_component_product'); 697 var $wrap = $this.closest('.wooco-wrap'); 698 699 if ($this.val() !== '') { 700 var $default = jQuery('option:selected', this); 701 702 wooco_selected($default, $selection, $component); 703 wooco_init($wrap, 'selected', $default); 704 } 705 706 $this.select2({ 707 templateResult: wooco_select2_state, 708 width: '100%', 709 containerCssClass: 'wpc-select2-container', 710 dropdownCssClass: 'wpc-select2-dropdown', 711 }); 712 }); 713 } else { 714 jQuery('.wooco_component_product_select').each(function () { 715 // check on start 716 var $this = jQuery(this); 717 var $selection = $this.closest('.wooco_component_product_selection'); 718 var $component = $this.closest('.wooco_component_product'); 719 var $wrap = $this.closest('.wooco-wrap'); 720 var $selected = jQuery('option:selected', this); 721 722 wooco_selected($selected, $selection, $component); 723 wooco_init($wrap, 'selected', $selected); 724 }); 725 } 726 727 jQuery('.wooco_component_product_selection_item.wooco_item_selected').each(function () { 728 var $this = jQuery(this); 729 var $selection = $this.closest('.wooco_component_product_selection'); 730 var $component = $this.closest('.wooco_component_product'); 731 var $wrap = $this.closest('.wooco-wrap'); 732 733 wooco_selected($this, $selection, $component); 734 wooco_init($wrap, 'selected', $this); 735 }); 736} 737 738function wooco_selected($selected, $selection, $component) { 739 var id = $selected.attr('data-id'); 740 var pid = $selected.attr('data-pid'); 741 var price = $selected.attr('data-price'); 742 var purchasable = $selected.attr('data-purchasable'); 743 var regular_price = $selected.attr('data-regular-price'); 744 var link = $selected.attr('data-link'); 745 var image = '<img src="' + $selected.attr('data-imagesrc') + '"/>'; 746 var price_html = $selected.attr('data-price-html'); 747 var availability = $selected.attr('data-availability'); 748 var custom_qty = $component.attr('data-custom-qty'); 749 var qid = id; // product ID for quick view 750 751 if (purchasable === 'yes') { 752 $component.attr('data-id', id); 753 } else { 754 $component.attr('data-id', 0); 755 } 756 757 // Store selected product display name for selected summary 758 var selectedName = jQuery.trim( 759 $selected.attr('data-name') 760 || $selected.text() 761 || '' 762 ); 763 $component.attr('data-selected-name', selectedName); 764 765 $component.attr('data-price', price); 766 $component.attr('data-price-html', price_html); 767 $component.attr('data-regular-price', regular_price); 768 769 if (custom_qty === 'yes') { 770 if ($selected.find('.wooco_qty').length) { 771 $component.attr('data-qty', $selected.find('.wooco_qty').val()); 772 } else if ($selected.find('.qty').length) { 773 $component.attr('data-qty', $selected.find('.qty').val()); 774 } 775 } 776 777 if ((wooco_vars.quickview_variation === 'parent') && pid) { 778 qid = pid; 779 } 780 781 if (wooco_vars.product_link !== 'no') { 782 $selection.find('.wooco_component_product_link').remove(); 783 if (link !== '') { 784 if (wooco_vars.product_link === 'yes_popup') { 785 $selection.append('<a class="wooco_component_product_link woosq-link" data-id="' + qid + '" data-context="wooco" href="' + link + '" target="_blank"> </a>'); 786 } else { 787 $selection.append('<a class="wooco_component_product_link" href="' + link + '" target="_blank"> </a>'); 788 } 789 } 790 } 791 792 $component.find('.wooco_component_product_image').html(image); 793 $component.find('.wooco_component_product_price').html(price_html); 794 $component.find('.wooco_component_product_availability').html(availability); 795 796 jQuery(document).trigger('wooco_selected', [$selected, $selection, $component]); 797} 798 799function wooco_deselect($selected, $selection, $component) { 800 jQuery(document).trigger('wooco_deselected', [$selected, $selection, $component]); 801} 802 803function wooco_select2_state(state) { 804 if (!state.id) { 805 return state.text; 806 } 807 808 var $state = {}; 809 810 if (jQuery(state.element).attr('data-imagesrc') !== '') { 811 $state = jQuery('<span class="image"><img src="' + jQuery(state.element).attr('data-imagesrc') + '"/></span><span class="info"><span class="name">' + state.text + '</span> <span class="desc">' + jQuery(state.element).attr('data-description') + '</span></span>'); 812 } else { 813 $state = jQuery('<span class="info"><span class="name">' + state.text + '</span> <span class="desc">' + jQuery(state.element).attr('data-description') + '</span></span>'); 814 } 815 816 return $state; 817} 818 819function wooco_round(value) { 820 return Number(Math.round(value + 'e' + wooco_vars.price_decimals) + 'e-' + wooco_vars.price_decimals); 821} 822 823function wooco_decimal_places(num) { 824 var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); 825 826 if (!match) { 827 return 0; 828 } 829 830 return Math.max(0, // Number of digits right of decimal point. 831 (match[1] ? match[1].length : 0) 832 // Adjust for scientific notation. 833 - (match[2] ? +match[2] : 0)); 834} 835 836function wooco_format_money(number, places, symbol, thousand, decimal) { 837 number = number || 0; 838 places = !isNaN(places = Math.abs(places)) ? places : 2; 839 symbol = symbol !== undefined ? symbol : '$'; 840 thousand = thousand || ''; 841 decimal = decimal || ''; 842 843 var negative = number < 0 ? '-' : '', i = parseInt(number = Math.abs(+number || 0).toFixed(places), 10) + '', j = 0; 844 845 if (i.length > 3) { 846 j = i.length % 3; 847 } 848 849 if (wooco_vars.trim_zeros === '1') { 850 return symbol + negative + (j ? i.substr(0, j) + thousand : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand) + (places && (parseFloat(number) > parseFloat(i)) ? decimal + Math.abs(number - i).toFixed(places).slice(2).replace(/(\d*?[1-9])0+$/g, '$1') : ''); 851 } else { 852 return symbol + negative + (j ? i.substr(0, j) + thousand : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand) + (places ? decimal + Math.abs(number - i).toFixed(places).slice(2) : ''); 853 } 854} 855 856function wooco_format_number(number) { 857 return parseFloat(number.replace(/[^0-9.,]/g, '').replace(',', '.')); 858} 859 860function wooco_format_price(price) { 861 var price_html = '<span class="woocommerce-Price-amount amount">'; 862 var price_formatted = wooco_format_money(price, wooco_vars.price_decimals, '', wooco_vars.price_thousand_separator, wooco_vars.price_decimal_separator); 863 864 switch (wooco_vars.price_format) { 865 case '%1$s%2$s': 866 //left 867 price_html += '<span class="woocommerce-Price-currencySymbol">' + wooco_vars.currency_symbol + '</span>' + price_formatted; 868 break; 869 case '%1$s %2$s': 870 //left with space 871 price_html += '<span class="woocommerce-Price-currencySymbol">' + wooco_vars.currency_symbol + '</span> ' + price_formatted; 872 break; 873 case '%2$s%1$s': 874 //right 875 price_html += price_formatted + '<span class="woocommerce-Price-currencySymbol">' + wooco_vars.currency_symbol + '</span>'; 876 break; 877 case '%2$s %1$s': 878 //right with space 879 price_html += price_formatted + ' <span class="woocommerce-Price-currencySymbol">' + wooco_vars.currency_symbol + '</span>'; 880 break; 881 default: 882 //default 883 price_html += '<span class="woocommerce-Price-currencySymbol">' + wooco_vars.currency_symbol + '</span> ' + price_formatted; 884 } 885 886 price_html += '</span>'; 887 888 return price_html; 889} 890 891function wooco_price_html(regular_price, sale_price) { 892 var price_html = ''; 893 894 if (wooco_round(sale_price) !== wooco_round(regular_price)) { 895 if (wooco_round(sale_price) < wooco_round(regular_price)) { 896 price_html = '<del>' + wooco_format_price(regular_price) + '</del> <ins>' + wooco_format_price(sale_price) + '</ins>'; 897 } else { 898 price_html = wooco_format_price(sale_price); 899 } 900 } else { 901 price_html = wooco_format_price(regular_price); 902 } 903 904 return price_html; 905} 906 907/** 908 * Update the .wooco-selected summary div with a list of all selected products across steps. 909 * If the container doesn't exist yet (stale cache), it is injected before .wooco-total. 910 */ 911function wooco_step_update_selected($wrap) { 912 var $container = $wrap.find('.wooco-selected'); 913
914 // Inject container if PHP cache served old HTML without it 915 if (!$container.length) { 916 var $summary = $wrap.find('.wooco_summary, .wooco-summary').first(); 917 918 if ($summary.length) { 919 $summary.before('<div class="wooco-selected"></div>'); 920 $container = $wrap.find('.wooco-selected'); 921 } 922 923 if (!$container.length) { 924 return; 925 } 926 } 927 928 var $steps = $wrap.find('.wooco-components').children('.wooco_component'); 929 930 if (!$steps.length) { 931 $container.hide(); 932 return; 933 } 934 935 var rows = []; 936 937 $steps.each(function () { 938 var $step = jQuery(this); 939 var $product = $step.find('.wooco_component_product').first(); 940 var labelEl = $step.find('.wooco_component_name').first().text().trim(); 941 var name = wooco_step_get_selected_name($product); 942 943 // Skip components with no selection 944 if (!name || !labelEl) { 945 return; 946 } 947 948 rows.push( 949 '<div class="wooco-selected-row">' 950 + '<span class="wooco-selected-label">' + labelEl + ':</span> ' 951 + '<span class="wooco-selected-name">' + name + '</span>' 952 + '</div>' 953 ); 954 }); 955 956 if (rows.length === 0) { 957 $container.html('').hide(); 958 } else { 959 $container.html(rows.join('')).show(); 960 } 961} 962 963/** 964 * Get the display name of the currently selected product inside a .wooco_component_product element. 965 * Returns null when nothing is selected (id <= 0). 966 * Prepend quantity (qty à name) if custom quantity is enabled or qty > 1. 967 */ 968function wooco_step_get_selected_name($product) { 969 var isMultiple = $product.attr('data-multiple') === 'yes'; 970 var isCustomQty = $product.attr('data-custom-qty') === 'yes'; 971 972 // --- Multiple selection: collect all selected item names --- 973 if (isMultiple) { 974 var names = []; 975 976 $product.find('.wooco_item_selected').each(function () { 977 var $item = jQuery(this); 978 var name = jQuery.trim( 979 $item.find('.wooco_component_product_selection_list_item_name').first().text() 980 || $item.find('.wooco_component_product_selection_grid_item_name').first().text() 981 || $item.attr('data-name') 982 || '' 983 ); 984 985 if (name) { 986 var itemQty = parseFloat($item.find('.wooco_qty, .qty').first().val()) 987 || parseFloat($item.attr('data-qty')) 988 || parseFloat($product.attr('data-qty')) 989 || 1; 990 991 if (isCustomQty || itemQty > 1) { 992 name = itemQty + ' × ' + name; 993 } 994 995 names.push(name); 996 } 997 }); 998 999 return names.length > 0 ? names.join('; ') : null; 1000 } 1001 1002 // --- Single selection --- 1003 var selectedId = parseInt($product.attr('data-id') || 0); 1004 1005 if (selectedId <= 0) { 1006 return null; 1007 } 1008 1009 var name = null; 1010 1011 // 1. Check cached name stored by wooco_selected() 1012 var cachedName = jQuery.trim($product.attr('data-selected-name') || ''); 1013 if (cachedName) { 1014 name = cachedName; 1015 } 1016 1017 if (!name) { 1018 // --- Dropdown selectors (select / ddslick / select2) --- 1019 var $select = $product.find('.wooco_component_product_select'); 1020 1021 if ($select.length) { 1022 // Option with matching value 1023 var $opt = $select.find('option[value="' + selectedId + '"]'); 1024 if ($opt.length) { 1025 name = jQuery.trim($opt.text()); 1026 } 1027 1028 if (!name) { 1029 // Option with matching data-id attribute 1030 $opt = $select.find('option').filter(function () { 1031 return parseInt(jQuery(this).attr('data-id') || 0) === selectedId; 1032 }); 1033 if ($opt.length) { 1034 name = jQuery.trim($opt.first().text()); 1035 } 1036 } 1037 1038 if (!name) { 1039 // Whatever option is marked :selected 1040 var $chosen = $select.find('option:selected'); 1041 if ($chosen.length && parseInt($chosen.val()) > 0) { 1042 name = jQuery.trim($chosen.text()); 1043 } 1044 } 1045 } 1046 } 1047 1048 if (!name) { 1049 // ddslick selected label text 1050 var $ddText = $product.find('.dd-selected-text'); 1051 if ($ddText.length) { 1052 var ddName = jQuery.trim($ddText.text()); 1053 if (ddName) { 1054 name = ddName; 1055 } 1056 } 1057 } 1058 1059 if (!name) { 1060 // --- List layout --- 1061 var $listName = $product.find('.wooco_item_selected .wooco_component_product_selection_list_item_name').first(); 1062 if ($listName.length) { 1063 name = jQuery.trim($listName.text()); 1064 } 1065 } 1066 1067 if (!name) { 1068 // --- Grid layout --- 1069 var $gridName = $product.find('.wooco_item_selected .wooco_component_product_selection_grid_item_name').first(); 1070 if ($gridName.length) { 1071 name = jQuery.trim($gridName.text()); 1072 } 1073 } 1074 1075 if (!name) { 1076 // --- Generic fallback: data-name on any selected item --- 1077 var $anyItem = $product.find('.wooco_item_selected').first(); 1078 if ($anyItem.length && $anyItem.attr('data-name')) { 1079 name = jQuery.trim($anyItem.attr('data-name')); 1080 } 1081 } 1082 1083 if (!name) { 1084 return null; 1085 } 1086 1087 // Prepend quantity for single selection 1088 var $selectedItem = $product.find('.wooco_item_selected').first(); 1089 var $qtyInput = $selectedItem.length 1090 ? $selectedItem.find('.wooco_qty, .qty').first() 1091 : $product.find('.wooco_component_product_qty_input, .wooco_qty, .qty').first(); 1092 1093 var qty = parseFloat($qtyInput.val()) 1094 || parseFloat($product.attr('data-qty')) 1095 || 1; 1096 1097 if (isCustomQty || qty > 1) { 1098 name = qty + ' × ' + name; 1099 } 1100 1101 return name; 1102}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.