2

So, I'm kinda new to Craft so there might be a easy trick to do this but I can't seem to get it working (even with some heavy googling).

On the homepage I've got three entries (from the Projects page) loaded and I'd like to load +3 more entries everytime a 'load more' button is clicked. I've already figured out the best way to do this is using the {% paginate %} function limited to 3 entries but thats where I'm kinda stuck right now..

Is there a way to change the limit on click or something better?

4 Answers 4

2

You will have to accomplish this without pagination. This is a non-javascript way.

{% set page = craft.request.getParam('page') ? craft.request.getParam('page')|number_format : 1 %}
{% set batch = 3 %}
{% set limit = page * batch %}
{% set newPage = page + 1 %}

{% set items = craft.entries.section('projects').limit(limit) %}

{% for item in items %}
    <h2>{{ item.title }}</h2>
    {# other markup for each item #}
{% endfor %}


<a href="?page={{ newPage }}">More</a>

This just increases the limit by the page number and the factor of BATCH while providing the next page number for the button url.

5
  • Okay so how would I implement this inside my page? I mean, how do I specify the content markup? Commented Dec 23, 2016 at 11:07
  • What is the section's handle you are trying to output?
    – a-am
    Commented Dec 23, 2016 at 16:28
  • Section handle will be 'projects'. Commented Jan 2, 2017 at 14:45
  • I have updated the answer to show you how you add the content markup. Basically you loop through the items from projects and output the attributes in any html markup.
    – a-am
    Commented Jan 3, 2017 at 4:01
  • Thanks! This works! How can I do this without the whole page refreshing? I've added some jquery to maintain the scroll position but this doesn't give the desired effect. Commented Jan 4, 2017 at 10:13
2

This post by Andrew Welch includes a pretty comprehensive example of a "load more" function to dyamically load entries from the Element API: https://nystudio107.com/blog/lazy-loading-with-the-element-api-vuejs

2

An efficient way is the other answer using the element api and vue.js. The element api returns JSON and VUE uses javascript templating to output the markup. The same can be done in jQuery using a template framework like Mustache. However if you need something less in-depth with jQuery here is a simple way to accomplish it. First in your settings go to Routes and create a new route to the template file which will generate your posts.
enter image description here

For the more button you could use a data attribute to capture the current page along with how many you would like to load at a time.

<button id="more-button" data-page="0" data-batch="3">More</button>

In jQuery listen for the button click and run your query to the template.

$("#more-button").on('click', function () {
    var btn = $(this),
        page = btn.data('page'),
        batch = btn.data('batch'),
        offset = page * batch,
        newPage = page + 1;

    loadPosts(offset, batch);
    // set the buttons page attribute to the new page it is on.
    btn.data('page',newPage);
});

function loadPosts (offset, limit) {
    $.get('/ajax/posts', { offset:offset, limit:limit }, function (data) {
        var postOutput = $('#post-output');
        postOutput.html(data);
    });
}

In your template you will need to capture the offset & limit params.

{% set offset = craft.request.getParam('offset') %}
{% set limit = craft.request.getParam('limit') %}
{% set items = craft.entries.section('projects').limit(limit).offset(offset) %}

In this example we are retrieving the next set and appending them to the rest of the posts. Again for a more efficient experience try using element api & javascript templating.

1

If someone wants to hide load more and load more button is outside the loop

{# set gloabl var so that can use them outside the loop #}
{% set page = 0 %}
{% set totalPage = 0 %}

 {% set page = craft.request.getParam('page') ? craft.request.getParam('page')|number_format : 1 %}
{% set batch = 6 %}
{% set limit = page * batch %}
{% set newPage = page + 1 %}


{% set items = craft.entries.section('properties').limit(limit) %}
{% for entry in items %}

{# show your data #}
<div class="item">
    ...
</div>

{# get total page #}
{% set totalPage = loop.length / batch %}

{% endfor %}

{# outside for loop and hide if we are on last page #}

{% if page|number_format != totalPage|number_format %}

    <div class="center">
        <a href="?page={{ newPage }}" class="btn btn-primary">Load More</a>
    </div>
{% endif %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.