How do I sort "Out of Stock" products to the end of a collection?

New Member
1 0 1

That's because the code does not define the sortedProductsIndex. That needs to be defined and you can see that in Joe's solution. Joe's solution works for cases where number of products <=50, but not when you have more than 50 products in the collection, as the for loop works on the first 50 products only. I have been trying to figure that out, but nothing much has come out of it unfortunately.

Tourist
7 0 2

Hi, Do you have any solution for this yet? I'm having the same issue. Thanks

0 Likes
New Member
8 0 0

Is there a way to send the products to the back of the collection if tagged it as "sold out"?

 

 

0 Likes
Shopify Partner
3 0 0

Hi @Qoo99 and @hkpghkpg ,

I've just developed an app, it's very easy to use! Give it a try https://apps.shopify.com/pushlast.

0 Likes
New Member
8 0 0

hey thanks - is there anyway for your app to sort my products to the back via tag?

because I have

a) out stock items that will be gone forever (at the back), tagged as sold out

b) out of stock items but is available and can be custom ordered (need to stay in collection)

0 Likes
Shopify Partner
3 0 0

Hi @hkpghkpg ,

I understand your question, but at the moment is not possibile, maybe I can work on this functionality in the future. I'll let you know.

Meantime you can try also other apps more complex with more functionalities to assolve your needs.

0 Likes
Tourist
6 0 2

Find this code in which file?

0 Likes
Tourist
3 0 1

Hi,

The solution for the code provided by @Joe_at_LC_Fermi is not limited to just 50 products, I made a small change:

 

In the section collection-template.liquid, we have to locate the line doing the pagination (Simple theme example here):

{% paginate collection.products by (total amount of products in your store or the amount you want to limit per collection) %}

Then add this snippet BELOW the pagination line:

{% assign unsortedProducts = collection.products | reverse | reverse %}

{% comment %} Yes I know, reverse | reverse looks redundant, but there does seem to be some value in getting an array out of the reverse filter instead of trying to use collection.products directly (avoids an error where concat complains that is needs an array argument), and since we don't want to actually change the order here, we have to reverse it back. {% endcomment %} {% for product in unsortedProducts %} {% assign sliceIndex = forloop.index0 %} {% assign aProduct = unsortedProducts | slice: sliceIndex, 1 %} {% if product.available == true %} {% if availableProducts.size == 0 %} {% assign availableProducts = aProduct %} {% else %} {% assign availableProducts = availableProducts | concat:aProduct %} {% endif %} {% else %} {% if unavailableProducts.size == 0 %} {% assign unavailableProducts = aProduct %} {% else %} {% assign unavailableProducts = unavailableProducts | concat: aProduct %} {% endif %} {% endif %} {% endfor %} {% assign sortedProducts = collection.products %} {% if unavailableProducts.size > 0 and availableProducts.size > 0 %} {% assign sortedProducts = availableProducts | concat:unavailableProducts %} {% endif %}

 

Then the line that passes the product to the grid or list snippet needs to be changed. For the Simple theme, the line is:

{% include 'product-grid-item' %}

And that line needs to be replaced with this:

{% assign sortedProductsIndex = paginate.current_offset | plus: forloop.index0 %}
{% include 'product-grid-item', product: sortedProducts[sortedProductsIndex] %}

---

After making the above changes, comment on where the pagination renders so as not to get strange code.

 

This code solved my problem, the only issue is that if the store has many products, it may take a long time to load.

 

Hope this helps.

New Member
1 0 0

Great snippet, thank you very much for sharing it with the community.

There's one issue though - I got desired behaviour - products are sorted by its availability but when I'm trying to loop over with paginate I get the following error:

 

Liquid error (sections/static-collection.liquid line 94): Array 'sortedProducts' is not paginateable.

 

 

Looks like assigning "collection products" disables pagination, try the following snippet on collection page:

 

{% assign sortedProducts = collection.products %}

{% paginate sortedProducts | sort: 'available' by paginate_by %}
  {% for product in sortedProducts %}
    {{ product.title }} - {{ product.available}} 
    <!--show product details here -->
  {% endfor %}
{% endpaginate %}

 

 

Any ideas how to make "sortedProducts" variable a paginateable object?

0 Likes
New Member
3 0 0

For anyone looking for an easier way to do this, I include my code below (it incorporates some of the already included code here). Basically, you sort the total collection first (all products, not just in this collection) and you manually display the collection based on the offset and limit of the collection combined with what we know about the current pagination from that object. Works like a charm and no JS needed.

Note: Here we paginate by 12 items a page.

 

 

{% assign unsortedProducts = collection.all_products | reverse | reverse %}

{% comment %}
Yes I know, reverse | reverse looks redundant, but there does seem to be some value in getting an array out of the reverse filter instead of trying to use collection.products directly (avoids an error where concat complains that is needs an array argument), and since we don't want to actually change the order here, we have to reverse it back.
{% endcomment %}

{% for product in unsortedProducts %}
	{% assign sliceIndex = forloop.index0 %}
	{% assign aProduct = unsortedProducts | slice: sliceIndex, 1 %}

	{% if product.available == true %}
		{% if availableProducts.size == 0 %}
			{% assign availableProducts = aProduct %}
		{% else %}
			{% assign availableProducts = availableProducts | concat:aProduct %}
		{% endif %}
	{% else %}
		{% if unavailableProducts.size == 0 %}
			{% assign unavailableProducts = aProduct %}
		{% else %}
			{% assign unavailableProducts = unavailableProducts | concat: aProduct %}
		{% endif %}
	{% endif %}
{% endfor %}

{% assign sortedProducts = collection.all_products %}
{% if unavailableProducts.size > 0 and availableProducts.size > 0 %}
	{% assign sortedProducts = availableProducts | concat:unavailableProducts %}
{% endif %}

 

...

 

{% for product in sortedProducts offset: paginate.current_offset limit: 12 %}
    {% include 'product-grid-collage' %}
{% endfor %}

 

 

 

0 Likes