Skip to content

Instantly share code, notes, and snippets.

@CarsonBain
Last active October 15, 2019 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save CarsonBain/996d054123f3bb3c80b8fd5761c953e5 to your computer and use it in GitHub Desktop.
Save CarsonBain/996d054123f3bb3c80b8fd5761c953e5 to your computer and use it in GitHub Desktop.
Order Form Page for Shopify using AJAX API
<header class="section-header mb-0 text-center">
<h1>{{ page.title }}</h1>
<hr class="hr--small">
</header>
<div class="grid">
<div class="grid__item large--four-fifths push--large--one-tenth">
<div class="rte rte--nomargin rte--indented-images">
{{ page.content }}
</div>
</div>
</div>
<!-- Start of order form table -->
<table>
<!-- Button to hide images to clean up form -->
<button type="button" class="btn--small hide-images">Hide Images</button>
<!-- Form Headers -->
<tr>
<th class="image-header">Image</th>
<th class="sku-header">SKU</th>
<th class="product-header">Product</th>
<th class="quantity-header">Quantity</th>
<th class="price-header">Item Price</th>
<th class="subtotal-header">Subtotal</th>
</tr>
{% assign counter = 0 %}
{% for product in collections['quick-order'].products %}
{% for variant in product.variants %}
{% assign outer_forloop = forloop %}
{% assign current_variant = product.selected_or_first_available_variant %}
<tr class="row">
<!-- Image Column -->
<td class="product-images">
<img alt="{{image.alt}}" src="{{ product.featured_image | product_img_url}}">
</td>
<!--SKU Column -->
<td class="sku">
{{ variant.sku }}
</td>
<!-- Title Column -->
<td class="product-title">
<a class="text-link" href="{{ product.url }}" target="_blank">{{ product.title }}</a>
<!--Don't display variant title if there's only one option-->
{% assign hide_default_title = false %}
{% if variant.title contains 'Default' %}
{% assign hide_default_title = true %}
{% endif %}
{% if hide_default_title %}{% else %}<div class="variant-title">{{ variant.title }}</div>{% endif %}
</td>
<!-- Product Qty Textboxes -->
{% assign counter = counter | plus: 1 %}
<td class="quantity" class="input">
<input type="number" class="order-quantity" data-variant-price="{{ variant.price | money_without_currency}}" data-variant="{{ variant.id }}" id="quantity-{{ counter }}" name="quantity" pattern="[0-9]*" value="0" min="0">
</td>
<!-- Item Price -->
<td class="price">
{{ variant.price | money }}
</td>
<!-- Sub Total -->
<td class="subtotal">$<span>0</span></td>
</tr>
{% endfor %}
{% endfor %}
</table>
<!-- Product and Price Total -->
<div class="order-form-totals">
<div class="product_total">
<strong>Product Total:</strong> <span class="product-total-amount">0</span>
</div>
<div class="order_total">
<strong>Order Total:</strong> <span class="order-total-amount">$<span>0</span></span>
</div>
<div>
<input type="submit" value="Add to Cart" class="btn" id="add-items" />
</div>
</div>
<script>
$(document).ready(function () {
//Start with an empty array of items
Shopify.queue = [];
//Watch for all changes on quantity inputs
$('.quantity input').on('input',function() {
//Set an initial flag for a new item
var newItem = true;
//Declare product property variables
var price = $(this).attr('data-variant-price');
var quantity = parseInt($(this).val(), 10) || 0;
var variant = $(this).attr('data-variant');
var totalQuantity = $('.product-total-amount');
var totalPrice = $('.order-total-amount span');
//Function to update the subtotal price, total item quantity, and total price
var totalQuantityCount = 0;
var totalPriceAmount = 0;
function updateTotals($element, prc, qty) {
//Traverse DOM to find subtotal field
var $subtotal = $($element).parent().siblings('.subtotal').find('span')
//Update subtotal column
$subtotal.html((price * quantity).toFixed(2))
//Update total quantity, and total order price elements
for (var index in Shopify.queue) {
totalQuantityCount += Shopify.queue[index].quantity;
totalPriceAmount += Shopify.queue[index].quantity * Shopify.queue[index].price;
}
totalQuantity.html(totalQuantityCount);
totalPrice.html(totalPriceAmount.toFixed(2));
}
//Check the queue and add items
//If queue is empty, add the item and update totals
if(Shopify.queue.length <= 0) {
Shopify.queue.push( {
variantId: variant,
quantity: quantity,
price: price
});
updateTotals($(this), price, quantity);
}
//If queue contains items, check to see if the item exists already
//If item exists, update quantity values, totals, then exit
else if (Shopify.queue.length > 0) {
for (var index in Shopify.queue) {
if(parseInt(Shopify.queue[index].variantId) == variant) {
Shopify.queue[index].quantity = quantity;
newItem = false;
updateTotals($(this), price, quantity);
return;
}
}
//If item doesn't exist in queue, add item to queue and update totals
if(newItem == true) {
Shopify.queue.push({
variantId: variant,
quantity: quantity,
price: price
});
updateTotals($(this), price, quantity);
}
}
});
//Add item to cart AJAX request function
Shopify.addItem = function(variant,qty,callback) {
var params = {
quantity: qty,
id: variant
};
$.ajax({
type: 'POST',
url: '/cart/add.js',
dataType: 'json',
data: params,
success: function(){
if(typeof callback === 'function'){
callback();
}
},
error: function(request){
alert(request.responseJSON.description + ' Please try again');
$('#add-items').val('Add to cart');
}
});
};
Shopify.moveAlong = function($element) {
// If we still have requests in the queue, let's process the next one.
if (Shopify.queue.length) {
var request = Shopify.queue.shift();
Shopify.addItem(request.variantId, request.quantity, Shopify.moveAlong);
}
// If the queue is empty, redirect to the cart page.
else {
document.location.href = '/cart';
}
};
//Run when clicking Add to Cart
$("#add-items").click(function(e) {
e.preventDefault();
Shopify.moveAlong($(this));
$(this).val('Adding items...');
});
//Function to hide image column if user chooses
$('.hide-images').click(function() {
$('.image-header, .product-images').toggle();
if ($('.hide-images').text() === 'Hide Images') {
$('.hide-images').text('Show Images');
} else $(this).text('Hide Images');
});
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment