Create a snippet named bold-upsell-checkout-fix.liquid and add the following code:
<script>
document.addEventListener('click', function(event){
if( (event.target.className.indexOf('bold_clone') === -1 ) &&
( ( event.target.name === 'checkout' && event.target.form ) ||
( event.target.closest('form') && event.target.closest('[name="checkout"]') ) )
){
event.preventDefault();
var form = event.target.closest('form');
var request = new XMLHttpRequest();
request.onload = function(){
if( BOLD && BOLD.common && BOLD.common.eventEmitter && typeof BOLD.common.eventEmitter.emit === 'function' ){
BOLD.common.eventEmitter.emit('BOLD_COMMON_cart_loaded');
}
document.location = '/checkout';
};
request.open("POST", "/cart/update.js?" + $(form).serialize());
request.send();
}
});
</script>
ajax-cart-hack-fix.liquid
Create a snippet named ajax-cart-hack-fix.liquid and add the following code:
<script>
//wraps ajax-cart code and calls on load
window.addEventListener("load", function(event) {
! function($) {
var AjaxCart = function($ele, settings) {
this.$ele = $ele, this.settings = settings, this.connection = new CartConnection, this.cartDisplay = new CartDisplay(this.settings.cartCountElement,this.settings.cartDropdownElement), this.cartPrice = new CartPrice(this.settings.cartPriceElement), this.cartFormQueue = [], this.cartForms = [], this._buildForms(), this._addEventHandlers()
};
AjaxCart.prototype._buildForms = function() {
var self = this;
this.$ele.find('form[action="/cart/add"]').each(function(i) {
var cartForm = new ProductForm(this, self.settings.form, i);
self.cartForms.push(cartForm)
}), this.$ele.find('form[action="/cart"]').each(function(i) {
var cartForm = new CartForm(this, self.settings.form, i);
self.cartForms.push(cartForm)
})
}, AjaxCart.prototype._addEventHandlers = function() {
var self = this;
this.$ele.on("cartCollected", function(e, cartData) {
self.cart = cartData, self.cartCount = cartData.item_count, self.cartDisplay.updateCartCountElement(self.cartCount), self.cartDisplay.updateCartDropdownElement(self.cartCount, cartData);
if( BOLD && BOLD.common && BOLD.common.eventEmitter && typeof BOLD.common.eventEmitter.emit === 'function' ){
BOLD.common.eventEmitter.emit('BOLD_COMMON_cart_loaded');
}
}), this.$ele.on("sendToCart", function(e, formData, formID) {
var form = self.cartForms[formID];
self.cartFormQueue.push(form), self.connection.postToCart(formData, form)
}), this.$ele.on("postToCartSuccess", function(e, result) {
result.item_count ? (self.cartCount = result.item_count, self.cartPrice.updatePriceElement(result)) : self.cartCount++, self.cartDisplay.updateCartCountElement(self.cartCount);
var cartForm = self.cartFormQueue.shift();
cartForm.sendToCartSuccess(result)
self.connection.getCart();
}), this.$ele.on("postToCartError", function(e, err, status) {
var cartForm = self.cartFormQueue.shift();
cartForm.sendToCartError(err, status)
})
};
var CartConnection = function() {
this.getCart()
};
CartConnection.prototype.getCart = function() {
$.ajax({
type: "GET",
dataType: "json",
url: "/cart.js"
}).done(function(data) {
$.event.trigger("cartCollected", data)
})
}, CartConnection.prototype.postToCart = function(formData, form) {
if(formData.indexOf('quantity=0') == -1) {
$.ajax({
type: "POST",
dataType: "json",
url: form.postURL,
data: formData
}).done(function(result) {
$.event.trigger("postToCartSuccess", result)
}).fail(function(err, status) {
$.event.trigger("postToCartError", [err, status])
})
}
else {
$.event.trigger("postToCartError", [null, 0])
}
};
var CartForm = function(form, settings, id) {
this.$form = $(form), this.settings = settings, this.id = id, this.postURL = "/cart/update.js", this._addEventHandlers()
};
CartForm.prototype.sendToCartSuccess = function() {
var message = "Cart successfully updated.";
this._displayMessage(message, "success")
}, CartForm.prototype.sendToCartError = function(err, status) {
try {
var response = jQuery.parseJSON(err.responseText);
this._displayMessage(response.message + ": " + response.description, "danger")
} catch (e) {
this._displayMessage("ERROR: There was an error adding your item to the cart.", "danger")
}
}, CartForm.prototype._addEventHandlers = function() {
var self = this;
this.$form.on("keyup", '[name^="updates"]', function(e) {
this === document.activeElement && self._isNumberKeyCode(e.keyCode) && (e.preventDefault(), $.event.trigger("sendToCart", [self.$form.serialize(), self.id]))
})
}, CartForm.prototype._displayMessage = function(message, messageType) {
var messageMarkup = this.settings.cartMessageMarkup(message, messageType);
this.$form.prepend(messageMarkup);
var self = this;
window.setTimeout(function() {
self._removeMessage()
}, 6e3)
}, CartForm.prototype._removeMessage = function() {
this.$form.find(".ajax-cart-message").hide(186, function() {
this.remove()
})
}, CartForm.prototype._isNumberKeyCode = function(keyCode) {
var keyMatch = !1,
keyCodes = [8, 9, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105];
for (var i in keyCodes)
if (keyCode === keyCodes[i]) {
keyMatch = !0;
break
}
return keyMatch
};
var ProductForm = function(form, settings, id) {
this.$form = $(form), this.settings = settings, this.id = id, this.postURL = "/cart/add.js", this.formButton = this._getFormButton(), this._addEventHandlers()
};
ProductForm.prototype.sendToCartSuccess = function(result) {
var message = result.title + ' successfully added. <a href="/cart">View cart</a>';
this._displayMessage(message, "success")
}, ProductForm.prototype.sendToCartError = function(err, status) {
try {
var response = jQuery.parseJSON(err.responseText);
this._displayMessage(response.message + ": " + response.description, "danger")
} catch (e) {
this._displayMessage("ERROR: There was an error adding your item to the cart.", "danger")
}
}, ProductForm.prototype._getFormButton = function() {
var $button = this.$form.find('input[name="add"],button[name="add"]');
return $button.length > 0 ? new CartFormButton($button, this.settings) : !1
}, ProductForm.prototype._addEventHandlers = function() {
var self = this;
this.$form.on("submit", function(e) {
e.preventDefault(), self.formButton && self.formButton.updateButton("Adding...", !0), $.event.trigger("sendToCart", [$(this).serialize(), self.id])
})
}, ProductForm.prototype._displayMessage = function(message, messageType) {
this.formButton.updateButton(!1, !1);
var messageMarkup = this.settings.productMessageMarkup(message, messageType);
this.$form.append(messageMarkup);
var self = this;
window.setTimeout(function() {
self._removeMessage()
}, 6e3)
}, ProductForm.prototype._removeMessage = function() {
this.$form.find(".ajax-cart-message").hide(186, function() {
this.remove()
})
};
var CartFormButton = function($ele, settings) {
this.$ele = $ele, this.settings = settings, this.defaultSubmitValue = this.$ele.val() || this.settings.defaultSubmitValue
};
CartFormButton.prototype.updateButton = function(message, disable) {
message || (message = this.defaultSubmitValue), this.$ele.val(message).prop("disabled", disable)
};
var CartDisplay = function(cartCountElement, cartDropdownElement) {
this.$cartCountElement = $(cartCountElement), this.$cartCountBadge = this.$cartCountElement.find(".badge"), this.$cartDropdownElement = $(cartDropdownElement)
};
CartDisplay.prototype.updateCartCountElement = function(count) {
count > 0 && (0 === this.$cartCountBadge.length && (this.$cartCountElement.append(' <span class="badge"></span> <span class="caret"></span>'), this.$cartCountBadge = this.$cartCountElement.find(".badge")), this.$cartCountBadge.text() !== count && this.$cartCountBadge.text(count))
};
CartDisplay.prototype.updateCartDropdownElement = function(count, cart) {
$('li.quick-cart-row').remove();
if(cart.item_count == 0) {
$(".cart-dropdown").prepend('<li class="quick-cart-row text-center">Your cart is empty</li>');
}
else {
for(var i = 0; i < cart.items.length; i++) {
$(".cart-dropdown").prepend('<li class="quick-cart-row"><a href="'+cart.items[i].url+'">'+ cart.items[i].title +' x'+cart.items[i].quantity+'</a><span class="quick-remove" href="javascript:void(0);" onclick="Shopify.removeItem('+ cart.items[i].variant_id +')"><i class="fa fa-times"></i></span></li>');
}
}
};
var CartPrice = function(ele) {
this.$ele = $(ele), this.freeShipping = $(document).data("_freeShipping")
};
CartPrice.prototype.updatePriceElement = function(result) {
if (this.$ele.length > 0) {
var formattedMoney = Shopify.formatMoney(result.total_price);
this.$ele.find(".money").replaceWith('<span class="money">' + formattedMoney + "</span>"), "undefined" != typeof Currency && Currency.shopCurrency !== Currency.currentCurrency && Currency.convertAll(Currency.shopCurrency, Currency.currentCurrency), this.freeShipping && this.freeShipping.update({
cart_total: result.total_price
}), this._recalcShipping()
}
}, CartPrice.prototype._recalcShipping = function() {
var $shippingCalc = $(".shipping-calculator-wrapper"),
$responseWrapper = $shippingCalc.find("#wrapper-response");
$shippingCalc.length > 0 && "" !== $responseWrapper.html() && $shippingCalc.find(".get-rates").trigger("click")
}, $.fn.ajaxCart = function(opts) {
var settings = $.extend({}, $.fn.ajaxCart.defaults, opts);
return this.each(function() {
var $ele = $(this);
$ele.data("_ajaxCart", new AjaxCart($ele, settings))
})
}, $.fn.ajaxCart.defaults = {
cartCountElement: ".cartCount",
cartDropdownElement: ".cart-dropdown",
cartPriceElement: 'form[action="/cart"] .product-price',
form: {
defaultSubmitValue: "Add to cart",
productMessageMarkup: function(message, messageType) {
return '<span class="ajax-cart-message help-block text-' + messageType + '">' + message + "</span>"
},
cartMessageMarkup: function(message, messageType) {
return '<div class="ajax-cart-message alert alert-' + messageType + '">' + message + "</div>"
}
}
}
Shopify.onCartUpdate = function(cart) {
$('li.quick-cart-row').remove();
$('.cartCount').find(".badge").text(cart.item_count);
if(cart.item_count == 0) {
$(".cart-dropdown").prepend('<li class="quick-cart-row text-center">Your cart is empty</li>');
}
else {
for(var i = 0; i < cart.items.length; i++) {
$(".cart-dropdown").prepend('<li class="quick-cart-row"><a href="'+cart.items[i].url+'">'+ cart.items[i].title +' x'+cart.items[i].quantity+'</a><span class="quick-remove" href="javascript:void(0);" onclick="Shopify.removeItem('+ cart.items[i].variant_id +')"><i class="fa fa-times"></i></span></li>');
}
}
};
}(jQuery);
{% if settings.ajax-cart %}
$(document).ajaxCart();
{% endif %}
});
</script>
theme.liquid
Open theme.liquid and add the following code before the bold include files and before the </body> tag.
{% include 'ajax-cart-hack-fix' %}
Still inside of theme.liquid add the following code before the </body> tag, but after {% include 'ajax-cart-hack-fix' %}.
{% include 'bold-upsell-checkout-fix' %}
CART.LIQUID (FIND AND REPLACE)
Find the section of code that contains
<input type="number" class="form-control" name="updates[{{ i.id }}]" id="updates_{{ i.id }}" value="{{ i.quantity }}" min="0"{% if product_max_qty %} max="{{ product_max_qty }}"{% endif %} onfocus="this.select();"{{ bold_qty_attr }}/>
&
Replace with the following
{% if i.product.tags contains 'DISCOUNT_HIDDEN_PRODUCT' %}
<input type="number" name="updates[{{ i.id }}]" id="updates_{{ i.id }}" value="{{ i.quantity }}" disabled>
{% else %}
<input type="number" class="form-control" name="updates[{{ i.id }}]" id="updates_{{ i.id }}" value="{{ i.quantity }}" min="0"{% if product_max_qty %} max="{{ product_max_qty }}"{% endif %} onfocus="this.select();"{{ bold_qty_attr }}/>
{% endif %}