Skip to content

Instantly share code, notes, and snippets.

@davecap
Last active March 19, 2024 13:08
Show Gist options
  • Star 60 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save davecap/1187078 to your computer and use it in GitHub Desktop.
Save davecap/1187078 to your computer and use it in GitHub Desktop.
"Infinite" scrolling in Shopify collections
{% paginate collection.products by 20 %}
<!-- the top of your collections.liquid -->
<!-- START PRODUCTS -->
{% for product in collection.products %}
<!-- START PRODUCT {{ forloop.index | plus:paginate.current_offset }} -->
<div class="product" id="product-{{ forloop.index | plus:paginate.current_offset }}">
{% include 'product' with product %}
</div>
<!-- END PRODUCT {{ forloop.index | plus:paginate.current_offset }} -->
{% endfor %}
{% if paginate.next %}
<div id="more"><p>&darr; <a href="{{ paginate.next.url }}">More</a></p></div>
{% endif %}
<div id="product-list-foot"></div>
<!-- END PRODUCTS -->
<!-- the bottom of your collections.liquid -->
{% endpaginate %}
{% if template contains 'collection' %}
function ScrollExecute() {
if($(document).height() - 800 < ($(document).scrollTop() + $(window).height())) {
scrollNode = $('#more').last();
scrollURL = $('#more p a').last().attr("href");
if(scrollNode.length > 0 && scrollNode.css('display') != 'none') {
$.ajax({
type: 'GET',
url: scrollURL,
beforeSend: function() {
scrollNode.clone().empty().insertAfter(scrollNode).append('<img src=\"{{ "loading.gif" | asset_url }}\" />');
scrollNode.hide();
},
success: function(data) {
// remove loading feedback
scrollNode.next().remove();
var filteredData = $(data).find(".product");
filteredData.insertBefore( $("#product-list-foot") );
},
dataType: "html"
});
}
}
}
$(document).ready(function () {
$(window).scroll(function(){
$.doTimeout( 'scroll', 200, ScrollExecute);
});
});
{% endif %}
@rickydazla
Copy link

@davecap - Nice. This one does it non-automatically (i.e. Click to reveal next, and click for the next. And again!) https://gist.github.com/1489365

Rick

@davecap
Copy link
Author

davecap commented Dec 21, 2011

Awesome, thanks :)

@rickydazla
Copy link

No worries. Hey, if you need it there is a "View all" script here too: https://gist.github.com/1507382 combine a couple and you can make a really nice pagination organizing McTing!

@alex-seedcms
Copy link

For those having problem with the code like I did
A) You need the dotimeout script http://benalman.com/code/projects/jquery-dotimeout/docs/files/jquery-ba-dotimeout-js.html
B) Not sure why it's .product#more .product#more a as that doesn't exists. Just take out the .product

@magician11
Copy link

magician11 commented Jun 14, 2016

Where does the paginate.next.url get inserted? It looks like only elements with class .product get inserted on a successful ajax call?

SOLUTION: make sure to wrap your start to end products with a div class product.

@ActualKeith
Copy link

ActualKeith commented Feb 1, 2017

Impelenting this correctly loads the next page's products, extending my collection... however the elements themselves are completely invisible. Tried both in Chrome and Safari. Inspect shows them exactly as the visible products, but they just take up invisible whitespace. Any thoughts?

Check it out: http://g.recordit.co/gPuXItW2m1.gif

@jarvisjohnson
Copy link

@ActualKeith - i got this infinite scroll to work just now. Seems to be pretty smooth. Let me know if you want help with it.

@shaunfal
Copy link

@jarvisjohnson I check out your link and gave it a go with no luck. Im currently running the Debut Theme and would like to integrate infinite scroll for my products page. Could you help me with it?

@sergical
Copy link

sergical commented Mar 1, 2017

does this only work once? I am not seeing the div#more after first pagination. let's say i have a limit of 9 and i paginate 3 at a time

@zoo-loop
Copy link

@416serg I'm having the same issue, loads the items from page 2, but doesn't load anymore than that. Did you find a fix for it?

@amjadfaraz
Copy link

@jburdi me also having same issue. anyone have a solution for this?

@mjmeilahn
Copy link

@416serg @jburdi @amjadfaraz replace the div or href value in the callback response - access what you need inside the success function.

@aton1004
Copy link

aton1004 commented Aug 7, 2017

@davecap I followed the code and I am seeing a type error: $.doTimeout is not a function, could you please help me out? what could have gone wrong?

@davecap on further investigation I figured out that there is some issue of this plugin wiht debut theme that shopify comes by default.

could you please point me towards right direction?

@kevinhf
Copy link

kevinhf commented Aug 24, 2017

I had a pagination problem as well and was short on time. I ended up trying this - https://elkfox.github.io/Ajaxify/#getting-started - Works like a charm. Got the AJAX pagination working less than 5 mins.

@UihyunKim
Copy link

@aton1004 $.doTimeout is not the basic function of jquery, if you want to make this working, you need to add http://benalman.com/code/projects/jquery-dotimeout/docs/files/jquery-ba-dotimeout-js.html such as @alex-seedcms said. But it doesn't work though.

As @CodeLegendVI said, ajaxify is working good on this job with well documented.
https://elkfox.github.io/Ajaxify/#getting-started

@ahmedMshaban
Copy link

@416serg @jburdi @amjadfaraz I fixed the load just one time issue and here is the full code I used.

theme.liquid.js

function ScrollExecute() {       
           if($(document).height() - 800 < ($(document).scrollTop() + $(window).height())) {
               scrollNode = $('.homeProducts a').last();    
               scrollURL = $('.homeProducts a').last().attr("href");
               changeNode = $('.homeProducts a').last(); 
                pageNumber = $('.homeProducts a').last().attr("href");
             	pagesEnd = $('.pagesEnd').text();
                pagesEnd = parseInt(pagesEnd);
               pageNumber =  parseInt(pageNumber.substring(7,));
                alert(pagesEnd);
               if(pagesEnd >= pageNumber){            	                   	
                    if(scrollNode.length > 0 && scrollNode.css('display') != 'none') {
                        $.ajax({
                            type: 'GET',
                            url: scrollURL,
                            beforeSend: function() {
                                scrollNode.clone().empty().insertAfter(scrollNode).append('<img src=\"{{ "loading.gif" | asset_url }}\" />');
                                //    scrollNode.hide();
                            },
                            success: function(data) {
                                // remove loading feedback
                                var filteredData = $(data).find(".product");
                                filteredData.insertBefore( $("#product-list-foot") );
                                    pageNumber ++;
                                    changeNode.attr("href","/?page="+pageNumber.toString());
                                changeNode.insertBefore( $("#product-list-foot") );
                            },
                            dataType: "html"
                        });
                    }
               } 
           }
         }
 
         $(document).ready(function () {
           $(window).scroll(function(){
               $.doTimeout( 'scroll', 200, ScrollExecute);
           });
         });

collections.liquid.html

{% assign collection = collections.frontpage %}
 {% paginate collection.products by 9 %}
    <!-- the top of your collections.liquid -->
    
    <!-- START PRODUCTS -->
    {% for product in collection.products %}
    	    <!-- START PRODUCT {{ forloop.index | plus:paginate.current_offset }} -->
    	    <div class="product grid__item large--one-third medium--one-half" id="product-{{ forloop.index | plus:paginate.current_offset }}">
                {% include 'product-grid-item' %}
            </div> 
    	    <!-- END PRODUCT {{ forloop.index | plus:paginate.current_offset }} -->
    {% endfor %}
	
    {% if paginate.next %}
         <a id="more" href="{{ paginate.next.url }}"></a>       
    {% endif %}
    	<p class="pagesEnd">{{ paginate.pages }}</p>
    



    <div id="product-list-foot"></div>
    <!-- END PRODUCTS -->
    
    <!-- the bottom of your collections.liquid -->
    {% endpaginate %}

@harisbabic
Copy link

Hey guys, I am using the Shopify Debut theme and I would love to implement this code but not exactly sure where to add this within the files and what to take out from the files-- if anything?

Thanks so much

@Nomled
Copy link

Nomled commented Jul 4, 2018

Hi,
I use the Shopify Brooklyn theme
It currently used ‘pages’ and I want to convert it to ‘infinite scrolling. I want the product to load as you scroll down.
I want to go into the code and make my product page have infinite scrolling. I do not want to change the theme and use an app please help me thAnks

@lowkeyshift
Copy link

I had a pagination problem as well and was short on time. I ended up trying this - https://elkfox.github.io/Ajaxify/#getting-started - Works like a charm. Got the AJAX pagination working less than 5 mins.

Hey kevinhf I tried following the documentation for the Ajaxify, but wasn't able to get it working. Would you be able to give me some pointers on where the code is supposed to be injected? Or what steps you took to integrate that infinity scroll solution?

@luxendary
Copy link

Hi guys,

I'm using narrate theme and getting "Liquid error: Could not find asset snippets/product.liquid" error.
Have Product-card.liquid and product-form.liquid in my nippets.

@luxendary
Copy link

@davecap do you happen to know a quick workaround with newer Shopify themes that use product-card and product-form snippet names?

@davecap
Copy link
Author

davecap commented Oct 28, 2019

Sorry, I haven't worked with Shopify themes in several years...

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