spine_paginator 0.1.0 → 0.1.1
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/Gruntfile.coffee +19 -4
- data/README.md +12 -14
- data/dist/spine.pagination_controller.js +142 -0
- data/dist/spine.pagination_controller.min.js +5 -0
- data/dist/spine.paginator.js +108 -70
- data/dist/spine.paginator.min.js +1 -1
- data/examples/spine_pagination.coffee +57 -0
- data/examples/spine_pagination.css +2 -0
- data/examples/spine_pagination.html +1 -0
- data/examples/spine_pagination.js +120 -0
- data/examples/spine_pagination.scss +3 -0
- data/examples/spine_pagination.slim +25 -0
- data/lib/spine_paginator/version.rb +1 -1
- data/package.json +5 -3
- data/spec/lib/handlebars.js +2239 -0
- data/src/spine.pagination_controller.coffee +119 -0
- data/src/spine.paginator.coffee +97 -54
- metadata +13 -3
- data/LICENSE-MIT +0 -22
@@ -0,0 +1,119 @@
|
|
1
|
+
Spine = @Spine or require('spine')
|
2
|
+
|
3
|
+
###
|
4
|
+
|
5
|
+
Usage
|
6
|
+
|
7
|
+
see https://github.com/vkill/spine_paginator/examples/spine_pagination.coffee
|
8
|
+
|
9
|
+
###
|
10
|
+
|
11
|
+
|
12
|
+
class Spine.PaginationController extends Spine.Controller
|
13
|
+
|
14
|
+
@MODEL = null
|
15
|
+
@PER_PAGES = [10, 20, 30, 40]
|
16
|
+
@PAGINATE_EVENT = "paginate"
|
17
|
+
|
18
|
+
@PAGE = 1
|
19
|
+
@PER_PAGE = null
|
20
|
+
@PAGINATION = null
|
21
|
+
|
22
|
+
constructor: ->
|
23
|
+
super
|
24
|
+
throw new Error("please defined class variable MODEL") unless @constructor.MODEL?
|
25
|
+
@constructor.PER_PAGE = @constructor.PER_PAGES[0]
|
26
|
+
throw new Error("please defined class variable PER_PAGES") unless @constructor.PER_PAGE?
|
27
|
+
@constructor.MODEL.bind @constructor.PAGINATE_EVENT, @render
|
28
|
+
|
29
|
+
@refresh: ->
|
30
|
+
@PAGE = 1
|
31
|
+
@load()
|
32
|
+
|
33
|
+
@toPage: (page)->
|
34
|
+
@PAGE = page
|
35
|
+
@load()
|
36
|
+
|
37
|
+
@load: ->
|
38
|
+
pagination = @MODEL.page(@PAGE, {perPage: @PER_PAGE})
|
39
|
+
@PAGINATION = pagination
|
40
|
+
@MODEL.trigger(@PAGINATE_EVENT)
|
41
|
+
|
42
|
+
|
43
|
+
render: =>
|
44
|
+
pagination = @constructor.PAGINATION
|
45
|
+
if pagination.records.length > 0
|
46
|
+
@html @templateHtml()
|
47
|
+
else
|
48
|
+
@html @templateHtmlDataEmpty()
|
49
|
+
|
50
|
+
#
|
51
|
+
# custom
|
52
|
+
#
|
53
|
+
events:
|
54
|
+
'click a[data-page]': 'clickPage'
|
55
|
+
|
56
|
+
|
57
|
+
clickPage: (e)->
|
58
|
+
e.preventDefault()
|
59
|
+
|
60
|
+
page = @getPageFromE(e)
|
61
|
+
return unless page?
|
62
|
+
@constructor.toPage(page)
|
63
|
+
|
64
|
+
getPageFromE: (e) ->
|
65
|
+
$node = $(e.target)
|
66
|
+
return null if $node.parent('.disabled, .active').length > 0
|
67
|
+
_page = $node.data('page')
|
68
|
+
|
69
|
+
page = null
|
70
|
+
switch _page
|
71
|
+
when 'first'
|
72
|
+
page = @constructor.PAGINATION.firstPage()
|
73
|
+
when 'prev'
|
74
|
+
page = @constructor.PAGINATION.currentPage() - 1
|
75
|
+
when 'next'
|
76
|
+
page = @constructor.PAGINATION.currentPage() + 1
|
77
|
+
when 'last'
|
78
|
+
page = @constructor.PAGINATION.lastPage()
|
79
|
+
when 'gap'
|
80
|
+
page = null
|
81
|
+
else
|
82
|
+
page = _page
|
83
|
+
page
|
84
|
+
|
85
|
+
templateHtmlDataEmpty: =>
|
86
|
+
""
|
87
|
+
|
88
|
+
templateHtml: ->
|
89
|
+
pagination = @constructor.PAGINATION
|
90
|
+
source = """
|
91
|
+
<div class="pagination pagination-small pull-right">
|
92
|
+
<ul>
|
93
|
+
<li {{#unless hasFirst}}class="disabled"{{/unless}}>
|
94
|
+
<a href="javascript:void(0);" data-page="first">first</a>
|
95
|
+
</li>
|
96
|
+
<li {{#unless hasPrev}}class="disabled"{{/unless}}>
|
97
|
+
<a href="javascript:void(0);" data-page="prev">prev</a>
|
98
|
+
</li>
|
99
|
+
{{#each pages}}
|
100
|
+
{{#if this.gap}}
|
101
|
+
<li class="disabled">
|
102
|
+
<a href="javascript:void(0);" data-page='gap'>...</a>
|
103
|
+
</li>
|
104
|
+
{{else}}
|
105
|
+
<li {{#if this.current}}class="active"{{/if}}>
|
106
|
+
<a href="javascript:void(0);" data-page={{this.number}}>{{this.number}}</a>
|
107
|
+
</li>
|
108
|
+
{{/if}}
|
109
|
+
{{/each}}
|
110
|
+
<li {{#unless hasNext}}class="disabled"{{/unless}}>
|
111
|
+
<a href='javascript:void(0);' data-page="next">next</a>
|
112
|
+
</li>
|
113
|
+
<li {{#unless hasLast}}class="disabled"{{/unless}}>
|
114
|
+
<a href='javascript:void(0);' data-page="last">last</a>
|
115
|
+
</li>
|
116
|
+
</ul>
|
117
|
+
</div>
|
118
|
+
"""
|
119
|
+
Handlebars.compile(source)(pagination.locals)
|
data/src/spine.paginator.coffee
CHANGED
@@ -1,5 +1,13 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
|
2
|
+
###
|
3
|
+
Usage
|
4
|
+
|
5
|
+
data = ({name: String.fromCharCode(num)} for num in ['a'.charCodeAt(0)..'z'.charCodeAt(0)])
|
6
|
+
pagination = new Paginator(data, 2, {perPage: 3})
|
7
|
+
pagination.records
|
8
|
+
pagination.locals
|
9
|
+
pagination.buttons
|
10
|
+
###
|
3
11
|
|
4
12
|
class Paginator
|
5
13
|
@DEFAULT_PER_PAGE = 25
|
@@ -8,11 +16,22 @@ class Paginator
|
|
8
16
|
@OUTER_WINDOW = 0
|
9
17
|
@LEFT = 0
|
10
18
|
@RIGHT = 0
|
19
|
+
|
20
|
+
@PAGE_TEXTS =
|
21
|
+
first: 'first'
|
22
|
+
prev: 'prev'
|
23
|
+
current: 'current'
|
24
|
+
next: 'next'
|
25
|
+
last: 'last'
|
26
|
+
gap: 'gap'
|
11
27
|
|
12
28
|
constructor: (records, @_page, options={}) ->
|
29
|
+
records = [records] unless isArray(records)
|
30
|
+
@originalRecords = records
|
31
|
+
@totalCount = @originalRecords.length
|
32
|
+
|
13
33
|
@_page = parseInt(@_page)
|
14
34
|
@_page = 1 if isNaN(@_page) or @_page <= 0
|
15
|
-
|
16
35
|
@_originalPage = @_page
|
17
36
|
|
18
37
|
@perPage = options.perPage || @constructor.DEFAULT_PER_PAGE
|
@@ -28,9 +47,6 @@ class Paginator
|
|
28
47
|
@right = options.right || @constructor.RIGHT
|
29
48
|
@right = outer_window if @right == 0
|
30
49
|
|
31
|
-
@originalRecords = @cloneArray(records)
|
32
|
-
@totalCount = @originalRecords.length
|
33
|
-
|
34
50
|
@skipbuildButtonsAndLocals = options.skipbuildButtonsAndLocals
|
35
51
|
|
36
52
|
@records = []
|
@@ -70,29 +86,6 @@ class Paginator
|
|
70
86
|
|
71
87
|
isLastPage: -> @currentPage() >= @lastPage()
|
72
88
|
|
73
|
-
|
74
|
-
pages: ->
|
75
|
-
currentPage = @currentPage()
|
76
|
-
firstPage = @firstPage()
|
77
|
-
lastPage = @lastPage()
|
78
|
-
|
79
|
-
_pages = []
|
80
|
-
last = null
|
81
|
-
for page in [firstPage..lastPage]
|
82
|
-
result = @buildPage(page, last, currentPage, firstPage, lastPage)
|
83
|
-
if result.isLeftOuter or result.isRightOuter or result.isInsideWindow
|
84
|
-
last = null
|
85
|
-
else
|
86
|
-
last = 'gap'
|
87
|
-
_pages.push result
|
88
|
-
_pages
|
89
|
-
|
90
|
-
curPage: ->
|
91
|
-
currentPage = @currentPage()
|
92
|
-
firstPage = @firstPage()
|
93
|
-
lastPage = @lastPage()
|
94
|
-
@buildPage(currentPage, null, currentPage, firstPage, lastPage)
|
95
|
-
|
96
89
|
|
97
90
|
# private
|
98
91
|
|
@@ -116,7 +109,29 @@ class Paginator
|
|
116
109
|
isLeftOuter: page <= @left
|
117
110
|
isRightOuter: (lastPage - page) < @right
|
118
111
|
isInsideWindow: Math.abs(currentPage - page) <= @window
|
119
|
-
isWasTruncated: last == 'gap'
|
112
|
+
isWasTruncated: last == @constructor.PAGE_TEXTS['gap']
|
113
|
+
|
114
|
+
curPage: ->
|
115
|
+
currentPage = @currentPage()
|
116
|
+
firstPage = @firstPage()
|
117
|
+
lastPage = @lastPage()
|
118
|
+
@buildPage(currentPage, null, currentPage, firstPage, lastPage)
|
119
|
+
|
120
|
+
pages: ->
|
121
|
+
currentPage = @currentPage()
|
122
|
+
firstPage = @firstPage()
|
123
|
+
lastPage = @lastPage()
|
124
|
+
|
125
|
+
_pages = []
|
126
|
+
last = null
|
127
|
+
for page in [firstPage..lastPage]
|
128
|
+
result = @buildPage(page, last, currentPage, firstPage, lastPage)
|
129
|
+
if result.isLeftOuter or result.isRightOuter or result.isInsideWindow
|
130
|
+
last = null
|
131
|
+
else
|
132
|
+
last = @constructor.PAGE_TEXTS['gap']
|
133
|
+
_pages.push result
|
134
|
+
_pages
|
120
135
|
|
121
136
|
buildButtonsAndLocals: ->
|
122
137
|
_buttons = []
|
@@ -126,13 +141,13 @@ class Paginator
|
|
126
141
|
pages = @pages()
|
127
142
|
|
128
143
|
unless curPage.isFirst
|
129
|
-
_buttons.push('first')
|
144
|
+
_buttons.push(@constructor.PAGE_TEXTS['first'])
|
130
145
|
_locals.hasFirst = true
|
131
146
|
else
|
132
147
|
_locals.hasFirst = false
|
133
148
|
|
134
149
|
unless curPage.isFirst
|
135
|
-
_buttons.push('prev')
|
150
|
+
_buttons.push(@constructor.PAGE_TEXTS['prev'])
|
136
151
|
_locals.hasPrev = true
|
137
152
|
else
|
138
153
|
_locals.hasPrev = false
|
@@ -141,24 +156,24 @@ class Paginator
|
|
141
156
|
for page in pages
|
142
157
|
if page.isLeftOuter or page.isRightOuter or page.isInsideWindow
|
143
158
|
if page.isCurrent
|
144
|
-
_buttons.push('current')
|
159
|
+
_buttons.push(@constructor.PAGE_TEXTS['current'])
|
145
160
|
_locals.pages.push({number: page.number, current: true})
|
146
161
|
else
|
147
162
|
_buttons.push(page.number)
|
148
163
|
_locals.pages.push({number: page.number, current: false})
|
149
164
|
|
150
165
|
else if !page.isWasTruncated
|
151
|
-
_buttons.push('gap')
|
166
|
+
_buttons.push(@constructor.PAGE_TEXTS['gap'])
|
152
167
|
_locals.pages.push({number: page.number, gap: true})
|
153
168
|
|
154
169
|
unless curPage.isLast
|
155
|
-
_buttons.push('next')
|
170
|
+
_buttons.push(@constructor.PAGE_TEXTS['next'])
|
156
171
|
_locals.hasNext = true
|
157
172
|
else
|
158
173
|
_locals.hasNext = false
|
159
174
|
|
160
175
|
unless curPage.isLast
|
161
|
-
_buttons.push('last')
|
176
|
+
_buttons.push(@constructor.PAGE_TEXTS['last'])
|
162
177
|
_locals.hasLast = true
|
163
178
|
else
|
164
179
|
_locals.hasLast = false
|
@@ -174,26 +189,54 @@ class Paginator
|
|
174
189
|
@buttons = _buttons
|
175
190
|
@locals = _locals
|
176
191
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
Extend =
|
181
|
-
_perPaginateRecords: -> @records
|
182
|
-
page: (n, options={})-> new Paginator(@_perPaginateRecords(), n, options)
|
183
|
-
|
184
|
-
Model.Paginator =
|
185
|
-
extended: ->
|
186
|
-
@extend Extend
|
192
|
+
isArray = (value) ->
|
193
|
+
Object::toString.call(value) is '[object Array]'
|
187
194
|
|
188
|
-
|
195
|
+
Paginator.isArray = isArray
|
189
196
|
|
190
|
-
# Usage
|
191
197
|
#
|
192
|
-
#
|
193
|
-
# @extend Spine.Model.Paginator
|
194
|
-
#
|
195
|
-
# App.MyModel.fetch()
|
196
|
-
# pagination = App.MyModel.page(6).per(10)
|
197
|
-
# pagination.locals
|
198
|
+
# if your want use window.Paginator, please set `window.MyPaginatorName = 'Paginator' ` before require this.
|
198
199
|
#
|
200
|
+
if @MyPaginatorName?
|
201
|
+
@[@MyPaginatorName] = Paginator
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
if @Spine?
|
206
|
+
###
|
207
|
+
# Spine Usage
|
208
|
+
|
209
|
+
App = {}
|
210
|
+
|
211
|
+
class App.User extends Spine.Model
|
212
|
+
@configure 'User', 'name'
|
213
|
+
@extend Spine.Model.Paginator
|
214
|
+
|
215
|
+
data = ({name: String.fromCharCode(num)} for num in ['a'.charCodeAt(0)..'z'.charCodeAt(0)])
|
216
|
+
|
217
|
+
App.User.refresh(data)
|
218
|
+
pagination = App.User.page(2).per(5) #or App.User.page(2, {perPage: 5})
|
219
|
+
pagination.records
|
220
|
+
pagination.locals
|
221
|
+
pagination.buttons
|
222
|
+
App.User.PAGINATION = pagination
|
223
|
+
|
224
|
+
###
|
225
|
+
Paginator.SpineModelExtend =
|
226
|
+
page: (n, options={})-> new Paginator(@_perPaginateRecords(), n, options)
|
227
|
+
|
228
|
+
# private
|
229
|
+
_perPaginateRecords: -> @all()
|
230
|
+
|
231
|
+
Spine = @Spine
|
232
|
+
Spine.Paginator = Paginator
|
233
|
+
|
234
|
+
Spine.Model.Paginator =
|
235
|
+
extended: ->
|
236
|
+
@extend Paginator.SpineModelExtend
|
237
|
+
|
238
|
+
|
239
|
+
|
240
|
+
|
241
|
+
|
199
242
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spine_paginator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-11 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Paginator for Spine
|
15
15
|
email:
|
@@ -21,22 +21,31 @@ files:
|
|
21
21
|
- .gitignore
|
22
22
|
- Gemfile
|
23
23
|
- Gruntfile.coffee
|
24
|
-
- LICENSE-MIT
|
25
24
|
- LICENSE.txt
|
26
25
|
- README.md
|
27
26
|
- Rakefile
|
28
27
|
- component.json
|
29
28
|
- dist/.gitkeep
|
29
|
+
- dist/spine.pagination_controller.js
|
30
|
+
- dist/spine.pagination_controller.min.js
|
30
31
|
- dist/spine.paginator.js
|
31
32
|
- dist/spine.paginator.min.js
|
33
|
+
- examples/spine_pagination.coffee
|
34
|
+
- examples/spine_pagination.css
|
35
|
+
- examples/spine_pagination.html
|
36
|
+
- examples/spine_pagination.js
|
37
|
+
- examples/spine_pagination.scss
|
38
|
+
- examples/spine_pagination.slim
|
32
39
|
- lib/spine_paginator.rb
|
33
40
|
- lib/spine_paginator/railtie.rb
|
34
41
|
- lib/spine_paginator/version.rb
|
35
42
|
- package.json
|
36
43
|
- spec/lib/.gitkeep
|
44
|
+
- spec/lib/handlebars.js
|
37
45
|
- spec/lib/spine.js
|
38
46
|
- spec/spine.paginator/.gitkeep
|
39
47
|
- spine_paginator.gemspec
|
48
|
+
- src/spine.pagination_controller.coffee
|
40
49
|
- src/spine.paginator.coffee
|
41
50
|
homepage: https://github.com/vkill/spine_paginator
|
42
51
|
licenses: []
|
@@ -64,5 +73,6 @@ specification_version: 3
|
|
64
73
|
summary: Paginator for Spine
|
65
74
|
test_files:
|
66
75
|
- spec/lib/.gitkeep
|
76
|
+
- spec/lib/handlebars.js
|
67
77
|
- spec/lib/spine.js
|
68
78
|
- spec/spine.paginator/.gitkeep
|
data/LICENSE-MIT
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2013 vkill
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person
|
4
|
-
obtaining a copy of this software and associated documentation
|
5
|
-
files (the "Software"), to deal in the Software without
|
6
|
-
restriction, including without limitation the rights to use,
|
7
|
-
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
-
copies of the Software, and to permit persons to whom the
|
9
|
-
Software is furnished to do so, subject to the following
|
10
|
-
conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be
|
13
|
-
included in all copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
-
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
-
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
-
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
-
OTHER DEALINGS IN THE SOFTWARE.
|