Ajax load more for grouped items

Hi!

I’ve followed this K2 tutorial to implement an ajax load more call for a page on my site:

https://k2.getkirby.com/docs/cookbook/ajax-load-more

it’s still working wonderfully! (Although I’m probably going to rewrite the jQuery to vanilla JS sometime soon)

There’s a different page where I would like to create the same functionality, but the items on the page are grouped. I created a snippet for the items, but I’m failing to understand how the page controller should look like for this scenario. Wasn’t there a cookbook page where the grouping was done via page controller? I can’t find it…

Thankful for any hints!

You can put any logic into your controller, grouping or not. Instead of loading a number of items, you would load a group (or multiple groups). The logic would be more or less the same, with limit and offset applied to the groups collection rather than simple pages collection.

Yep, that makes sense. You could use the fetch API.

I don’t understand what needs to be done. I think my brain is too tired for this right now… Gonna try again tomorrow morning :zzz:

Good night :sleeping_bed:

Good morning :sun_with_face:

I’ve changed my plans for this. Instead of a grouped collection on a single page ($topics = page('views', 'editorial', 'publishing')->children()->listed()->groupBy('topic'); , there will now be a topics page as well as a topic template for subpages of the topics page:

$items = page('items', 'editorial', 'publishing')->children()->listed()->filterBy('topic', $page->id());

this is working well when opening i.e mysite.com/topics/archive, but I can’t really get the logic for the ajax load more json file to work. What I am trying to achieve, instead of having to create a json.php for each of the topics’ page children, to have a central topic.json that gets a topic parameter via URL and renders only the needed topic, just like the regular page request would:

controllers/topic.php

if(r::ajax() && get('offset') && get('limit') && get('topic')) {

$offset = intval(get('offset'));
$limit  = intval(get('limit'));
$topic  = get('topic');

$items = page('items', 'editorial', 'publishing')->children()->listed()->filterBy('topic', $topic);

$more = $count > $offset + $limit;

} else {

$offset   = 0;
$limit    = 1;
$items    = $items->limit($limit);

}

templates/topic.json.php

<?php

$html = '';

foreach($items as $item) {

  $html .= snippet('topic_item', ['item' => $item], true);

}

$data['html'] = $html;
$data['more'] = $more;

echo json_encode($data);

script.js

            var element = $('.posts_container');
            var url     = '../' + element.data('page') + '.json';
            var limit   = parseInt(element.data('limit'));
            var offset  = limit;
            var topic   = element.data('topic');

            $('.load-more').on('click', function(e) {

              $.get(url, {limit: limit, offset: offset, topic: topic}, function(data) {

                if(data.more === false) {
                  $('.load-more').hide();
                }

                element.children().last().after(data.html);

                offset += limit;

              });

            });

and:

<div class="grid-container-w12 full_page_bar_right posts_container"
data-page="topic"
data-limit="<?= $limit ?>"
data-topic="<?= $page->slug(); ?>"
>

Does that even make sense? where is the error in my thinking? Right now, trying to open the topic.json file redirects me to the default site. I did get it to work briefly but it was fetching the wrong items… I don’t remember what changes I made since then (what is git?) so I was hoping for some help in the forum :~~~)

I don’t have time now to study this, so if nobody else chirps in, this will have to wait til tonight.