(function( $ ) { 'use strict'; // Create the defaults once var pluginName = "compareProducts", defaults = { // Add to Compare addToCompareLink : '.add-to-compare-button', removeFromCompareLink : '.remove-from-compare-button', // Compare Bar openCloseBarLink : $('#woocommerce-compare-bar-open-close'), openCloseBarIcon : $('#woocommerce-compare-bar-open-close i'), openCloseBarContainer : $('#woocommerce-compare-bar-open-close-container'), compareBar : $('#woocommerce-compare-bar'), compareBarItems : $('#woocommerce-compare-bar-items'), compareBarClear : $('#woocommerce-compare-bar-action-clear'), compareBarRemoveLink : '.woocommerce-compare-bar-item-remove', // Compare Sidebar compareSidebar : $('#woocommerce-compare-sidebar'), compareSidebarItems : $('#woocommerce-compare-sidebar-items'), compareSidebarClear : $('#woocommerce-compare-sidebar-action-clear'), compareSidebarRemoveLink : '.woocommerce-compare-sidebar-item-remove', // Actions clearAllLink : $('.clear-all-compared-products'), // Compare Table compareTable : $('#woocommerce-compare-table'), compareTableOpenLink : $('.woocommerce-compare-table-action-compare'), compareTableContainer : $('#woocommerce-compare-table-container'), compareTableCloseLink : $('#woocommerce-compare-table-close'), compareTableHideSimilaritiesCheckbox : $('.woocommerce-compare-table-hide-similarities'), compareTableHighlightDifferencesCheckbox : $('.woocommerce-compare-table-highlight-differences'), compareAutocompleteInput : $('.woocommerce-compare-autocomplete-field'), compareAutocompleteIcon : $('.woocommerce-compare-autocomplete').find('.fa'), compareAutocompleteMessage : $('.woocommerce-compare-autocomplete-message'), }; // The actual plugin constructor function Plugin ( element, options ) { this.element = element; this.settings = $.extend( {}, defaults, options ); this._defaults = defaults; this.trans = this.settings.trans; this._name = pluginName; this.init(); } // Avoid Plugin.prototype conflicts $.extend( Plugin.prototype, { init: function() { this.window = $(window); this.currentURL = window.location.href; this.documentHeight = $( document ).height(); this.windowHeight = this.window.height(); this.products = {}; var singleCompareValues = {}; $('.single-product-compare-value').each(function() { var compareValue = '.' + ($(this).attr('class').slice(34)); singleCompareValues[compareValue] = compareValue; }); this.singleCompareValues = singleCompareValues; this.compareBarOpenClose(); this.compareBarAdd(); this.compareBarRemove(); this.compareTableOpen(); this.compareTableClose(); this.compareTableHighlightDifferences(); this.compareTableHideSimilarities(); this.loadSaved(); this.clearAll(); this.singleProductSlider(); this.singleCompareTableSlider(); this.singleCompareTableHighlightDifferences(); this.singleCompareTableHideSimilarities(); this.compareBarAutocomplete(); this.alignCompareTableRowHeight(); }, loadSaved: function() { var that = this; var savedProducts = that.readCookie('compare_products_products'); var urlProducts = that.getParameterByName('compare'); if(!that.isEmpty(savedProducts)) { that.products = savedProducts; $.each(savedProducts, function(i, index) { that.getSingleProduct(i, true); }); $.each($(that.settings.addToCompareLink), function(i, index) { var $this = $(this); var product_id = $(index).data('product-id'); if(typeof(that.products[product_id]) != "undefined") { $this.removeClass('add-to-compare-button').addClass('remove-from-compare-button').html(that.trans.remove); } }); } else if(!that.isEmpty(urlProducts)) { var jsonStrig = '{'; var items = urlProducts.split(','); for (var i = 0; i < items.length; i++) { jsonStrig += '"' + items[i] + '":"' + items[i] + '",'; } jsonStrig = jsonStrig.substr(0, jsonStrig.length - 1); jsonStrig += '}'; that.products = JSON.parse(jsonStrig); $.each(that.products, function(i, index) { that.getSingleProduct(i); }); $.each($(that.settings.addToCompareLink), function(i, index) { var $this = $(this); var product_id = $(index).data('product-id'); if(typeof(that.products[product_id]) != "undefined") { $this.removeClass('add-to-compare-button').addClass('remove-from-compare-button').html(that.trans.remove); } }); } }, compareBarAdd : function() { var that = this; var product_id; $(document).on('click', that.settings.addToCompareLink, function(e) { e.preventDefault(); var $this = $(this); $this.html('') product_id = $this.data('product-id'); if(product_id == "") { $this.html(that.trans.add); return; } if(typeof(that.products[product_id]) != 'undefined') { $this.html(that.trans.add); return; } // if(that.isEmpty(that.products)) { // that.compareBarClose(); // } that.getSingleProduct(product_id); }); }, compareBarRemove : function() { var that = this; $('.woocommerce-compare-bar-items').on('click', that.settings.compareBarRemoveLink, function(e) { e.preventDefault(); var $this = $(this); var product_id = $this.data('product-id'); $(document).find('.remove-from-compare-button[data-product-id="' + product_id + '"]').removeClass('remove-from-compare-button').addClass('add-to-compare-button').html(that.trans.add); that.removeProduct(product_id); }); $('.woocommerce-compare-sidebar-items').on('click', that.settings.compareSidebarRemoveLink, function(e) { e.preventDefault(); var $this = $(this); var product_id = $this.data('product-id'); $(document).find('.remove-from-compare-button[data-product-id="' + product_id + '"]').removeClass('remove-from-compare-button').addClass('add-to-compare-button').html(that.trans.add); that.removeProduct(product_id); }); $(document).on('click', that.settings.removeFromCompareLink, function(e) { e.preventDefault(); var $this = $(this); var product_id = $this.data('product-id'); $(document).find('.remove-from-compare-button[data-product-id="' + product_id + '"]').removeClass('remove-from-compare-button').addClass('add-to-compare-button').html(that.trans.add); that.removeProduct(product_id); }); }, removeProduct : function(product_id) { var that = this; var barContainer = $('.woocommerce-compare-bar-items').find('.woocommerce-compare-bar-item-container[data-product-id="' + product_id + '"]'); barContainer.addClass('woocommerce-compare-bar-item-placeholder').removeData('data-product-id'); barContainer.find('.woocommerce-compare-bar-item').html(''); var sidebarContainer = $('.woocommerce-compare-sidebar-items').find('.woocommerce-compare-sidebar-item-container[data-product-id="' + product_id + '"]'); sidebarContainer.addClass('woocommerce-compare-sidebar-item-placeholder').removeData('data-product-id'); sidebarContainer.find('.woocommerce-compare-sidebar-item').html(''); delete that.products[product_id]; if (window.history.replaceState) { that.buildReplaceState(); } that.saveCookie('compare_products_products', that.products, 30); }, getSingleProduct: function(product_id, isSaved) { var that = this; if(isSaved === undefined) { isSaved = false; } that.products[product_id] = product_id; if (window.history.replaceState) { that.buildReplaceState(); } if(that.getObjectSize(that.products) > that.settings.maxProducts) { delete that.products[product_id]; $('.add-to-compare-button[data-product-id="' + product_id + '"]').html(that.trans.add) alert(that.trans.max); return; } that.saveCookie('compare_products_products', that.products, 30); jQuery.ajax({ url: that.settings.ajax_url, type: 'post', dataType: 'JSON', data: { action: 'compare_products_get_single', product: product_id }, success : function( response ) { if(that.settings.compareBar.length > 0) { that.addProductToBar(response, isSaved); } if(that.settings.compareSidebar.length > 0) { that.addProductToSidebar(response); } $('.add-to-compare-button[data-product-id="' + product_id + '"]').removeClass('add-to-compare-button').addClass('remove-from-compare-button').html(that.trans.remove); }, error: function(jqXHR, textStatus, errorThrown) { that.removeProduct(product_id); console.log('An Error Occured: ' + jqXHR.status + ' ' + errorThrown + '! Please contact System Administrator!'); } }); }, addProductToBar : function(product, isSaved) { var that = this; var emptyBarItemContainers = $('.woocommerce-compare-bar-item-placeholder') var product_id = product['ID']; if(isSaved === undefined) { isSaved = false; } if(emptyBarItemContainers.length > 0) { var emptyBarItemContainer = $(emptyBarItemContainers[0]); emptyBarItemContainer.attr('data-product-id', product_id); emptyBarItemContainer.removeClass('woocommerce-compare-bar-item-placeholder'); var html = ''; html += '
' + product.title + '
'; emptyBarItemContainer.find('.woocommerce-compare-bar-item').html(html); if(that.getObjectSize(that.products) >= 2 && !isSaved) { that.compareBarOpen(); } } }, addProductToSidebar : function(product) { var that = this; var emptySidebarItemContainers = $('.woocommerce-compare-sidebar-item-placeholder') var compareBarExists = that.settings.compareBar; var product_id = product['ID']; if(emptySidebarItemContainers.length > 0) { var emptySidebarItemContainer = $(emptySidebarItemContainers[0]); emptySidebarItemContainer.attr('data-product-id', product_id); emptySidebarItemContainer.removeClass('woocommerce-compare-sidebar-item-placeholder'); var html = '
'; html += ''; html += '
'; html += '
' + product.title + '
'; html += '
'; emptySidebarItemContainer.find('.woocommerce-compare-sidebar-item').html(html); } }, compareBarOpenClose: function() { var that = this; that.settings.openCloseBarLink.on('click', function(e) { e.preventDefault(); if(that.settings.compareBarItems.is(':visible')) { that.compareBarClose(); } else { that.compareBarOpen(); } }); }, compareBarOpen: function() { this.settings.compareBarItems.slideDown(1000); this.settings.openCloseBarIcon.removeClass('fa-angle-double-up').addClass('fa-angle-double-down'); }, compareBarClose: function() { this.settings.compareBarItems.slideUp(1000); this.settings.openCloseBarIcon.removeClass('fa-angle-double-down').addClass('fa-angle-double-up'); }, compareTableOpen : function() { var that = this; that.settings.compareTableOpenLink.on('click', function(e) { if (!(/#/.test(this.href))) { return; } e.preventDefault(); if(that.isEmpty(that.products)) { return; } that.compareBarClose(); jQuery.ajax({ url: that.settings.ajax_url, type: 'post', dataType: 'JSON', data: { action: 'compare_products_get_all', products: that.products }, success : function( response ) { that.settings.compareTableContainer.slideDown(1000); if(that.isEmpty(response)) { return; } that.renderCompareTable(response); }, error: function(jqXHR, textStatus, errorThrown) { console.log('An Error Occured: ' + jqXHR.status + ' ' + errorThrown + '! Please contact System Administrator!'); } }); }); }, renderCompareTable : function (data) { var that = this; var html = ""; var compareTable = that.settings.compareTable; var maxCols = 12; var attributeNameCols = 2; var productsCount = that.getObjectSize(that.products); maxCols = maxCols - attributeNameCols; var singleColXS = Math.floor(12 / productsCount); var singleCol = Math.floor(maxCols / productsCount); var tableCompareValues = {}; compareTable.html(); $.each(data, function(i, products) { var compareValue = '.compare-table-row-attribute-value-' + i; tableCompareValues[compareValue] = compareValue; html += '
'; html += '
' + that.trans[i] + '
'; $.each(products, function(product_id, product_data) { // if(i == "im") { // product_data = ''; // } html += '
' + product_data + '
'; }); html += '
'; html += '
'; }); that.tableCompareValues = tableCompareValues; compareTable.html(html); $('.compare-table-row-attribute-value').each(function() { var compareValue = '.' + ($(this).attr('class').slice(43)); }); }, compareTableClose : function () { var that = this; that.settings.compareTableCloseLink.on('click', function(e) { e.preventDefault(); that.settings.compareTableContainer.slideUp(1000); // that.compareBarOpen(); }); }, clearAll : function () { var that = this; that.settings.clearAllLink.on('click', function(e) { e.preventDefault(); $.each(that.products, function(i, product_id) { $('.remove-from-compare-button[data-product-id="' + product_id + '"]').removeClass('remove-from-compare-button').addClass('add-to-compare-button').html(that.trans.add); var barContainer = $('.woocommerce-compare-bar-items').find('.woocommerce-compare-bar-item-container[data-product-id="' + product_id + '"]'); barContainer.addClass('woocommerce-compare-bar-item-placeholder').removeData('data-product-id'); barContainer.find('.woocommerce-compare-bar-item').html(''); var sidebarContainer = $('.woocommerce-compare-sidebar-items').find('.woocommerce-compare-sidebar-item-container[data-product-id="' + product_id + '"]'); sidebarContainer.addClass('woocommerce-compare-sidebar-item-placeholder').removeData('data-product-id'); sidebarContainer.find('.woocommerce-compare-sidebar-item').html(''); }); that.compareBarClose(); that.products = {}; that.deleteCookie('compare_products_products') var savedProducts = that.readCookie('compare_products_products'); that.buildReplaceState(); }); }, compareBarAutocomplete : function() { var that = this; if(that.settings.compareAutocompleteInput.length < 1) { return false; } that.settings.compareAutocompleteInput.on('keypress', function (e) { if (e.which != 13) { return true; } var $this = $(this); var skuOrProduct = $this.val(); if(skuOrProduct == "") { return false; } that.settings.compareAutocompleteIcon.removeClass('fa-eye').addClass('fa-spin fa-circle-o-notch'); jQuery.ajax({ url: that.settings.ajax_url, type: 'post', dataType: 'json', data: { action: 'compare_check_product', skuOrProduct: skuOrProduct }, success : function( response ) { that.settings.compareAutocompleteMessage.text(response.message); that.settings.compareAutocompleteIcon.removeClass('fa-spin fa-circle-o-notch').addClass('fa-eye'); if(response.product != "") { $this.val(''); if(typeof(that.products[response.product]) != 'undefined') { that.settings.compareAutocompleteMessage.text('Already on Compare List'); return; } that.getSingleProduct(response.product); } }, error: function(jqXHR, textStatus, errorThrown) { console.log('An Error Occured: ' + jqXHR.status + ' ' + errorThrown + '! Please contact System Administrator!'); } }); return false; }); }, compareTableHighlightDifferences : function() { var that = this; that.settings.compareTableHighlightDifferencesCheckbox.on('change', function(e) { var $this = $(this); if($this.is(':not(:checked)')) { $.each(that.tableCompareValues, function(i, index) { $(index).removeClass('compare-table-highlight'); }); return; } $.each(that.tableCompareValues, function(i, index){ var values = []; var columns = $(index); $.each(columns, function(){ values.push($(this).text()); }); if(values.length > 0) { var allSame = !!values.reduce(function(a, b){ return (a === b) ? a : NaN; }); if(allSame == false){ columns.addClass('compare-table-highlight'); } } }); }); }, compareTableHideSimilarities : function() { var that = this; that.settings.compareTableHideSimilaritiesCheckbox.on('change', function(e) { var $this = $(this); if($this.is(':not(:checked)')) { $.each(that.tableCompareValues, function(i, index) { var row = index.replace('value', 'name'); $(row).removeClass('compare-table-hidden'); $(index).removeClass('compare-table-hidden'); }); return; } $.each(that.tableCompareValues, function(i, index){ var values = []; var columns = $this.parent().parent().find(index); if(i == ".compare-table-row-attribute-value-rm" || i.substr(0, 40) == ".compare-table-row-attribute-value-group") { return; } $.each(columns, function(){ values.push($(this).text()); }); if(values.length > 0) { var allSame = !!values.reduce(function(a, b){ return (a === b) ? a : NaN; }); if(allSame == true){ var row = index.replace('value', 'name'); $(row).addClass('compare-table-hidden'); columns.addClass('compare-table-hidden'); } } }); }); }, singleCompareTableHideSimilarities : function() { var that = this; that.settings.compareTableHideSimilaritiesCheckbox.on('change', function(e) { var $this = $(this); if($this.is(':not(:checked)')) { $.each(that.singleCompareValues, function(i, index) { $(index).removeClass('compare-table-hidden'); }); return; } $.each(that.singleCompareValues, function(i, index){ var values = []; var columns = $this.parent().parent().find(index); $.each(columns, function(){ values.push($(this).text()); }); if(values.length > 0) { var allSame = !!values.reduce(function(a, b){ return (a === b) ? a : NaN; }); if(allSame == true){ columns.addClass('compare-table-hidden'); } } }); }); }, singleCompareTableHighlightDifferences : function() { var that = this; that.settings.compareTableHighlightDifferencesCheckbox.on('change', function(e) { var $this = $(this); if($this.is(':not(:checked)')) { $.each(that.singleCompareValues, function(i, index) { $(index).removeClass('compare-table-highlight'); }); return; } $.each(that.singleCompareValues, function(i, index){ var values = []; var columns = $(index); $.each(columns, function(){ values.push($(this).text()); }); if(values.length > 0) { var allSame = !!values.reduce(function(a, b){ return (a === b) ? a : NaN; }); if(allSame == false){ columns.addClass('compare-table-highlight'); } } }); }); }, singleProductSlider : function() { var sliderExists = $('.single-product-compare-products-slick'); if(sliderExists.length > 0) { sliderExists.not('.slick-initialized').slick(); } }, singleCompareTableSlider : function() { var sliderExists = $('.woocommerce-single-compare-table-slick'); if(sliderExists.length > 0) { sliderExists.not('.slick-initialized').slick(); } }, alignCompareTableRowHeight : function() { // var classes = {}; // var compareValues = $('.single-product-compare-value'); // $(compareValues).each(function() { // var classs = '.' + ($(this).attr('class').slice(34)); // classes[classs] = classs; // }); $.each(this.singleCompareValues, function(i, index) { $(this).matchHeight({byRow: false}); }); }, buildReplaceState : function() { var that = this; var products = that.products; that.currentURL = that.removeURLParameter(that.currentURL, 'compare'); var queryCheck = that.currentURL.split('?'); if (queryCheck.length > 1 && queryCheck[1] !== '') { var url = that.currentURL + '&'; } else if(queryCheck.length > 1 && queryCheck[1] == '') { var url = that.currentURL; } else { var url = that.currentURL + '?'; } if(!that.isEmpty(products)) { url += 'compare=' + Object.keys(products).map(function(k){return products[k]}).join(",");; } window.history.replaceState('woo_better_compare', 'WooCommerce Better Compare', url); }, getParameterByName : function (name, url) { if (!url) url = window.location.href; name = name.replace(/[\[\]]/g, "\\$&"); var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(url); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\+/g, " ")); }, removeURLParameter : function (url, parameter) { //prefer to use l.search if you have a location/link object var urlparts= url.split('?'); if (urlparts.length>=2) { var prefix= encodeURIComponent(parameter)+'='; var pars= urlparts[1].split(/[&;]/g); //reverse iteration as may be destructive for (var i= pars.length; i-- > 0;) { //idiom for string.startsWith if (pars[i].lastIndexOf(prefix, 0) !== -1) { pars.splice(i, 1); } } url= urlparts[0]+'?'+pars.join('&'); return url; } else { return url; } }, ////////////////////// ///Helper Functions/// ////////////////////// isEmpty: function(obj) { if (obj == null) return true; if (obj.length > 0) return false; if (obj.length === 0) return true; for (var key in obj) { if (hasOwnProperty.call(obj, key)) return false; } return true; }, saveCookie: function(name, value, days) { var expires = ""; if (days) { var date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toGMTString(); } var cookie = name + '=' + JSON.stringify(value) + expires + '; path=/;'; document.cookie = cookie; }, readCookie: function(name) { var result = document.cookie.match(new RegExp(name + '=([^;]+)')); result && (result = JSON.parse(result[1])); return result; }, deleteCookie: function(name) { document.cookie = [name, '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/;'].join(''); }, getObjectSize : function(obj) { var size = 0, key; for (key in obj) { if (obj.hasOwnProperty(key)) size++; } return size; }, } ); // Constructor wrapper $.fn[ pluginName ] = function( options ) { return this.each( function() { if ( !$.data( this, "plugin_" + pluginName ) ) { $.data( this, "plugin_" + pluginName, new Plugin( this, options ) ); } } ); }; $.fn.emulateTransitionEnd = function (duration) { var called = false var $el = this $(this).one('bsTransitionEnd', function () { called = true }) var callback = function () { if (!called) $($el).trigger($.support.transition.end) } setTimeout(callback, duration) return this } $(document).ready(function() { $( "body" ).compareProducts( woocommerce_better_compare_options ); } ); })( jQuery );