nether 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -20
- data/README.rdoc +34 -41
- data/Rakefile +37 -37
- data/app/controllers/nether_controller.rb +7 -7
- data/app/helpers/nether_helper.rb +12 -12
- data/lib/generators/nether/install/USAGE +18 -18
- data/lib/generators/nether/install/install_generator.rb +8 -8
- data/lib/generators/nether/install/templates/jquery.pageless.js.erb +178 -178
- data/lib/nether.rb +3 -3
- data/lib/nether/engine.rb +16 -16
- data/lib/nether/version.rb +3 -3
- data/lib/tasks/nether_tasks.rake +4 -4
- data/test/dummy/Rakefile +7 -7
- data/test/dummy/app/assets/javascripts/application.js +9 -9
- data/test/dummy/app/assets/stylesheets/application.css +6 -6
- data/test/dummy/app/controllers/application_controller.rb +3 -3
- data/test/dummy/app/helpers/application_helper.rb +2 -2
- data/test/dummy/app/views/layouts/application.html.erb +14 -14
- data/test/dummy/config.ru +4 -4
- data/test/dummy/config/application.rb +45 -45
- data/test/dummy/config/boot.rb +9 -9
- data/test/dummy/config/database.yml +25 -25
- data/test/dummy/config/environment.rb +5 -5
- data/test/dummy/config/environments/development.rb +30 -30
- data/test/dummy/config/environments/production.rb +60 -60
- data/test/dummy/config/environments/test.rb +39 -39
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -7
- data/test/dummy/config/initializers/inflections.rb +10 -10
- data/test/dummy/config/initializers/mime_types.rb +5 -5
- data/test/dummy/config/initializers/secret_token.rb +7 -7
- data/test/dummy/config/initializers/session_store.rb +8 -8
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -14
- data/test/dummy/config/locales/en.yml +5 -5
- data/test/dummy/config/routes.rb +58 -58
- data/test/dummy/public/404.html +26 -26
- data/test/dummy/public/422.html +26 -26
- data/test/dummy/public/500.html +26 -26
- data/test/dummy/script/rails +6 -6
- data/test/nether_test.rb +7 -7
- data/test/test_helper.rb +10 -10
- metadata +9 -12
data/MIT-LICENSE
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
Copyright 2012 Matthew Cross
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
|
+
Copyright 2012 Matthew Cross
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
CHANGED
@@ -1,41 +1,34 @@
|
|
1
|
-
= Nether
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
==
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
== Help
|
36
|
-
You will find an example app at nether_example[https://github.com/maecro/nether_example].
|
37
|
-
|
38
|
-
== Todo
|
39
|
-
* Remove dependancy on assets pipeline.
|
40
|
-
* Compatability with other pagination solutions.
|
41
|
-
* Test, test, test.
|
1
|
+
= Nether
|
2
|
+
Nether is a rails engine for easily adding endless page functionality to paginated content. It uses jquery.pageless[https://github.com/jney/jquery.pageless] and is based heavily on their demo application.
|
3
|
+
|
4
|
+
== Requirements
|
5
|
+
Currently only supports apps using the assets pipeline.
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
Add the following to your Gemfile and run the bundle command.
|
9
|
+
|
10
|
+
gem 'nether'
|
11
|
+
|
12
|
+
Once the gem is installed execute the generator to install the js files and images.
|
13
|
+
|
14
|
+
rails generate nether:install
|
15
|
+
|
16
|
+
== Usage (will_paginate)
|
17
|
+
Endless page functionality is handled by a helper function that takes three arguments by default. The number of pages, the path to get more content and the css id of the dom object to render. There is also an optional fourth argument for specifying the dom object containing the content to be rendered.
|
18
|
+
|
19
|
+
To use the helper add the following to your view after the will paginate helper, replacing variables as necessary.
|
20
|
+
|
21
|
+
<%= nether(@articles.total_pages, articles_path, "#content" %>
|
22
|
+
|
23
|
+
You must also add a helper to the action handling the pagination. The helper takes the partial to render as an argument and an optional argument to delay rendering.
|
24
|
+
|
25
|
+
render_nether("articles/article")
|
26
|
+
|
27
|
+
== Usage (kaminari)
|
28
|
+
Usage is the same as for will_paginate, however the method num_pages is instead used to return the number of pages.
|
29
|
+
|
30
|
+
<%= nether(@articles.num_pages, articles_path, "#content") %>
|
31
|
+
|
32
|
+
== Help
|
33
|
+
* You will find an example app at nether_example[https://github.com/maecro/nether_example].
|
34
|
+
* The wiki[https://github.com/maecro/nether/wiki] contains other useful information and examples.
|
data/Rakefile
CHANGED
@@ -1,37 +1,37 @@
|
|
1
|
-
#!/usr/bin/env rake
|
2
|
-
begin
|
3
|
-
require 'bundler/setup'
|
4
|
-
rescue LoadError
|
5
|
-
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
-
end
|
7
|
-
begin
|
8
|
-
require 'rdoc/task'
|
9
|
-
rescue LoadError
|
10
|
-
require 'rdoc/rdoc'
|
11
|
-
require 'rake/rdoctask'
|
12
|
-
RDoc::Task = Rake::RDocTask
|
13
|
-
end
|
14
|
-
|
15
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
-
rdoc.rdoc_dir = 'rdoc'
|
17
|
-
rdoc.title = 'Nether'
|
18
|
-
rdoc.options << '--line-numbers'
|
19
|
-
rdoc.rdoc_files.include('README.rdoc')
|
20
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
Bundler::GemHelper.install_tasks
|
26
|
-
|
27
|
-
require 'rake/testtask'
|
28
|
-
|
29
|
-
Rake::TestTask.new(:test) do |t|
|
30
|
-
t.libs << 'lib'
|
31
|
-
t.libs << 'test'
|
32
|
-
t.pattern = 'test/**/*_test.rb'
|
33
|
-
t.verbose = false
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
task :default => :test
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'Nether'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
Bundler::GemHelper.install_tasks
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'lib'
|
31
|
+
t.libs << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
task :default => :test
|
@@ -1,8 +1,8 @@
|
|
1
|
-
module NetherController
|
2
|
-
def render_nether(partial, delay=3)
|
3
|
-
if request.xhr?
|
4
|
-
sleep(delay)
|
5
|
-
render :partial => partial
|
6
|
-
end
|
7
|
-
end
|
1
|
+
module NetherController
|
2
|
+
def render_nether(partial, delay=3)
|
3
|
+
if request.xhr?
|
4
|
+
sleep(delay)
|
5
|
+
render :partial => partial
|
6
|
+
end
|
7
|
+
end
|
8
8
|
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
module NetherHelper
|
2
|
-
def nether(total_pages, url=nil, identifier=nil, container=nil)
|
3
|
-
opts = {
|
4
|
-
:totalPages => total_pages,
|
5
|
-
:url => escape_javascript(url),
|
6
|
-
:loaderMsg => 'Loading more results'
|
7
|
-
}
|
8
|
-
|
9
|
-
container && opts[:container] ||= container
|
10
|
-
|
11
|
-
javascript_tag("$('#{identifier}').pageless(#{opts.to_json});")
|
12
|
-
end
|
1
|
+
module NetherHelper
|
2
|
+
def nether(total_pages, url=nil, identifier=nil, container=nil)
|
3
|
+
opts = {
|
4
|
+
:totalPages => total_pages,
|
5
|
+
:url => escape_javascript(url),
|
6
|
+
:loaderMsg => 'Loading more results'
|
7
|
+
}
|
8
|
+
|
9
|
+
container && opts[:container] ||= container
|
10
|
+
|
11
|
+
javascript_tag("$('#{identifier}').pageless(#{opts.to_json});")
|
12
|
+
end
|
13
13
|
end
|
@@ -1,19 +1,19 @@
|
|
1
|
-
Description:
|
2
|
-
The install generator downloads jquery.pageless from
|
3
|
-
github to assets/javascripts.
|
4
|
-
|
5
|
-
|
6
|
-
Options:
|
7
|
-
|
8
|
-
Examples:
|
9
|
-
rails generate nether:install
|
10
|
-
|
11
|
-
This will create two files:
|
12
|
-
Layout: app/views/layouts/application.rhtml
|
13
|
-
Stylesheet: public/stylesheets/application.css
|
14
|
-
|
15
|
-
|
16
|
-
./script/generate app_layout myname --no-css
|
17
|
-
|
18
|
-
This will create one file:
|
1
|
+
Description:
|
2
|
+
The install generator downloads jquery.pageless from
|
3
|
+
github to assets/javascripts.
|
4
|
+
|
5
|
+
|
6
|
+
Options:
|
7
|
+
|
8
|
+
Examples:
|
9
|
+
rails generate nether:install
|
10
|
+
|
11
|
+
This will create two files:
|
12
|
+
Layout: app/views/layouts/application.rhtml
|
13
|
+
Stylesheet: public/stylesheets/application.css
|
14
|
+
|
15
|
+
|
16
|
+
./script/generate app_layout myname --no-css
|
17
|
+
|
18
|
+
This will create one file:
|
19
19
|
Layout: app/views/layouts/myname.rhtml
|
@@ -1,9 +1,9 @@
|
|
1
|
-
module Nether
|
2
|
-
class InstallGenerator < Rails::Generators::Base
|
3
|
-
source_root File.expand_path('../templates', __FILE__)
|
4
|
-
def install_pageless
|
5
|
-
copy_file "jquery.pageless.js.erb", "app/assets/javascripts/jquery.pageless.js.erb"
|
6
|
-
copy_file "load.gif", "app/assets/images/load.gif"
|
7
|
-
end
|
8
|
-
end
|
1
|
+
module Nether
|
2
|
+
class InstallGenerator < Rails::Generators::Base
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
4
|
+
def install_pageless
|
5
|
+
copy_file "jquery.pageless.js.erb", "app/assets/javascripts/jquery.pageless.js.erb"
|
6
|
+
copy_file "load.gif", "app/assets/images/load.gif"
|
7
|
+
end
|
8
|
+
end
|
9
9
|
end
|
@@ -1,179 +1,179 @@
|
|
1
|
-
// =======================================================================
|
2
|
-
// PageLess - endless page
|
3
|
-
//
|
4
|
-
// Pageless is a jQuery plugin.
|
5
|
-
// As you scroll down you see more results coming back at you automatically.
|
6
|
-
// It provides an automatic pagination in an accessible way : if javascript
|
7
|
-
// is disabled your standard pagination is supposed to work.
|
8
|
-
//
|
9
|
-
// Licensed under the MIT:
|
10
|
-
// http://www.opensource.org/licenses/mit-license.php
|
11
|
-
//
|
12
|
-
// Parameters:
|
13
|
-
// currentPage: current page (params[:page])
|
14
|
-
// distance: distance to the end of page in px when ajax query is fired
|
15
|
-
// loader: selector of the loader div (ajax activity indicator)
|
16
|
-
// loaderHtml: html code of the div if loader not used
|
17
|
-
// loaderImage: image inside the loader
|
18
|
-
// loaderMsg: displayed ajax message
|
19
|
-
// pagination: selector of the paginator divs.
|
20
|
-
// if javascript is disabled paginator is provided
|
21
|
-
// params: paramaters for the ajax query, you can pass auth_token here
|
22
|
-
// totalPages: total number of pages
|
23
|
-
// url: URL used to request more data
|
24
|
-
//
|
25
|
-
// Callback Parameters:
|
26
|
-
// scrape: A function to modify the incoming data.
|
27
|
-
// complete: A function to call when a new page has been loaded (optional)
|
28
|
-
// end: A function to call when the last page has been loaded (optional)
|
29
|
-
//
|
30
|
-
// Usage:
|
31
|
-
// $('#results').pageless({ totalPages: 10
|
32
|
-
// , url: '/articles/'
|
33
|
-
// , loaderMsg: 'Loading more results'
|
34
|
-
// });
|
35
|
-
//
|
36
|
-
// Requires: jquery
|
37
|
-
//
|
38
|
-
// Author: Jean-Sébastien Ney (https://github.com/jney)
|
39
|
-
//
|
40
|
-
// Contributors:
|
41
|
-
// Alexander Lang (https://github.com/langalex)
|
42
|
-
// Lukas Rieder (https://github.com/Overbryd)
|
43
|
-
//
|
44
|
-
// Thanks to:
|
45
|
-
// * codemonky.com/post/34940898
|
46
|
-
// * www.unspace.ca/discover/pageless/
|
47
|
-
// * famspam.com/facebox
|
48
|
-
// =======================================================================
|
49
|
-
|
50
|
-
(function($) {
|
51
|
-
|
52
|
-
var FALSE = !1
|
53
|
-
, TRUE = !FALSE
|
54
|
-
, element
|
55
|
-
, isLoading = FALSE
|
56
|
-
, loader
|
57
|
-
, namespace = '.pageless'
|
58
|
-
, SCROLL = 'scroll' + namespace
|
59
|
-
, RESIZE = 'resize' + namespace
|
60
|
-
, settings = { container: window
|
61
|
-
, currentPage: 1
|
62
|
-
, distance: 100
|
63
|
-
, pagination: '.pagination'
|
64
|
-
, params: {}
|
65
|
-
, url: location.href
|
66
|
-
, loaderImage: "<%= asset_path 'load.gif' %>"
|
67
|
-
}
|
68
|
-
, container
|
69
|
-
, $container;
|
70
|
-
|
71
|
-
$.pageless = function(opts) {
|
72
|
-
$.isFunction(opts) ? settings.call() : init(opts);
|
73
|
-
};
|
74
|
-
|
75
|
-
var loaderHtml = function () {
|
76
|
-
return settings.loaderHtml || '\
|
77
|
-
<div id="pageless-loader" style="display:none;text-align:center;width:100%;">\
|
78
|
-
<div class="msg" style="color:#e9e9e9;font-size:2em"></div>\
|
79
|
-
<img src="' + settings.loaderImage + '" alt="loading more results" style="margin:10px auto" />\
|
80
|
-
</div>';
|
81
|
-
};
|
82
|
-
|
83
|
-
// settings params: totalPages
|
84
|
-
var init = function (opts) {
|
85
|
-
if (settings.inited) return;
|
86
|
-
settings.inited = TRUE;
|
87
|
-
|
88
|
-
if (opts) $.extend(settings, opts);
|
89
|
-
|
90
|
-
container = settings.container;
|
91
|
-
$container = $(container);
|
92
|
-
|
93
|
-
// for accessibility we can keep pagination links
|
94
|
-
// but since we have javascript enabled we remove pagination links
|
95
|
-
if(settings.pagination) $(settings.pagination).remove();
|
96
|
-
|
97
|
-
// start the listener
|
98
|
-
startListener();
|
99
|
-
};
|
100
|
-
|
101
|
-
$.fn.pageless = function (opts) {
|
102
|
-
var $el = $(this)
|
103
|
-
, $loader = $(opts.loader, $el);
|
104
|
-
|
105
|
-
init(opts);
|
106
|
-
element = $el;
|
107
|
-
|
108
|
-
// loader element
|
109
|
-
if (opts.loader && $loader.length) {
|
110
|
-
loader = $loader;
|
111
|
-
} else {
|
112
|
-
loader = $(loaderHtml());
|
113
|
-
$el.append(loader);
|
114
|
-
// if we use the default loader, set the message
|
115
|
-
if (!opts.loaderHtml) {
|
116
|
-
$('#pageless-loader .msg').html(opts.loaderMsg);
|
117
|
-
}
|
118
|
-
}
|
119
|
-
};
|
120
|
-
|
121
|
-
//
|
122
|
-
var loading = function (bool) {
|
123
|
-
(isLoading = bool)
|
124
|
-
? (loader && loader.fadeIn('normal'))
|
125
|
-
: (loader && loader.fadeOut('normal'));
|
126
|
-
};
|
127
|
-
|
128
|
-
// distance to end of the container
|
129
|
-
var distanceToBottom = function () {
|
130
|
-
return (container === window)
|
131
|
-
? $(document).height()
|
132
|
-
- $container.scrollTop()
|
133
|
-
- $container.height()
|
134
|
-
: $container[0].scrollHeight
|
135
|
-
- $container.scrollTop()
|
136
|
-
- $container.height();
|
137
|
-
};
|
138
|
-
|
139
|
-
var stopListener = function() {
|
140
|
-
$container.unbind(namespace);
|
141
|
-
};
|
142
|
-
|
143
|
-
// * bind a scroll event
|
144
|
-
// * trigger is once in case of reload
|
145
|
-
var startListener = function() {
|
146
|
-
$container.bind(SCROLL+' '+RESIZE, watch)
|
147
|
-
.trigger(SCROLL);
|
148
|
-
};
|
149
|
-
|
150
|
-
var watch = function() {
|
151
|
-
// listener was stopped or we've run out of pages
|
152
|
-
if (settings.totalPages <= settings.currentPage) {
|
153
|
-
stopListener();
|
154
|
-
// if there is a afterStopListener callback we call it
|
155
|
-
if (settings.end) settings.end.call();
|
156
|
-
return;
|
157
|
-
}
|
158
|
-
|
159
|
-
// if slider past our scroll offset, then fire a request for more data
|
160
|
-
if(!isLoading && (distanceToBottom() < settings.distance)) {
|
161
|
-
loading(TRUE);
|
162
|
-
// move to next page
|
163
|
-
settings.currentPage++;
|
164
|
-
// set up ajax query params
|
165
|
-
$.extend( settings.params
|
166
|
-
, { page: settings.currentPage });
|
167
|
-
// finally ajax query
|
168
|
-
$.get( settings.url
|
169
|
-
, settings.params
|
170
|
-
, function (data) {
|
171
|
-
$.isFunction(settings.scrape) ? settings.scrape(data) : data;
|
172
|
-
loader ? loader.before(data) : element.append(data);
|
173
|
-
loading(FALSE);
|
174
|
-
// if there is a complete callback we call it
|
175
|
-
if (settings.complete) settings.complete.call();
|
176
|
-
}, 'html');
|
177
|
-
}
|
178
|
-
};
|
1
|
+
// =======================================================================
|
2
|
+
// PageLess - endless page
|
3
|
+
//
|
4
|
+
// Pageless is a jQuery plugin.
|
5
|
+
// As you scroll down you see more results coming back at you automatically.
|
6
|
+
// It provides an automatic pagination in an accessible way : if javascript
|
7
|
+
// is disabled your standard pagination is supposed to work.
|
8
|
+
//
|
9
|
+
// Licensed under the MIT:
|
10
|
+
// http://www.opensource.org/licenses/mit-license.php
|
11
|
+
//
|
12
|
+
// Parameters:
|
13
|
+
// currentPage: current page (params[:page])
|
14
|
+
// distance: distance to the end of page in px when ajax query is fired
|
15
|
+
// loader: selector of the loader div (ajax activity indicator)
|
16
|
+
// loaderHtml: html code of the div if loader not used
|
17
|
+
// loaderImage: image inside the loader
|
18
|
+
// loaderMsg: displayed ajax message
|
19
|
+
// pagination: selector of the paginator divs.
|
20
|
+
// if javascript is disabled paginator is provided
|
21
|
+
// params: paramaters for the ajax query, you can pass auth_token here
|
22
|
+
// totalPages: total number of pages
|
23
|
+
// url: URL used to request more data
|
24
|
+
//
|
25
|
+
// Callback Parameters:
|
26
|
+
// scrape: A function to modify the incoming data.
|
27
|
+
// complete: A function to call when a new page has been loaded (optional)
|
28
|
+
// end: A function to call when the last page has been loaded (optional)
|
29
|
+
//
|
30
|
+
// Usage:
|
31
|
+
// $('#results').pageless({ totalPages: 10
|
32
|
+
// , url: '/articles/'
|
33
|
+
// , loaderMsg: 'Loading more results'
|
34
|
+
// });
|
35
|
+
//
|
36
|
+
// Requires: jquery
|
37
|
+
//
|
38
|
+
// Author: Jean-Sébastien Ney (https://github.com/jney)
|
39
|
+
//
|
40
|
+
// Contributors:
|
41
|
+
// Alexander Lang (https://github.com/langalex)
|
42
|
+
// Lukas Rieder (https://github.com/Overbryd)
|
43
|
+
//
|
44
|
+
// Thanks to:
|
45
|
+
// * codemonky.com/post/34940898
|
46
|
+
// * www.unspace.ca/discover/pageless/
|
47
|
+
// * famspam.com/facebox
|
48
|
+
// =======================================================================
|
49
|
+
|
50
|
+
(function($) {
|
51
|
+
|
52
|
+
var FALSE = !1
|
53
|
+
, TRUE = !FALSE
|
54
|
+
, element
|
55
|
+
, isLoading = FALSE
|
56
|
+
, loader
|
57
|
+
, namespace = '.pageless'
|
58
|
+
, SCROLL = 'scroll' + namespace
|
59
|
+
, RESIZE = 'resize' + namespace
|
60
|
+
, settings = { container: window
|
61
|
+
, currentPage: 1
|
62
|
+
, distance: 100
|
63
|
+
, pagination: '.pagination'
|
64
|
+
, params: {}
|
65
|
+
, url: location.href
|
66
|
+
, loaderImage: "<%= asset_path 'load.gif' %>"
|
67
|
+
}
|
68
|
+
, container
|
69
|
+
, $container;
|
70
|
+
|
71
|
+
$.pageless = function(opts) {
|
72
|
+
$.isFunction(opts) ? settings.call() : init(opts);
|
73
|
+
};
|
74
|
+
|
75
|
+
var loaderHtml = function () {
|
76
|
+
return settings.loaderHtml || '\
|
77
|
+
<div id="pageless-loader" style="display:none;text-align:center;width:100%;">\
|
78
|
+
<div class="msg" style="color:#e9e9e9;font-size:2em"></div>\
|
79
|
+
<img src="' + settings.loaderImage + '" alt="loading more results" style="margin:10px auto" />\
|
80
|
+
</div>';
|
81
|
+
};
|
82
|
+
|
83
|
+
// settings params: totalPages
|
84
|
+
var init = function (opts) {
|
85
|
+
if (settings.inited) return;
|
86
|
+
settings.inited = TRUE;
|
87
|
+
|
88
|
+
if (opts) $.extend(settings, opts);
|
89
|
+
|
90
|
+
container = settings.container;
|
91
|
+
$container = $(container);
|
92
|
+
|
93
|
+
// for accessibility we can keep pagination links
|
94
|
+
// but since we have javascript enabled we remove pagination links
|
95
|
+
if(settings.pagination) $(settings.pagination).remove();
|
96
|
+
|
97
|
+
// start the listener
|
98
|
+
startListener();
|
99
|
+
};
|
100
|
+
|
101
|
+
$.fn.pageless = function (opts) {
|
102
|
+
var $el = $(this)
|
103
|
+
, $loader = $(opts.loader, $el);
|
104
|
+
|
105
|
+
init(opts);
|
106
|
+
element = $el;
|
107
|
+
|
108
|
+
// loader element
|
109
|
+
if (opts.loader && $loader.length) {
|
110
|
+
loader = $loader;
|
111
|
+
} else {
|
112
|
+
loader = $(loaderHtml());
|
113
|
+
$el.append(loader);
|
114
|
+
// if we use the default loader, set the message
|
115
|
+
if (!opts.loaderHtml) {
|
116
|
+
$('#pageless-loader .msg').html(opts.loaderMsg);
|
117
|
+
}
|
118
|
+
}
|
119
|
+
};
|
120
|
+
|
121
|
+
//
|
122
|
+
var loading = function (bool) {
|
123
|
+
(isLoading = bool)
|
124
|
+
? (loader && loader.fadeIn('normal'))
|
125
|
+
: (loader && loader.fadeOut('normal'));
|
126
|
+
};
|
127
|
+
|
128
|
+
// distance to end of the container
|
129
|
+
var distanceToBottom = function () {
|
130
|
+
return (container === window)
|
131
|
+
? $(document).height()
|
132
|
+
- $container.scrollTop()
|
133
|
+
- $container.height()
|
134
|
+
: $container[0].scrollHeight
|
135
|
+
- $container.scrollTop()
|
136
|
+
- $container.height();
|
137
|
+
};
|
138
|
+
|
139
|
+
var stopListener = function() {
|
140
|
+
$container.unbind(namespace);
|
141
|
+
};
|
142
|
+
|
143
|
+
// * bind a scroll event
|
144
|
+
// * trigger is once in case of reload
|
145
|
+
var startListener = function() {
|
146
|
+
$container.bind(SCROLL+' '+RESIZE, watch)
|
147
|
+
.trigger(SCROLL);
|
148
|
+
};
|
149
|
+
|
150
|
+
var watch = function() {
|
151
|
+
// listener was stopped or we've run out of pages
|
152
|
+
if (settings.totalPages <= settings.currentPage) {
|
153
|
+
stopListener();
|
154
|
+
// if there is a afterStopListener callback we call it
|
155
|
+
if (settings.end) settings.end.call();
|
156
|
+
return;
|
157
|
+
}
|
158
|
+
|
159
|
+
// if slider past our scroll offset, then fire a request for more data
|
160
|
+
if(!isLoading && (distanceToBottom() < settings.distance)) {
|
161
|
+
loading(TRUE);
|
162
|
+
// move to next page
|
163
|
+
settings.currentPage++;
|
164
|
+
// set up ajax query params
|
165
|
+
$.extend( settings.params
|
166
|
+
, { page: settings.currentPage });
|
167
|
+
// finally ajax query
|
168
|
+
$.get( settings.url
|
169
|
+
, settings.params
|
170
|
+
, function (data) {
|
171
|
+
$.isFunction(settings.scrape) ? settings.scrape(data) : data;
|
172
|
+
loader ? loader.before(data) : element.append(data);
|
173
|
+
loading(FALSE);
|
174
|
+
// if there is a complete callback we call it
|
175
|
+
if (settings.complete) settings.complete.call();
|
176
|
+
}, 'html');
|
177
|
+
}
|
178
|
+
};
|
179
179
|
})(jQuery);
|