2

On my blog i need a load more button on the bottom of each section that simply loads more posts when clicked. Everything i look at people are using other javascript libraries. I just want to use ajax no external libraries

{% for entry in craft.entries.section('news').limit(10) %}
{% set categories = craft.categories.relatedTo(entry) %}
<div class="article-container">
<hr />
<div class="row">
    <div class="col-lg-4">
        <div class="article-featured-image">
            {% for asset in entry.newsFeaturedImage %}
                 <img src="{{ asset.url }}" alt="{{ asset.title }}" class="mx-auto d-block img-fluid">
            {% endfor %}
        </div>
    </div>
    <div class="col-lg-8">
        <div class="article-meta">
            {% for category in categories %}
                <small class="hl-heading-yellow">
                    <span>{{ category.title }}</span>
                </small>
            {% endfor %}
            <div class="article-title">
                <span>{{entry.title}}</span>
            </div>
            <div class="article-excerpt">
                {{ entry.newsExcerpt|length > 150 ? entry.newsExcerpt|slice(0, 150) ~ '...' : entry.newsExcerpt  }}
            </div>
            <div class="article-url">
                <a href="{{entry.url}}" class="dark-btn">Continue Reading</a>
            </div>
        </div>
    </div>
   </div>
 </div>
   {% endfor %}
2

First you create a function to send the data to a custom controller

var offset = 10
var getElements = function(){
    var data = new FormData();
    data.append('offset', offset);
    data.append('action', 'plugin-name/controller-name/function-name);
    data.append(window.csrfTokenName, window.csrfToken);

    var xhr = new XMLHttpRequest();
    xhr.open('POST', '', true);
    xhr.onload = function () {
        // check for errors
        if(this.status === 200){
            var response = {};
            try {
                response = JSON.parse(this.responseText);
            } catch(error) {
                throw Error("server did not return valid JSON: " + this.statusText + ' ' + this.status);
                return false;
            }
            // append your response to the object/container you like
            offset += response.elements;
        }
    }
    xhr.send(data);
}

Then in your controller just fetch the entries

public function actionGetElements(): Response
{
    $offset = Craft::$app->getRequest()->getBodyParam('offset');
    $query = Entry::find()->section(['whatever'])->limit(10)->offset($offset);
    $elements = $query->all();
    $html = Craft::$app->getView()->renderTemplate('path/to/template', [
        'elements' => $elements
    ]);
    $fetchedElements = \count($elements);
    $totalElements = $query->count();
    return $this->asJson(
        [
            'html' => $html,
            'success' => true,
            'elements' => $fetchedElements,
            // check if the number of fetched element + offset is equal to the number of total elements
            // if that's the case you can hide the button to load more since there are no more elements
            'hideButton' => $fetchedElements + $offset === $totalElements
        ]
    );
}

Keep in mind to include a CSRF token data.append(window.csrfTokenName, window.csrfToken); and to include an protected $allowAnonymous = [ 'actionGetElements']; to your controller

| improve this answer | |
  • Robin, this didn't work for me, i just need something simple and easy to setup, i've looked at any different articles regarding pagination and ajax. It seems to me that a lot of things in craft don't work like they should ( from what i've gathered from the forums ) – Kevin Love Aug 17 '18 at 18:28
  • Most things in Craft work perfectly but the learning curve is steady. But in general if it doesn't work it's not because of the system since everything works as it should. But in general it would be more helpful to explain what doesn't work in order to receive help – Robin Schambach Aug 18 '18 at 23:14
  • I'm just not 100% sure how to add this and how this connects to my load more button. If that makes sense. – Kevin Love Aug 20 '18 at 18:30
  • So you aren't experienced in web development at all? Maybe you could think about reading beginner tutorials before you start something huge as creating a website. Another possible way is to join craft cms slack to receive more help – Robin Schambach Aug 20 '18 at 18:31
  • I'm pretty experienced i just dont know the logic here with this stuff you provided. Craft is just a little confusing. I'm actually just a wordpress developer trying to figure out craft. – Kevin Love Aug 20 '18 at 21:31

Your Answer

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

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