skip to Main Content

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.

Where is my mistake?

2

Answers


  1. Chosen as BEST ANSWER

    I got a working solution:

    (function($) {
    
        var currentPage = 2,
            maxPage = $('#postsContainer').data('max-page'),
            posts = null;
    
        $('.pagination').hide();
    
        $(window).scroll(function() {
            var toBottom = $(window).scrollTop() >= $(document).height() - $(window).height() - 25;
    
            if (toBottom && currentPage <= maxPage) {
                loadMore();
            }
        });
    
        function loadMore() {
            $.ajax({
                    url: baseUrl + '?page=' + currentPage,
                    type: 'GET',
                    beforeSend: function() {
                        if (typeof posts != 'undefined') {
                            $('.loader').show();
                        }
                    }
                })
                .done(function(data) {
                    $('.loader').hide();
                    posts = $(data).find('#postsContainer').html();
    
                    if (typeof posts != 'undefined') {
                        $('#postsContainer').append(posts);
                        currentPage = currentPage + 1;
    
                        if (currentPage > maxPage) {
                            $('#postsContainer').append('<p class="text-center text-muted">No more posts to load</p>');
                        }
                    }
                });
        }
    
    })(jQuery);
    

  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search