gavinhewitt
6/25/2013 - 1:29 PM

Twitter Bootstrap plugin that enables infinite scrolling

Twitter Bootstrap plugin that enables infinite scrolling

/*
 * Example of how to apply the infinite scroll plugin
 */

(function ($) {
    $(function () {
        $('#searchListing').infiniteScroll({
            calculateBottom: function () {
                return ($('.searchListing').position().top + $('.searchListing').height()) - $(window).height() + 50;
            },
            processResults: function (results) {
                $('#number-of-results').text(results.Key);
 
                for (var i = 0; i < results.Value.length; i++) {
                    $('#search-results').append($('<div class="divider"></div>'));
 
                    var result = results.Value[i];
 
                    var el = $('#result-template').find('.item').clone();
                    el.find('#result-url').attr('href', result.Url).html(result.Title);
                    el.find('#result-description').html(result.Description);
                    el.find('.section').html(result.Category);
 
                    $('#search-results').append(el);
                }
            },
            url: $('#searchListing').data('url') + '/GetSearchResults',
            getData: function () {
                return { "query": $('#hidQuery').val() };
            }
        });
    });
} (jQuery));
<!-- Example of HTML usage -->
<div id='searchListing' data-url='http://localhost/services/searchservice.asmx'>
    <div class='spinner hide'>
        <img src="/content/images/ajaxLoader.gif" />
    </div>
    <div id='search-results'>
        <!-- initial starting results -->
    </div>
    <div id='number-of-results'>20</div>
    <div id='end-of-results' class='hide alert alert-info'>
        <em>End of results</em>
    </div>
</div>

<div id='result-template' class='hide'>
    <a id='result-url' href='#'>Whatever</a>
    <div id='result-description'></div>
    <div class='section'></div>
</div>
/* ============================================
 * bootstrap-infiniteScroll.js
 * ============================================ */

!function ($) {
    'use strict';
    var InfiniteScroll = function (el, options) {
        this.$element = $(el);
        this.$data = $(el).data();
        this.$options = options;
 
        this.executing = false;
        this.endOfResults = false;
        this.currentPage = 1;
 
        var that = this;
 
        $(window).scroll(function () {
            if ($(window).scrollTop() >= that.$options.calculateBottom()) {
                that.loadMore();
            }
        });
    };
 
    InfiniteScroll.prototype = {
        constructor: InfiniteScroll,
 
        loadMore: function () {
            var $this = this;
            if ($this.executing || $this.endOfResults) return;
 
            $this.$element.find('.spinner').removeClass('hide');
 
            $this.executing = true;
            $this.currentPage += 1;
 
            var data = $this.$options.getData();
            data.page = $this.currentPage;
 
            $.ajax({
                contentType: 'application/json; charset=UTF-8',
                data: JSON.stringify(data),
                url: $this.$options.url,
                type: 'POST',
                success: function (retVal) {
                    $this.$options.processResults(retVal);
 
                    if (retVal.Value.length == 0) {
                        $this.endOfResults = true;
                        $this.$element.find('#end-of-results').removeClass('hide');
                    }
 
                    $this.$element.find('.spinner').addClass('hide');
                    $this.executing = false;
                }
            });
        }
    };
 
    $.fn.infiniteScroll = function (option) {
        return this.each(function () {
            var $this = $(this),
                data = $this.data('infinite-search'),
                options = $.extend({}, $.fn.infiniteScroll.defaults, typeof option == 'object' && option);
            if (!data) $this.data('infinite-search', (data = new InfiniteScroll(this, options)));
            if (typeof options == 'string') data[options]();
        });
    };
 
    $.fn.infiniteScroll.defaults = {
        calculateBottom: function () { },
        getData: function () { },
        processResults: function () { },
        url: ''
    };
 
    $.fn.infiniteScroll.Constructor = InfiniteScroll;
} (window.jQuery);