<p>First you create a function to send the data to a custom controller</p>

<pre class="lang-js prettyprint-override"><code>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);
}
</code></pre>

<p>Then in your controller just fetch the entries</p>

<pre class="lang-twig prettyprint-override"><code>public function actionGetElements(): Response
{
    $offset = Craft::$app-&gt;getRequest()-&gt;getBodyParam('offset');
    $query = Entry::find()-&gt;section(['whatever'])-&gt;limit(10)-&gt;offset($offset);
    $elements = $query-&gt;all();
    $html = Craft::$app-&gt;getView()-&gt;renderTemplate('path/to/template', [
        'elements' =&gt; $elements
    ]);
    $fetchedElements = \count($elements);
    $totalElements = $query-&gt;count();
    return $this-&gt;asJson(
        [
            'html' =&gt; $html,
            'success' =&gt; true,
            'elements' =&gt; $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' =&gt; $fetchedElements + $offset === $totalElements
        ]
    );
}
</code></pre>

<p>Keep in mind to include a <a href="https://docs.craftcms.com/v3/changes-in-craft-3.html#csrf-token-params" rel="nofollow noreferrer">CSRF token</a> <code>data.append(window.csrfTokenName, window.csrfToken);</code> and to include an <code>protected $allowAnonymous = [ 'actionGetElements'];</code> to your controller</p>

CC BY-SA 4.0
2018-08-17T18:28:16.737Z
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
CC BY-SA 4.0
2018-08-18T23:14:31.743Z
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
CC BY-SA 4.0
2018-08-20T18:30:15.190Z
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
CC BY-SA 4.0
2018-08-20T18:31:58.983Z
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
CC BY-SA 4.0
2018-08-20T21:31:02.447Z
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
CC BY-SA 4.0
2018-08-20T21:34:04.653Z
Then just attach the event handler to your element and call the function when someone clicks the button. It's basic Javascript it works the same way in WordPress  and every other framework - That will trigger the Ajax request in order to access your custom controller. You said you want to use basic ajax without a framework -> no jquery
Robin Schambach
CC BY-SA 4.0
2018-08-16T16:54:24.530Z
2018-08-16T17:03:06.153Z
2018-08-16T17:03:06.153Z
Robin Schambach
<p>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</p>

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

<entries><craft3><ajax>
Ajax Load more Posts
# Ajax Load more Posts

(Asked by: username_0 on 2018-08-16)

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) %}



    
        
            {% for asset in entry.newsFeaturedImage %}
                 
            {% endfor %}
        
    
    
        
            {% for category in categories %}
                
                    {{ category.title }}
                
            {% endfor %}
            
                {{entry.title}}
            
            
                {{ entry.newsExcerpt|length > 150 ? entry.newsExcerpt|slice(0, 150) ~ '...' : entry.newsExcerpt  }}
            
            
                Continue Reading
            
        
    
   
 
   {% endfor %}

**Tags:** entries, craft3, ajax

---

## 1 answers

### Answer by username_1 on 2018-08-16. Score: 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

> **Comments:**
> **username_0**: 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 )  
> **username_1**: 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  
> **username_0**: I'm just not 100% sure how to add this and how this connects to my load more button. If that makes sense.  
> **username_1**: 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  
> **username_0**: 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.  
> **username_1**: Then just attach the event handler to your element and call the function when someone clicks the button. It's basic Javascript it works the same way in WordPress  and every other framework - That will trigger the Ajax request in order to access your custom controller. You said you want to use basic ajax without a framework -> no jquery  

---

