0

Following up on previous questions of mine: How to use multiple different instances Element API "Load More" button?

I have a website that utilizes the "load More" (button) method shown here: http://craftsnippets.com/articles/infinite-scrolling-and-lazy-loading-with-craft-cms

How can I load more entries of a category on that category's page? Currently when I add .relatedTo(category) to the loop on the category page, it works sorta, but it will also load all the rest of the entries after it's gone through the entries of that category. I only want it to load the entries of the category.

Also: Same thing as my last question (linked above) I need this to be used independently of other instances. Martin Spain's answer addressed this in my last question, and worked perfectly. I just don't if/how I can implement it for categories.

element-api.php

<?php

use Craft;
use craft\elements\Entry;
use League\Fractal\TransformerAbstract;
use craft\web\View;

class TwigTransformer extends TransformerAbstract
{

    public function __construct($settings)
    {
        $this->settings = $settings;
    }

    public function transform( $entry )
    {
        $oldMode = Craft::$app->view->getTemplateMode();
        Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_SITE);
        $html = Craft::$app->view->renderTemplate( $this->settings['templatePath'], [$this->settings['variableName'] => $entry]);
        Craft::$app->view->setTemplateMode($oldMode);

        return [
            'id' => $entry->id,
            'html' => $html
        ];
    }
}

return [
    'endpoints' => [
        'lazy-load' => function() {

        // validate and decode settings
        $hashed_settings = Craft::$app->request->getParam('settings');
        $settings = [];

        foreach ($hashed_settings as $key => $value) {
            $value = Craft::$app->security->validateData($value);
            if($value === false){
                return false;
            }else{
                $settings[$key] = $value;
            }
        }

        // criteria
        $skipEntries = Craft::$app->request->getParam('skip') ?? 0;
        $criteria = [
            'section' => $settings['section'], 
            'limit' =>  $settings['limit'],
            'offset' =>  $settings['limit'] * Craft::$app->request->getParam('offset') + $skipEntries,
            'order' => $settings['orderBy'],
        ];
      
        return [
            'elementType' => Entry::class,
            'criteria' => $criteria,
            'paginate' => true,
            'transformer' => new TwigTransformer($settings),
        ];
        },
    ]
];

_category.twig

<section>
            {# settings #}
            {% set element_api_url = 'lazy-load' %}
            {% set settings = {
                section: 'aBetterPost',
                variableName: 'article',
                templatePath: '_layouts/_post.twig',
                orderBy: 'postDate DESC',
                limit: 6,
            } %}

            {# hashed settings #}
            {% set hashed_settings = [] %}
            {% for key, setting in settings %}
               {% set hashed_settings = hashed_settings|merge({(key): setting|hash}) %}
            {% endfor %}

            {# initial content #}
            {# initial content #}
            <div class="js-lazy-wrapper">
                <div class="more-posts-section">
                    <div class="section-header">
                        <h2>More Posts in <span>{{ category.title }}</span></h2>
                    </div>
                    
                    <div class="more-posts-wrap-border">
                        <div class="more-posts-wrap js-lazy-list">
                            {% for page in craft.entries.section(settings.section).orderBy(settings.orderBy).relatedTo(category).limit(settings.limit).all() %}
                              {% include settings.templatePath with {(settings.variableName): page} %}
                            {% endfor %}
                        </div>
                    </div>
                    
                    <div class="load-button-wrap">
                        <button class="js-load-more load-button">{{'load more'|t}}</button>
                    </div>

                </div>
            </div>
        </section>

        


        {# ajax request #}
        {% js %}
        // twig to js
        var lazy_settings = {{hashed_settings|json_encode|raw}};
        var element_api_url = '{{url(element_api_url)}}';

        //variables
        var lazy_offset = 1
        var current_request = null;

        //html elements
        var lazy_wrapper = $('.js-lazy-wrapper');
        var lazy_button = lazy_wrapper.find('.js-load-more');
        var lazy_list = lazy_wrapper.find('.js-lazy-list');

        lazy_button.on('click', function(){
          if (current_request == null){

            current_request = $.ajax({
              url: element_api_url,
              method: 'GET',
              data: {
                skip: 0,
                offset: lazy_offset,
                settings: lazy_settings,
              },
              beforeSend: function(){
                lazy_button.addClass('is-loading');
              },        
            }).always(function(returned) {
                lazy_button.removeClass('is-loading');
                current_request = null;
            }).done(function(returned) {
              lazy_offset ++
              var html = ''
              $.each(returned.data, function(index, article){
                html += article.html
              })
              lazy_list.append(html)
              if(returned.data.length == 0){
                lazy_button.hide();
              }
            }).fail(function(data){
              alert('error');
            })
          }
        });
        {% endjs %}

  • Can you add the code that you currently have? – dmatthams Jul 14 at 10:57
  • @user3788089 Code added. – Justin Kendall Jul 15 at 3:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.