<p>Could you just append a new "load more" button to the page as part of the requested AJAX template and remove the old one when it's successfully loaded?</p>

<p>Each load more button might look something like this:</p>

<pre><code>{% if paginate.nextUrl %}
  &lt;a href="{{ paginate.nextUrl ~ queryString }}" class="sr-button" 
     data-related-grid="artefact-grid" 
     data-method="loadonclick"&gt;Load More&lt;/a&gt;
{% endif %}
</code></pre>

<p>Then in your <code>isotopeLoadMore()</code> function, you can remove the load more button that was clicked on if you get a successful response and replace it with a button from the AJAX response. Something like this:</p>

<pre><code>/* isotope load more function
------------------------------------------------*/
function isotopeLoadMore(grid,el,url,datas) {

  // create a var for the button's parent so we can reuse it
  var loadIsotope = el.parent(".load-isotope")
  loadIsotope.addClass('loading');

  if (url === '#' || !url) { url = srvars.ajaxurl }
  var addData = ''; if (datas) { addData = { action:'sr_load_more', o:datas }; }
  jQuery.ajax({
    type:'POST',      // this might lead to issues for html template
    url:url,
    data: addData,
    dataType:"html",
    error: function () {
      loadIsotope.addClass("disabled");  
    },
    success: function(response) { 
      //console.log(response);
      if (response) {
        setTimeout(function(){ 
          var items = jQuery( jQuery(response).find('#'+grid.attr('id')).html());
          // Find the new Load More button in the response
          var loadMode = jQuery( jQuery(response).find('.load-isotope').html());
          items.imagesLoaded(function(){
            grid.append( items ).isotope( 'appended', items);
            // add the new Load More button
            loadIsotope.append( loadMode );
            // remove the original Load More button
            el.remove();
            animateOnScroll(false);
            // init video bg for appended items
            if(jQuery().phatVideoBg) { grid.find('.videobg-section').phatVideoBg(); }
          });
          loadIsotope.removeClass('loading');
        },500);
      } else {
        loadIsotope.addClass("disabled");  
      }
    }
  });

}
</code></pre>

<p>But you'll have to attach your 'click' handler a little differently to make sure the dynamically loaded buttons will fire the same click function.</p>

<p>So instead of using...</p>

<pre><code>var loadMore = jQuery('.load-isotope:not(.disabled) a');

loadMore.click(function(){ ...
</code></pre>

<p>That code will only attach the click function once when the page loads to the first button, but not any buttons that are dynamically added to the page thru your AJAX call.</p>

<p>Here's an example JSFiddle of a script that creates buttons and an alert. Only the original button works. New buttons don't do anything.</p>

<p><a href="https://jsfiddle.net/alexroper/0aup8e5d/" rel="nofollow noreferrer">https://jsfiddle.net/alexroper/0aup8e5d/</a></p>

<p>But this JSFiddle uses <a href="http://api.jquery.com/on/#direct-and-delegated-events" rel="nofollow noreferrer">delegated events</a> like this...</p>

<pre><code>$('.load-isotope').on('click', '.sr-button' ,function(event){ ...
</code></pre>

<p>... to attached click events to any <code>$('.sr-button')</code> element that's a child of <code>$('.load-isotope')</code>:</p>

<p><a href="https://jsfiddle.net/alexroper/uq613627/1/" rel="nofollow noreferrer">https://jsfiddle.net/alexroper/uq613627/1/</a></p>

<p>It's a similar problem to this Stack Overflow question:
<a href="https://stackoverflow.com/questions/15090942/jquery-event-handler-not-working-on-dynamic-content">Jquery event handler not working on dynamic content</a></p>

<p>So here's a stab at what that might look like in your code. I'm not totally sure what everything in your code does, so you still may have to tweak it.</p>

<pre><code>$('.load-isotope').on('click', '.sr-button' ,function(event){
  event.preventDefault();
  var el = $(this);
  var related = $('#' + el.data('related-grid'));
  var href = el.attr('href')
  var datas = '';
  if ( ! el.parents('.load-isotope').hasClass('disabled') ) {
    isotopeLoadMore(related,el,href,datas);
  }
});
</code></pre>

CC BY-SA 3.0
2017-02-16T12:48:25.947Z
Hi, Thanks for your response. This is where my knowledge is struggling. For what I understand you're suggesting that the when the ajax content is called the button should also be refreshed and therefore the url (for the next paginated content) will also be updated? That would make sense. However what is the JS you provided doing exactly?
Scott Robinson
CC BY-SA 3.0
2017-02-16T20:24:36.763Z
I'm suggesting the original load more button that was clicked gets removed completely and a new load more button gets loaded by AJAX. So an AJAX request for the same button from the URL `/p2` would render `{{ paginate.nextUrl }}` as `href="/p3"`. The JS I wrote above isn't complete because I don't know everything you scripts are trying to do. I'll try to flesh it out more with some more explanations.
Alex Roper
CC BY-SA 3.0
2017-02-17T10:15:52.500Z
Alex, Thank you so much for giving such a detailed response. That is seriously awesome. The only issue was the href was cycling back to the beginning but I put the button in a {% if paginate.nextUrl %} and it works perfectly. I have been seriously struggling with getting a working version of ajax pagination up on my site ... you have resolved my one big headache, so thank you again.
Scott Robinson
CC BY-SA 3.0
2017-02-17T18:17:50.270Z
Awesome. I'll update my answer with that conditional. if this answer has solved your question please consider [accepting it](http://meta.stackexchange.com/q/5234/179419) by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this.
Alex Roper
CC BY-SA 3.0
2017-02-14T20:12:00.637Z
2017-02-17T18:19:09.017Z
2017-05-23T12:38:53.957Z
Alex Roper
<p>I am using a template which has a 'LOAD MORE' button beneath a grid of entries (entries 1-10). Click this link loads addition content to the grid via AJAX from another page (which contains entries 11-20). There is also a second page which has entries 21-30. The code looks like this:</p>

<pre><code>&lt;div class="load-isotope align-center"&gt;
  &lt;a  href="p2.html" class="sr-button" 
    data-related-grid="artefact-grid" 
    data-method="loadonclick"&gt;Load More&lt;/a&gt;
  &lt;span class="load-message"&gt;No more items to show&lt;/span&gt;
&lt;/div&gt;
</code></pre>

<p>There is JS that will change the p2.html to p3.html when it is clicked, so the second time the button is click the 3rd set of entries is added.</p>

<p>I would like some help as to how to change the JS to make this work with craft pagination. I can add</p>

<pre><code>{{ paginate.nextUrl ~ queryString }}
</code></pre>

<p>as the target URL which works for the first click (the link is rendering out as URL/section/p2 and the content is added via AJAX in the correct place) but I need this to change to /p3 etc with each click.</p>

<p>It seems as though the LOAD MORE function in the JS is mentioned in 2 places:</p>

<pre><code>/* isotope load more function
------------------------------------------------*/
function isotopeLoadMore(grid,el,url,datas) {

  el.parent(".load-isotope").addClass('loading');

  if (url === '#' || !url) { url = srvars.ajaxurl }
  var addData = ''; if (datas) { addData = { action:'sr_load_more', o:datas }; }
  jQuery.ajax({
    type:'POST',      // this might lead to issues for html template
    url:url,
    data: addData,
    dataType:"html",
    error: function () {
      el.parent(".load-isotope").addClass("disabled");  
    },
    success: function(response) { 
      //console.log(response);
      if (response) {
        setTimeout(function(){ 
          var items = jQuery( jQuery(response).find('#'+grid.attr('id')).html());
          items.imagesLoaded(function(){
            grid.append( items ).isotope( 'appended', items);
            animateOnScroll(false);
            // init video bg for appended items
            if(jQuery().phatVideoBg) { grid.find('.videobg-section').phatVideoBg(); }
          });
          el.parent(".load-isotope").removeClass('loading');
        },500);
      } else {
        el.parent(".load-isotope").addClass("disabled");  
      }
    }
  });

}
</code></pre>

<p>AND:</p>

<pre><code>/* Load More isotope
------------------------------------------------*/
var loadMore = jQuery('.load-isotope:not(.disabled) a');

loadMore.click(function(){      
  var el = jQuery(this);
  if(el.data("loadpage") === undefined) { el.data("loadpage","2"); }
  else { el.data("loadpage", parseInt(el.data("loadpage"),10)+1); }
  var   related = el.data('related-grid');
  var   href = el.attr('href').replace("/2", '/'+el.data("loadpage"));
  href = href.replace("2", el.data("loadpage"));
  var datas = '';
  if(el.data("options") !== undefined &amp;&amp; el.data("options")) { datas = el.data('options').replace("paged=2", "paged="+el.data("loadpage")); }
  isotopeLoadMore(jQuery('#'+related),el,href,datas);
  return false;
});
</code></pre>

<p>Any help with this would be massively appreciated</p>

<ajax><pagination>
Using pagination with Ajax load.. help need on JS
# Using pagination with Ajax load.. help need on JS

(Asked by: username_0 on 2017-02-13)

I am using a template which has a 'LOAD MORE' button beneath a grid of entries (entries 1-10). Click this link loads addition content to the grid via AJAX from another page (which contains entries 11-20). There is also a second page which has entries 21-30. The code looks like this:

  Load More
  No more items to show


There is JS that will change the p2.html to p3.html when it is clicked, so the second time the button is click the 3rd set of entries is added.
I would like some help as to how to change the JS to make this work with craft pagination. I can add
{{ paginate.nextUrl ~ queryString }}

as the target URL which works for the first click (the link is rendering out as URL/section/p2 and the content is added via AJAX in the correct place) but I need this to change to /p3 etc with each click.
It seems as though the LOAD MORE function in the JS is mentioned in 2 places:
/* isotope load more function
------------------------------------------------*/
function isotopeLoadMore(grid,el,url,datas) {

  el.parent(".load-isotope").addClass('loading');

  if (url === '#' || !url) { url = srvars.ajaxurl }
  var addData = ''; if (datas) { addData = { action:'sr_load_more', o:datas }; }
  jQuery.ajax({
    type:'POST',      // this might lead to issues for html template
    url:url,
    data: addData,
    dataType:"html",
    error: function () {
      el.parent(".load-isotope").addClass("disabled");  
    },
    success: function(response) { 
      //console.log(response);
      if (response) {
        setTimeout(function(){ 
          var items = jQuery( jQuery(response).find('#'+grid.attr('id')).html());
          items.imagesLoaded(function(){
            grid.append( items ).isotope( 'appended', items);
            animateOnScroll(false);
            // init video bg for appended items
            if(jQuery().phatVideoBg) { grid.find('.videobg-section').phatVideoBg(); }
          });
          el.parent(".load-isotope").removeClass('loading');
        },500);
      } else {
        el.parent(".load-isotope").addClass("disabled");  
      }
    }
  });

}

AND:
/* Load More isotope
------------------------------------------------*/
var loadMore = jQuery('.load-isotope:not(.disabled) a');

loadMore.click(function(){      
  var el = jQuery(this);
  if(el.data("loadpage") === undefined) { el.data("loadpage","2"); }
  else { el.data("loadpage", parseInt(el.data("loadpage"),10)+1); }
  var   related = el.data('related-grid');
  var   href = el.attr('href').replace("/2", '/'+el.data("loadpage"));
  href = href.replace("2", el.data("loadpage"));
  var datas = '';
  if(el.data("options") !== undefined && el.data("options")) { datas = el.data('options').replace("paged=2", "paged="+el.data("loadpage")); }
  isotopeLoadMore(jQuery('#'+related),el,href,datas);
  return false;
});

Any help with this would be massively appreciated

**Tags:** ajax, pagination


---

## 1 answers

### Answer by username_1 on 2017-02-14. Score: 1

Could you just append a new "load more" button to the page as part of the requested AJAX template and remove the old one when it's successfully loaded?
Each load more button might look something like this:
{% if paginate.nextUrl %}
  Load More
{% endif %}

Then in your isotopeLoadMore() function, you can remove the load more button that was clicked on if you get a successful response and replace it with a button from the AJAX response. Something like this:
/* isotope load more function
------------------------------------------------*/
function isotopeLoadMore(grid,el,url,datas) {

  // create a var for the button's parent so we can reuse it
  var loadIsotope = el.parent(".load-isotope")
  loadIsotope.addClass('loading');

  if (url === '#' || !url) { url = srvars.ajaxurl }
  var addData = ''; if (datas) { addData = { action:'sr_load_more', o:datas }; }
  jQuery.ajax({
    type:'POST',      // this might lead to issues for html template
    url:url,
    data: addData,
    dataType:"html",
    error: function () {
      loadIsotope.addClass("disabled");  
    },
    success: function(response) { 
      //console.log(response);
      if (response) {
        setTimeout(function(){ 
          var items = jQuery( jQuery(response).find('#'+grid.attr('id')).html());
          // Find the new Load More button in the response
          var loadMode = jQuery( jQuery(response).find('.load-isotope').html());
          items.imagesLoaded(function(){
            grid.append( items ).isotope( 'appended', items);
            // add the new Load More button
            loadIsotope.append( loadMode );
            // remove the original Load More button
            el.remove();
            animateOnScroll(false);
            // init video bg for appended items
            if(jQuery().phatVideoBg) { grid.find('.videobg-section').phatVideoBg(); }
          });
          loadIsotope.removeClass('loading');
        },500);
      } else {
        loadIsotope.addClass("disabled");  
      }
    }
  });

}

But you'll have to attach your 'click' handler a little differently to make sure the dynamically loaded buttons will fire the same click function.
So instead of using...
var loadMore = jQuery('.load-isotope:not(.disabled) a');

loadMore.click(function(){ ...

That code will only attach the click function once when the page loads to the first button, but not any buttons that are dynamically added to the page thru your AJAX call.
Here's an example JSFiddle of a script that creates buttons and an alert. Only the original button works. New buttons don't do anything.
https://jsfiddle.net/alexroper/0aup8e5d/
But this JSFiddle uses delegated events like this...
$('.load-isotope').on('click', '.sr-button' ,function(event){ ...

... to attached click events to any $('.sr-button') element that's a child of $('.load-isotope'):
https://jsfiddle.net/alexroper/uq613627/1/
It's a similar problem to this Stack Overflow question:
Jquery event handler not working on dynamic content
So here's a stab at what that might look like in your code. I'm not totally sure what everything in your code does, so you still may have to tweak it.
$('.load-isotope').on('click', '.sr-button' ,function(event){
  event.preventDefault();
  var el = $(this);
  var related = $('#' + el.data('related-grid'));
  var href = el.attr('href')
  var datas = '';
  if ( ! el.parents('.load-isotope').hasClass('disabled') ) {
    isotopeLoadMore(related,el,href,datas);
  }
});

> **Comments:**
> **username_0**: Hi, Thanks for your response. This is where my knowledge is struggling. For what I understand you're suggesting that the when the ajax content is called the button should also be refreshed and therefore the url (for the next paginated content) will also be updated? That would make sense. However what is the JS you provided doing exactly?  
> **username_1**: I'm suggesting the original load more button that was clicked gets removed completely and a new load more button gets loaded by AJAX. So an AJAX request for the same button from the URL `/p2` would render `{{ paginate.nextUrl }}` as `href="/p3"`. The JS I wrote above isn't complete because I don't know everything you scripts are trying to do. I'll try to flesh it out more with some more explanations.  
> **username_0**: Alex, Thank you so much for giving such a detailed response. That is seriously awesome. The only issue was the href was cycling back to the beginning but I put the button in a {% if paginate.nextUrl %} and it works perfectly. I have been seriously struggling with getting a working version of ajax pagination up on my site ... you have resolved my one big headache, so thank you again.  
> **username_1**: Awesome. I'll update my answer with that conditional. if this answer has solved your question please consider [accepting it](http://meta.stackexchange.com/q/5234/179419) by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this.  

---

