Shopify themes, liquid, logos, and UX
Hello,
I have a big issue when trying to update number of products in my shop's cart (https://drwunder.pl/cart). While increasing amount of products in cart, by clicking "+", my shop is redirecting straight into checkout page. How can I achieve a proper functionality of my cart (clicking + and the value of cart is increasing like in a normal shop).
Underneath attaching some files, which can be associated with my issue 🙂
AJAX-CART-TEMPLATE.LIQUID:
<!-- /snippets/ajax-cart-template.liquid -->
{% comment %}
This snippet provides the default handlebars.js templates for
the ajax cart plugin. Use the raw liquid tags to keep the
handlebar.js template tags as available hooks.
{% endcomment %}
<script id="CartTemplate" type="text/template">
{% raw %}
<form action="/cart" method="post" novalidate class="cart ajaxcart">
<ul class="ajaxcart__inner">
{{#items}}
<li class="ajaxcart__product">
<div class="ajaxcart row" data-line="{{line}}">
<div class="item_img"><a href="{{url}}" class="ajaxcart__product-image"> <img src="{{img}}" alt=""></a> </a></div>
<div class="details">
<h6><a href="{{url}}" class="ajaxcart__product-name">{{name}}</a></h6>
<div class="item-desc">
<div class="item_dtl">
{{#if variation}}
<p class="ajaxcart__product-meta">{{variation}}</p>
{{/if}}
{{#properties}}
{{#each this}}
{{#if this}}
<span class="ajaxcart__product-meta">{{@key}}: {{this}}</span>
{{/if}}
{{/each}}
{{/properties}}
{% endraw %}{% if settings.cart_vendor_enable %}{% raw %}
<span class="ajaxcart__product-meta">{{ vendor }}</span>
{% endraw %}{% endif %}{% raw %}
<div class="pricing">
{{#if discountsApplied}}
<span class="hidden">{% endraw %}{{ 'products.general.sale_price' | t }}{% raw %}</span>
<span class="ajaxcart__price onsale"><span class="money">{{{discountedPrice}}}</span></span>
<span class="hidden">{% endraw %}{{ 'products.general.regular_price' | t }}{% raw %}</span>
<del class="ajaxcart__price"><span class="money">{{{price}}}</span></del>
{{else}}
<span class="ajaxcart__price"><span class="money">{{{price}}}</span></span>
{{/if}}
{{#if discountsApplied}}
{{#each discounts}}
<p class="onsale"><i class="la la-tag"></i> {{ this.discount_application.title }} (-<span class="money">{{{ this.formattedAmount }}}</span>)</p>
{{/each}}
{{/if}}
</div>
</div>
<div class="ajaxcart__qty product-item-caption-qty">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--minus quantity-increment" data-id="{{id}}" data-qty="{{itemMinus}}" data-line="{{line}}">
<span>−</span>
</button>
<input type="text" name="updates[]" class="ajaxcart__qty-num input-number" value="{{itemQty}}" min="0" data-id="{{id}}" data-line="{{line}}" aria-label="quantity" pattern="[0-9]*">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--plus quantity-increment" data-id="{{id}}" data-line="{{line}}" data-qty="{{itemAdd}}">
<span>+</span>
</button>
</div>
<span id="changeQty" class="ajaxcart__qty-remove remove-btn dt-sc-btn close-icon" data-id="{{key}}" data-line="{{line}}" data-qty="{{itemAdd}}"></span>
</div>
</div>
</div>
</div>
{{/items}}
{% endraw %}{% if settings.cart_notes_enable %}{% raw %}
<div class="rte-accordion row">
<div id="cart-notes" class="item">
<label class="accordion-label" for="item-one"><span class="item-heading">{% endraw %}{{ 'cart.general.note' | t }}{% raw %}</span></label>
<div class="item-content">
<textarea name="note" id="note" rows="5" cols="60">{{note}}</textarea>
</div>
</div>
</li>
{% endraw %}{% endif %}{% raw %}
</ul>
<div class="ajaxcart__footer row">
<div class="subtotal">
<p class="title">{% endraw %}{{ 'cart.label.total' | t }}{% raw %}</p>
<p class="subtotal-price"><span class="cart-original-total money">{{{subTotalPrice}}}</span></p>
</div>
{% endraw %}{%- if settings.show_tax_note -%}{% raw %}
<div class="tax">
<p class="title">{% endraw %}{{ 'cart.general.tax' | t }}{% raw %}</p>
<p class="value">{% endraw %}{{ 'cart.general.at_checkout' | t }}{% raw %}</p>
</div>
{% endraw %}{%- endif -%}{% raw %}
{% endraw %}{%- if settings.show_shipping_note -%}{% raw %}
<div class="shipping">
<p class="title">{% endraw %}{{ 'cart.general.shipping' | t }}{% raw %}</p>
<p class="value">{% endraw %}{{ 'cart.general.at_checkout' | t }}{% raw %}</p>
</div>
{% endraw %}{%- endif -%}{% raw %}
<div class="discounts">
{{#if cartDiscountsApplied}}
<p>{% endraw %}{{ 'cart.general.discounts' | t }}{% raw %}</p>
<ul>
{{#each cartDiscounts}}
<li><i class="la la-tag"></i> (-<span class="money">{{{ this.formattedAmount }}}</span>)</li>
{{/each}}
</ul>
{{/if}}
{{#if cartTotalSavings}}
<div class="cart_savings onsale">
<p><em>{% endraw %}{{ 'cart.general.savings_html' | t }}{% raw %}</em></p>
<p class="cart-savings-amount"><em><span class="money">{{cartTotalDiscounts}}</span></em></p>
</div>
{{/if}}
</div>
<div class="total">
<p>{% endraw %}{{ 'cart.general.shipping_at_checkout' | t }}{% raw %}</p>
</div>
<button type="submit" class="cart__checkout dt-sc-btn" name="checkout">
{% endraw %}{{ 'cart.general.checkout' | t }}{% raw %}
</button>
{% endraw %}{% if additional_checkout_buttons %}
<div class="additional_checkout_buttons">{{ content_for_additional_checkout_buttons }}</div>
{% endif %}{% raw %}
<a class="dt-sc-btn" href="/cart">{% endraw %}{{ 'cart.general.view_cart' | t }} {% raw %}</a>
</div>
</form>
{% endraw %}
</script>
<script id="AjaxQty" type="text/template">
{% raw %}
<div class="ajaxcart__qty">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--minus icon-fallback-text" data-id="{{id}}" data-qty="{{itemMinus}}">
<span class="icon icon-minus" aria-hidden="true"></span>
<span class="fallback-text">−</span>
</button>
<input type="text" class="ajaxcart__qty-num" value="{{itemQty}}" min="0" data-id="{{id}}" aria-label="quantity" pattern="[0-9]*">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--plus icon-fallback-text" data-id="{{id}}" data-qty="{{itemAdd}}">
<span class="icon icon-plus" aria-hidden="true"></span>
<span class="fallback-text">+</span>
</button>
</div>
<span id="changeQty" class="ajaxcart__qty-adjust remove-btn" data-id="{{key}}" data-line="{{line}}" data-qty="{{itemAdd}}"><i class="fa fa-trash" aria-hidden="true"></i></span>
{% endraw %}
</script>
<script id="JsQty" type="text/template">
{% raw %}
<div class="js-qty">
<button type="button" class="js-qty__adjust js-qty__adjust--minus quantity-increment hide" data-id="{{id}}" data-qty="{{itemMinus}}">
<span>−</span>
</button>
<input type="number" class="js-qty__num" value="{{itemQty}}" min="1" data-id="{{id}}" aria-label="quantity" pattern="[0-9]*" name="{{inputName}}" id="{{inputId}}" >
<button type="button" class="js-qty__adjust js-qty__adjust--plus quantity-increment hide" data-id="{{id}}" data-qty="{{itemAdd}}">
<span>+</span>
</button>
</div>
<span id="changeQty" class="ajaxcart__qty-adjust remove-btn" data-id="{{key}}" data-line="{{line}}" data-qty="{{itemAdd}}"><i class="fa fa-trash" aria-hidden="true"></i></span>
{% endraw %}
</script>
{% if settings.ajax_cart_method == 'drawer' %}
<script>
jQuery(function($) {
ajaxCart.init({
formSelector: '[data-product-form]',
cartContainer: '#CartContainer',
addToCartSelector: '.dT_AddToCart',
cartCountSelector: '.CartCount',
cartCostSelector: '.CartCost',
moneyFormat: {{ shop.money_format | json }}
});
});
jQuery('body').on('ajaxCart.afterCartLoad', function(evt, cart) {
theme.RightDrawer.open();
});
{% if settings.show_multiple_currencies %}
jQuery('body').on('ajaxCart.afterCartLoad', function(evt, cart) {
Currency.convertAll(shopCurrency, Currency.currentCurrency);
});
{% endif %}
</script>
{% endif %}
{% if template contains 'product' %}
<script type="text/javascript">
var recentlyViewed = $('.recently-viewed-products');
if ( recentlyViewed.length ) {
Shopify.Products.recordRecentlyViewed();
}
</script>
{% endif %}
AJAX-CART.JS.LIQUID:
/*============================================================================
Ajax the add to cart experience by revealing it in a side drawer
Plugin Documentation - http://shopify.github.io/Timber/#ajax-cart
(c) Copyright 2015 Shopify Inc. Author: Carson Shold (@cshold). All Rights Reserved.
This file includes:
- Basic Shopify Ajax API calls
- Ajax cart plugin
This requires:
- jQuery 1.8+
- handlebars.min.js (for cart template)
- modernizer.min.js
- snippet/ajax-cart-template.liquid
Customized version of Shopify's jQuery API
(c) Copyright 2009-2015 Shopify Inc. Author: Caroline Schnapp. All Rights Reserved.
==============================================================================*/
if ((typeof ShopifyAPI) === 'undefined') { ShopifyAPI = {}; }
/*============================================================================
API Helper Functions
==============================================================================*/
function attributeToString(attribute) {
if ((typeof attribute) !== 'string') {
attribute += '';
if (attribute === 'undefined') {
attribute = '';
}
}
return jQuery.trim(attribute);
};
/*============================================================================
API Functions
==============================================================================*/
ShopifyAPI.onCartUpdate = function(cart) {
// alert('There are now ' + cart.item_count + ' items in the cart.');
};
ShopifyAPI.updateCartNote = function(note, callback) {
var params = {
type: 'POST',
url: '/cart/update.js',
data: 'note=' + attributeToString(note),
dataType: 'json',
success: function(cart) {
if ((typeof callback) === 'function') {
callback(cart);
}
else {
ShopifyAPI.onCartUpdate(cart);
}
},
error: function(XMLHttpRequest, textStatus) {
ShopifyAPI.onError(XMLHttpRequest, textStatus);
}
};
jQuery.ajax(params);
};
ShopifyAPI.onError = function(XMLHttpRequest, textStatus) {
var data = eval('(' + XMLHttpRequest.responseText + ')');
if (!!data.message) {
alert(data.message + '(' + data.status + '): ' + data.description);
}
};
/*============================================================================
POST to cart/add.js returns the JSON of the cart
- Allow use of form element instead of just id
- Allow custom error callback
==============================================================================*/
ShopifyAPI.addItemFromForm = function(form, callback, errorCallback) {
var params = {
type: 'POST',
url: '/cart/add.js',
data: jQuery(form).serialize(),
dataType: 'json',
success: function(line_item) {
if ((typeof callback) === 'function') {
callback(line_item, form);
}
else {
ShopifyAPI.onItemAdded(line_item, form);
}
},
error: function(XMLHttpRequest, textStatus) {
if ((typeof errorCallback) === 'function') {
errorCallback(XMLHttpRequest, textStatus);
}
else {
ShopifyAPI.onError(XMLHttpRequest, textStatus);
}
}
};
jQuery.ajax(params);
};
// Get from cart.js returns the cart in JSON
ShopifyAPI.getCart = function(callback) {
jQuery.getJSON('/cart.js', function (cart, textStatus) {
if ((typeof callback) === 'function') {
callback(cart);
}
else {
ShopifyAPI.onCartUpdate(cart);
}
});
};
// POST to cart/change.js returns the cart in JSON
ShopifyAPI.changeItem = function(line, quantity, callback) {
var params = {
type: 'POST',
url: '/cart/change.js',
data: 'quantity=' + quantity + '&line=' + line,
dataType: 'json',
success: function(cart) {
if ((typeof callback) === 'function') {
callback(cart);
}
else {
ShopifyAPI.onCartUpdate(cart);
}
},
error: function(XMLHttpRequest, textStatus) {
ShopifyAPI.onError(XMLHttpRequest, textStatus);
}
};
jQuery.ajax(params);
};
/*============================================================================
Ajax Shopify Add To Cart
==============================================================================*/
var ajaxCart = (function(module, $) {
'use strict';
// Public functions
var init, loadCart;
// Private general variables
var settings, isUpdating, $body;
// Private plugin variables
var $formContainer, $addToCart, $cartCountSelector, $cartCostSelector, $cartContainer, $drawerContainer;
// Private functions
var updateCountPrice, formOverride, itemAddedCallback, itemErrorCallback, cartUpdateCallback, buildCart, cartCallback, adjustCart, adjustCartCallback, createQtySelectors, qtySelectors, validateQty;
/*============================================================================
Initialise the plugin and define global options
==============================================================================*/
init = function (options) {
// Default settings
settings = {
formSelector : 'form[action^="/cart/add"]',
cartContainer : '#CartContainer',
addToCartSelector : 'input[type="submit"]',
cartCountSelector : 'CartCount',
cartCostSelector : null,
moneyFormat : '${{amount}}',
disableAjaxCart : false,
enableQtySelectors : true
};
// Override defaults with arguments
$.extend(settings, options);
// Select DOM elements
$formContainer = $(settings.formSelector);
$cartContainer = $(settings.cartContainer);
$addToCart = $formContainer.find(settings.addToCartSelector);
$cartCountSelector = $(settings.cartCountSelector);
$cartCostSelector = $(settings.cartCostSelector);
// General Selectors
$body = $('body');
// Track cart activity status
isUpdating = false;
// Setup ajax quantity selectors on the any template if enableQtySelectors is true
if (settings.enableQtySelectors) {
qtySelectors();
}
// Take over the add to cart form submit action if ajax enabled
if (!settings.disableAjaxCart && $addToCart.length) {
formOverride();
}
// Run this function in case we're using the quantity selector outside of the cart
adjustCart();
};
loadCart = function () {
$body.addClass('drawer--is-loading');
ShopifyAPI.getCart(cartUpdateCallback);
};
updateCountPrice = function (cart) {
if ($cartCountSelector) {
$cartCountSelector.html(cart.item_count).removeClass('hidden-count');
if (cart.item_count === 0) {
$cartCountSelector.addClass('hidden-count');
}
}
if ($cartCostSelector) {
$cartCostSelector.html(Shopify.formatMoney(cart.total_price, settings.moneyFormat));
}
};
formOverride = function () {
$formContainer.on('submit', function(evt) {
evt.preventDefault();
// Add class to be styled if desired
$addToCart.removeClass('is-added').addClass('is-adding');
// Remove any previous quantity errors
$('.qty-error').remove();
ShopifyAPI.addItemFromForm(evt.target, itemAddedCallback, itemErrorCallback);
});
};
itemAddedCallback = function (product) {
$addToCart.removeClass('is-adding').addClass('is-added');
ShopifyAPI.getCart(cartUpdateCallback);
};
itemErrorCallback = function (XMLHttpRequest, textStatus) {
var data = eval('(' + XMLHttpRequest.responseText + ')');
$addToCart.removeClass('is-adding is-added');
if (!!data.message) {
if (data.status == 422) {
var $addButtoncontainer = $formContainer.find('.product-add');
$addButtoncontainer.before('<div class="errors qty-error">'+ data.description +'</div>')
}
}
};
cartUpdateCallback = function (cart) {
// Update quantity and price
updateCountPrice(cart);
buildCart(cart);
};
buildCart = function(cart) {
// Start with a fresh cart div
$cartContainer.empty();
// Show empty cart
if (cart.item_count === 0) {
$cartContainer
.append('<p class="cart-content"> Your cart is currently empty. <a class="dt-sc-btn" href="/collections/all">Continue Shopping</a></p>');
cartCallback(cart);
return;
}
// Handlebars.js cart layout
var items = [],
item = {},
data = {},
source = $('#CartTemplate').html(),
template = Handlebars.compile(source);
// Add each item to our handlebars.js data
$.each(cart.items, function(index, cartItem) {
/* Hack to get product image thumbnail
* - If image is not null
* - Remove file extension, add _small, and re-add extension
* - Create server relative link
* - A hard-coded url of no-image
*/
var prodImg;
if (cartItem.image !== null) {
prodImg = cartItem.image
.replace(/(\.[^.]*)$/, '_medium$1')
.replace('http:', '');
} else {
prodImg =
'//cdn.shopify.com/s/assets/admin/no-image-medium-cc9732cb976dd349a0df1d39816fbcc7.gif';
}
if (cartItem.properties !== null) {
$.each(cartItem.properties, function(key, value) {
if (key.charAt(0) === '_' || !value) {
delete cartItem.properties[key];
}
});
}
if (cartItem.properties !== null) {
$.each(cartItem.properties, function(key, value) {
if (key.charAt(0) === '_' || !value) {
delete cartItem.properties[key];
}
});
}
if (cartItem.line_level_discount_allocations.length !== 0) {
for (var discount in cartItem.line_level_discount_allocations) {
var amount =
cartItem.line_level_discount_allocations[discount].amount;
cartItem.line_level_discount_allocations[
discount
].formattedAmount = Shopify.formatMoney(
amount,
settings.moneyFormat
);
}
}
if (cart.cart_level_discount_applications.length !== 0) {
for (var cartDiscount in cart.cart_level_discount_applications) {
var cartAmount =
cart.cart_level_discount_applications[cartDiscount]
.total_allocated_amount;
cart.cart_level_discount_applications[
cartDiscount
].formattedAmount = Shopify.formatMoney(
cartAmount,
settings.moneyFormat
);
}
}
// Create item's data object and add to 'items' array
item = {
key: cartItem.key,
line: index + 1, // Shopify uses a 1+ index in the API
url: cartItem.url,
img: prodImg,
name: cartItem.product_title,
variation: cartItem.variant_title,
properties: cartItem.properties,
itemAdd: cartItem.quantity + 1,
itemMinus: cartItem.quantity - 1,
itemQty: cartItem.quantity,
price: Shopify.formatMoney(
cartItem.original_line_price,
settings.moneyFormat
),
discountedPrice: Shopify.formatMoney(
cartItem.final_line_price,
settings.moneyFormat
),
discounts: cartItem.line_level_discount_allocations,
discountsApplied:
cartItem.line_level_discount_allocations.length === 0 ? false : true,
vendor: cartItem.vendor
};
items.push(item);
});
// Gather all cart data and add to DOM
data = {
items: items,
note: cart.note,
subTotalPrice: Shopify.formatMoney(
cart.items_subtotal_price,
settings.moneyFormat
),
totalPrice: Shopify.formatMoney(
cart.total_price,
settings.moneyFormat
),
cartTotalDiscounts: Shopify.formatMoney(
cart.total_discount,
settings.moneyFormat
),
cartDiscounts: cart.cart_level_discount_applications,
cartDiscountsApplied:
cart.cart_level_discount_applications.length === 0 ? false : true,
cartTotalSavings: cart.cart_level_discount_applications.length === 0 && cart.total_discount > 0
};
$cartContainer.append(template(data));
cartCallback(cart);
};
cartCallback = function(cart) {
$body.removeClass('drawer--is-loading');
$body.trigger('ajaxCart.afterCartLoad', cart);
if (window.Shopify && Shopify.StorefrontExpressButtons) {
Shopify.StorefrontExpressButtons.initialize();
}
};
adjustCart = function () {
// Delegate all events because elements reload with the cart
// Add or remove from the quantity
$body.on('click', '.ajaxcart__qty-adjust', function() {
var $el = $(this),
line = $el.data('line'),
$qtySelector = $el.siblings('.ajaxcart__qty-num'),
qty = parseInt($qtySelector.val().replace(/\D/g, ''));
var qty = validateQty(qty);
// Add or subtract from the current quantity
if ($el.hasClass('ajaxcart__qty--plus')) {
qty += 1;
} else {
qty -= 1;
if (qty <= 0) qty = 0;
}
// If it has a data-line, update the cart.
// Otherwise, just update the input's number
if (line) {
updateQuantity(line, qty);
} else {
$qtySelector.val(qty);
}
});
// Add or remove from the quantity
$body.on('click', '.ajaxcart__qty-remove', function() {
var $el = $(this),
line = $el.data('line'),
$qtySelector = $el.siblings('.ajaxcart__qty-num'),
qty = parseInt($qtySelector.val());
if (!isNaN(qty)) {
var qty = validateQty(qty);
}
else
{
qty = 0;
}
if (line) {
updateQuantity(line, qty);
} else {
$qtySelector.val(qty);
}
});
// Update quantity based on input on change
$body.on('change', '.ajaxcart__qty-num', function() {
var $el = $(this),
line = $el.data('line'),
qty = parseInt($el.val().replace(/\D/g, ''));
var qty = validateQty(qty);
// If it has a data-line, update the cart
if (line) {
updateQuantity(line, qty);
}
});
// Prevent cart from being submitted while quantities are changing
$body.on('submit', 'form.ajaxcart', function(evt) {
if (isUpdating) {
evt.preventDefault();
}
});
// Highlight the text when focused
$body.on('focus', '.ajaxcart__qty-adjust', function() {
var $el = $(this);
setTimeout(function() {
$el.select();
}, 50);
});
function updateQuantity(line, qty) {
isUpdating = true;
// Add activity classes when changing cart quantities
var $row = $('.ajaxcart__row[data-line="' + line + '"]').addClass('is-loading');
if (qty === 0) {
$row.parent().addClass('is-removed');
}
// Slight delay to make sure removed animation is done
setTimeout(function() {
ShopifyAPI.changeItem(line, qty, adjustCartCallback);
}, 250);
}
// Save note anytime it's changed
$body.on('change', 'textarea[name="note"]', function() {
var newNote = $(this).val();
// Update the cart note in case they don't click update/checkout
ShopifyAPI.updateCartNote(newNote, function(cart) {});
});
};
adjustCartCallback = function (cart) {
isUpdating = false;
// Update quantity and price
updateCountPrice(cart);
// Reprint cart on short timeout so you don't see the content being removed
setTimeout(function() {
ShopifyAPI.getCart(buildCart);
}, 150)
};
createQtySelectors = function() {
// If there is a normal quantity number field in the ajax cart, replace it with our version
if ($('input[type="number"]', $cartContainer).length) {
$('input[type="number"]', $cartContainer).each(function() {
var $el = $(this),
currentQty = $el.val();
var itemAdd = currentQty + 1,
itemMinus = currentQty - 1,
itemQty = currentQty;
var source = $("#AjaxQty").html(),
template = Handlebars.compile(source),
data = {
id: $el.data('id'),
itemQty: itemQty,
itemAdd: itemAdd,
itemMinus: itemMinus
};
// Append new quantity selector then remove original
$el.after(template(data)).remove();
});
}
};
qtySelectors = function() {
// Change number inputs to JS ones, similar to ajax cart but without API integration.
// Make sure to add the existing name and id to the new input element
var numInputs = $('input[type="number"]');
if (numInputs.length) {
numInputs.each(function() {
var $el = $(this),
currentQty = $el.val(),
inputName = $el.attr('name'),
inputId = $el.attr('id');
var itemAdd = currentQty + 1,
itemMinus = currentQty - 1,
itemQty = currentQty;
var source = $("#JsQty").html(),
template = Handlebars.compile(source),
data = {
id: $el.data('id'),
itemQty: itemQty,
itemAdd: itemAdd,
itemMinus: itemMinus,
inputName: inputName,
inputId: inputId
};
// Append new quantity selector then remove original
$el.after(template(data)).remove();
});
// Setup listeners to add/subtract from the input
$('.js-qty__adjust').on('click', function() {
var $el = $(this),
id = $el.data('id'),
$qtySelector = $el.siblings('.js-qty__num'),
qty = parseInt($qtySelector.val().replace(/\D/g, ''));
var qty = validateQty(qty);
// Add or subtract from the current quantity
if ($el.hasClass('js-qty__adjust--plus')) {
qty += 1;
} else {
qty -= 1;
if (qty <= 1) qty = 1;
}
});
}
};
validateQty = function (qty) {
if((parseFloat(qty) == parseInt(qty)) && !isNaN(qty)) {
// We have a valid number!
} else {
// Not a number. Default to 1.
qty = 1;
}
return qty;
};
module = {
init: init,
load: loadCart
};
return module;
}(ajaxCart || {}, jQuery));
CART-TEMPLATE.LIQUID:
<div class="counter-wrapper">
W związku z wysokim zainteresowaniem, dostępność towaru szybko maleje. Twoje zamówienie zostało zarezerwowane na
<span class="counter">15:00</span>
minut.
</div>
<script src="{{ 'dT_shipping-cart.js' | asset_url }}" defer="defer"></script>
<div class="container">
<div class="row">
{% comment %}
This is your /cart template.
{% endcomment %}
{% if cart.item_count > 0 %}
<div class="cart_table">
<form action="/cart" method="post" novalidate class="cart dt-sc-column two-third-one-third ">
<div class="cart__items">
{% if cart.announcements.size > 0 %}
<ul class="note">
{% for announcement in cart.announcements %}
<li>{{ announcement }}</li>
{% endfor %}
</ul>
{% endif %}
{% if cart.errors.size > 0 %}
<ul class="note errors">
{% for error in cart.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<div class="cart__row cart__header-labels"> <h4 class="cart_heading"> {{ 'cart.label.products' | t }} </h4> </div>
{% comment %}
Loop through products in the cart
{% endcomment %}
{% for item in cart.items %}
<div class="cart__row">
<div class="cart_items">
<a href="{{ item.url | within: collections.all }}" class="cart__image">
{% comment %}
More image size options at:
- http://docs.shopify.com/themes/filters/product-img-url
{% endcomment %}
<img src="{{ item | img_url: 'small' }}" alt="{{ item.title | escape }}">
</a>
</div>
<div class="product-info">
<div class="cart-title ">
<h5><a href="{{ item.url }}" class="product-name">
{{ item.product.title }}
</a>
</h5>
{% unless item.variant.title contains 'Default' %}
<p>{{ item.variant.title }}</p>
{% endunless %}
{% if settings.cart_vendor_enable %}
<p>{{ item.vendor }}</p>
{% endif %}
{% comment %}
Optional, loop through custom product line items if available
For more info on line item properties, visit:
- http://docs.shopify.com/support/your-store/products/how-do-I-collect-additional-information-on-the-product-page-Like-for-a-monogram-engraving-or-customization
{% endcomment %}
{% if item.properties.size > 0 %}
{% for p in item.properties %}
{% unless p.last == blank %}
{{ p.first }}:
{% comment %}
Check if there was an uploaded file associated
{% endcomment %}
{% if p.last contains '/uploads/' %}
<a href="{{ p.last }}">{{ p.last | split: '/' | last }}</a>
{% else %}
{{ p.last }}
{% endif %}
<br>
{% endunless %}
{% endfor %}
{% endif %}
</div>
<div class="price ">
<strong> {{ item.price | money }} </strong>
</div>
<div class="qty-box-set">
<input type="button" value="-" class="qtyminus1">
<input type="text" class="quantity-selector cart-number" name="updates[]" id="updates_{{ item.id }}" value="{{ item.quantity }}" min="0">
<input type="button" value="+" class="qtyplus1">
</div>
<div class="price ">
<span class="cart_total">{{ 'cart.general.total' | t }}</span>
<strong>
{{ item.line_price | money }}
{% if item.original_line_price != item.line_price %}
<del class="cart-item__original-price">{{ item.original_line_price | money }}</del>
{% endif %}
</strong>
</div>
{% if item.original_line_price != item.line_price %}
{% for discount in item.discounts %}
<p><small class="cart-item__discount">
{{ discount.title }} - <strong>{{ discount.amount | money }}</strong>
</small>
</p>
{% endfor %}
{% endif %}
</div>
<a href="/cart/change?line={{ forloop.index }}&quantity=0" class="cart__remove close_icon">
<span class="dt-sc-btn close-icon"></span>
</a>
</div>
{% endfor %}
<div class="btn_actions">
<a class="dt-sc-btn" href="/collections/all">{{ 'cart.general.continue_shopping' | t }}</a>
<input type="submit" name="update" class="dt-sc-btn update-cart right" value="{{ 'cart.general.update' | t }}">
</div>
{% if cart.discounts.size > 0 %}
<div class="cart-additional-savings text-right cart__row">
<span class="label cart-additional-savings__label">{{ 'cart.general.additional_savings' | t }}</span>
<span class="h4 cart-additional-savings__price">{{ cart.discount.total_savings | money }}</span>
{% for discount in cart.discounts %}
<small class="cart-additional-savings__savings">{{ discount.title }}</small>
{% endfor %}
</div>
{% endif %}
{% if cart.discounts.size > 0 %}
<div class="cart-additional-savings text-right cart__row">
<span class="label cart-additional-savings__label">{{ 'cart.general.additional_savings' | t }}</span>
<span class="h4 cart-additional-savings__price">{{ cart.discount.total_savings | money }}</span>
{% for discount in cart.discounts %}
<small class="cart-additional-savings__savings">{{ discount.title }}</small>
{% endfor %}
</div>
{% endif %}
</div>
<div class="shipping-section">
<div class="order_summary">
<h4 class="cart_heading">{{ 'cart.general.order_summary' | t }}</h4>
<p class="cart_total_price">
<span class="cart__subtotal-title">{{ 'cart.general.subtotal' | t }}</span>
<span class="cart__subtotal"><span class="zrx-cart-total"><span class="ufe-cart-total-price">{{ cart.total_price | money }}</span></span></span>
</p>
<p>
{% if cart.total_discounts > 0 %}
{% assign savings = cart.total_discounts | money %}
<small class="cart-subtotal__savings"> {{ 'cart.general.savings_html' | t: price: savings }}</small>
{% endif %}
</p>
{% comment %}
Optional, add a textarea for special notes
- Your theme settings can turn this on or off. Default is on.
- Make sure you have name="note" for the message to be submitted properly
{% endcomment %}
{% assign noteSize = cart.note | size %}
<p class="shopping-checkout"><em>{{ 'cart.general.shipping_at_checkout' | t }}</em></p>
{% comment %}
Continue shopping button
{% endcomment %}
<div class="btn_actions">
<a class="continue-btn" href="/collections/all">{{ 'cart.general.continue_shopping' | t }}</a>
<!-- <input type="submit" name="update" class="dt-sc-btn update-cart right" value="{{ 'cart.general.update' | t }}"> -->
</div>
<div class="cart_btn">
<input type="submit" name="checkout" class="shopify-payment-button__button--unbranded" style="width:100%" value="{{ 'cart.general.checkout' | t }}">
</div>
<br>
<br>
<img src="https://cdn.shopify.com/s/files/1/0598/3754/6677/files/up3.jpg?v=1635202230" />
<img src="https://cdn.shopify.com/s/files/1/0598/3754/6677/files/up1.jpg?v=1635202080" />
{% include 'shipping-calculator' %}
</div>
</div>
</form>
</div>
{% else %}
{% comment %}
The cart is empty
{% endcomment %}
<div class="cart_empty_msg">
<img src="{{ "empty-cart.png" | asset_url }}" alt="{{ 'cart.general.empty' | t }}" />
<h4>{{ 'cart.general.empty' | t }}</h4>
<p>{{ 'cart.general.add_items' | t }}</p>
<p><a href="{{ routes.collections_url }}" class='dt-sc-btn'>{{ 'cart.general.start_shop' | t }}</a></p>
</div>
{% endif %}
<img src="https://cdn.shopify.com/s/files/1/0598/3754/6677/files/plat.png?v=1633910688" width="100%" />
</div>
</div>
{% schema %}
{
"name": "Cart page",
"settings": []
}
{% endschema %}
{% stylesheet %}
{% endstylesheet %}
{% javascript %}
{% endjavascript %}
Portrait of Stephen positioned next to an image of planet Earth, with the Stephen's World ...
By JasonH Mar 18, 2024Digital marketers and app developers have tracked activity in apps and websites for yea...
By Ollie Mar 13, 2024February was an exciting month with Shopify Editions, informative webinars, and more! F...
By JasonH Mar 7, 2024