'Shopify 'View all' button implementation

Shopify has a max display limit of 50 products per page.

To get around this limitation I've made a jquery code snippet. The script grabs the url from each pagination link, and performs an ajax load - adding the result to the main content area.

It worked perfectly for me - but not for my friend. He was missing a page each time. So I thought it may be an async issue with his connection being slower than mine. So I rewrote the script a few times to be more explicit. But it still didn't work for him.

After much trouble shooting, it appears that if logged in as admin - everything works. If not logged in, then the middle page fails to load.

Here is my most recent code:

{% if template contains 'collection' %}
 <script>

$(document).ready(function() {

$('#viewFewerProducts').hide();


// when viewAllProducts is clicked
$("#viewAllProducts").click( function (e) {
e.preventDefault();
$("#viewAllProducts , #paginationMagic").hide(); // hide pagination buttons
// and clear out collectionThumbs - but add the ViewAllRow back in.
$("#collectionThumbs").empty().html('<div class="row" id="viewAllRow"></div>');

// see how many pagination links there are. Add 1 because of index 0
var numberOfPages = $('#paginateNumbers .item').length + 1
var path = window.location.pathname;
var pageURL;


// this bit adapted from blog post... but cant remember url
for (var i=1;i<numberOfPages;i++) { 
    $.ajax(
    {
        type: 'GET',
        url:  pageURL = path + "?page=" + i, // build pagination page url
        ajaxI: i, // Capture the current value of 'i'.
        success: function(data)
    {
        i = this.ajaxI; // Reinstate the correct value for 'i'.
    $(data).find('#collectionThumbs').each(function()
    {
      // Read data... and stick it in the page
     var importedCollection = $(data).find("#collectionThumbs a").unwrap();
     importedCollection.appendTo("#viewAllRow");
    });
    },
        error: function(data)
    {
    // Handle errors here.
    }
    });
}
///

    $("#viewFewerProducts").show();

});

// reload the window
$("#viewFewerProducts").click( function (e) {
    e.preventDefault();
    $("#viewFewerProducts").text('loading...').removeAttr('id');
    location.reload();
});


});

</script>
{% endif %}

and I've written it several other different ways. It just doesn't work if not logged in? I've checked - and dont get any errors in the console either.

So my question is - does anyone know why it would work if logged in, but not if not logged in to admin? Its really bizzarre - as this is not running on any admin pages.

Edit:

{% if template contains 'collection' %}
 <script>

$(document).ready(function() {

$('#viewFewerProducts').hide();



$("#viewAllProducts").click( function (e) {
e.preventDefault();
    $("#viewAllProducts , #paginationMagic").hide();


    var numberOfPages = $('#paginateNumbers .item').length + 1
    var path = window.location.pathname;
    // console.log(path);
    var pageURL;

    //

    for (var i=1;i<numberOfPages;i++) {
    // console.log(i + 'a')
    $.ajax(
    {
    type: 'GET',
    url:  pageURL = path + "?page=" + i,
    beforeSend: function() {
    $("#collectionThumbs").empty();
    },
    ajaxI: i, // Capture the current value of 'i'.
    success: function(data)
    {
    i = this.ajaxI; // Reinstate the correct value for 'i'.

        $(data).find('#collectionThumbs').each(function() {
        // Read data from XML...
         $('<div class="row" id="viewAllRow' + i + '"></div>').appendTo("#collectionThumbs");
         var importedCollection = $(data).find("#collectionThumbs a").unwrap(); 
          importedCollection.appendTo("#viewAllRow" + i );

        // alert("now showing " +  ($("#viewAllRow" + i + " a").length)  + " products" );
        });

        var numberOfRows = $('#collectionThumbs .row').length + 1
        var viewAllRowItem = []

        for (var x=1;x<numberOfRows;x++) {
            //put each row into a variable
             viewAllRowItem[x] = $("#viewAllRow" + x ).clone();
             $("#viewAllRow" + x ).remove();
             // console.log(viewAllRowItem[x])
        }

        for (var x=1;x<numberOfRows;x++) {
                $(viewAllRowItem[x]).appendTo('#collectionThumbs');
        }

    },
    dataType: "html",
    error: function(data)
    {
    // Handle errors here.
    }
    });




}



$("#viewFewerProducts").show();


});


$("#viewFewerProducts").click( function (e) {
e.preventDefault();
$("#viewFewerProducts").text('loading...').removeAttr('id');
location.reload();

});

});

</script>
{% endif %}

The above code seems to work - not sure why... was a process of elimination. I did have to add a bit of code to reorder the elements once loaded (as some ajax responses came back more quickly than others - and appeared on the page in the wrong order).



Solution 1:[1]

$('[js-load-more]').on('click', function(){
  var $this = $(this),totalPages = parseInt($('[data-total-pages]').val()),currentPage = parseInt($('[data-current-page]').val());
  $this.attr('disabled', true);
  $this.find('[load-more-text]').addClass('hide');
  $this.find('[loader]').removeClass('hide');
  currentPage = currentPage+1;
  var nextUrl = $('[data-next-url]').val().replace(/page=[0-9]+/,'page='+currentPage);
  $('[data-current-page]').val(currentPage);
  $.ajax({
    url: nextUrl,
    type: 'GET',
    dataType: 'html',
    success: function(responseHTML){
      $('.grid--view-items').append($(responseHTML).find('.grid--view-items').html());
    },
    complete: function() {
      if(currentPage >= totalPages) {
        $this.remove();
      }
      else {
        $this.attr('disabled', false);
        $this.find('[load-more-text]').removeClass('hide');
        $this.find('[loader]').addClass('hide');
      }
    }
  })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
        <input type="hidden" value="{{ paginate.next.url }}" data-next-url>
        <input type="hidden" value="{{ paginate.pages }}" data-total-pages>
        <input type="hidden" value="{{ paginate.current_page  }}" data-current-page>
        <div class="load-more_wrap">
          <button class="btn" js-load-more>
            <span load-more-text>Load more</span>
            <span class="hide" loader></span>
          </button>
        </div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 chirag khunt