Skip to content

Instantly share code, notes, and snippets.

@freakdesign
Last active September 15, 2022 20:53
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save freakdesign/7c309cf8c4d78993c396 to your computer and use it in GitHub Desktop.
Save freakdesign/7c309cf8c4d78993c396 to your computer and use it in GitHub Desktop.
Add a previous Shopify order to the cart

#Add order to cart

If you've got awesome Shopify customers that return each month to buy the same thing you don't want to force them to have to re-add everything to cart each time. With some theme edits it's possible to add a feature that does just this - let's explore some very example Liquid and JavaScript code.

Relates to the blog post How to create a button to let customers repeat their previous order

To use, create a snippet called 'order-to-cart.liquid' and paste the content of the gist in. In order.liquid just add {% include 'order-to-cart' %} wherever you like.

Now if you just want to use permalinks instead you could use this bit of magic instead:

<a href="/cart/{% for line_item in order.line_items %}{{ line_item.variant_id }}:{{ line_item.quantity }}{% unless forloop.last %},{% endunless %}{% endfor %}">Reorder this</a>
{% if order.line_items.size > 0 %}
<p>
<button class="btn place-same-order">Add order to cart</button>
<script>
(function(){
/* Check for the button */
var buttonOrder = document.getElementsByClassName('place-same-order') || false;
if(!buttonOrder){ return }
/* Setup the order object. Extend this as needed. */
var order = {
items:[
{% for line_item in order.line_items %}
{
variant_id: {{ line_item.variant.id | json }},
product_id: {{ line_item.product.id | json }},
properties: {{ line_item.properties | json }},
available: {{ line_item.variant.available | json }}
}{% unless forloop.last %},{% endunless %}
{% endfor %}
]
};
/* Simple function to check the queue */
var checkQueue = function(){
order.items.shift();
if(order.items.length){
orderItems()
}else{
window.location.href = '/cart';
}
};
/* Simple function add to cart */
var orderItems = function(){
if(!order.items.length){ return }
if(!order.items[0].available){
checkQueue();
}
var request = new XMLHttpRequest();
request.open('post', '/cart/add.js', true);
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.onload = function() {
var resp = request.responseText;
if (request.status >= 200 && request.status < 400) {
checkQueue();
} else { /* add your error handling in here */ }
};
request.onerror = function() {
/* add your error handling in here */
};
request.send(JSON.stringify({
'quantity':order.items[0].quantity,
'id':order.items[0].variant_id
}));
};
buttonOrder[0].addEventListener("click", function (event) {
event.preventDefault();
/* Get the button we just clicked */
var t = event.target || event.srcElement;
/* Very simple method to stop a double click. You should make something fancier. */
t.setAttribute('disabled','disabled');
t.innerHTML = 'Adding to cart...';
/* Fire the function that adds to cart */
orderItems();
});
})();
</script>
</p>
{% endif %}
@markgenest
Copy link

Hi there,

Great snippet! Works well for me, with one issue. Each of my products may or may not display custom line item properties.

The script seems to call them on line 18:

properties: {{ line_item.properties | json }}

But they don't display when added back into the cart. Do I need to modify my cart.liquid? I am calling them in my cart like so:

            {% if property_size > 0 %}

                  {% for p in item.properties %}
                    {% assign first_character_in_key = p.first | truncate: 1, '' %}
                    {% unless p.last == blank or first_character_in_key == '_' %}
                      <div class="label-info">{{ p.first }}:
                        <strong class="input-info">{{ p.last }}</strong>
                      </div>
                    {% endunless %}
                  {% endfor %}

            {% endif %}

I'm not the best at liquid and am newer to Shopify, so any help you could provide would be greatly appreciated.

Thanks so much!
Mark

@bretto36
Copy link

For anyone else who is using this. It works well, it just doesn't put the quantity in
Add this line in the json creator so that if they ordered more than 1 item it comes through
quantity: {{ line_item.quantity | json }},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment