├── .gitignore
├── CHANGELOG.md
├── Gemfile
├── LICENSE
├── README.md
├── app
└── assets
│ └── javascripts
│ └── jquery.infinite-pages.js.coffee
├── jquery-infinite-pages.gemspec
└── lib
├── jquery-infinite-pages.rb
└── jquery
└── infinite_pages
├── engine.rb
└── version.rb
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | *.gem
3 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Ch-Ch-Ch-Changes
2 | ================
3 |
4 | #### 0.2.0 (February 12, 2015)
5 |
6 | * Add context option to define scrolling container (thanks @pdw207)
7 | * Added coffee-script gem dependency (thanks @stgeneral)
8 |
9 | #### 0.1.2 (August 7, 2014)
10 |
11 | * Corrected possibly ambiguous coffeescript (thanks @crystalneth)
12 |
13 | #### 0.1.1 (April 14, 2014)
14 |
15 | * First release
16 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # Specify your gem's dependencies in redactor-rails.gemspec
4 | gemspec
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2014 Magoosh, Inc. http://magoosh.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | jQuery Infinite Pages
2 | =====================
3 |
4 | [](http://badge.fury.io/rb/jquery-infinite-pages)
5 |
6 | A light-weight jQuery plugin for adding infinite scrolling to paginated HTML views
7 | that tastes great with [Rails](https://github.com/rails/rails) and
8 | [Kaminari](https://github.com/amatsuda/kaminari).
9 |
10 | This project was originally designed for Rails, but the core plugin is flexible
11 | enough to use anywhere.
12 |
13 | Installation
14 | ------------
15 |
16 | Add this line to your application's `Gemfile`:
17 | ```ruby
18 | gem 'jquery-infinite-pages'
19 | ```
20 |
21 | And then execute:
22 | ```
23 | bundle install
24 | ```
25 |
26 | Add to your `application.js` file:
27 | ```javascript
28 | //= require jquery.infinite-pages
29 | ```
30 |
31 | ### Non-Rails
32 |
33 | Just copy the `jquery.infinite-pages.js.coffee` file from `app/assets/javascripts` to
34 | wherever you want it.
35 |
36 | Usage
37 | -----
38 | jQuery Infinite Pages binds to an element containing a `rel="next"` pagination link and
39 | watches for scroll events.
40 |
41 | When the link is close to the bottom of the screen, an async request to the next page
42 | is triggered. The server's response should then append the new page and update the
43 | pagination link.
44 |
45 | ```coffeescript
46 | # Setup plugin and define optional event callbacks
47 | $('.infinite-table').infinitePages
48 | debug: true
49 | buffer: 200 # load new page when within 200px of nav link
50 | context: '.pane' # define the scrolling container (defaults to window)
51 | loading: ->
52 | # jQuery callback on the nav element
53 | $(this).text("Loading...")
54 | success: ->
55 | # called after successful ajax call
56 | error: ->
57 | # called after failed ajax call
58 | $(this).text("Trouble! Please drink some coconut water and click again")
59 | ```
60 |
61 | You can also manually control the firing of load events:
62 |
63 | ```coffeescript
64 | # Force load of the next page
65 | $('.infinite-table').infinitePages('next')
66 |
67 | # Pause firing of events on scroll
68 | $('.infinite-table').infinitePages('pause')
69 |
70 | # Resume...
71 | $('.infinite-table').infinitePages('resume')
72 | ```
73 |
74 | Rails/Kaminari Example
75 | ----------------------
76 |
77 | The following is an example of how to integrate this plugin into your Rails app
78 | using Kaminari.
79 |
80 | Set up pagination in `lessons_controller.rb`:
81 |
82 | ```ruby
83 | class LessonsController
84 | def index
85 | @lessons = Lesson.order('lessons.name ASC').page(params[:page])
86 | end
87 | end
88 | ```
89 |
90 | Write the template for your list of lessons in `app/views/lessons/index.html.erb`:
91 |
92 | ```erb
93 |
94 |
95 |
96 | Lesson |
97 | |
98 |
99 | <%= render :partial => 'lessons', :object => @lessons %>
100 |
101 |
104 |
105 | ```
106 |
107 | ...and `app/views/lessons/_lessons.html.erb`:
108 |
109 | ```erb
110 | <% @lessons.each do |lesson| %>
111 |
112 | <%= lesson.name %> (<%= lesson.length.format %>) |
113 | <%= link_to "watch", lesson_path(lesson) %> |
114 |
115 | <% end %>
116 | ```
117 |
118 | Append new data to the table in `app/views/lessons/index.js.erb`:
119 |
120 | ```javascript
121 | // Append new data
122 | $("<%=j render(:partial => 'lessons', :object => @lessons) %>")
123 | .appendTo($(".infinite-table table"));
124 |
125 | // Update pagination link
126 | <% if @lessons.last_page? %>
127 | $('.pagination').html("That's all, folks!");
128 | <% else %>
129 | $('.pagination')
130 | .html("<%=j link_to_next_page(@lessons, 'Next Page', :remote => true) %>");
131 | <% end %>
132 | ```
133 |
134 | At this point, the pagination link at the bottom of your table should allow you
135 | to load the next page without refreshing. Finally, we trigger the next page load
136 | with the `infinitePages` plugin in `app/assets/javascripts/lessons.js.coffee`:
137 |
138 | ```coffee
139 | $ ->
140 | # Configure infinite table
141 | $('.infinite-table').infinitePages
142 | # debug: true
143 | loading: ->
144 | $(this).text('Loading next page...')
145 | error: ->
146 | $(this).button('There was an error, please try again')
147 | ```
148 |
149 | Voila! You should now have an infinitely long list of lessons.
150 |
--------------------------------------------------------------------------------
/app/assets/javascripts/jquery.infinite-pages.js.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | jQuery Infinite Pages v0.2.0
3 | https://github.com/magoosh/jquery-infinite-pages
4 |
5 | Released under the MIT License
6 | ###
7 |
8 | #
9 | # Built with a class-based template for jQuery plugins in Coffeescript:
10 | # https://gist.github.com/rjz/3610858
11 | #
12 |
13 | (($, window) ->
14 | # Define the plugin class
15 | class InfinitePages
16 |
17 | # Default settings
18 | defaults:
19 | debug: false # set to true to log messages to the console
20 | navSelector: 'a[rel=next]'
21 | buffer: 1000 # 1000px buffer by default
22 | loading: null # optional callback when next-page request begins
23 | success: null # optional callback when next-page request finishes
24 | error: null # optional callback when next-page request fails
25 | context: window # context to define the scrolling container
26 | state:
27 | paused: false
28 | loading: false
29 |
30 | # Constructs the new InfinitePages object
31 | #
32 | # container - the element containing the infinite table and pagination links
33 | constructor: (container, options) ->
34 | @options = $.extend({}, @defaults, options)
35 | @$container = $(container)
36 | @$table = $(container).find('table')
37 | @$context = $(@options.context)
38 | @init()
39 |
40 | # Setup and bind to related events
41 | init: ->
42 |
43 | # Debounce scroll event to improve performance
44 | scrollTimeout = null
45 | scrollHandler = (=> @check())
46 |
47 | @$context.scroll ->
48 | if scrollTimeout
49 | clearTimeout(scrollTimeout)
50 | scrollTimeout = null
51 | scrollTimeout = setTimeout(scrollHandler, 250)
52 |
53 | # Internal helper for logging messages
54 | _log: (msg) ->
55 | console?.log(msg) if @options.debug
56 |
57 | # Check the distance of the nav selector from the bottom of the window and fire
58 | # load event if close enough
59 | check: ->
60 | nav = @$container.find(@options.navSelector)
61 | if nav.size() == 0
62 | @_log "No more pages to load"
63 | else
64 | windowBottom = @$context.scrollTop() + @$context.height()
65 | distance = nav.offset().top - windowBottom
66 |
67 | if @options.state.paused
68 | @_log "Paused"
69 | else if @options.state.loading
70 | @_log "Waiting..."
71 | else if (distance > @options.buffer)
72 | @_log "#{distance - @options.buffer}px remaining..."
73 | else
74 | @next() # load the next page
75 |
76 | # Load the next page
77 | next: ->
78 | if @options.state.done
79 | @_log "Loaded all pages"
80 | else
81 | @_loading()
82 |
83 | $.getScript(@$container.find(@options.navSelector).attr('href'))
84 | .done(=> @_success())
85 | .fail(=> @_error())
86 |
87 | _loading: ->
88 | @options.state.loading = true
89 | @_log "Loading next page..."
90 | if typeof @options.loading is 'function'
91 | @$container.find(@options.navSelector).each(@options.loading)
92 |
93 | _success: ->
94 | @options.state.loading = false
95 | @_log "New page loaded!"
96 | if typeof @options.success is 'function'
97 | @$container.find(@options.navSelector).each(@options.success)
98 |
99 | _error: ->
100 | @options.state.loading = false
101 | @_log "Error loading new page :("
102 | if typeof @options.error is 'function'
103 | @$container.find(@options.navSelector).each(@options.error)
104 |
105 | # Pause firing of events on scroll
106 | pause: ->
107 | @options.state.paused = true
108 | @_log "Scroll checks paused"
109 |
110 | # Resume firing of events on scroll
111 | resume: ->
112 | @options.state.paused = false
113 | @_log "Scroll checks resumed"
114 | @check()
115 |
116 | # Define the plugin
117 | $.fn.extend infinitePages: (option, args...) ->
118 | @each ->
119 | $this = $(this)
120 | data = $this.data('infinitepages')
121 |
122 | if !data
123 | $this.data 'infinitepages', (data = new InfinitePages(this, option))
124 | if typeof option == 'string'
125 | data[option].apply(data, args)
126 |
127 | ) window.jQuery, window
128 |
--------------------------------------------------------------------------------
/jquery-infinite-pages.gemspec:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | require File.expand_path('../lib/jquery/infinite_pages/version', __FILE__)
3 |
4 | Gem::Specification.new do |s|
5 | s.name = "jquery-infinite-pages"
6 | s.version = JqueryInfinitePages::VERSION
7 | s.licenses = ["MIT"]
8 | s.summary = "Infinite pages for jQuery + Rails"
9 | s.description = "A light-weight infinite scrolling jQuery plugin, wrapped in a gem for Rails"
10 | s.authors = ["Zach Millman"]
11 | s.email = ["zach@magoosh.com"]
12 | s.homepage = "https://github.com/magoosh/jquery-infinite-pages"
13 | s.files = Dir["{lib,app}/**/*"] + ["LICENSE", "README.md"]
14 |
15 | s.add_dependency "jquery-rails"
16 | s.add_dependency "coffee-script"
17 | s.add_dependency "railties", ">= 3.1"
18 | end
19 |
--------------------------------------------------------------------------------
/lib/jquery-infinite-pages.rb:
--------------------------------------------------------------------------------
1 | require 'jquery/infinite_pages/version'
2 | require 'jquery/infinite_pages/engine'
3 |
--------------------------------------------------------------------------------
/lib/jquery/infinite_pages/engine.rb:
--------------------------------------------------------------------------------
1 | module Jquery
2 | module InfinitePages
3 | class Engine < ::Rails::Engine
4 | end
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/lib/jquery/infinite_pages/version.rb:
--------------------------------------------------------------------------------
1 | module JqueryInfinitePages
2 | VERSION = "0.2.0"
3 | end
4 |
--------------------------------------------------------------------------------