ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Using AJAX to page thru items, need total number of possible results

September 02, 2010 6:00pm

Subscribe [5]
  • #1 / Sep 02, 2010 6:00pm

    chichilatte

    43 posts

    Hi, I’m using jQuery AJAX to page through a list of news items, very simple. i’m a bit of a newbie, so not sure if there’s a way to get the total number of news items.

    My template which retrieves a single news item is called “index_news_items”:

    {exp:weblog:entries weblog="news"  orderby="date" sort="desc" limit="1" offset="{segment_2}" show_future_entries="no" dynamic="off" disable="member_data|pagination|trackbacks"}
        {title}
        {entry_date format="%g:%i%a %l %j%S %F %Y"}
        {news_article}
    {/exp:weblog:entries}

    That gets loaded into a page which also has a “More news” button. Here’s the javascript jQuery which runs when the button is clicked:

    var newsOffset = 0;
    $(function($) {
        $('.main .news .more a.link').click(function(){
            newsOffset++;
            $('#newsAjaxWrapper').load('/index_news_items/'+newsOffset);
            return false;
        });
    });

    This works *perfectly*, but you can see there’s no way to know when there are no more news items left to display (so that i could disable the More button).

    The {total_results} tag isn’t any good, since it’s affected by the “limit” variable. Can anyone suggest a neat way of getting the total number of news items?

    thanks!

  • #2 / Sep 02, 2010 9:11pm

    Brandon Jones

    5500 posts

    Hi chichilatte,

    This could be accomplished with a custom query. Essentially, the query that the Weblog module runs is going to be limited to only what it needs to show for performance reasons.

    We can’t provide specific support for custom queries, but I can move this over to the CodeShare Corner if you’d like.

  • #3 / Sep 03, 2010 4:21am

    leeaston

    634 posts

    Hey chichilatte, if you get AJAX to page thru working would you mind sharing the code?

    Best wishes
    Lee

  • #4 / Sep 03, 2010 9:17am

    Ingmar

    29245 posts

    Moving as indicated by Brandon.

  • #5 / Sep 03, 2010 9:45am

    chichilatte

    43 posts

    Thanks brandon, no time to fart around with custom queries tho.

    I whipped up a quick bit of php to pump out the right total…

    <?php $newsTotal = 0; ?>
    {exp:weblog:entries weblog="news"  orderby="date" sort="desc" offset="0" show_future_entries="no" dynamic="off" disable="member_data|pagination|trackbacks"}
        <?php $newsTotal++; ?>
    {/exp:weblog:entries}

    ...and in the javascript, used by the jQuery…

    < script>
        var newsTotal = <?php echo $newsTotal; ?>;
    </ script>

    That’s probably very wasteful of resources, but it works. Worse than resources, it’s just bloody confusing looking code, mixing, like, three languages. Personally, i’d love some kind of addon to EE that gave us the ability to get a total number of results without looping through each row in the weblog. I know SQL does it no bother, so wouldn’t be hard to implement.

    NOTE: you have to turn on php parsing in your template for this solution to work!

  • #6 / Sep 03, 2010 10:01am

    chichilatte

    43 posts

    Here you are lee.

    There’s your main page template…

    
    
    


    And then there’s your little template which the main page’s jQuery loads into the main page…

    {exp:weblog:entries weblog="news"  orderby="date" sort="desc" limit="1" offset="{segment_2}" show_future_entries="no" dynamic="off" disable="member_data|pagination|trackbacks"}
             {title}
             {entry_date format="%g:%i%a %l %j%S %F %Y"}
             
                 {news_article}
             
    {/exp:weblog:entries}

    Hope that makes sense 😊

  • #7 / Sep 03, 2010 10:04am

    leeaston

    634 posts

    thanks very much chichilatte, that should keep me up late tonight 😊

  • #8 / Sep 03, 2010 10:05am

    chichilatte

    43 posts

    I would just say, brandon, that it would be a good idea to put a little note on the {total_results} section of the EE documentation (and maybe other appropriate places) to tell people there’s no built in way to do what I’ve done here.

    I’m finding that EE is taking ages to learn because there are lots of problems like this cropping up and it takes exhaustive research to find out something doesn’t exist! It’s like WMD all over.

    ta
    chichi

  • #9 / Sep 03, 2010 4:56pm

    Brandon Jones

    5500 posts

    Hi chichi,

    I thought there was something to that effect, but couldn’t find it when I glanced at the documentation yesterday. Perhaps it was my imagination, but behold:

    absolute_count and absolute_results

    That work?  😊

  • #10 / Sep 04, 2010 4:38am

    chichilatte

    43 posts

    Ah, looks promising! i’m off on holiday for two weeks, but will investigate when i get back, thanks buddy

  • #11 / Oct 12, 2010 10:52am

    Brennan Sang

    17 posts

    I needed to do something similar, but with multiple results per page, so I let EE handle the pagination for me and used jQuery to hijack the pagination links. I put a hidden input (#currentPage) inside the pagination results to allow for handling the “<“ and “>” links.

    I call the script on document.ready and then call it after each ajax load.

    I’m sure there are more elegant ways to handle this, but this is what I’ve come up with.

    in my main template:

    <div id="reviews">
        {embed="embeds/review_listing" cat="{segment_1_category_id}"}
    </div>

    embeds/review_listing:

    {exp:channel:entries channel="reviews" dynamic="off" limit=“5” orderby="review_date" paginate="bottom"}
    <div class="review">
        <h3>{title}</h3><p><div class="stars s{review_stars}">{review_stars}</div><br />
        </p><h4>By {review_name}{if review_title}, {review_title}{/if} on {review_date format="%D, %F %d, %Y"}</h4>
    <p>    {review_copy}<br />
    </div><br />
    {paginate}<br />
    <input type="hidden" id="currentPage" value="{current_page}"><br />
    Page {current_page} of {total_pages} pages <span>{pagination_links}</span><br />
    {/paginate}<br />
    {/exp:channel:entries}

    the script:

    function ajaxifyPaginationLinks() {
        var $ajaxDiv = $("#reviews"); // set the div whose content we'd like to change
        $ajaxDiv.removeClass("changing"); // allow CSS to return normal appearance of AJAX div
        $("span#review_pagination_links a").click(function(e) { // grab links to ajaxify
            var $itemsPerPage = 5; // put the number of items per page here (should equaly "limit" in your exp:channel:entries tag)
            e.preventDefault(); // don't follow the link's href
            $ajaxDiv.addClass("changing"); // allow CSS to change appearance of AJAX div during AJAX load
            var $this = $(this); // avoid unneccessary calls to $(this)
            var $currentPage = (($("input#currentPage").val() * $itemsPerPage)-$itemsPerPage); // get current page number from input#currentPage, multiply it by $itemsPerPage to get the current offset
            
            if ($this.attr('innerHTML') == ">") {
                var pageNumber = ($currentPage + $itemsPerPage); // if the link is ">" add $itemsPerPage to the current offset
            } else if ($this.attr('innerHTML') == "<") {
                var pageNumber = ($currentPage - $itemsPerPage); // if the link is "<" subtract $itemsPerPage to the current offset
            } else {
                var pageNumber = (($this.attr('innerHTML')-1) * $itemsPerPage) // if the link is a number, figure the desired offset
            }
            
            var $url = "/embeds/review_listing/P" + pageNumber + “/"; // build url
            $ajaxDiv.load($url, function() { ajaxifyPaginationLinks(); }); // change contents of $ajaxDiv with result of call to $url
        })
    };
.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases