The forum of the forums

Would you like to react to this message? Create an account in a few clicks or log in to continue.
The forum of the forums
5 posters

    Pagination : Load More

    Ange Tuteur
    Ange Tuteur
    Forumaster


    Male Posts : 13207
    Reputation : 3000
    Language : English & 日本語
    Location : Pennsylvania

    Pagination : Load More Empty Pagination : Load More

    Post by Ange Tuteur June 26th 2015, 3:48 pm

    Requirements

    Forum Version : phpbb3
    Other : Topics with more than one page

    Introduction

    This is a small project I started a few weeks ago, but never completely finished. Basically it applies a button to the topic which allows you to load more pages, similar to "endless" scrolling. Here's a demonstration : http://generaltesting.forumotion.com/t1-test-subject

    You will see a button by scrolling to the bottom of the topic.
    Pagination : Load More Captur10

    Clicking this button loads the next ( or previous ) page, without transitioning to a new page.
    Pagination : Load More Captur11

    It uses a global object -- $fa_topic -- to store necessary data related to the current topic. Mostly topic data, page numbers, nodes, and a method for getting pages.
    Pagination : Load More Captur12

    It's still in the early stages, as the script is only optimized for phpbb3.

    Installation

    The only things that need to be changed to work, would be the perpage variable. This should be changed to the amount of replies you allow perpage; Default is 15. You can find this value by going to Administration Panel > General > Messages > Configuration > Posts per page

    There's also a language config object in case you want to change or translate words.

    To install : go to Administration Panel > Modules > JavaScript codes management > Create a new script

    Placement : In the topics
    Code:
    $(function() {
      
      // start up variables
      var perpage = 15,
      
          // general language config
          lang = {
            next : 'Next Page',
            previous : 'Previous Page',
            first : 'Reached Beginning of Topic',
            last : 'Reached End of Topic',
            loading : 'Loading...',
            page : 'Page'
          },
          
          main = document.getElementById('main-content'), // main container
          topicId = window.location.href.replace(/.*?t(\d+).*/, '$1'),
          pagination = $('p.pagination', main),
          first = $('.post', main)[0],
          title = document.createElement('H2'),
          
          topHook,
          bottomHook = document.anchors.bottomtitle,
          
          topBlock = document.createElement('DIV'),
          bottomBlock = document.createElement('DIV'),
          
          next = document.createElement('INPUT'),
          previous = document.createElement('INPUT'),
          page,
          i = 0;
      
      if (!pagination[0]) return; // return if no pagination
      
      page = $('a[href^="/t' + topicId + 'p"]:not(.pag-img)', pagination[0]); // get page list
      topHook = pagination[0].nextSibling.nextSibling;
      
      window.$fa_topic = {
        id : topicId, // topic id
        title : document.title.replace(/(.*?)\s-.*/, '$1'), // topic title ( non-slug )
        
        next : next, // next button
        previous : previous, // previous button
        loading : false, // currently loading the next page ?
        
        prevPage : +pagination[0].getElementsByTagName('STRONG')[0].innerHTML, // previous page number
        currentPage : +pagination[0].getElementsByTagName('STRONG')[0].innerHTML, // current page number
        lastPage : pagination[0].getElementsByTagName('SPAN')[0].lastChild.tagName == 'STRONG' ? +pagination[0].getElementsByTagName('STRONG')[0].innerHTML : +page[page.length - 1].innerHTML, // last page number
        
        hook : [bottomHook, topHook],
        
        perpage : perpage,
        pageList : {}, // contains a list of page links
        lang : lang,
        
        // gets the page specified
        // @param page : a number representing a valid page
        // @param position : a string; 'top' or 'bottom', Depends where the next page is placed
        getPage : function(page, position) {
          if ($fa_topic.loading) return;
          position = position ? position.toLowerCase() : 'bottom';
          
          if (position == 'bottom' && $fa_topic.currentPage >= $fa_topic.lastPage) return $fa_topic.next.innerHTML = $fa_topic.lang.last;
          else if (position == 'top' && 1 >= $fa_topic.prevPage) return $fa_topic.previous.innerHTML = $fa_topic.lang.first;
          
          var where = position == 'bottom' ? true : false, payload = document.createElement('DIV'), dropPoint = $fa_topic.hook[where ? 0 : 1], i = 0, posts, j;
          $fa_topic.loading = true;
          where ? $fa_topic.currentPage++ : $fa_topic.prevPage--;
          $fa_topic.next.value = $fa_topic.lang.loading;
          $fa_topic.previous.value = $fa_topic.lang.loading;
          payload.style.display = 'none';
          payload.innerHTML = '<div style="height:30px" id="fa_topic_page' + (where ? $fa_topic.currentPage : $fa_topic.prevPage) + '"></div><h2>' + $fa_topic.title + ' - ' + $fa_topic.lang.page + ' ' + (where ? $fa_topic.currentPage : $fa_topic.prevPage) + '</h2>';
          
          $.get($fa_topic.pageList[page], function(d) {
            for (posts = $('div.post', d), j = posts.length; i < j; i++) posts[i].nextSibling.tagName != 'HR' && payload.appendChild(posts[i]);
            dropPoint.parentNode.insertBefore(payload, where ? dropPoint : dropPoint.nextSibling.nextSibling);
            $(payload).fadeIn(750);
            
            $fa_topic.next.value = $fa_topic.currentPage >= $fa_topic.lastPage ? $fa_topic.lang.last : $fa_topic.lang.next + ' (' + ($fa_topic.currentPage + 1) + ' / ' + $fa_topic.lastPage +  ')';
            $fa_topic.previous.value = 1 >= $fa_topic.prevPage ? $fa_topic.lang.first : $fa_topic.lang.previous + ' (' + ($fa_topic.prevPage - 1) + ' / ' + $fa_topic.lastPage +  ')';
            
            $fa_topic.loading = false;
            window.location.hash = 'fa_topic_page' + (where ? $fa_topic.currentPage : $fa_topic.prevPage);
          });
        }
      };
      
      // insert current title
      title.innerHTML = $fa_topic.title + ' - ' + $fa_topic.lang.page + ' ' + $fa_topic.currentPage;
      title.id = 'fa_topic_page' + $fa_topic.currentPage;
      first.parentNode.insertBefore(title, first);
      
      // next button attributes
      next.type = 'button';
      next.className = 'button2';
      next.value = $fa_topic.currentPage == $fa_topic.lastPage ? $fa_topic.lang.last : $fa_topic.lang.next + ' (' + ($fa_topic.currentPage + 1) + ' / ' + $fa_topic.lastPage + ')';
      next.onclick = function() {
        $fa_topic.getPage($fa_topic.currentPage + 1, 'bottom');
      };
      
      // previous button attributes
      if ($fa_topic.currentPage > 1) {
        previous.type = 'button';
        previous.className = 'button2';
        previous.value = $fa_topic.lang.previous + ' (' + ($fa_topic.prevPage - 1) + ' / ' + $fa_topic.lastPage + ')';
        previous.onclick = function() {
          $fa_topic.getPage($fa_topic.prevPage - 1, 'top');
        };
        
        topBlock.style.textAlign = 'center';
        topBlock.appendChild(previous);
        topHook.parentNode.insertBefore(topBlock, topHook.nextSibling);
      }
      
      // append bottom nodes
      bottomBlock.style.textAlign = 'center';
      bottomBlock.appendChild(next);
      bottomHook.parentNode.insertBefore(bottomBlock, bottomHook.nextSibling);
      
      // form page list so it can be used to load later pages
      while (i ++< $fa_topic.lastPage) $fa_topic.pageList[i] = '/t' + $fa_topic.id + 'p' + ($fa_topic.perpage * i - $fa_topic.perpage) + '-';
      'par ange tuteur';
    });

    In the mean time, if you use phpbb3 you can enjoy this.. Razz
    JScript
    JScript
    Forumember


    Male Posts : 741
    Reputation : 175
    Language : PT-BR, EN
    Location : Brazil

    Pagination : Load More Empty Re: Pagination : Load More

    Post by JScript June 26th 2015, 4:20 pm

    Excellent, even better if it worked on all versions!!!

    But this is easy to solve...

    5 * from me,

    JS
    Zzbaivong
    Zzbaivong
    Forumember


    Posts : 101
    Reputation : 51
    Language : JavaScript ^^

    Pagination : Load More Empty Re: Pagination : Load More

    Post by Zzbaivong June 26th 2015, 5:31 pm

    I see you haven't updated the number of pages after loaded.
    If you are loading the next page, a new post has been submitted, and this post has added a new page. Or Mod deleted posts, and that has reduced pages. That may cause errors.

    Here is my code, I let it start the loading process when it scroll to the bottom of the page.
    Code:
    /**
     * Load content while scrolling to the bottom of the page
     * by Zzbaivong (devs.forumvi.com)
     */
    $(function() {

        var $win = $(window),
            $page = $(document),
            $pag = $(".pagination").last(),
            $next = $pag.find('img[alt="Next"]'),
            current, last,
            endPage = false; // Enable load content while scrolling to the bottom of the page

        if ($next.length) { // Has next posts page

            current = $pag.find("b").text(); // Number of current page

            last = $pag.find("a").last().prev().text(); // Number of last page

            // console.log(current + "/" + last);

            $win.scroll(function() {

                if ($page.height() <= $win.scrollTop() + $win.height() + 100 && !endPage) { // 100(px) is the gap before the end of the page

                    endPage = true; // Disable

                    $.get($next.parent().attr("href"), function(data) { // NEXT is URL for next posts page

                        $pag = $(data).find(".pagination").last();

                        $next = $pag.find('img[alt="Next"]'); // Update URL for next posts page

                        current = $pag.find("b").text(); // Update number of current page

                        if (!$next.length) {

                            last = current; // Update number of last page
                        } else {

                            endPage = false; // Enable

                            last = $pag.find("a").last().prev().text(); // Update number of last page
                        }

                        // console.log(current + "/" + last);

                        // Add content to after loaded

                    });
                 
                }

            });

        }
     
    });
    Ange Tuteur
    Ange Tuteur
    Forumaster


    Male Posts : 13207
    Reputation : 3000
    Language : English & 日本語
    Location : Pennsylvania

    Pagination : Load More Empty Re: Pagination : Load More

    Post by Ange Tuteur June 26th 2015, 6:26 pm

    JScript wrote:Excellent, even better if it worked on all versions!!!

    But this is easy to solve...

    5 * from me,

    JS
    It's certainly possible. I was thinking of a collection that's generated based on the user version, most likely automatically as that would be convenient.

    Zzbaivong wrote:I see you haven't updated the number of pages after loaded.
    If you are loading the next page, a new post has been submitted, and this post has added a new page. Or Mod deleted posts, and that has reduced pages. That may cause errors.
    I was originally going to replace the pagination with a new one, and add page links based on the number of pages loaded -- if you haven't noticed the window hash change. Dawa

    There's always going to be error's with code, but there's nothing a little error handling and worst case scenario F5 couldn't fix, right ? You could update the list by polling the topic, but I'd rather not make topics request heavy.

    I did however, forget to add a check on the pages, such as if the number input is available in the object. I should also have added a check for posts on the next page. The following would suffice in checking if the page has any posts:
    Code:
    $.get('/t1p90-', function(d) {
      console.log($('.post', d)[0] ? true : false);
    });

    Our product is never perfect, so we must constantly polish until it's perfect, just until another problem is discovered. Razz

    I tried your script ( phpbb3, punbb ), but I had not result. I'm assuming it works under certain circumstances ?
    Zzbaivong
    Zzbaivong
    Forumember


    Posts : 101
    Reputation : 51
    Language : JavaScript ^^

    Pagination : Load More Empty Re: Pagination : Load More

    Post by Zzbaivong June 26th 2015, 6:45 pm

    That is the code hints. I do not want it too confusing when discussing.

    Remove 2 slash in front:
    Code:
    console.log(current + "/" + last);
    ... you will see the page number in the console results.

    Write code after loading below:
    Code:
    // add content to this script after loaded
    Zzbaivong
    Zzbaivong
    Forumember


    Posts : 101
    Reputation : 51
    Language : JavaScript ^^

    Pagination : Load More Empty Re: Pagination : Load More

    Post by Zzbaivong June 26th 2015, 7:18 pm

    I've run the test here. it worked.

    Code:
    var $win = $(window),
        $page = $(document),
        $pag = $("p.pagination:last").find("span"),
        $next = $pag.find('img[alt="Next"]'),
        current, last,
        endPage = false; // Enable load content while scrolling to the bottom of the page

    if ($next.length) { // Has next posts page

        current = $pag.find("strong").text(); // Number of current page

        last = $pag.find("a").last().prev().text(); // Number of last page

        console.log(current + "/" + last);

        $win.scroll(function() {

            if ($page.height() <= $win.scrollTop() + $win.height() + 100 && !endPage) { // 100(px) is the gap before the end of the page

                endPage = true; // Disable

                $.get($next.parent().attr("href"), function(data) { // NEXT is URL for next posts page

                    var $data = $(data);

                    $pag = $data.find("p.pagination:last").find("span");

                    $next = $pag.find('img[alt="Next"]'); // Update URL for next posts page

                    current = $pag.find("strong").text(); // Update number of current page

                    if (!$next.length) {

                        last = current; // Update number of last page
                    } else {

                        endPage = false; // Enable

                        last = $pag.find("a").last().prev().text(); // Update number of last page
                    }

                    console.log(current + "/" + last);

                    // Add content to after loaded

                    $(".post:last").after('<hr class="newPage" style="border-top: 50px dashed red;">');

                    $data.find(".post:not(:first)").insertAfter(".newPage:last");

                });

            }

        });

    }

    Result:
    Pagination : Load More Nextpa10
    Tonight
    Tonight
    Forumember


    Male Posts : 312
    Reputation : 80
    Language : Estonian, English, Russian
    Location : Estonia

    Pagination : Load More Empty Re: Pagination : Load More

    Post by Tonight June 26th 2015, 11:18 pm

    How to have similar loading (without page change) for pagination buttons? If I click 8, then it shows page 8 without reloading etc.
    Ange Tuteur
    Ange Tuteur
    Forumaster


    Male Posts : 13207
    Reputation : 3000
    Language : English & 日本語
    Location : Pennsylvania

    Pagination : Load More Empty Re: Pagination : Load More

    Post by Ange Tuteur June 27th 2015, 2:08 am

    @Zzbaivong I see it now.. Wink

    @Tonight that's fairly simple. You can create a contain which will load the newest posts and or pages. I wrote up a quick draft which only utilizes JavaScript. Utilizing template modifications would be much more effective in my opinion, as you won't need to do as much DOM manipulation as I'm doing here.

    For now this will suffice as a starting point...because I'm sleepy. Mr. Green

    Placement : In the topics
    Code:
    $(function() {
      var node = document.createElement('DIV'),
          main = document.getElementById('main-content'),
          page = $('p.pagination', main),
          post = $('div.post', main),
          func = function() {
            $.get(this.href, function(d) {
              var node = document.getElementById('faTopicData'),
                  page = $('p.pagination', d),
                  post = $('div.post', d);
         
              node.innerHTML = '';
              node.appendChild(page[0]);
              $(node).append('<div class="clear"></div>');
              $(node).append(post);
              node.appendChild(page[1]);
             
              page.find('> span > a').click(func);
            });
            return false;
          };
     
      node.id = 'faTopicData';
      post[0].parentNode.insertBefore(node, post[0]);
     
      node.appendChild(page[0]);
      $(node).append('<div class="clear"></div>');
      $(node).append(post);
      node.appendChild(page[1]);
     
      page.find('> span > a').click(func);
    });

    I will see you all later, around 05:00 EDT salut
    Van-Helsing
    Van-Helsing
    Hyperactive


    Male Posts : 2431
    Reputation : 116
    Language : English, Greek

    Pagination : Load More Empty Re: Pagination : Load More

    Post by Van-Helsing July 2nd 2015, 2:41 am

    Nice tutorial Ange Tuteur thumright

      Current date/time is November 13th 2024, 7:20 pm