I have been working on an online newspaper/blogging application with CodeIgniter 3.1.8 and Twitter Bootstrap 4. I am currently working on a lazy loading (of posts) feature.
By default, the posts are paginated and displayed 12 at a time, at http://myblog.com/
, http://myblog.com/?page=2
, and so on.
In applicationcontrollersPosts.php
I have
private function _initPagination($path, $totalRows, $query_string_segment = 'page')
{
//load and configure pagination
$this->load->library('pagination');
$config['base_url'] = base_url($path);
$config['query_string_segment'] = $query_string_segment;
$config['enable_query_strings'] = TRUE;
$config['reuse_query_string'] = TRUE;
$config['total_rows'] = $totalRows;
$config['per_page'] = 12;
if($this->Static_model->get_static_data()['has_pager']){
$config['display_pages'] = FALSE;
$config['first_link'] = FALSE;
$config['last_link'] = FALSE;
$config['prev_tag_open'] = '<li class="prev">';
$config['prev_tag_close'] = '</li>';
$config['next_tag_open'] = '<li class="next">';
$config['next_tag_close'] = '</li>';
}
if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
$_GET[$config['query_string_segment']] = 1;
}
$this->pagination->initialize($config);
$limit = $config['per_page'];
$offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;
return array(
'limit' => $limit,
'offset' => $offset
);
}
public function index()
{
//call initialization method
$config = $this->_initPagination("/", $this->Posts_model->get_num_rows());
$data = $this->Static_model->get_static_data();
$data['base_url'] = base_url("/");
$data['pages'] = $this->Pages_model->get_pages();
$data['categories'] = $this->Categories_model->get_categories();
$data['search_errors'] = validation_errors();
//use limit and offset returned by _initPaginator method
$data['posts'] = $this->Posts_model->get_posts($config['limit'], $config['offset']);
$this->twig->addGlobal('pagination', $this->pagination->create_links());
// featured posts
if ($data['is_featured']) {
$data['featured'] = $this->Posts_model->featured_posts();
$this->twig->addGlobal('featuredPosts', "themes/{$data['theme_directory']}/partials/hero.twig");
}
$this->twig->display("themes/{$data['theme_directory']}/layout", $data);
}
In order to load the posts via jQuery Ajax instead, I have:
(function($) {
var currentPage = 1;
// Hide pahination
$('.pagination').hide();
$(window).scroll(function() {
if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
loadMore();
}
});
function loadMore() {
$.ajax({
url: baseUrl + '?page=' + currentPage,
type: 'POST',
beforeSend: function() {
$('.loader').show();
}
})
.done(function(data) {
$('.loader').hide();
// Append new posts to the posta container
$("#postsContainer").append(data);
currentPage = currentPage + 1;
});
}
})(jQuery);
The HTML
<div class="col-lg-8 col-md-10 mx-auto" id="postsContainer">
<div class="post-preview">
<a href="http://myblog.com/learn-to-code-with-us-for-a-better-future">
<h2 class="post-title">Learn to code with us, for a better future</h2>
<h3 class="post-subtitle">Learn to code with us. We have the best teachers in the country.</h3>
</a>
<p class="post-meta">
Posted in <a href="http://myblog.com/categories/posts/1" title="All posts in Uncategorized">Uncategorized</a>, on Nov 19, 2019
</p>
</div>
<hr>
...
</div>
The problem
For a reason I have not been able to figure out, when I scroll to the bottom of the page, instead of the posts to be appended to the posts container, the entire page is appended.
2
Answers
I got a working solution:
You seem to be trying to reload the entire page with paginated data – that’s a really bad practice. In the long run, you’ll end up with slower pages that way.
You would be better off having a separate endpoint for your AJAX that outputs a JSON array of HTML strings, one for each post. This is still slower than using a 2-tier solution like Codeigniter and React, but it’s certainly faster than constantly rerendering the entire UI.