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.
@@ -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)
@@ -1,5 +1,13 @@
1
- Spine = @Spine or require('spine')
2
- Model = Spine.Model
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
- cloneArray: (array) ->
178
- (value.clone() for value in array)
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
- Spine.Paginator = Paginator
195
+ Paginator.isArray = isArray
189
196
 
190
- # Usage
191
197
  #
192
- # class App.MyModel extends Spine.Model
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.0
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-09 00:00:00.000000000 Z
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.