Created
June 25, 2020 20:29
-
-
Save williambsb/72915e277e3b10125ff536b7ee92edff to your computer and use it in GitHub Desktop.
Cart Drawer - HC Shopify
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
/** | |
* Module to ajaxify all add to cart forms on the page. | |
* | |
* Copyright (c) 2015 Caroline Schnapp (11heavens.com) | |
* Dual licensed under the MIT and GPL licenses: | |
* http://www.opensource.org/licenses/mit-license.php | |
* http://www.gnu.org/licenses/gpl.html | |
* | |
*/ | |
Shopify.AjaxifyCart = (function($) { | |
// Some configuration options. | |
// I have separated what you will never need to change from what | |
// you might change. | |
var _config = { | |
// What you might want to change | |
addToCartBtnLabel: 'Add to cart', | |
addedToCartBtnLabel: 'Thank you!', | |
addingToCartBtnLabel: 'Adding...', | |
soldOutBtnLabel: 'Sold Out', | |
howLongTillBtnReturnsToNormal: 1000, // in milliseconds. | |
cartCountSelector: '.cart-count, #cart-count a:first, #gocart p a, #cart .checkout em, .item-count, #CartCount', | |
cartTotalSelector: '#cart-price', | |
// 'aboveForm' for top of add to cart form, | |
// 'belowForm' for below the add to cart form, and | |
// 'nextButton' for next to add to cart button. | |
feedbackPosition: 'belowForm', | |
// What you will never need to change | |
addToCartBtnSelector: '[type="submit"]', | |
addToCartFormSelector: 'form[action="/cart/add"]', | |
shopifyAjaxAddURL: '/cart/add.js', | |
shopifyAjaxCartURL: '/cart.js' | |
}; | |
// We need some feedback when adding an item to the cart. | |
// Here it is. | |
var _showFeedback = function(success, html, $addToCartForm) { | |
$('.ajaxified-cart-feedback').remove(); | |
var feedback = '<p class="ajaxified-cart-feedback ' + success + '">' + html + '</p>'; | |
switch (_config.feedbackPosition) { | |
case 'aboveForm': | |
$addToCartForm.before(feedback); | |
jQuery('.ajaxify_success_message_container').before(feedback); | |
break; | |
case 'belowForm': | |
$addToCartForm.after(feedback); | |
jQuery('.ajaxify_success_message_container').after(feedback); | |
break; | |
case 'nextButton': | |
default: | |
$addToCartForm.find(_config.addToCartBtnSelector).after(feedback); | |
jQuery('.ajaxify_success_message_container').after(feedback); | |
break; | |
} | |
// If you use animate.css | |
// $('.ajaxified-cart-feedback').addClass('animated bounceInDown'); | |
$('.ajaxified-cart-feedback').slideDown(); | |
}; | |
var _setText = function($button, label) { | |
if ($button.children().length) { | |
$button.children().each(function() { | |
if ($.trim($(this).text()) !== '') { | |
$(this).text(label); | |
} | |
}); | |
} | |
else { | |
$button.val(label).text(label); | |
} | |
}; | |
var _init = function() { | |
$(document).ready(function() { | |
$(_config.addToCartFormSelector).submit(function(e) { | |
e.preventDefault(); | |
var $addToCartForm = $(this); | |
var $addToCartBtn = $addToCartForm.find(_config.addToCartBtnSelector); | |
_setText($addToCartBtn, _config.addingToCartBtnLabel); | |
$addToCartBtn.addClass('disabled').prop('disabled', true); | |
// Add to cart. | |
$.ajax({ | |
url: _config.shopifyAjaxAddURL, | |
dataType: 'json', | |
type: 'post', | |
data: $addToCartForm.serialize(), | |
success: function(itemData) { | |
// Re-enable add to cart button. | |
$addToCartBtn.addClass('inverted'); | |
_setText($addToCartBtn, _config.addedToCartBtnLabel); | |
_showFeedback('success','<i class="fa fa-check"></i> Added to cart! <a href="/cart">View cart</a> or <a href="/collections/all">continue shopping</a>.',$addToCartForm); | |
window.setTimeout(function(){ | |
$addToCartBtn.prop('disabled', false).removeClass('disabled').removeClass('inverted'); | |
_setText($addToCartBtn,_config.addToCartBtnLabel); | |
}, _config.howLongTillBtnReturnsToNormal); | |
// Update cart count and show cart link. | |
$.getJSON(_config.shopifyAjaxCartURL, function(cart) { | |
var size = cart.item_count; | |
$('.hc-items-count').text(cart.item_count); | |
$('.hc-mini-table').remove(); | |
$('.amount').text(Shopify.formatMoney(cart.total_price, Shopify.moneyFormat)); | |
$('.hc-append').append('<table class="hc-mini-table">'); | |
$(cart.items).each(function(index, item) { | |
$('.hc-mini-table').append('<tr class="item-details" data-id="'+item.id+'"><td class="td-image"><img src="' + item.image + '" /></td><td><div class="mini_cart_title_price"><div>' + item.product_title + '</div> ' + item.variant_title + '<span class="item-price">' + Shopify.formatMoney(item.price, theme.moneyFormat) + '</span></div><a href class="minus-quantity">−</a><input type="text" class="quantity-input" value="' + item.quantity + '"><a href class="plus-quantity">+</a><a class="hc-remove" href="">Remove</a></td></tr>'); | |
}); | |
$('.hc-append').append('</table>'); | |
$('#CartCount > span').text(size); | |
$(".custom-overlay").toggle(); | |
jQuery('body').addClass('active_slide_cart'); | |
$('div#mini-cart').fadeIn('slow', function(){ | |
setTimeout(function() { | |
jQuery('body').removeClass('active_slide_cart'); | |
$(".custom-overlay").fadeOut('fast'); | |
}, 5000); | |
}); | |
if (_config.cartCountSelector && $(_config.cartCountSelector).size()) { | |
var value = $(_config.cartCountSelector).html() || '0'; | |
$(_config.cartCountSelector).html(value.replace(/[0-9]+/,cart.item_count)).removeClass('hidden-count'); | |
} | |
if (_config.cartTotalSelector && $(_config.cartTotalSelector).size()) { | |
if (typeof Currency !== 'undefined' && typeof Currency.moneyFormats !== 'undefined') { | |
var newCurrency = ''; | |
if ($('[name="currencies"]').size()) { | |
newCurrency = $('[name="currencies"]').val(); | |
} | |
else if ($('#currencies span.selected').size()) { | |
newCurrency = $('#currencies span.selected').attr('data-currency'); | |
} | |
if (newCurrency) { | |
$(_config.cartTotalSelector).html('<span class=money>' + Shopify.formatMoney(Currency.convert(cart.total_price, "{{ shop.currency }}", newCurrency), Currency.moneyFormats[newCurrency].money_with_currency_format) + '</span>'); | |
} | |
else { | |
$(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price, "{{ shop.money_format | remove: "'" | remove: '"' }}")); | |
} | |
} | |
else { | |
$(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price, "{{ shop.money_format | remove: "'" | remove: '"' }}")); | |
} | |
}; | |
}); | |
}, | |
error: function(XMLHttpRequest) { | |
var response = eval('(' + XMLHttpRequest.responseText + ')'); | |
response = response.description; | |
if (response.slice(0,4) === 'All ') { | |
_showFeedback('error', response.replace('All 1 ', 'All '), $addToCartForm); | |
$addToCartBtn.prop('disabled', false); | |
_setText($addToCartBtn, _config.soldOutBtnLabel); | |
$addToCartBtn.prop('disabled',true); | |
} | |
else { | |
_showFeedback('error', '<i class="fa fa-warning"></i> ' + response, $addToCartForm); | |
$addToCartBtn.prop('disabled', false).removeClass('disabled'); | |
_setText($addToCartBtn, _config.addToCartBtnLabel); | |
} | |
} | |
}); | |
return false; | |
}); | |
}); | |
}; | |
return { | |
init: function(params) { | |
// Configuration | |
params = params || {}; | |
// Merging with defaults. | |
$.extend(_config, params); | |
// Action | |
$(function() { | |
_init(); | |
}); | |
}, | |
getConfig: function() { | |
return _config; | |
} | |
} | |
})(jQuery); | |
Shopify.AjaxifyCart.init(); | |
var Shopify = Shopify || {}; | |
// --------------------------------------------------------------------------- | |
// Money format handler | |
// --------------------------------------------------------------------------- | |
Shopify.money_format = "${{amount}}"; | |
Shopify.formatMoney = function(cents, format) { | |
if (typeof cents == 'string') { cents = cents.replace('.',''); } | |
var value = ''; | |
var placeholderRegex = /\{\{\s*(\w+)\s*\}\}/; | |
var formatString = (format || this.money_format); | |
function defaultOption(opt, def) { | |
return (typeof opt == 'undefined' ? def : opt); | |
} | |
function formatWithDelimiters(number, precision, thousands, decimal) { | |
precision = defaultOption(precision, 2); | |
thousands = defaultOption(thousands, ','); | |
decimal = defaultOption(decimal, '.'); | |
if (isNaN(number) || number == null) { return 0; } | |
number = (number/100.0).toFixed(precision); | |
var parts = number.split('.'), | |
dollars = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands), | |
cents = parts[1] ? (decimal + parts[1]) : ''; | |
return dollars + cents; | |
} | |
switch(formatString.match(placeholderRegex)[1]) { | |
case 'amount': | |
value = formatWithDelimiters(cents, 2); | |
break; | |
case 'amount_no_decimals': | |
value = formatWithDelimiters(cents, 0); | |
break; | |
case 'amount_with_comma_separator': | |
value = formatWithDelimiters(cents, 2, '.', ','); | |
break; | |
case 'amount_no_decimals_with_comma_separator': | |
value = formatWithDelimiters(cents, 0, '.', ','); | |
break; | |
} | |
return formatString.replace(placeholderRegex, value); | |
}; | |
</script> | |
{% comment %} | |
If you want to animate your feedback message. | |
{% endcomment %} | |
{% comment %} | |
{{ '//cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.0/animate.min.css' | stylesheet_tag }} | |
{% endcomment %} | |
{{ '//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.css' | stylesheet_tag }} | |
<style> | |
.ajaxified-cart-feedback { | |
display: block; | |
line-height: 36px; | |
font-size: 90%; | |
vertical-align: middle; | |
} | |
.ajaxified-cart-feedback.success { | |
color: #3D9970; | |
} | |
.ajaxified-cart-feedback.error { | |
color: #FF4136; | |
} | |
.ajaxified-cart-feedback a { | |
border-bottom: 1px solid; | |
} | |
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="mini-cart" class="hc-cartDrawer"> | |
<h4>Cart</h4> | |
<span class="hc-close" aria-hidden="true">×</span> | |
<div class="count"> | |
<span class="hc-items-count">{{cart.item_count }}</span> item(s) in your cart | |
</div> | |
<form action="/cart" method="post" novalidate class="cart"> | |
<div class="hc-append"></div> | |
<table class="hc-mini-table"> | |
{% for item in cart.items %} | |
<tr class="item-details" data-id="{{ item.id }}"> | |
<td class="td-image"> | |
<img src="{{ item | img_url: 'x100' }}" /> | |
</td> | |
<td> | |
<div class="mini_cart_title_price"> | |
<div>{{ item.title }}</div> | |
<span class="item-price">{{item.price | money }}</span> | |
</div> | |
<a href class="minus-quantity">−</a> | |
<input type="text" class="quantity-input" value="{{item.quantity}}"> | |
<a href class="plus-quantity">+</a> | |
<a class="hc-remove" href="">Remove</a> | |
</td> | |
</tr> | |
{% endfor %} | |
</table> | |
<div class="hc-buttons action buttons"> | |
<div class="subtotal"> | |
<strong class="float-left">Subtotal </strong> | |
<strong class="amount">{{ cart.total_price | money }}</strong> | |
</div> | |
<a href="/cart" rel="nofollow" class="cart-grey-btn">View Cart</a> | |
<a class="checkout" href="/checkout" rel="nofollow">Checkout</a> | |
<div class="additional-checkout-buttons">{{ content_for_additional_checkout_buttons }}</div> | |
</div> | |
</form> | |
</div> | |
<div class="custom-overlay"></div> | |
<style> | |
.additional-checkout-button+.additional-checkout-button, .additional-checkout-button--google-pay { | |
width: 100% !important; | |
margin-left: 0; | |
} | |
form.cart { | |
display: flex; | |
flex-direction: column; | |
justify-content: space-between; | |
height: 90vh; | |
} | |
body { | |
-webkit-transition: transform 0.5s ease; | |
-moz-transition: transform 0.5s ease; | |
-o-transition: transform 0.5s ease; | |
transition: transform 0.5s ease; | |
} | |
body.active_slide_cart { | |
position: static; | |
overflow: hidden !important; | |
} | |
@media screen and (max-width: 480px) { | |
body.active_slide_cart { | |
position: fixed; | |
overflow: auto !important; | |
} | |
} | |
#mini-cart { | |
width: 500px; | |
position: fixed; | |
top: 0; | |
z-index: 999; | |
background: #f7f7f7; | |
color: #000; | |
display: block; | |
padding: 15px; | |
height: 100vh; | |
right: -500px; | |
bottom: 0; | |
} | |
body.active_slide_cart { | |
-ms-transform: translate(-500px, 0px); /* IE 9 */ | |
-webkit-transform: translate(-500px, 0px); /* Safari */ | |
transform: translate(-500px, 0px); | |
-webkit-transition: transform 0.5s ease; | |
-moz-transition: transform 0.5s ease; | |
-o-transition: transform 0.5s ease; | |
transition: transform 0.5s ease; | |
} | |
#mini-cart .count, #mini-cart .subtotal, #mini-cart .buttons { | |
padding: 10px; | |
} | |
#mini-cart .subtotal { | |
text-align: right; | |
padding-right: 5px; | |
} | |
#mini-cart .subtotal .amount { | |
display: inline-block; | |
padding: 0 10px; | |
} | |
#mini-cart table tr, #mini-cart .count { | |
border-bottom: 1px solid #ccc; | |
} | |
#mini-cart table td { | |
border: none; | |
padding: 5px; | |
vertical-align: top; | |
} | |
#mini-cart a { | |
padding: 5px; | |
} | |
.hc-mini-table { | |
overflow-y: auto; | |
max-height: 500px; | |
display: block; | |
} | |
@media screen and (max-width: 480px) { | |
.hc-mini-table { | |
max-height: 300px; | |
} | |
} | |
#mini-cart .action.buttons a { | |
padding: 16px; | |
width: 100%; | |
text-align: center; | |
display: block; | |
font-size: 14px; | |
margin-bottom: 10px; | |
background: #666; | |
} | |
#mini-cart .action.buttons a.checkout { | |
background: #000; | |
} | |
.cart-grey-btn { | |
background: #666; | |
color: #fff; | |
} | |
#mini-cart a.checkout { | |
float: right; | |
background: #000; | |
color: #fff; | |
} | |
#mini-cart .item-price { | |
float: right; | |
margin-right: 24px; | |
margin-top: 18px; | |
margin-left: 10px; | |
} | |
.custom-overlay { | |
display: none; | |
position: fixed; | |
width: 100%; | |
height: 100%; | |
background: rgba(0, 0, 0, 0.5); | |
top: 0; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
z-index: 99; | |
} | |
.action.buttons { | |
overflow: hidden; | |
position: absolute; | |
width: 95%; | |
bottom: 0; | |
text-transform: uppercase; | |
} | |
#mini-cart .action.buttons a:hover { | |
opacity: .9; | |
color: #fff; | |
} | |
.float-left { | |
float: left; | |
} | |
.hc-close { | |
float: right; | |
font-size: 20px; | |
font-weight: bold; | |
cursor: pointer; | |
border-radius: 50%; | |
width: 21px; | |
text-align: center; | |
} | |
.td-image{ | |
width: 100px; | |
} | |
#mini-cart a { | |
padding: 10px 15px; | |
background-color: #ffffff; | |
border: 1px solid #e8e9eb; | |
} | |
input.quantity-input { | |
width: 41px; | |
display: inline-block; | |
text-align: center; | |
padding: 10px 0px; | |
} | |
#mini-cart a.hc-remove { | |
float: right; | |
vertical-align: top; | |
display: inline-block; | |
padding: 0px 5px; | |
margin-top: 7.5px; | |
} | |
.mini_cart_title_price { | |
display: block; | |
width: 100%; | |
clear: both; | |
position: relative; | |
margin-bottom: 10px; | |
} | |
.mini_cart_title_price div { | |
display: inline-block; | |
} | |
td.td-image img { | |
max-height: 100px; | |
height: 100%; | |
width: initial; | |
} | |
#mini-cart .hc-buttons.action.buttons { | |
z-index: 999999; | |
position: relative; | |
} | |
@media screen and (max-width: 767px) { | |
#mini-cart { | |
width: 100%; | |
} | |
#mini-cart .item-price, | |
#mini-cart a.hc-remove { | |
float: none; | |
} | |
#mini-cart .action.buttons a { | |
padding: 10px; | |
} | |
form.cart { | |
height: 87vh; | |
} | |
} | |
div#mini-cart.mini-cart-popup { | |
display: none; | |
} | |
.mini_cart_trigger { | |
padding: 11px; | |
} | |
div#mini-cart.mini-cart-popup { | |
right: 0; | |
height: initial; | |
top: 40px; | |
width: 360px; | |
bottom: initial; | |
left: initial; | |
position: absolute; | |
} | |
div#mini-cart.mini-cart-popup .hc-append { | |
max-height: initial; | |
overflow-x: hidden; | |
} | |
div#mini-cart.mini-cart-popup td.td-image img { | |
max-height: initial; | |
height: initial; | |
width: 100%; | |
vertical-align: middle; | |
display: inline-block; | |
} | |
div#mini-cart.mini-cart-popup .mini_cart_title_price { | |
font-size: 14px; | |
} | |
.mini_cart_trigger:hover + div#mini-cart.mini-cart-popup, | |
div#mini-cart.mini-cart-popup:hover { | |
display: block !important; /* Overwriting js script */ | |
} | |
div#mini-cart.mini-cart-popup table td { | |
vertical-align: middle; | |
} | |
@media screen and (max-width: 767px) { | |
div#mini-cart.mini-cart-popup { | |
width: 300px; | |
} | |
div#mini-cart.mini-cart-popup .item-price, | |
div#mini-cart.mini-cart-popup a.hc-remove { | |
float: right; | |
clear: both; | |
display: block; | |
} | |
} | |
</style> | |
<script> | |
$(function() { | |
$('.slide_out_cart_trigger, .custom-overlay').click(function(event) { | |
event.preventDefault(); | |
$(".custom-overlay").toggle(); | |
jQuery('body').toggleClass('active_slide_cart'); | |
}); | |
$('.hc-close').click(function() { | |
$(".custom-overlay").hide(); | |
jQuery('body').removeClass('active_slide_cart'); | |
}); | |
$(document).on('click', '.plus-quantity',function(e){ | |
e.preventDefault(); | |
var $input = $(this).siblings('.quantity-input'); | |
var newValue = parseInt($input.val()) + 1; | |
$input.val(newValue).trigger('change'); | |
return false; | |
}); | |
$(document).on('click', '.minus-quantity',function(e){ | |
e.preventDefault(); | |
var $input = $(this).siblings('.quantity-input'); | |
var newValue = parseInt($input.val()) - 1; | |
$input.val(newValue).trigger('change'); | |
return false; | |
}); | |
$(document).on('click', '.hc-remove',function(e){ | |
e.preventDefault(); | |
var $input = $(this).siblings('.quantity-input'); | |
$input.val('0').trigger('change'); | |
return false; | |
}); | |
$(document).on('change', '.quantity-input', function() { | |
var $update = {}; | |
$update[$(this).closest('.item-details').data('id')] = parseInt($(this).val()); | |
$.ajax({ | |
method: 'POST', | |
datatype: 'json', | |
data: { updates: $update }, | |
url: '/cart/update.js', | |
success: function(){ | |
// console.log('success'); | |
}, | |
error: function(message){ | |
if (message['status'] == 200) { | |
$.getJSON('/cart.js', function(cart) { | |
var size = cart.item_count; | |
$('.hc-items-count').text(size); | |
$('.hc-mini-table').remove(); | |
$('.amount').text(Shopify.formatMoney(cart.total_price, Shopify.moneyFormat)); | |
$('.hc-append').append('<table class="hc-mini-table">'); | |
$(cart.items).each(function(index, item) { | |
$('.hc-mini-table').append('<tr class="item-details" data-id="'+item.id+'"><td class="td-image"><img src="' + item.image + '" /></td><td><div class="mini_cart_title_price"><div>' + item.product_title + ' ' + item.variant_title + '</div><span class="item-price">' + Shopify.formatMoney(item.price, theme.moneyFormat) + '</span></div><a href class="minus-quantity">−</a><input type="text" class="quantity-input" value="' + item.quantity + '"><a href class="plus-quantity">+</a><a class="hc-remove" href="">Remove</a></td></tr>'); | |
}); | |
$('.hc-append').append('</table>'); | |
$('#CartCount > span').text(size); | |
}); | |
} | |
} | |
}); | |
return false; | |
}); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment