Coded something up in Couch in an interesting way? Have a snippet or shortcode to share? Post it here for the community to benefit.
15 posts Page 1 of 2
We have all seen those kind of list pages where, instead of a paginator at the bottom, there is a button that says 'Load more' clicking which loads more entries asynchronously. Clicking the button again fetches more entries until there are no more entries to be shown and the button changes to 'No more entries' (or something to that effect).

I was asked today to help create something like this in Couch.
It was apparent that the process would require AJAX but, as I am wont to do before diving headlong into coding, I looked around the Internet to see how others are implementing this functionality.

There exist a plethora of tutorials online explaining various techniques ranging from ultra-simple to fairly complex.
Most required the use of a separate PHP script that sends back the entries in response to AJAX requests but then I came across one that 'retrofits' within the existing list page with only very minimal changes to the original code (much like Couch :) ).

To my mind, this technique was superior to others as it offered two clear advantages -
1. Requires minimal changes to existing code
2. Degrades gracefully by falling back to the original pagination if JS is not enabled

You can find the original code at http://www.problogdesign.com/wordpress/ ... with-ajax/ with a working demo at http://www.problogdesign.com/demo/ajax-load-posts/.

The code above is a Wordpress plugin but was easily adapted for use with Couch as it involved only a little tweaking of JS code.

I'll explain below how you can use it with your existing Couch listing pages.

Download the attached zip, extract the 'pbd-ajax-load-posts' folder and place it within 'couch/addons'.
If you take a look at the folder you'll find that there are no PHP scripts in there. We make use of only the frontend JS code - the backend part would be handled by Couch tags.

So let us ajaxify an existing list page.

As the first step we need to link the JS file (and optionally the CSS file which only serves to style the button) we extracted above to the the Couch template that is doing the listing.

Modify the <HEAD> element to add the following declarations -
Code: Select all
<head>
    <script type="text/javascript" src="<cms:show k_admin_link />includes/jquery.min-1.5.1.js"></script>
    <script type="text/javascript" src="<cms:show k_admin_link />addons/pbd-ajax-load-posts/js/load-posts.js?ver=1.0"></script>
   
    <link rel="stylesheet" href="<cms:show k_admin_link />addons/pbd-ajax-load-posts/css/style.css?ver=1.0" type="text/css" media="all" />
</head>

Now let us make some little changes to the existing code in the template that lists the cloned pages.

If we strip any listing code in Couch to the basics, we'll end up with something like this (we are assuming the template is 'blog.php') -
Code: Select all
<cms:pages masterpage='blog.php' limit='10' paginate='1'>
   
    <h2><a href="<cms:show k_page_link />"><cms:show k_page_name /></a></h2>
    <cms:show some_content />
   
    <cms:paginator />
   
</cms:pages>

The code above will list a maximum of 10 blog posts and show the paginator at the bottom, if required, for navigation.

To make the code above use AJAX to fetch more pages, we need only four little changes -
1. Wrap the <cms:pages> block with a DIV having an id of 'my_post_container'
Code: Select all
<div id="my_post_container">
    <cms:pages masterpage='blog.php' limit='10' paginate='1'>
       
        <h2><a href="<cms:show k_page_link />"><cms:show k_page_name /></a></h2>
        <cms:show some_content />
       
        <cms:paginator />
       
    </cms:pages>
</div>

This will mark out the section where the dynamically fetched pages would be displayed.

2. Wrap the portion of the code representing one single post with a DIV having a class named 'my_post'
Code: Select all
<div id="my_post_container">
    <cms:pages masterpage='blog.php' limit='10' paginate='1'>
       
        <div class="my_post">
            <h2><a href="<cms:show k_page_link />"><cms:show k_page_name /></a></h2>
            <cms:show some_content />
        </div>
       
        <cms:paginator />
       
    </cms:pages>
</div>

If there is already a block element wrapping one full post, you can add the class to that element instead.

3. Wrap the existing paginator with a DIV of id 'my_paginator'. This will help the JS in hiding the paginator when the 'Load more' button kicks in.
Code: Select all
<div id="my_post_container">
    <cms:pages masterpage='blog.php' limit='10' paginate='1'>
       
        <div class="my_post">
            <h2><a href="<cms:show k_page_link />"><cms:show k_page_name /></a></h2>
            <cms:show some_content />
        </div>
       
        <cms:if k_paginated_bottom && k_paginator_required>
            <div id="my_paginator">
                <cms:paginator />
            </div>
        </cms:if>
       
    </cms:pages>
</div>

As you can see, we had to place a check for 'k_paginated_bottom' (i.e. last element in list) and 'k_paginator_required' (i.e. total posts are numerous enough to require the paginator) before outputting the DIV enclosing the paginator.

4. Finally, we place a bit of JS code that'll connect with the main JS addon file
Code: Select all
<div id="my_post_container">
    <cms:pages masterpage='blog.php' limit='10' paginate='1'>
   
        <cms:if k_paginated_top && k_paginator_required >
            <script type="text/javascript">
            var my_ajax = {
                startPage:"<cms:show k_current_page />",
                maxPages:"<cms:show k_total_pages />",
                nextLink:"<cms:show k_paginate_link_next />"
            };
            </script>
        </cms:if>
   
        <div class="my_post">
            <h2><a href="<cms:show k_page_link />"><cms:show k_page_name /></a></h2>
            <cms:show some_content />
        </div>
       
        <cms:if k_paginated_bottom && k_paginator_required>
            <div id="my_paginator">
                <cms:paginator />
            </div>
        </cms:if>
       
    </cms:pages>
</div>

Once again, since we want to output the JS code just once in the list loop, we check for the first element and if paginator is required at all.

And that's it. That is all that we need to do with the original code to make it load in an AJAXified manner.
Access the template in list-view and you should see the 'Load More Posts' button instead of the regular paginator.

Hope this helps.

Attachments

removed
Hi KK,

Just wondering if you can use this load more with more than one masterpages? So lets say i have a page that is displaying more than one cloned template.

so it'll be displaying two different templates on one page.

status
articles
Simon,

While we can certainly use our normal (i.e. non-AJAX) paginated listings multiple times on the same page (viewtopic.php?f=2&t=8411&p=15625), I think we won't be able to do that using this AJAX method.

Reason is that it is using several hard-coded CSS IDs e.g. 'my_post_container', 'my_paginator' etc.
Using them multiple times will likely confuse the AJAX handler.
awesome KK, thanks!
Thank you for coding this up, it was a life saver. I'm running into an issue where the regular expression that updates the url to load isn't being changed when the page number is incremented. What could be the issue?
Hi Jon723,

Can you please tell us more about the problem? Or, better still, if your site is online please PM me the link where I can see the problem first-hand.

Thanks.
Hi KK,


Thanks for you great solution to add AJAX load more button in couchCMS Blog post. it's work fine in my site.

But i have face one issues. i am display by default 3 post, after press Load more button more 3 post load. But in this last 3 post above it's add <div class="pbd-alp-placeholder-2"> div. this div create issue in my post filtration.

So please help me how can i remove this <div class="pbd-alp-placeholder-2"> div after press on Load more button.

i am waiting your replay.


Thanks,
Ketan.
Hi Ketan :)

Taking a look at the JS code that does all heavy-lifting (couch/addons/pbd-ajax-load-posts/js/load-posts.js) shows that the code works by appending (at every 'Load more..') a DIV with ID "pbd-alp-placeholder-'+ pageNum and then loading the fetched posts inside this DIV
Code: Select all
$('#my_post_container')
     .append('<div class="pbd-alp-placeholder-'+ pageNum +'"></div>')

This, I'm afraid, is the default logic of the original code (Couch's addon just makes a tad easier to integrate it with cms:pages tag).

I can see how the additional DIVs could interfere with other existing JS code under certain conditions (as is happening in your case). However, I regret I won't be able to modify the curent JS logic as that is not my handiwork (and, in any case, my JS skills are nothing to write home about :) ).

If you feel like doing it, you may modify the JS code to suit your specific needs, though.
Hi KK,

Thanks for your replay.

I am modify your js as below and fix my issues.

Code: Select all
/*
* Adapted from http://www.problogdesign.com/wordpress/load-next-wordpress-posts-with-ajax/
*/
jQuery(document).ready(function($){
    if (typeof my_ajax == 'object') {
        // The number of the next page to load (/page/x/).
        var pageNum = parseInt(my_ajax.startPage) + 1;
       
        // The maximum number of pages the current query can return.
        var max = parseInt(my_ajax.maxPages);
       
        // The link of the next page of posts.
        var nextLink = my_ajax.nextLink;
       
        /**
         * Replace the traditional navigation with our own,
         * but only if there is at least one page of new posts to load.
         */
        if(pageNum <= max) {
            // Insert the "More Posts" link.
            $('#my_post_container')
                .append('<div class="pbd-alp-placeholder-hidden pbd-alp-placeholder-'+ pageNum +'"></div>')
                .append('<p id="pbd-alp-load-posts"><a href="#" class="w-button blog-button my">Load More</a></p>');
           
        }
        else{
            $('#my_post_container')
                .append('<p id="pbd-alp-load-posts"><a href="#" class="w-button blog-button my">No more posts</a></p>');
        }
        // Remove the traditional navigation.
        $('#my_paginator').remove();
       
        /**
         * Load new posts when the link is clicked.
         */
        $('#pbd-alp-load-posts a').click(function() {
       
            // Are there more posts to load?
            if(pageNum <= max) {
           
                // Show that we're working.
                $(this).text('Loading posts...');
               
                $('.pbd-alp-placeholder-'+ pageNum).load(nextLink + ' .my_post',
                    function() {
                        // Update page number and nextLink.
                  currentPageNum = pageNum;
                        pageNum++;
                        nextLink = nextLink.replace(/\?pg=[1-9]+/, '?pg='+ pageNum);
                       
                        // Add a new placeholder, for when user clicks again.
                        $('#pbd-alp-load-posts')
                            .before('<div class="pbd-alp-placeholder-hidden pbd-alp-placeholder-'+ pageNum +'"></div>')
                       
                        // Update the button message.
                        if(pageNum <= max) {
                            $('#pbd-alp-load-posts a').html('Load More');
                        } else {
                            $('#pbd-alp-load-posts a').html('No more posts');
                        }
                  
                  $('.pbd-alp-placeholder-'+ currentPageNum).before($('.pbd-alp-placeholder-'+ currentPageNum).html());
                  $('.pbd-alp-placeholder-'+ currentPageNum).remove();
                    }
                );
            } else {
                $('#pbd-alp-load-posts a').append('.');
            }   
           
            return false;
        });
    }
});




Thanks,
Ketan.
15 posts Page 1 of 2