-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
219 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,103 @@ | ||
jquery-infinite-pages | ||
jQuery Infinite Pages | ||
===================== | ||
|
||
Simple infinite pages for Rails + jQuery + Kaminari | ||
A custom jQuery plugin for adding infinite scrolling to paginated HTML views, designed | ||
for integration with the Kaminari Rails plugin. | ||
|
||
When the user scrolls to the point where the `rel="next"` link is within a set number | ||
of pixels of the bottom of the screen, an async request to the next page is triggered. | ||
The response should then update the displayed data and the pagination link. | ||
|
||
Installation | ||
------------ | ||
|
||
Just copy the `jquery.infinite-pages.js.coffee` file in your `app/assets/javascripts` | ||
folder. | ||
|
||
(It would be awesome to make this a gem, so consider that a feature request :smile:) | ||
|
||
Plugin Usage | ||
------------ | ||
|
||
``` | ||
# Setup plugin and define optional event callbacks | ||
$('.infinite-table').infinitePages | ||
debug: true | ||
buffer: 200 # load new page when within 200px of nav link | ||
loading: -> | ||
# jQuery callback on the nav element | ||
$(this).text("Loading...") | ||
success: -> | ||
# called after successful ajax call | ||
error: -> | ||
# called after failed ajax call | ||
$(this).text("Trouble! Please drink some coconut water and try again") | ||
# Force load of the next page | ||
$('.infinite-table').infinitePages('next') | ||
# Pause firing of events on scroll | ||
$('.infinite-table').infinitePages('pause') | ||
# Resume... | ||
$('.infinite-table').infinitePages('resume') | ||
``` | ||
|
||
Rails/Kaminari Example | ||
---------------------- | ||
|
||
Example `lessons_controller.rb`: | ||
|
||
```ruby | ||
class LessonsController | ||
def index | ||
@lessons = current_user.subscribed_lessons.page(params[:page]) | ||
end | ||
end | ||
``` | ||
|
||
Example `index.html.erb`: | ||
|
||
```erb | ||
<div class="infinite-table"> | ||
<table> | ||
<thead> | ||
<tr> | ||
<th>Lesson</th> | ||
<th>Length</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<%= render :partial => 'lessons', :object => @lessons %> | ||
</tbody> | ||
</table> | ||
<p class="pagination"> | ||
<%= link_to_next_page(@lessons, 'Next Page'))%> | ||
</p> | ||
</div> | ||
``` | ||
|
||
Example `_lessons.html.erb`: | ||
|
||
```erb | ||
<% @lessons.each do |lesson| %> | ||
<tr> | ||
<td><%= lesson.name %></td> | ||
<td><%= lesson.length.format %></td> | ||
</tr> | ||
<% end %> | ||
``` | ||
|
||
Example `index.js.erb`: | ||
|
||
```javascript | ||
// Append new data | ||
$("<%=j render(:partial => 'lessons', :object => @lessons) %>").appendTo($(".infinite-table tbody")); | ||
|
||
// Update pagination link | ||
<% if answers.last_page? %> | ||
$('.pagination').remove(); | ||
<% else %> | ||
$('.pagination').html("<%=j link_to_next_page(@lessons, 'Next Page'))%>"); | ||
<% end %> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
### | ||
jQuery Infinite Pages v0.1.0 | ||
https://github.com/magoosh/jquery-infinite-pages | ||
Released under the MIT License | ||
### | ||
|
||
# | ||
# Built with a class-based template for jQuery plugins in Coffeescript: | ||
# https://gist.github.com/rjz/3610858 | ||
# | ||
|
||
(($, window) -> | ||
# Define the plugin class | ||
class InfinitePages | ||
|
||
# Default settings | ||
defaults: | ||
debug: false # set to true to log messages to the console | ||
navSelector: 'a[rel=next]' | ||
buffer: 1000 # 1000px buffer by default | ||
loading: null # optional callback when next-page request begins | ||
success: null # optional callback when next-page request finishes | ||
error: null # optional callback when next-page request fails | ||
state: | ||
paused: false | ||
loading: false | ||
|
||
# Constructs the new InfinitePages object | ||
# | ||
# container - the element containing the infinite table and pagination links | ||
constructor: (container, options) -> | ||
@options = $.extend({}, @defaults, options) | ||
@$container = $(container) | ||
@$table = $(container).find('table') | ||
|
||
@init() | ||
|
||
# Setup and bind to related events | ||
init: -> | ||
$(window).scroll => | ||
@check() | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
zmillman
Author
Contributor
|
||
|
||
# Internal helper for logging messages | ||
_log: (msg) -> | ||
console?.log(msg) if @options.debug | ||
|
||
# Check the distance of the nav selector from the bottom of the window and fire | ||
# load event if close enough | ||
check: -> | ||
nav = @$container.find(@options.navSelector) | ||
if nav.size() == 0 | ||
@_log "No more pages to load" | ||
else | ||
windowBottom = $(window).scrollTop() + $(window).height() | ||
distance = nav.offset().top - windowBottom | ||
|
||
if @options.state.paused | ||
@_log "Paused" | ||
else if @options.state.loading | ||
@_log "Waiting..." | ||
else if (distance > @options.buffer) | ||
@_log "#{distance - @options.buffer}px remaining..." | ||
else | ||
@next() # load the next page | ||
|
||
# Load the next page | ||
next: -> | ||
if @options.state.done | ||
@_log "Loaded all pages" | ||
else | ||
@_loading() | ||
|
||
$.getScript(@$container.find(@options.navSelector).attr('href')) | ||
.done (=> @_success()) | ||
.fail (=> @_error()) | ||
|
||
_loading: -> | ||
@options.state.loading = true | ||
@_log "Loading next page..." | ||
if typeof @options.loading is 'function' | ||
@$container.find(@options.navSelector).each(@options.loading) | ||
|
||
_success: -> | ||
@options.state.loading = false | ||
@_log "New page loaded!" | ||
if typeof @options.success is 'function' | ||
@$container.find(@options.navSelector).each(@options.success) | ||
|
||
_error: -> | ||
@options.state.loading = false | ||
@_log "Error loading new page :(" | ||
if typeof @options.error is 'function' | ||
@$container.find(@options.navSelector).each(@options.error) | ||
|
||
# Pause firing of events on scroll | ||
pause: -> | ||
@options.state.paused = true | ||
@_log("Scroll checks paused") | ||
|
||
# Resume firing of events on scroll | ||
resume: -> | ||
@options.state.paused = false | ||
@_log("Scroll checks resumed") | ||
@check() | ||
|
||
# Define the plugin | ||
$.fn.extend infinitePages: (option, args...) -> | ||
@each -> | ||
$this = $(this) | ||
data = $this.data('infinitepages') | ||
|
||
if !data | ||
$this.data 'infinitepages', (data = new InfinitePages(this, option)) | ||
if typeof option == 'string' | ||
data[option].apply(data, args) | ||
|
||
) window.jQuery, window |
Doing a lot of things in scroll event slows down the browser. jQuery creator John Resig suggests not to do this in this blog post. I think it's better to do something like the following: