Liquid, JavaScript, themes, sales channels
We are trying to prevent users from checking out if they have products from more than one collection... we have some code snippets to try to work the problem, but we are unsure how to implement them.
The template we are trying to affect would have a logic like..
{% if can_checkout == true %}
<button id="button" type="submit" name="checkout" data-terms-required="{{ settings.cart_terms_conditions_enable }}" class="btn cart__checkout">
{{ 'cart.general.checkout' | t }}
</button>
{%else if can_checkout == false%}
<button id="button" disabled type="submit" name="checkout" data-terms-required="{{ settings.cart_terms_conditions_enable }}" class="btn cart__checkout">
Can't checkout - Check cart
</button>
{% endif %}
We also have the following snippet(s)
The first one we tried
{% 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
%}
The second attempt we made was with
{% 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 we dont know how to do is inject the liquid script into the snippet so we can disable the button.
Any help would be greatly appreciated
we have also tried
{%- assign check = 0 -%}
{%- assign checkCollection = '' -%}
{%- for item in cart.items -%}
{%- if checkCollection != item.product.collections[0].handle -%}
{%- assign check = check | plus: 1 -%}
{%- assign checkCollection = item.product.collections[0].handle -%}
{%- endif -%}
{%- endfor -%}
{%- if check > 1 -%}
// show button checkout
{%- endif -%}
Hello, @SquareMarket
Here's a simple way to go about it.
Just grab line items using the cart object (cart js works) then:
//you can loop through the line items, accessing it's collection attribute
line_item.product.collections
//set a variable on the first item,
//then for each item, check if it matches the name for the last item
//if it doesn't match the previous item, then there are more than one collection
{% for collection in product.collections %}
{{ collection.title }}
{% endfor %}
//if your loop makes it here, then there is only one collection which all these items belong to.
Could you provide some code for the pseudo code you wrote?
Hello, @SquareMarket
This is the basic logic.
{% assign line_items=cart.items %}
//grab the whole cart
{% for line_item in line_items %}
//main loop. loop through the cart
{% for collection in line_item.product.collections %}
//now loop through the collections within each item
//some items belong to multiple collections
//(if they do it will count as different collections)
//now create a "previous item's collection" variable
//to check against if it doesn't exist
//and a flag (starts as true) to mark if it was the same as the last item.
{% if prev_collection == Nil %}
{% assign prev_collection = {{ collection.title }} %}
{% assign same_collection = true %}
{% endif %}
//now check if the current collection being checked
//is the same as the previous collection
{% if prev_collection != {{collection.title}} %}
{% assign same_collection = false %}
//if it's not, we mark the flag as false and pack it up.
//then we break out of the inner loop.
{% break %}
{% endif %}
//the current name is assigned to previous after checking
{% assign prev_collection = {{ collection.title }} %}
{% endfor %}
{% if same_collection == false %}
//we also break out of the outer loop.
{% break %}
{% endif %}
{% endfor %}
//now if the flag is false, no cart for you.
{% if same_collection ==true %}
// you get a cart.
{% endif %}
You might have to make some changes depending on weather you'll store a global variable to block purchase or just use it to hide the cart button.
The comments aren't liquid so you'll have to edit those out. It's easier to follow the logic without {% comment %} tags everywhere.
it unfortunately always returns false, so it didnt work 😞
Hello @SquareMarket,
I'm sorry to hear that. I'll try debugging the code. I'll post back in about a day when I'm at my development setup.
Hey @SquareMarket,
If you're still looking for the solution, try this:
{%- assign item_collections = '' -%}
{%- for line_item in cart.items -%}
{%- for collection in line_item.product.collections -%}
{%- assign item_collections = item_collections | append: collection.title | append: ',' -%}
{%- endfor -%}
{%- endfor -%}
{%- assign item_collections = item_collections | split: ',' | uniq -%}
{%- if item_collections.size > 1 -%}
//Can not checkout
{%- else -%}
//Checkout
{%- endif -%}
Hello @SquareMarket,
If the above solution doesn't work, it might be better to output each item and it's respective collection to see what might actually happening.
If you'd like me to work on a copy of your store theme to sort this out, let me know. (Or any other developer)
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