1jQuery(function ($) { 2 "use strict"; 3 4 if (window?.wc?.blocksCheckout) { 5 const { 6 registerCheckoutFilters 7 } = wc.blocksCheckout; 8 const { 9 sprintf, 10 __ 11 } = wp.i18n; 12 const modifyItemName = (defaultValue, extensions, args) => { 13 if (!extensions?.iconic_sales_booster?.added_via_at_checkout_bump) { 14 return defaultValue; 15 } 16 return sprintf(__('(Offer) %s', 'iconic-wsb'), defaultValue); 17 }; 18 registerCheckoutFilters('iconic-sales-booster', { 19 itemName: modifyItemName 20 }); 21 } 22 $(document).on('change', '[data-iconic-wsb-checkout-bump-trigger]', function () { 23 if (!$(this).parents('[data-block-name="woocommerce/checkout"]').length) { 24 return; 25 } 26 if (!wc?.blocksCheckout?.extensionCartUpdate) { 27 return; 28 } 29 const $fields = $(this).siblings('input[type="hidden"]'); 30 const data = { 31 'bump-type': 'at-checkout', 32 'iconic-wsb-bump-id': $fields.filter('[name="iconic-wsb-bump-id"]').val(), 33 'iconic-wsb-checkout-bump-action': $(this).prop('checked') ? 'add' : 'remove', 34 'iconic-wsb-checkout-product-id': $fields.filter('[name="iconic-wsb-checkout-product-id"]').val(), 35 'iconic-wsb-checkout-variation-id': $fields.filter('[name="iconic-wsb-checkout-variation-id"]').val(), 36 'iconic-wsb-checkout-variation-data': $fields.filter('[name="iconic-wsb-checkout-variation-data"]').val() 37 }; 38 $('.wp-block-woocommerce-checkout').block({ 39 message: null, 40 overlayCSS: { 41 background: '#fff', 42 opacity: 0.6 43 } 44 }); 45 wc.blocksCheckout.extensionCartUpdate({ 46 namespace: 'iconic-sales-booster', 47 data 48 }).then(() => { 49 checkoutBumpVariableProduct.handleSwatchesLabel(); 50 checkoutBumpVariableProduct.handleOverlay(); 51 checkoutBumpVariableProduct.handleCheckbox(); 52 $('.wp-block-woocommerce-checkout').unblock(); 53 }); 54 }); 55 wp.data.subscribe(() => { 56 if (!wp.data.select('wc/store/checkout')?.isBeforeProcessing()) { 57 return; 58 } 59 if (!$('[data-iconic-wsb-acb-modal]').length) { 60 return; 61 } 62 wp.data.dispatch('wc/store/checkout').__internalSetIdle(); 63 $.magnificPopup.open({ 64 items: { 65 type: 'inline', 66 src: $('[data-iconic-wsb-acb-modal]') 67 } 68 }); 69 }, 'wc/store/checkout'); 70 $('[data-iconic-wsb-acb-add-to-cart-button]').on('click', function (event) { 71 if (!window?.wc?.blocksCheckout) { 72 return; 73 } 74 event.preventDefault(); 75 const $fields = $('.iconic-wsb-acb-fields input[type="hidden"]'); 76 const data = { 77 'bump-type': 'after-checkout', 78 'iconic-wsb-acb-action': 'add', 79 'iconic-wsb-acb-bump-id': $fields.filter('[name="iconic-wsb-acb-bump-id"]').val(), 80 'iconic-wsb-acb-variation-id': $fields.filter('[name="iconic-wsb-acb-variation-id"]').val(), 81 'iconic-wsb-acb-variation-data': $fields.filter('[name="iconic-wsb-acb-variation-data"]').val() 82 }; 83 wc.blocksCheckout.extensionCartUpdate({ 84 namespace: 'iconic-sales-booster', 85 data 86 }).then(() => { 87 $.magnificPopup.close(); 88 $('[data-iconic-wsb-acb-modal]').remove(); 89 wp.data.dispatch('wc/store/checkout').__internalSetBeforeProcessing(); 90 }); 91 }); 92 $('[data-iconic-wsb-acb-close-button]').on('click', function (event) { 93 if (!window?.wc?.blocksCheckout) { 94 return; 95 } 96 event.preventDefault(); 97 $.magnificPopup.close(); 98 $('[data-iconic-wsb-acb-modal]').remove(); 99 wp.data.dispatch('wc/store/checkout')?.__internalSetBeforeProcessing(); 100 }); 101 102 /** 103 * Trigger add offered product to order 104 */ 105 $(document).on('change', '[data-iconic-wsb-checkout-bump-trigger]', function () { 106 var actionTypeInput = $('[name=iconic-wsb-checkout-bump-action]'); 107 var bumpInForm = true; 108 var bumpWrapper = $(this).closest('.iconic-wsb-checkout-bump'); 109 110 // If the hook is outside of the form, make sure it still works. 111 if (!$(this).closest('form.checkout').length) { 112 bumpInForm = false; 113 } 114 if (!$(this).prop('checked')) { 115 actionTypeInput.val('remove'); 116 } else { 117 actionTypeInput.val('add'); 118 if (!bumpInForm) { 119 bumpWrapper.find('input[name="iconic-wsb-bump-id"]').clone().appendTo('form.checkout'); 120 bumpWrapper.find('input[name="iconic-wsb-checkout-bump-action"]').clone().appendTo('form.checkout'); 121 bumpWrapper.find('input[name="iconic-wsb-checkout-product-id"]').clone().appendTo('form.checkout'); 122 bumpWrapper.find('input[name="iconic-wsb-checkout-variation-id"]').clone().appendTo('form.checkout'); 123 bumpWrapper.find('input[name="iconic-wsb-checkout-variation-data"]').clone().appendTo('form.checkout'); 124 } 125 } 126 $('body').trigger('update_checkout'); 127 128 // If we are removing, we need to wait for the form to finish posting. 129 if (!$(this).prop('checked') && !bumpInForm) { 130 setTimeout(function () { 131 $('form.checkout input[name="iconic-wsb-bump-id"]').remove(); 132 $('form.checkout input[name="iconic-wsb-checkout-bump-action"]').remove(); 133 $('form.checkout input[name="iconic-wsb-checkout-product-id"]').remove(); 134 $('form.checkout input[name="iconic-wsb-checkout-variation-id"]').remove(); 135 $('form.checkout input[name="iconic-wsb-checkout-variation-data"]').remove(); 136 }, 500); 137 } 138 }); 139 140 /** 141 * After checkout bump 142 * @constructor 143 */ 144 var AfterCheckoutBump = function () {
145 this.isBumpShowed = false; 146 this.isFormSubmited = false; 147 this.init = function () { 148 this.$checkoutForm = $('form.checkout'); 149 this.container = '[data-iconic-wsb-acb-modal]'; 150 this.$bumpModal = $(this.container); 151 this.$addToCartButton = $('[data-iconic-wsb-acb-add-to-cart-button]'); 152 this.$closeButton = $('[data-iconic-wsb-acb-close-button]'); 153 this.actionInputSelector = '[name=iconic-wsb-acb-action]'; 154 this.$form = $('.iconic-wsb-after-checkout-bump-form'); 155 this.variation_dropdown = ".iconic-wsb-checkout-modal__select"; 156 this.variationHandler = new IconicVariationHandler(this.$form, this.container, this.onVariationFound.bind(this), this.onVariationNotFound.bind(this)); 157 var self = this; 158 159 // If suitable order bump exists 160 if (this.$bumpModal.length > 0) { 161 this.$checkoutForm.on('checkout_place_order.orderBump', this.openModal.bind(this)); 162 this.$closeButton.on('click', this.close.bind(this)); 163 this.$addToCartButton.on('click', function (e) { 164 e.preventDefault(); 165 this.addToCartBump(); 166 }.bind(this)); 167 $(this.container).on("change", this.variation_dropdown, this.variationHandler.getVariation.bind(this.variationHandler)); 168 $('.wsb_select_readonly option:not(:selected)').prop('disabled', true); 169 } 170 171 //to make compatible with WooCommerce Attribute Swatches plugin 172 this.$form.addClass("variations_form"); 173 this.$form.data("product_variations", false); 174 }; 175 this.close = function () { 176 $.magnificPopup.close(); 177 this.$checkoutForm.submit(); 178 }; 179 this.addToCartBump = function () { 180 $(this.actionInputSelector).val('add'); 181 this.$checkoutForm.trigger('update_checkout'); 182 this.$checkoutForm.off('checkout_place_order.orderBump', this.openModal.bind(this)); 183 $(document).ajaxComplete(function (event, xhr, settings) { 184 // ensure this is the update_order_review AJAX request. 185 if (!settings.url.includes("update_order_review")) { 186 return; 187 } 188 if (this.isFormSubmited === true) { 189 return; 190 } 191 this.isFormSubmited = true; 192 this.$checkoutForm.submit(); 193 }.bind(this)); 194 $.magnificPopup.close(); 195 }; 196 this.openModal = function () { 197 // Check if we have the modal element. 198 if (!$(this.container).length) { 199 return; 200 } 201 if (this.isBumpShowed === true) { 202 return true; 203 } 204 this.variationHandler.getVariation(); 205 var modalConfig = { 206 items: { 207 src: this.$bumpModal, 208 type: 'inline' 209 } 210 }; 211 modalConfig = Object.assign(modalConfig, Object(iconic_wsb_frontend_vars && iconic_wsb_frontend_vars.modal_options)); 212 $.magnificPopup.open(modalConfig); 213 this.isBumpShowed = true; 214 return false; 215 }; 216 this.onVariationFound = function (variation) { 217 this.$addToCartButton.attr("disabled", false); 218 this.$form.find(".iconic-wsb-checkout-modal-unavailable_msg").hide(); 219 this.$form.find(".iconic-wsb-modal-product-offer__price").html(variation.price_html); 220 $("[name='iconic-wsb-acb-variation-id']").val(variation.variation_id); 221 }; 222 this.onVariationNotFound = function () { 223 this.$addToCartButton.attr("disabled", true); 224 this.$form.find(".iconic-wsb-checkout-modal-unavailable_msg").slideDown(200); 225 this.$form.find(".iconic-wsb-modal-product-offer__price").html(""); 226 $("[name='iconic-wsb-acb-variation-id']").val(""); 227 }; 228 }; 229 var CheckoutBumpVariableProduct = function () { 230 this.allVariationSelectedFlag = null; 231 this.$attributeFields = null; 232 this.$woocommerceWrapper = $('.page.woocommerce-checkout, [data-block-name="woocommerce/checkout"]'); 233 this.container = ".iconic-wsb-checkout-bump"; 234 this.variation_dropdown = ".iconic-wsb-checkout-bump__select"; 235 236 /** 237 * Initialize 238 */ 239 this.init = function () { 240 var self = this; 241 self.variationHandler = new IconicVariationHandler(self.$woocommerceWrapper, this.container, this.onVariationFound.bind(self), this.onVariationNotFound.bind(self)); 242 $(self.$woocommerceWrapper).on("change", this.variation_dropdown, this.variationHandler.getVariation.bind(this.variationHandler)); 243 $(self.$woocommerceWrapper).on("change", this.variation_dropdown, this.handleCheckbox.bind(this));
244 self.product_type = self.$woocommerceWrapper.find(".iconic-wsb-checkout-bump").data("product_type"); 245 if (self.product_type === "variable") { 246 if (self.$woocommerceWrapper.find(".iconic-wsb-checkout-bump__select").length) { 247 self.$woocommerceWrapper.find(".iconic-wsb-checkout-bump__header-checkbox").attr("disabled", !self.variationHandler.checkAllSelects.bind(self.variationHandler)); 248 } 249 self.handleSwatchesLabel(); 250 self.handleOverlay(); 251 self.handleCheckbox(); 252 } 253 $(document.body).on('updated_checkout', function () { 254 self.product_type = self.$woocommerceWrapper.find(".iconic-wsb-checkout-bump").data("product_type"); 255 if (self.product_type === "variable") { 256 if (self.$woocommerceWrapper.find("[name=iconic-wsb-checkout-variation-id]").length && $("[name=iconic-wsb-checkout-variation-id]").val() === '') { 257 self.variationHandler.getVariation(false); //need to run getVariation after updated_checkout has been triggered 258 } 259 if (self.$woocommerceWrapper.find(".iconic-wsb-checkout-bump__select").length) { 260 self.$woocommerceWrapper.find(".iconic-wsb-checkout-bump__header-checkbox").attr("disabled", !self.variationHandler.checkAllSelects.bind(self.variationHandler)); 261 } 262 self.handleSwatchesLabel(); 263 self.handleOverlay(); 264 self.handleCheckbox(); 265 } 266 $('.wsb_select_readonly option:not(:selected)').prop('disabled', true); 267 }); 268 269 //to make compatible with WooCommerce Attribute Swatches plugin 270 this.$woocommerceWrapper.addClass("variations_form"); 271 this.$woocommerceWrapper.data("product_variations", false); 272 273 // handle order bump outside of form.checkout 274 if (!$('form.checkout .iconic-wsb-checkout-bump').length) { 275 if ($('.iconic-wsb-checkout-bump__header-checkbox').prop('checked')) { 276 this.$woocommerceWrapper.find('input[name="iconic-wsb-bump-id"]').clone().appendTo('form.checkout'); 277 this.$woocommerceWrapper.find('input[name="iconic-wsb-checkout-bump-action"]').clone().appendTo('form.checkout'); 278 this.$woocommerceWrapper.find('input[name="iconic-wsb-checkout-product-id"]').clone().appendTo('form.checkout'); 279 this.$woocommerceWrapper.find('input[name="iconic-wsb-checkout-variation-id"]').clone().appendTo('form.checkout'); 280 this.$woocommerceWrapper.find('input[name="iconic-wsb-checkout-variation-data"]').clone().appendTo('form.checkout'); 281 } 282 } 283 setTimeout(() => { 284 /** 285 * Set the value of the `data-value` attribute to the `value` attribute. 286 * 287 * When using the Checkou block, the `value` attribute is removed so 288 * we re-add by copying the data from `data-value`. 289 */ 290 $('.iconic-wsb-variation__select.iconic-wsb-checkout-bump__select option').each(function () { 291 $(this).attr('value', $(this).attr('data-value') || ''); 292 }); 293 }, 700); 294 }; 295 296 /** 297 * 1)Hides unavailable variation message 2) Enables the 'Add to cart' checkbox 298 */ 299 this.onVariationFound = function (variation) { 300 this.$woocommerceWrapper.find("[data-iconic-wsb-checkout-bump-trigger]").attr("disabled", false); 301 this.$woocommerceWrapper.find(".iconic-wsb-checkou-bump_unavailable_msg").hide(); 302 }; 303 304 /** 305 * 1)Shows unavailable variation message 2) Disables the 'Add to cart' checkbox 306 */ 307 this.onVariationNotFound = function () { 308 this.$woocommerceWrapper.find("[data-iconic-wsb-checkout-bump-trigger]").attr("disabled", true); 309 this.$woocommerceWrapper.find(".iconic-wsb-checkou-bump_unavailable_msg").slideDown(200); 310 }; 311 312 /** 313 * Show/Hide overlay to prevent user from changing the variation after the product has been added to cart. 314 */ 315 this.handleOverlay = function () { 316 var isInCart = this.$woocommerceWrapper.find("[data-iconic-wsb-checkout-bump-trigger]").prop("checked"); 317 if (isInCart) { 318 this.$woocommerceWrapper.find(".iconic-wsb-checkout-bump").addClass("iconic-wsb-checkout-bump__overlay_active");
319 this.$woocommerceWrapper.find(".iconic-wsb-checkout-bump__overlay").show(); 320 } else { 321 this.$woocommerceWrapper.find(".iconic-wsb-checkout-bump").removeClass("iconic-wsb-checkout-bump__overlay_active"); 322 this.$woocommerceWrapper.find(".iconic-wsb-checkout-bump__overlay").hide(); 323 } 324 }; 325 326 /** 327 * If Woocomerce Attributes Swatches plugin is enabled then makes sure that lables for attributes are visible 328 */ 329 this.handleSwatchesLabel = function () { 330 if (this.$woocommerceWrapper.find(".iconic-was-swatches").length) { 331 this.$woocommerceWrapper.find(".iconic-wsb-variation__select").each(function () { 332 var val = jQuery(this).val(); 333 if (val) { 334 var $row = jQuery(this).closest("tr"); 335 var html = $row.find("td.label label .iconic-was-chosen-attribute").html(); 336 if (html && html.trim() === "") { 337 var new_html = $row.find(".iconic-was-swatch--selected").data("attribute-value-name"); 338 $row.find("td.label label .iconic-was-chosen-attribute").html(new_html); 339 } 340 } 341 }); 342 } 343 }; 344 345 /** 346 * Enable or disable 'data-iconic-wsb-checkout-bump-trigger' checkbox 347 */ 348 this.handleCheckbox = function () { 349 var $checkbox = this.$woocommerceWrapper.find("[data-iconic-wsb-checkout-bump-trigger]"); 350 //1) If: $checkbox is checked then user should be able to uncheck it, hence always enable it. Else: if any of the attributes are not selected, then disable $checkox 351 if ($checkbox.prop("checked")) { 352 $checkbox.attr("disabled", false); 353 } else { 354 this.$woocommerceWrapper.find("[data-iconic-wsb-checkout-bump-trigger]").attr("disabled", !this.variationHandler.checkAllSelects()); 355 } 356 }; 357 }; 358 var afterCheckoutBump = new AfterCheckoutBump(); 359 var checkoutBumpVariableProduct = new CheckoutBumpVariableProduct(); 360 361 /** 362 * Clear After Add to Cart fragments on Checkout page. 363 * 364 * @returns void 365 */ 366 function clear_after_add_to_cart_fragment_on_checkout_page() { 367 if (!iconic_wsb_frontend_vars?.is_checkout) { 368 return; 369 } 370 const fragment_name = wc_cart_fragments_params?.fragment_name; 371 if (!fragment_name || 'string' !== typeof fragment_name) { 372 return; 373 } 374 let fragments = sessionStorage.getItem(fragment_name); 375 if (!fragments) { 376 return; 377 } 378 fragments = JSON.parse(fragments); 379 fragments['.iconic_wsb_after_add_to_cart_popup_placeholder'] = undefined; 380 sessionStorage.setItem(wc_cart_fragments_params.fragment_name, JSON.stringify(fragments)); 381 } 382 $(document).ready(function () { 383 checkoutBumpVariableProduct.init(); 384 clear_after_add_to_cart_fragment_on_checkout_page(); 385 if ($('[data-block-name="woocommerce/checkout"]').length) { 386 return; 387 } 388 afterCheckoutBump.init(); 389 $(document).on('updated_checkout', function (event, data) { 390 if (!data.fragments || !data.fragments['.iconic-wsb-modal']) { 391 return; 392 } 393 var refreshedAfterCheckoutBump = new AfterCheckoutBump(); 394 refreshedAfterCheckoutBump.init(); 395 }); 396 }); 397}); 398jQuery(function ($) { 399 "use strict"; 400 401 /** 402 * After add to cart bump 403 * @constructor 404 */ 405 var AfterAddToCartBump = function () { 406 this.init = function () { 407 this.$bumpModal = $('[data-iconic-wsb-acc-modal-bump]'); 408 this.$closeButton = $('[data-iconic-wsb-close-aac-modal]'); 409 this.$variation_wrap = jQuery(this.$bumpModal.selector + ' .single_variation_wrap'); 410 411 // If order bump modal exists 412 if (this.$bumpModal.length > 0) { 413 this.$closeButton.on('click', this.close.bind(this)); 414 this.$variation_wrap.on('show_variation', this.changeVariationImage); 415 this.openModal(); 416 } 417 }; 418 this.changeVariationImage = function (event, variation) { 419 if (variation.image.thumb_src !== undefined) { 420 var $image = $(this).closest('[data-iconic-wsb-acc-modal-bump-offer-product]').find('[data-iconic-wsb-acc-modal-bamp-offer-image]').find('img'); 421 $image.attr('srcset', ''); 422 $image.attr('src', variation.image.thumb_src); 423 } 424 }; 425 this.close = function () { 426 $.magnificPopup.close(); 427 $('[data-iconic-wsb-acc-modal-bump]').remove(); 428 }; 429 this.openModal = function () { 430 var modalConfig = { 431 items: { 432 src: this.$bumpModal, 433 type: 'inline' 434 } 435 }; 436 modalConfig = Object.assign(modalConfig, Object(iconic_wsb_frontend_vars && iconic_wsb_frontend_vars.modal_options)); 437 $.magnificPopup.open(modalConfig); 438 $('[data-iconic-wsb-acc-modal-bump]').fadeIn(100); 439 }; 440 }; 441 442 /** 443 * Handles all the events and actions for FBT module 444 */ 445 var FrequentlyBoughTogether = function () { 446 this.init = function () { 447 $('.variations_form').on('found_variation', this.variationChangeHandle.bind(this)); 448 $('.iconic-wsb-bump-product__select').change(function (e) { 449 this.toggleButtonStatus.bind(this)(); 450 this.updateTotalPrice.bind(this)(); 451 this.fetchVariationPrice.bind(e.target)(); 452 this.updateAttributeData.bind(e.target)(); 453 }.bind(this)); 454 $('.iconic-wsb-bump-product__checkbox').change(function () { 455 this.updateTotalPrice(); 456 this.toggleButtonStatus(); 457 }.bind(this)); 458 this.toggleButtonStatus(); 459 this.addToCartAjax(); 460 this.toggleProductImages(); 461 this.disableFormSubmitForDisabledButton(); 462 }; 463 464 /** 465 * Saves the attribute's data as JSON in hidden fields. Is called when FBT dropdown is changed. 466 */ 467 this.updateAttributeData = function () { 468 var product_id = $(this).data("product_id"), 469 attributes = $(this).find("option:selected").data("attributes"), 470 attributes_str = typeof attributes === 'object' ? JSON.stringify(attributes) : attributes; 471 $("[name='iconic-wsb-bump-product_attributes-" + product_id + "']").val(attributes_str); 472 }; 473 474 /** 475 * Disable "Add Selected to Cart" button when 476 * either variation is not selected for any variable products 477 * or no products are checked 478 */ 479 this.toggleButtonStatus = function () { 480 // Check if variations are selected 481 var variableSelectFlag = true; 482 $('.iconic-wsb-product-bumps__list-item').each(function () { 483 if ($(this).find(".iconic-wsb-bump-product__checkbox").prop("checked")) { 484 var $select = $(this).find(".iconic-wsb-bump-product__select"); 485 if ($select.length && !$select.val()) { 486 variableSelectFlag = false;
487 } 488 } 489 }); 490 491 // check if atleast one product is checked 492 var selectedProductsCount = $('.iconic-wsb-bump-product__checkbox:checked').length; 493 if (variableSelectFlag && selectedProductsCount) { 494 $(".iconic-wsb-product-bumps__button").removeClass("disabled"); 495 } else { 496 $(".iconic-wsb-product-bumps__button").addClass("disabled"); 497 } 498 }; 499 500 /** 501 * Disable form submit when the button is disabled ( variations needs to be selected ) 502 */ 503 this.disableFormSubmitForDisabledButton = function () { 504 /** 505 * As we have multiple submit buttons on the form. Here we are saving 506 * the button which was clicked. This data will be used in form submit event. 507 */ 508 $('form.cart').click(function (e) { 509 $(this).data('clicked', $(e.target)); 510 }); 511 $('form.cart').submit(function (e) { 512 // Only prevent form submit when clicked on "Add selected to cart" button. 513 if ($(this).data('clicked').is("[data-bump-product-form-submit]")) { 514 if ($(this).find('.iconic-wsb-product-bumps__button').hasClass("disabled")) { 515 e.preventDefault(); 516 return false; 517 } 518 } 519 }); 520 $('.iconic-wsb-product-bumps__button').click(function () { 521 if ($(this).hasClass("disabled")) { 522 alert(iconic_wsb_frontend_vars.i18n.disabled_add_to_cart); 523 } 524 }); 525 }; 526 527 /** 528 * Fetch price for the selected variation 529 */ 530 this.fetchVariationPrice = function () { 531 var data = { 532 action: 'iconic_wsb_get_variation_price', 533 variation_id: jQuery(this).val(), 534 _ajax_nonce: iconic_wsb_frontend_vars.nonce 535 }; 536 var self = this; 537 const selector = $('.variations_form').length ? '.variations_form' : '.iconic-wsb-product-bumps'; 538 $(selector).block({ 539 message: null, 540 overlayCSS: { 541 background: '#fff', 542 opacity: 0.6 543 } 544 }); 545 jQuery.post(iconic_wsb_frontend_vars.ajax_url, data, function (response) { 546 $(selector).unblock(); 547 if (!response.success) { 548 return; 549 } 550 jQuery(self).siblings(".iconic-wsb-bump-product__price").html(response.data.variation_price_html); 551 }); 552 }; 553 554 /** 555 * Fetches and shows the total price of selected products 556 */ 557 this.updateTotalPrice = function () { 558 var product_ids = []; 559 560 //collect all product IDs in product_ids 561 $(".iconic-wsb-product-bumps__list-item").each(function () { 562 if ($(this).find(".iconic-wsb-bump-product__checkbox").is(":checked")) { 563 if ($(this).data("product_type") === "variable") { 564 var parent_id = parseInt($(this).data("product_id")), 565 variation_value = parseInt($(this).find(".iconic-wsb-bump-product__select").val()), 566 id = variation_value > 0 ? variation_value : parent_id; 567 product_ids.push(id); 568 } else { 569 product_ids.push($(this).data("product_id")); 570 } 571 } 572 }); 573 var data = { 574 action: 'iconic_wsb_fbt_get_products_price', 575 product_ids: product_ids, 576 offer_product_id: $("[name='iconic-wsb-fbt-this-product']").val(), 577 _ajax_nonce: iconic_wsb_frontend_vars.nonce 578 }; 579 var $variation_form = $('.iconic-wsb-product-bumps').parents('.variations_form'); 580 $variation_form.block({ 581 message: null, 582 overlayCSS: { 583 background: '#fff', 584 opacity: 0.6 585 } 586 }); 587 $.post(iconic_wsb_frontend_vars.ajax_url, data, function (data) { 588 $(".iconic-wsb-product-bumps__total-price-amount").html(data.html); 589 $variation_form.unblock(); 590 }); 591 }; 592 593 /** 594 * Responsible for selecting the right option from the Dropdown under 595 * "Add Selected to Cart" when user changes attributes. 596 */ 597 this.variationChangeHandle = function (e, variation_data) { 598 this.variationId = variation_data.variation_id; 599 this.currentProductId = $("form.cart").data("product_id"); 600 if (this.variationId && $(".iconic-wsb-bump-product__select--" + this.currentProductId).length) { 601 var $select = $(".iconic-wsb-bump-product__select--" + this.currentProductId); 602 603 //gather all the Single product attributes in `currentProductAttributes` 604 var currentProductAttributes = {}; 605 $("form.cart .variations select").each(function () { 606 currentProductAttributes[$(this).data("attribute_name")] = $(this).find("option:selected").text(); 607 }); 608 609 //find the matching 'option in the dropdown' 610 var matchIndex = 0; 611 $(".iconic-wsb-bump-product__select--" + this.currentProductId + " option").each(function (optionIndex) { 612 var $option = $(this); 613 var optionAttribute = $option.data("attributes"); 614 var matchFlag = true; 615 var attribute; 616 for (attribute in currentProductAttributes) { 617 if (optionAttribute && optionAttribute[attribute]['label'] === currentProductAttributes[attribute]) { 618 //ok 619 } else { 620 matchFlag = false;
621 } 622 } 623 if (matchFlag) { 624 matchIndex = optionIndex; 625 $select.find("option").eq(matchIndex).prop('selected', true); 626 $select.change(); 627 } 628 }); 629 } 630 }; 631 632 /** 633 * Adds products to the cart with AJAX rather than page reload, when AJAX setting is enabled 634 */ 635 this.addToCartAjax = function () { 636 $(document.body).on('click', '[data-bump-product-form-submit]', function (e) { 637 var $button = $(this); 638 if ($button.prop('disabled') || $button.hasClass('disabled') || '1' !== iconic_wsb_frontend_vars.fbt_use_ajax) { 639 return; 640 } 641 var $bumps = $button.closest('.iconic-wsb-product-bumps'), 642 $form = $button.closest('form.cart'), 643 bumpInForm = true, 644 $product_id = $button.data('product-id'); 645 646 // If the bump is not within the form. 647 if (!$form.length) { 648 bumpInForm = false; 649 $form = $('form.cart'); 650 651 // If form is not on a product page. 652 if (!$form.length) { 653 $form = $(document.createElement('form')); 654 $('.iconic-wsb-product-bumps').clone().appendTo($form); 655 } else { 656 // Copy the hidden field to the form. 657 $bumps.find('input[name="iconic-wsb-fbt-this-product"]').clone().appendTo('form.cart'); 658 659 // Loop checked items and add those as hidden fields to the form. 660 $bumps.find('.iconic-wsb-bump-product__checkbox:checked').each(function () { 661 var element = $(document.createElement('input')); 662 element.attr('type', 'hidden'); 663 element.attr('name', $(this).attr('name')); 664 element.val($(this).val()); 665 element.attr('class', $(this).attr('class')); 666 element.appendTo($form); 667 var select = $(this).closest('label').find('select[name^="iconic-wsb-products-add-to-cart-variation-"]'); 668 if (select.length) { 669 var element = $(document.createElement('input')); 670 element.attr('type', 'hidden'); 671 element.attr('name', select.attr('name')); 672 element.attr('class', select.attr('class')); 673 element.val(select.val()); 674 element.data(select.data()); 675 element.appendTo($form); 676 } else { 677 $(this).closest('label').find('input[name^="iconic-wsb-products-add-to-cart-variation-"]').clone().appendTo($form); 678 } 679 $(this).closest('label').find('input[name^="iconic-wsb-bump-product_attributes-"]').clone().appendTo($form); 680 }); 681 } 682 } 683 e.preventDefault(); 684 $bumps.block({ 685 message: null, 686 overlayCSS: { 687 background: '#fff', 688 opacity: 0.6 689 } 690 }); 691 $button.prop("disabled", true); 692 693 // Clear messages. 694 $('.woocommerce-notices-wrapper').html(''); 695 $.ajax({ 696 type: 'POST', 697 url: wc_add_to_cart_params.ajax_url, 698 data: $form.serialize() + "&iconic-wsb-add-selected=1&action=iconic_wsb_fbt_add_to_cart&post_id=" + $product_id, 699 success: function (result) { 700 $button.text(iconic_wsb_frontend_vars.i18n.success); 701 702 // Show notice. 703 var notice_class = result.success ? 'woocommerce-message' : 'woocommerce-error'; 704 $('.woocommerce-notices-wrapper').append('<div class="' + notice_class + '">' + result.message + '</div>'); 705 jQuery.scroll_to_notices($(".woocommerce-notices-wrapper")); 706 $bumps.unblock(); 707 708 // Redirect to cart if set in Woocommerce settings. 709 if (wc_add_to_cart_params.cart_redirect_after_add === "yes") { 710 window.location = wc_add_to_cart_params.cart_url; 711 } else { 712 $(document.body).trigger('added_to_cart', [result.fragments, result.cart_hash]); 713 } 714 }, 715 error: function () { 716 $button.text(iconic_wsb_frontend_vars.i18n.error); 717 $bumps.unblock(); 718 }, 719 complete: function () { 720 setTimeout(function () { 721 $button.prop("disabled", false).text(iconic_wsb_frontend_vars.i18n.add_selected); 722 723 // If the bump was not in the form, clean it up. 724 if (!bumpInForm) { 725 $('form.cart input[name="iconic-wsb-fbt-this-product"]').remove(); 726 $('form.cart .iconic-wsb-bump-product__checkbox').remove(); 727 $('form.cart input[name^="iconic-wsb-bump-product_attributes-"]').remove(); 728 $('form.cart select[name^="iconic-wsb-products-add-to-cart-variation-"]').remove(); 729 } 730 }, 3000); 731 } 732 }); 733 }); 734 }; 735 736 /** 737 * Toggle the related thumbnail when checkbox for a product is deselected. 738 */ 739 this.toggleProductImages = function () { 740 $('.iconic-wsb-bump-product__checkbox').change(function () { 741 var $checkbox = $(this), 742 $list_item = $checkbox.closest('.iconic-wsb-product-bumps__list-item'), 743 $bumps = $checkbox.closest('.iconic-wsb-product-bumps'), 744 id = $checkbox.val(), 745 $images_wrapper = $('.iconic-wsb-product-bumps__images'), 746 $images = $('.iconic-wsb-product-bumps__image'); 747 if (!$checkbox.is(':checked')) { 748 $list_item.addClass('iconic-wsb-product-bumps__list-item--faded'); 749 $('.iconic-wsb-product-bumps__image[data-product-id=' + id + ']').hide(); 750 } else { 751 $list_item.removeClass('iconic-wsb-product-bumps__list-item--faded'); 752 $('.iconic-wsb-product-bumps__image[data-product-id=' + id + ']').show(); 753 } 754 755 // Remove plus on last visible item. 756 var $last_visible = $bumps.find('.iconic-wsb-product-bumps__image:visible:last'); 757 $images.removeClass('iconic-wsb-product-bumps__image--no-plus'); 758 $last_visible.addClass('iconic-wsb-product-bumps__image--no-plus'); 759 760 // Hide section if no images visible. 761 var toggle_images = !$images_wrapper.is(':visible') || 0 < $last_visible.length; 762 $images_wrapper.toggle(toggle_images); 763 }); 764 $('.iconic-wsb-bump-product__checkbox').trigger('change'); 765 }; 766 }; 767 var afterAddToCartBump = new AfterAddToCartBump(); 768 var frequentlyBoughTogether = new FrequentlyBoughTogether(); 769 $(document).ready(function () { 770 afterAddToCartBump.init(); 771 frequentlyBoughTogether.init(); 772 }); 773 $(document).on('added_to_cart', function (e, fragments) { 774 if (!fragments || !window.wc_cart_fragments_params || !wc_cart_fragments_params.fragment_name) { 775 return; 776 } 777 afterAddToCartBump.init(); 778 779 // Delete from fragments 780 fragments['.iconic_wsb_after_add_to_cart_popup_placeholder'] = undefined; 781 fragments['.woocommerce-notices-wrapper'] = undefined; 782 sessionStorage.setItem(wc_cart_fragments_params.fragment_name, JSON.stringify(fragments)); 783 }); 784}); 785"use strict"; 786 787/** 788 * Reusable utility to handles the dropdown changes for the variation dropdowns. 789 * 1. Fetches the variation price when all dropdowns are selected 790 * 2. Saves attributes data in hidden fields 'iconic-wsb-acb-variation-data' or 'iconic-wsb-checkout-variation-data' 791 * 3. Shows and Hides spinner while AJAX 792 * 793 * @param {Object} form The jQuery instance of the form where variation dropdowns reside 794 * @param {str} container_selector selector string for the containing div 795 * @param {Function} onVariationFound callback function to be called when the variation is purchasable 796 * @param {Function} onVariationNotFound callback function to be called when the variation is not purchasable 797 */ 798var IconicVariationHandler = function (form, container_selector, onVariationFound, onVariationNotFound) { 799 this.$form = form; 800 this.container_selector = container_selector; 801 this.getVariation = function () { 802 var self = this,
803 $variationIdField = self.$form.find(".iconic-wsb__variation_id"); 804 if ($variationIdField.length <= 0) { 805 return; 806 } 807 if (self.checkAllSelects()) { 808 self.$attributeFields = jQuery(self.container_selector).find('.iconic-wsb-variation__select'); 809 var attributes = self.getChosenAttributes(); 810 var currentAttributes = attributes.data; 811 //TODO: Make this more generic. 812 if (self.$form.hasClass("iconic-wsb-after-checkout-bump-form")) { 813 jQuery("[name='iconic-wsb-acb-variation-data']").val(JSON.stringify(currentAttributes)); 814 } else { 815 jQuery("[name='iconic-wsb-checkout-variation-data']").val(JSON.stringify(currentAttributes)); 816 } 817 currentAttributes.product_id = parseInt(jQuery(self.container_selector).find(".iconic-wsb__product_id").val()); 818 currentAttributes.action = "iconic_wsb_checkout_get_variation"; 819 currentAttributes.bump_id = jQuery(self.container_selector).find(".iconic-wsb__bump_id").val(); 820 currentAttributes._ajax_nonce = iconic_wsb_frontend_vars.nonce; 821 self.showLoader(); 822 self.xhr = jQuery.ajax({ 823 url: iconic_wsb_frontend_vars.ajax_url, 824 type: 'POST', 825 data: currentAttributes, 826 success: function (variation) { 827 if (variation) { 828 self.$form.find("#iconic-wsb-checkout-bump-variation").val(variation.variation_id); 829 self.$form.find(".iconic-wsb-checkout-bump__price_span").html(variation.price_html); 830 if (!variation.is_purchasable || !variation.is_in_stock || !variation.variation_is_visible) { 831 onVariationNotFound(); 832 $variationIdField.val(""); 833 } else { 834 onVariationFound(variation); 835 $variationIdField.val(variation.variation_id); 836 } 837 } else { 838 onVariationNotFound(); 839 $variationIdField.val(""); 840 } 841 self.hideLoader(); 842 }, 843 complete: function () { 844 self.hideLoader(); 845 } 846 }); 847 self.$form.find("[data-iconic-wsb-acb-add-to-cart-button] , [data-iconic-wsb-checkout-bump-trigger]").attr("disabled", false); 848 } else { 849 self.$form.find("[data-iconic-wsb-acb-add-to-cart-button], [data-iconic-wsb-checkout-bump-trigger]").attr("disabled", true); 850 } 851 }; 852 853 /** 854 * Checks all the variation dropdowns. 855 * @returns boolean. Returns true iff all attribute dropdowns have a selected value. Returns false even is a single attribute dropdown doesnt has a value. 856 */ 857 this.checkAllSelects = function () { 858 var self = this; 859 self.allVariationSelectedFlag = true; 860 jQuery(self.container_selector).find(".iconic-wsb-variation__select").each(function () { 861 if (jQuery(this).val()) { 862 jQuery(this).closest("tr").removeClass("iconic-wsb-variation-tr-valdation-error"); 863 } else { 864 self.allVariationSelectedFlag = false; 865 jQuery(this).closest("tr").addClass("iconic-wsb-variation-tr-valdation-error"); 866 } 867 }); 868 return self.allVariationSelectedFlag; 869 }; 870 871 /** 872 * Get chosen attributes from form. 873 * @return array 874 */ 875 this.getChosenAttributes = function () { 876 var data = {}; 877 var count = 0; 878 var chosen = 0; 879 this.$attributeFields.each(function () { 880 var attribute_name = jQuery(this).data('attribute_name') || jQuery(this).attr('name'); 881 var value = jQuery(this).val() || ''; 882 if (value.length > 0) { 883 chosen++; 884 } 885 count++; 886 data[attribute_name] = value; 887 }); 888 return { 889 'count': count, 890 'chosenCount': chosen, 891 'data': data 892 }; 893 }; 894 895 /** 896 * Show spinner/loader for ajax. 897 */ 898 this.showLoader = function () { 899 this.$form.block({ 900 message: null, 901 overlayCSS: { 902 background: '#fff', 903 opacity: 0.6 904 } 905 }); 906 }; 907 908 /** 909 * used in conjection to showLoader() to hide the spinner/loader 910 */ 911 this.hideLoader = function () { 912 this.$form.unblock(); 913 }; 914};
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.