(function($){
const removeAttrClass=cfvsw_swatches_settings.remove_attr_class;
const addRemoveWithCommonClass=`${ removeAttrClass } cfvsw-swatches-out-of-stock`;
const addRemoveDisableClass=removeAttrClass + '-disable';
const addRemoveDisableClassCommon=`${ addRemoveDisableClass } cfvsw-swatches-disabled`;
const SW={
init: ()=> {
if(cfvsw_swatches_settings.disable_out_of_stock){
SW.firstTime();
SW.Events();
}},
firstTime: ()=> {
const getVariationTable=$('table.variations').not('.cfvsw-variation-disable-logic'
);
getVariationTable.addClass('cfvsw-variation-disable-logic');
getVariationTable.each(function (){
const table=$(this);
const getForm=table.closest('[data-product_id][data-product_variations]'
);
const getFormData=getForm.data('product_variations');
SW.swatchesOptions(getForm, getFormData);
});
},
chooseOption(){
const option=$(this);
const getForm=option.closest('[data-product_id][data-product_variations]'
);
getForm
.find('.disable-to-select')
.removeClass('disable-to-select');
const td=option.closest('td');
const checkTdSelected=td
.find('.cfvsw-hidden-select select')
.val();
if(''!==checkTdSelected){
td.addClass('disable-to-select');
}
const getFormData=getForm.data('product_variations');
SW.swatchesOptions(getForm, getFormData);
},
getSelectedOptions:(getForm)=> {
const getSelectedSwatches=getForm.find('.cfvsw-hidden-select select'
);
const selected={};
getSelectedSwatches.each(function (){
const select=$(this);
const getValue=select.val();
const getAttrName=select.attr('data-attribute_name');
if(''!==getValue&&''!==getAttrName){
selected[ getAttrName ]=getValue;
}});
return selected;
},
swatchesOptions:(getForm, getFormData)=> {
const getTdAvoidCurrent=getForm
.find('td')
.not('.disable-to-select');
const getAllSelect=getTdAvoidCurrent.find('.cfvsw-swatches-container[swatches-attr]'
);
if(! getAllSelect.length){
return;
}
const getSelectedOptions=SW.getSelectedOptions(getForm);
const findToRemoveClass=getTdAvoidCurrent.find(`.${ addRemoveDisableClass }`
);
if(findToRemoveClass.length){
findToRemoveClass.removeClass(addRemoveDisableClassCommon);
}
getAllSelect.each(function (){
const select=$(this);
const getAttrName=select.attr('swatches-attr');
if(''!==getAttrName){
const findOptions=select.find('.cfvsw-swatches-option');
findOptions.each(function (){
const optValue=$(this);
const currentTermSlug=optValue.attr('data-slug');
if(currentTermSlug&&''!==currentTermSlug){
const hasStock=SW.checkOptionAvail(getAttrName,
currentTermSlug,
getSelectedOptions,
getFormData
);
if(! hasStock){
optValue.addClass(addRemoveDisableClassCommon
);
}}
});
}});
},
checkOptionAvail: (
getAttrName,
currentTermSlug,
getSelectedOptions,
getFormData
)=> {
let hasThisSwatch;
for(let index=0; index < getFormData.length; index++){
const productVariations=getFormData[ index ];
const { attributes, is_in_stock }=productVariations;
const passedInRaw=SW.checkInPreRawData(getSelectedOptions,
attributes,
getAttrName,
currentTermSlug,
is_in_stock
);
if(passedInRaw){
hasThisSwatch=is_in_stock;
break;
}}
return hasThisSwatch;
},
checkInPreRawData: (
getSelectedOptions,
attributes,
getAttrName,
currentTermSlug,
is_in_stock
)=> {
let hasThisSwatch=false;
const copySelected={ ...getSelectedOptions };
const selectedKeys=Object.keys(getSelectedOptions);
const getCurrentIndex=selectedKeys.indexOf(getAttrName);
const currentObj={};
currentObj[ getAttrName ]=currentTermSlug;
if(getCurrentIndex >=0){
selectedKeys.splice(getCurrentIndex, 1);
delete copySelected[ getAttrName ];
}
hasThisSwatch=SW.checkInRawData(attributes,
copySelected,
currentObj,
is_in_stock
);
return hasThisSwatch;
},
checkInRawData:(attribute, selected, currentObj, is_in_stock)=> {
const cloneAttr={ ...attribute };
const selectedCurrent={ ...selected, ...currentObj };
let checkAndAvail=true;
for(const checkIsAvail in selectedCurrent){
const value=selectedCurrent[ checkIsAvail ];
const attrValue=attribute[ checkIsAvail ];
if(''===attrValue){
delete cloneAttr[ checkIsAvail ];
continue;
}
if(value===attrValue){
delete cloneAttr[ checkIsAvail ];
continue;
}
checkAndAvail=false;
}
if(is_in_stock){
return checkAndAvail;
}
for(const cloneKey in cloneAttr){
const cloneValue=cloneAttr[ cloneKey ];
if(''!==cloneValue){
checkAndAvail=false;
}}
return checkAndAvail;
},
Events: ()=> {
$(document).on('click',
'.cfvsw-swatches-container .cfvsw-swatches-option[data-slug]',
SW.chooseOption
);
$(document).on('berocket_ajax_products_infinite_loaded',
function (){
SW.firstTime();
}
);
},
};
$(document).on('click', '.cfvsw-swatches-option', function (){
const swatchesOption=$(this);
if(swatchesOption.hasClass('cfvsw-swatches-disabled') ||
swatchesOption.hasClass('cfvsw-swatches-out-of-stock')
){
return;
}
onClickSwatchesOption(swatchesOption);
addVariationFunctionality();
});
$('body').on('click',
'.cfvsw_ajax_add_to_cart.cfvsw_variation_found',
function(e){
e.preventDefault();
triggerAddToCart($(this) );
}
);
function onClickSwatchesOption(swatch){
if(swatch.hasClass('cfvsw-selected-swatch') ){
swatch.removeClass('cfvsw-selected-swatch');
resetPrice(swatch);
resetThumbnail(swatch);
resetButtonData(swatch);
}else{
const parent=swatch.parent();
parent.find('.cfvsw-swatches-option').each(function (){
$(this).removeClass('cfvsw-selected-swatch');
});
swatch.addClass('cfvsw-selected-swatch');
}
updateSelectOption(swatch);
if(cfvsw_swatches_settings.html_design!=='inline'){
updateTitle(swatch);
}}
function updateSelectOption(swatch){
const value=swatch.hasClass('cfvsw-selected-swatch')
? swatch.data('slug')
: '';
const select=swatch
.closest('.cfvsw-swatches-container')
.prev()
.find('select');
select.val(value).change();
}
function updateTitle(swatch){
const label=swatch.closest('tr').children('.label');
label.find('.cfvsw-selected-label').remove();
if(! swatch.hasClass('cfvsw-selected-swatch') ){
return;
}
label
.children('label')
.append('<span class="cfvsw-selected-label"></span>');
label
.children('label')
.children('.cfvsw-selected-label')
.html(swatch.data('title') );
}
function triggerAddToCart(variant){
if(variant.is('.wc-variation-is-unavailable') ){
return window.alert(cfvsw_swatches_settings.unavailable_text);
}
const productId=variant.data('product_id');
let variationId=variant.attr('data-variation_id');
variationId=parseInt(variationId);
if(isNaN(productId) ||
productId===0 ||
isNaN(variationId) ||
variationId===0
){
return true;
}
let variation=variant.attr('data-selected_variant');
variation=JSON.parse(variation);
const data={
action: 'cfvsw_ajax_add_to_cart',
security: cfvsw_swatches_settings.ajax_add_to_cart_nonce,
product_id: productId,
variation_id: variationId,
variation,
};
$(document.body).trigger('adding_to_cart', [ variant, data ]);
variant.removeClass('added').addClass('loading');
$.ajax({
type: 'POST',
url: cfvsw_swatches_settings.ajax_url,
data,
dataType: 'json',
success(response){
if(! response){
return;
}
if(response.error&&response.product_url){
window.location=response.product_url;
return;
}
$(document.body).trigger('added_to_cart', [
response.fragments,
response.cart_hash,
variant,
]);
$(document.body).trigger('update_checkout');
variant.removeClass('loading').addClass('added');
},
error(errorThrown){
variant.removeClass('loading');
console.log(errorThrown);
},
});
}
$(document).on('change', '.cfvsw-hidden-select select', function (){
setTimeout(()=> {
updateSwatchesAvailability();
}, 1);
});
$('.reset_variations').on('click', function (){
resetSwatches($(this) );
});
$(document).on({
mouseenter(){
const addToTooltip=$(this);
const tooltip=addToTooltip.data('tooltip');
if(''===tooltip ||
'undefined'===typeof tooltip ||
addToTooltip.hasClass('cfvsw-label-option')
){
return;
}
if(addToTooltip.children('.cfvsw-tooltip').length===0){
addToTooltip.prepend(`<div class="cfvsw-tooltip"><span class="cfvsw-tooltip-label">${ tooltip }</span></div>`
);
$('.cfvsw-tooltip').fadeIn(500);
const swatchHeight=addToTooltip
.children('.cfvsw-swatch-inner')
.innerHeight();
$('.cfvsw-tooltip').css({
bottom: swatchHeight,
});
if(cfvsw_swatches_settings.tooltip_image &&
addToTooltip.hasClass('cfvsw-image-option')
){
$('.cfvsw-tooltip').prepend("<span class='cfvsw-tooltip-preview'></span>"
);
const preview=addToTooltip
.children('.cfvsw-swatch-inner')
.css('backgroundImage');
$('.cfvsw-tooltip').css({
bottom: swatchHeight - 30,
padding: '2px',
});
$('.cfvsw-tooltip-preview').css({
backgroundImage: preview,
backgroundSize: 'cover',
});
}}
},
mouseleave(){
$('.cfvsw-tooltip').remove();
},
},
'.cfvsw-swatches-option'
);
$(document).on('ready', function (){
setTimeout(()=> {
setSwatchesSelection();
}, 1);
$('.woocommerce-widget-layered-nav-list').each(function (){
if($(this).find('.cfvsw-swatches-container').length){
$(this).addClass('cfvsw-filters');
}});
});
$('.cfvsw-shop-variations').on('click', function(e){
e.preventDefault();
});
$('.cfvsw-shop-variations .cfvsw-more-link').on('click', function(e){
window.location=e.target.href;
});
function updateSwatchesAvailability(){
$('.cfvsw-hidden-select select').each(function (){
const availableOptions=[];
$(this)
.children('option')
.each(function (){
if(''!==$(this).val()){
availableOptions.push($(this).val());
}});
$(this)
.parent()
.next()
.find('.cfvsw-swatches-option')
.each(function (){
if(-1===$.inArray($(this).attr('data-slug'),
availableOptions
)
){
$(this).addClass(addRemoveWithCommonClass);
}else{
$(this).removeClass(addRemoveWithCommonClass);
}});
});
}
function setSwatchesSelection(){
$('.cfvsw-hidden-select select').each(function (){
const selected=$(this).val();
$(this)
.parent()
.next()
.find(`[data-slug='${ selected }']`)
.trigger('click');
});
}
function resetSwatches(resetButton){
$('.cfvsw-swatches-option').each(function (){
$(this).removeClass('cfvsw-selected-swatch');
});
$('.cfvsw-selected-label').remove();
if(cfvsw_swatches_settings.disable_out_of_stock){
const table=resetButton.closest('table');
const findDisabledAttr=table.find(`.${ addRemoveDisableClass }`
);
const findDisableSelect=table.find('.disable-to-select');
if(findDisableSelect.length){
findDisableSelect.removeClass('disable-to-select');
}
if(findDisabledAttr){
findDisabledAttr.removeClass(addRemoveDisableClassCommon);
}
setTimeout(()=> {
SW.firstTime();
}, 20);
}}
function addVariationFunctionality(){
$('.cfvsw_variations_form:not(.variation-function-added)').each(function (){
const thisForm=$(this);
thisForm.addClass('variation-function-added');
thisForm.wc_variation_form();
thisForm.on('found_variation', function(e, variation){
updateThumbnail(thisForm, variation.image);
if(thisForm.attr('data-cfvsw-catalog') ){
return;
}
updatePrice(thisForm, variation);
updatebuttonData(thisForm, variation);
});
}
);
}
$(window).on('load', function (){
addVariationFunctionality();
});
function updateThumbnail(swatch, imageData){
const listItem=swatch.closest('li');
const thumbnail=listItem.find('img:first');
if(0===listItem.find('.cfvsw-original-thumbnail').length){
const originalThumbnail=thumbnail.clone();
thumbnail.after('<span class="cfvsw-original-thumbnail"></span>');
listItem
.find('.cfvsw-original-thumbnail')
.html(originalThumbnail);
}
thumbnail.attr('src', imageData.thumb_src);
thumbnail.attr('srcset', '');
}
function resetThumbnail(swatch){
const listItem=swatch.closest('li');
if(listItem.find('.cfvsw-original-thumbnail').length){
const thumbnail=listItem.find('img:first');
thumbnail.replaceWith(listItem.find('.cfvsw-original-thumbnail').html()
);
listItem.find('.cfvsw-original-thumbnail').remove();
}}
function updatePrice(swatch, variation){
if(0===variation.price_html.length){
return;
}
if(swatch.parents('li').find('.cfvsw-original-price').length){
const price=swatch.parents('li').find('.price');
price.replaceWith(variation.price_html);
}else{
const price=swatch.parents('li').find('.price');
price.after(variation.price_html);
price.removeClass('price').addClass('cfvsw-original-price');
}}
function resetPrice(swatch){
if(swatch.parents('li').find('.cfvsw-original-price').length){
swatch.parents('li').find('.price').remove();
swatch
.parents('li')
.find('.cfvsw-original-price')
.removeClass('cfvsw-original-price')
.addClass('price');
}}
function updatebuttonData(variant, variation){
const select=variant.find('.variations select');
const data={};
const button=variant
.parents('li')
.find('.cfvsw_ajax_add_to_cart');
select.each(function (){
const attributeName =
$(this).data('attribute_name')||$(this).attr('name');
const value=$(this).val()||'';
data[ attributeName ]=value;
});
button.html(button.data('add_to_cart_text') );
button.addClass('cfvsw_variation_found');
button.attr('data-variation_id', variation.variation_id);
button.attr('data-selected_variant', JSON.stringify(data) );
}
function resetButtonData(variant){
const button=variant
.parents('li')
.find('.cfvsw_ajax_add_to_cart');
button.html(button.data('select_options_text') );
button.removeClass('cfvsw_variation_found');
button.attr('data-variation_id', '');
button.attr('data-selected_variant', '');
}
SW.init();
document.addEventListener('astraInfinitePaginationLoaded', function (){
SW.firstTime();
addVariationFunctionality();
});
document.addEventListener('cfvswVariationLoad', function (){
SW.firstTime();
addVariationFunctionality();
});
})(jQuery);