Reputation: 1608
I am trying to prevent orders with more than one collection from being checked out. If there's more than one collection, i just want to disable the checkout button. I know the syntax is bad, but i want to do something like this.
{% for item in cart.collections %}
{% if item.collection.length > 1 %}
<button disabled>Cant checkout</button>
{% else %}
<button disabled>Can checkout</button>
{% endif %}
This is the current code for the button
<div class="cart__checkout-wrapper">
<button disabled id="button" type="submit" name="checkout" data-terms-required="{{ settings.cart_terms_conditions_enable }}" class="btn cart__checkout">
{{ 'cart.general.checkout' | t }}
</button>
{% if additional_checkout_buttons and settings.cart_additional_buttons %}
<div class="additional-checkout-buttons additional-checkout-buttons--vertical">{{ content_for_additional_checkout_buttons }}</div>
{% endif %}
</div>
{% endfor %}
Upvotes: 0
Views: 989
Reputation: 3248
This simple check might work for what you need:
{% liquid
assign all_collections_in_cart = cart.items | map: 'product' | map: 'collections' | map: 'title' | uniq
assign collection_count = all_collections_in_cart.size
if collection_count > 1
assign can_checkout = false
else
assign can_checkout = true
endif
%}
What it does
First, we use a sequence of map
filters to 'drill down' through the object structure. Items in the cart do not themselves belong to any specific collection(s), but each item is associated with both a variant
and a product
. From the product
, we can then get all of the collections
that it belongs to, which will be an array of collection objects. We can't do much with the objects themselves, so we drill down one layer further to get something that can be compared, such as title
handle
or id
. At this point we now have an array of text entries (or numbers, if you swap to IDs), so we can apply the uniq
filter to remove any duplicates.
Now that we have an array with no duplicates, we can check the size
of the array to see if it is greater than one and set a variable appropriately.
Note that this will always return false if a single product belongs to more than one collection!
If instead you need to test that all products share a collection because products can belong to more than one at a time, we won't be able to take as many shortcuts. Instead, our code might look something like this:
{% liquid
assign can_checkout = true
if cart.items.size > 1
assign shared_collections = cart.items.first.product.collections | map: 'title'
for item in cart.items
if forloop.first
continue
endif
assign item_collections = item.product.collections | map: title
assign placeholder_array = ''
for coll in shared_collections
if item_collections contains coll
if placeholder_array.size > 0
assign placeholder_array = placeholder_array | append: ','
endif
assign placeholder_array = placeholder_array | append: coll
endif
endfor
assign shared_collections = placeholder_array | split: ','
if shared_collections.size == 0
assign can_checkout = false
break
endif
endfor
endif
%}
What it does
This second version will trigger if there are 2 or more items in the cart. If there are, we get all of the collection titles from the first item in the cart, then loop through all of the remaining items in the cart. At each step, we go through our list of shared collections to see how many are shared with the current item in the cart to make a new array. (Liquid does not let us make an array directly, so we have to build out a delimited string and then use the split
filter afterwards)
If at any time we have an array with 0 shared entries, we set our can_checkout
variable to false
and use the break
command to stop searching.
For both of the above methods, things might get a little bit trickier if you have certain collections that don't count towards your collection rules. For example, if you have 'featured' or 'summer sale' collections, you will want to make sure that you aren't counting those in the collection comparisons (for example, by having an array of exceptions and removing those items from the array of collections that the item belongs to).
Upvotes: 3