boldsupport
5/13/2016 - 1:27 PM

bold-compare.js

/* <script> // */
// Updated 2016-06-23

var BOLD = BOLD || {};
BOLD.Compare = BOLD.Compare || {};
BOLD.Compare.Widget = BOLD.Compare.Widget || {

    products: {},
    element: '<div class="bold-compare-widget" style="display:none;">\
                <div class="error"></div>\
                <div class="bold-title"><span class="title">Compare</span><span class="number"></span></div>\
                <div class="bold-compared-products"></div>\
                <div class="bold-compare-button-row"><button class="compare_btn">Compare Now</button></div>\
              </div>',
    cookie: {
        handles: '',
        ids: '',
        widget_status:false //true for hidden and false for not hidden
    },
    isHorizontalWidget: false,
    language: {},
    display: {},
    specsExist:false,

    /**
     * BOLD.Compare.Widget.init
     *
     * initialize the collection page compare feature
     *
     */
    init: function(domisready){

        if(typeof domisready == 'undefined') {
            domisready = false;
        }

        BOLD.Compare.Widget.element = BOLD.jQuery(BOLD.Compare.Widget.element);

        BOLD.Compare.Widget.specsExist();
        BOLD.Compare.Widget.initLanguage();

        if(domisready) {
            BOLD.Compare.Widget.initAfterDomReady();
        } else {
            BOLD.jQuery(function(){
                BOLD.Compare.Widget.initAfterDomReady();
            });
        }

    },

    /**
     * BOLD.Compare.Widget.initAfterDomReady
     *
     * Initialization that needs to occur only after the DOM is ready
     *
     */
    initAfterDomReady: function(){
        BOLD.Compare.Widget.initDisplay();
        BOLD.Compare.Widget.loadCookies();

        if(BOLD.jQuery('.bold_compare_checkbox,.bold_compare_button').length > 0) {
            // only show widget on a page with a compare trigger (checkbox or button)
            BOLD.Compare.Widget.initWidget();
        }

        if(BOLD.jQuery('.bold_compare_table').length > 0) { // on compare page
            // "Remove" button on Product Compare page
            BOLD.jQuery('.bold_compare_remove').on('click',function(event){
                event.preventDefault();
                var id = BOLD.jQuery(this).attr('data-product-id');
                BOLD.Compare.Widget.removeAndUpdate(id,function(){
                    window.location.reload();
                });
            });
        }

        BOLD.Compare.Widget.addCheckboxes();
        BOLD.Compare.Widget.addCompareButton();
    },

    /**
     * BOLD.Compare.Widget.specsExist
     *
     * check if specs exist for product
     *
     */
    specsExist: function(){
        if(BOLD.Compare.specs_size > 0){
            BOLD.Compare.Widget.specsExist = true;
        }
    },
    /**
     * BOLD.Compare.Widget.initWidget
     *
     * add the compare widget to the DOM and bind events
     *
     */
    initWidget: function(id){

        BOLD.Compare.Widget.isHorizontalWidget = BOLD.Compare.Widget.element.hasClass('bold-compare-horizontalwidget');
        BOLD.Compare.Widget.element.appendTo('body');
        BOLD.jQuery('div.bold-compare-widget').each(function(){
            BOLD.jQuery(this).find('div.bold-title').find('span.title').text(BOLD.Compare.language.widget_title);
            BOLD.jQuery(this).find('button.compare_btn').text(BOLD.Compare.language.widget_button);
            BOLD.Compare.Widget.updateTitleNumber();
        });

        BOLD.Compare.Widget.initWidgetDisplay();

        // bind event for compare button
        BOLD.jQuery('.compare_btn').on('click', BOLD.Compare.Widget.runCompare);

        // widget collapsing
        BOLD.jQuery('.bold-title').on('click',function(){
            var widget = BOLD.jQuery('.bold-compare-widget');
            if(widget.hasClass('bold-compare-collapsed')) {
                widget.removeClass('bold-compare-collapsed');
                BOLD.jQuery('.bold-compared-products, .bold-compare-button-row').slideDown(400,function(){
                    widget.css('width', 'auto');
                });
                BOLD.Compare.Widget.cookie.widget_status = false;
                BOLD.Compare.Widget.updateCookies();
            } else {
                widget.css('width', widget.width() + 'px');
                BOLD.jQuery('.bold-compared-products, .bold-compare-button-row').slideUp(400,function(){
                    widget.addClass('bold-compare-collapsed');
                });
                BOLD.Compare.Widget.cookie.widget_status = true;
                BOLD.Compare.Widget.updateCookies();
            }
            BOLD.jQuery('.bold-compare-widget .error').hide().text('');
        });

    },

    /**
     */
    updateTitleNumber:function(){
        var product_count = (Object.keys(BOLD.Compare.Widget.products).length > 0)?" ("+Object.keys(BOLD.Compare.Widget.products).length+")":"";
        BOLD.jQuery(BOLD.Compare.Widget.element).find('div.bold-title').find('span.number').text(product_count);
    },

    /**
     * BOLD.Compare.Widget.initWidgetDisplay
     *
     * initialize widget display
     *
     */
    initWidgetDisplay:function(){
        var widget = BOLD.jQuery('.bold-compare-widget');
        if(BOLD.Compare.Widget.cookie.widget_status == "true"){
            widget.css('width', widget.width() + 'px');
            BOLD.jQuery('.bold-compared-products, .bold-compare-button-row').slideUp(400,function(){
                widget.addClass('bold-compare-collapsed');
            });
        }else{
            widget.removeClass('bold-compare-collapsed');
            BOLD.jQuery('.bold-compared-products, .bold-compare-button-row').slideDown(400,function(){
                widget.css('width', 'auto');
            });
        }
    },

    /**
     * BOLD.Compare.Widget.initLanguage
     *
     * add language
     *
     */
    initLanguage: function(){
        if(typeof BOLD.Compare.language == 'string') {
            var bold_language_metafield = JSON.parse(BOLD.Compare.language);
            BOLD.Compare.language = {};
            if(bold_language_metafield != null) {
                for (i in bold_language_metafield) {
                    for (key in bold_language_metafield[i]) {
                        BOLD.Compare.language[key] = bold_language_metafield[i][key];
                    }
                }
            } else {
                BOLD.Compare.language = {"collection_checkbox":"Compare","compare_button":"Buy","compare_max_product_alert":"You have reached the maximum number of products that can be compared at one time.","compare_remove_text":"Remove","compare_title":"Compare Products","product_compare_button":"Compare","spec_detail":"Detail","spec_title":"Title","widget_button":"Compare Now","widget_title":"Compare"};
            }
        }
    },

    /**
     * BOLD.Compare.Widget.initDisplay
     *
     * add display settings
     *
     */
    initDisplay: function(){
        BOLD.Compare.display = JSON.parse(BOLD.Compare.display);

        if(BOLD.Compare.display != null) {
            if (BOLD.Compare.display.widget_position == 'bottomleft') {
                BOLD.Compare.Widget.element.addClass('bold-compare-bottomleft');
            }

            if (BOLD.Compare.display.widget_orientation == 'horizontal') {
                BOLD.Compare.Widget.element.addClass('bold-compare-horizontalwidget');
            }
        } else {
            BOLD.Compare.display = {"widget_position":"bottomright","widget_orientation":"vertical","max_compare_products":"5","show_specs_product_detail":"0"};
        }

        if(BOLD.Compare.display.show_specs_product_detail == "1"){
            BOLD.jQuery('.bold_specs').show();
        }

    },

    /**
     * BOLD.Compare.Widget.add
     *
     * add a new compare product
     *
     * @param (string) (id) the product id to add
     * @param (string) (handle) the product handle to add
     *
     */
    add: function(id, handle){

        if(Object.keys(BOLD.Compare.Widget.products).length < BOLD.Compare.display.max_compare_products) {

            BOLD.Compare.Widget.products[id] = handle;

            var existing_widget_product = BOLD.jQuery('.bold-compare-product[data-product-id=' + id + ']');
            if (existing_widget_product.length > 0) { // show product if we've requested it previously
                BOLD.Compare.Widget.showProduct(existing_widget_product);
            } else {
                BOLD.Compare.Widget.requestProduct(id, handle);
            }
            BOLD.jQuery('.bold-compare-widget .error').hide().text('');

        } else { // max_compare_products has been reached

            BOLD.jQuery('input.check-'+id).prop('checked',false);
            BOLD.jQuery('.bold-compare-widget .error').css('width',BOLD.Compare.Widget.element.width()+"px");
            BOLD.jQuery('.bold-compare-widget .error').show().text((BOLD.Compare.language.compare_max_product_alert));
        }

        BOLD.Compare.Widget.updateTitleNumber();

    },

    /**
     * BOLD.Compare.Widget.remove
     *
     * remove a compare product
     *
     * @param (string) (id) the product id to remove
     *
     */
    remove: function(id){
        delete BOLD.Compare.Widget.products[id];

        BOLD.Compare.Widget.hideProduct( BOLD.jQuery('.bold-compare-product[data-product-id='+id+']') );

        BOLD.jQuery('input.check-'+id).prop('checked',false);
        BOLD.Compare.Widget.updateTitleNumber();
        BOLD.jQuery('.bold-compare-widget .error').hide().text('');
        BOLD.Compare.Widget.updateCookies();
    },

    /**
     * BOLD.Compare.Widget.removeAndUpdate
     *
     * remove a compare product
     *
     * @param (string) (id) the product id to remove
     *
     */
    removeAndUpdate: function(id, callbackFunction){

        BOLD.Compare.Widget.remove(id);

        // send to cart
        BOLD.jQuery.ajax({
            type: 'POST',
            url: '/cart/update.js',
            data: {
                attributes:{
                    bold_compare_products: BOLD.Compare.Widget.cookie.handles
                }
            },
            dataType:'json',
            success: function(){
                if(typeof callbackFunction === 'function') {
                    callbackFunction();
                }
            }
        });

    },

    /**
     * BOLD.Compare.Widget.requestProduct
     *
     * request product data from Shopify
     *
     * @param (string) (id) the product id to add
     * @param (string) (handle) the product handle to add
     *
     */
    requestProduct: function(id, handle){

        BOLD.jQuery.ajax({
            type: 'GET',
            url: '/products/'+handle+'.js',
            dataType:'json',
            success: function(product){

                // Prepare image URL
                if( ! product.featured_image ) {
                    product_image_url = BOLD.Compare.default_product_image;
                } else {
                    // get thumb sized image
                    product_image_url = product.featured_image.replace(/(\.\w{3,4}\?v=)/gi, '_thumb$1');
                }

                // Add product to the widget (hidden)
                var product = BOLD.jQuery('<div class="bold-compare-product" data-product-id="'+id+'">\
                                          <a href="'+product.url+'">\
                                              <span class="bold-compare-img"><img src="'+product_image_url+'" alt="'+product.title+'"></span>\
                                              <span>'+product.title+'</span>\
                                          </a>\
                                          <span class="bold-compare-remove">&times;</span>\
                                      </div>').hide();

                // Bind event for removing product from widget
                BOLD.jQuery('.bold-compare-remove', product).on('click',function(){
                    var product_id = BOLD.jQuery(this).parents('.bold-compare-product').data('product-id');
                    BOLD.Compare.Widget.remove(product_id);
                });

                BOLD.jQuery('.bold-compared-products',BOLD.Compare.Widget.element).prepend(product);
                BOLD.Compare.Widget.showProduct(product);

            }
        });

    },

    /**
     * BOLD.Compare.Widget.loadCookies
     *
     * get current set of compare products from cookies
     *
     */
    loadCookies: function(){
        var bold_ids = decodeURIComponent(BOLD.Compare.Widget.getCookie('bold_compare_id'));
        var bold_handles =  decodeURIComponent(BOLD.Compare.Widget.getCookie('bold_compare_handle'));

        if(bold_ids != '' && bold_handles != '') {
            bold_ids = bold_ids.split(',');
            bold_handles =  bold_handles.split(',');
            BOLD.jQuery.each(bold_ids, function(index, id){
                BOLD.Compare.Widget.add(id, bold_handles[index]);
            });
        }

        BOLD.Compare.Widget.cookie.widget_status = decodeURIComponent(BOLD.Compare.Widget.getCookie('bold_compare_widget_status'));

        BOLD.Compare.Widget.updateCookies();
    },

    /**
     * BOLD.Compare.Widget.updateCookies
     *
     * update state cookies from the current set of compare products
     *
     */
    updateCookies: function(){
        BOLD.Compare.Widget.cookie.handles = '';
        BOLD.Compare.Widget.cookie.ids = '';

        var cookie_handle_array = [];
        var cookie_id_array = [];
        BOLD.jQuery.each(BOLD.Compare.Widget.products, function(id,handle){
            cookie_handle_array.push(handle);
            cookie_id_array.push(id);
        });

        BOLD.Compare.Widget.cookie.handles = cookie_handle_array.join(',');
        BOLD.Compare.Widget.cookie.ids = cookie_id_array.join(',');

        BOLD.Compare.Widget.deleteCookie("bold_compare_handle");
        BOLD.Compare.Widget.deleteCookie("bold_compare_id");
        BOLD.Compare.Widget.deleteCookie("bold_compare_widget_status");
        document.cookie = "bold_compare_handle="+BOLD.Compare.Widget.cookie.handles+";path=/;";
        document.cookie = "bold_compare_id="+BOLD.Compare.Widget.cookie.ids+";path=/;";
        document.cookie = "bold_compare_widget_status="+BOLD.Compare.Widget.cookie.widget_status+";path=/;";
    },

    /**
     * BOLD.Compare.Widget.addCompareButton
     *
     * add button in product page with meta fields
     *
     */
    addCompareButton: function(){
        if(BOLD.Compare.Widget.specsExist == true){
            var product_handle = BOLD.jQuery('div.bold_compare_button').data('handle');
            var product_id = BOLD.jQuery('div.bold_compare_button').data('id');
            var button_title = BOLD.Compare.language.product_compare_button;
            BOLD.jQuery('div.bold_compare_button').html('<a class="compare_product_btn btn" check-'+product_id+'" data-id="'+product_id+'" data-handle="'+product_handle+'">'+button_title+'</a>');
            BOLD.jQuery('a.compare_product_btn').click(BOLD.Compare.Widget.compareBtnClicked);
        }
    },

    /**
     * BOLD.Compare.Widget.compareBtnClicked
     *
     * compare button clicked in product detail page
     *
     */
    compareBtnClicked: function(){
        var handle = BOLD.jQuery(this).data('handle');
        var prod_id = BOLD.jQuery(this).data('id');

        BOLD.Compare.Widget.add(prod_id, handle);
        BOLD.Compare.Widget.updateCookies();
    },

    /**
     * BOLD.Compare.Widget.addCheckboxes
     *
     * add checkboxes to each product with meta fields
     *
     */
    addCheckboxes: function(){
        // add checkboxes to dom
        BOLD.jQuery('div.bold_compare_checkbox').each(function(){
            var product_handle = BOLD.jQuery(this).data('handle');
            var product_id = BOLD.jQuery(this).data('id');
            var checkbox_text = BOLD.Compare.language.collection_checkbox;
            BOLD.jQuery(this).html('<label><input class="compare_check check-'+product_id+'" type="checkbox" data-id="'+product_id+'" data-handle="'+product_handle+'"><span>'+checkbox_text+' </span></label>');
        });

        // bind event for checkboxes
        BOLD.jQuery('input.compare_check').change(BOLD.Compare.Widget.checkboxChange);

        // update checkboxes for current compared products
        BOLD.jQuery.each(BOLD.Compare.Widget.products, function(index, value){
            BOLD.jQuery('input.check-'+index).prop('checked',true);
        });
    },

    /**
     * BOLD.Compare.Widget.checkboxChange
     *
     * change event for checkboxes
     *
     */
    checkboxChange: function(){
        var handle = BOLD.jQuery(this).data('handle');
        var prod_id = BOLD.jQuery(this).data('id');

        if(BOLD.jQuery(this).is(':checked')){
            BOLD.Compare.Widget.add(prod_id, handle);
            BOLD.Compare.Widget.updateCookies();
        } else {
            BOLD.Compare.Widget.remove(prod_id);
        }
    },

    /**
     * BOLD.Compare.Widget.runCompare
     *
     * add the product set as a cart attribute and go to the compare page
     *
     */
    runCompare: function(){

        if(Object.keys(BOLD.Compare.Widget.products).length > 1) {
            BOLD.jQuery.ajax({
                type: 'POST',
                url: '/cart/update.js',
                data: {
                    attributes: {
                        bold_compare_products: BOLD.Compare.Widget.cookie.handles
                    }
                },
                dataType: 'json',
                success: function (response) {
                    has_attr = true;
                    window.location.href = "/pages/compare";
                }
            });
        } else {
            alert('Please select at least two products to compare.');
        }

    },

    /**
     * BOLD.Compare.Widget.showProduct
     *
     * shows a product in the widget
     *
     * @param (obj) (product) jquery object of the product element to slide down or left
     *
     */
    showProduct: function(product){

        product.removeClass('bold-compare-removed');

        if (BOLD.Compare.Widget.element.is(':hidden')) {
            product.show();
            BOLD.Compare.Widget.element.slideDown();
        } else if(BOLD.Compare.Widget.isHorizontalWidget) {
            product.animate({width:'toggle'});
        } else {
            product.slideDown();
        }

    },

    /**
     * BOLD.Compare.Widget.hideProduct
     *
     * hide a product in the widget
     *
     * @param (obj) (product) jquery object of the product element to slide down or left
     *
     */
    hideProduct: function(product){

        product.addClass('bold-compare-removed');

        if(BOLD.jQuery('.bold-compare-product').not('.bold-compare-removed').length == 0) {
            // hiding the last product
            BOLD.Compare.Widget.element.slideUp(400,function(){
                product.hide();
            });
        } else if(BOLD.Compare.Widget.isHorizontalWidget) {
            product.animate({width:'toggle'});
        } else {
            product.slideUp();
        }

    },

    /**
     * BOLD.Compare.Widget.getCookie
     *
     * read a cookie
     *
     * @param (string) (cname) the cookie name
     *
     */
    getCookie: function(cname){
        var name = cname + "=";
        var ca = document.cookie.split(';');
        for(var i=0; i<ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0)==' ') c = c.substring(1);
            if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
        }
        return "";
    },

    /**
     * BOLD.Compare.Widget.deleteCookie
     *
     * read a cookie
     *
     * @param (string) (cname) the cookie name
     *
     */
    deleteCookie: function(cname){
        document.cookie = cname + '=;path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
    }

}; // end of Bold.CompareWidget



function loadScript(url, callback) {

    var script = document.createElement("script")
    script.type = "text/javascript";

    if (script.readyState) {  //IE
        script.onreadystatechange = function () {
            if (script.readyState == "loaded" ||
                script.readyState == "complete") {
                script.onreadystatechange = null;
                callback();
            }
        };
    } else {  //Others
        script.onload = function () {
            callback();
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}

function js_version_good(version_number) {
    var is_good = false;
    var versions = version_number.split('.');
    if (parseInt(versions[0]) >= 2) {
        is_good = true;
    } else if (parseInt(versions[0]) >= 1 && parseInt(versions[1]) >= 9) {
        is_good = true;
    }

    return is_good;
}

function loadBOLDjQuery(callback) {
    if ((typeof jQuery === 'undefined') || !(js_version_good(jQuery.fn.jquery))) {
        loadScript('//ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js', function () {
            BOLD.jQuery = jQuery.noConflict(true);
            callback();
        });
    } else {
        BOLD.jQuery = jQuery;
        callback();
    }
}

/***************** INITIALIZE PRODUCT COMPARE *****************/

if(typeof BOLD.jQuery === 'undefined') {
    BOLD.Compare.Widget.initLanguage();
    loadBOLDjQuery(function(){
        BOLD.Compare.Widget.init(BOLD.jQuery.isReady);
    });
} else {
    BOLD.Compare.Widget.init(BOLD.jQuery.isReady);
}