luca 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/CHANGELOG +37 -14
  2. data/lib/luca/rails/version.rb +1 -1
  3. data/spec/components/collection_view_spec.coffee +24 -2
  4. data/spec/components/pagination_control_spec.coffee +0 -0
  5. data/spec/concerns/dom_helpers_spec.coffee +16 -0
  6. data/spec/concerns/filterable_spec.coffee +25 -0
  7. data/spec/concerns/model_presenter_spec.coffee +31 -0
  8. data/spec/concerns/paginatable_spec.coffee +0 -0
  9. data/spec/concerns/state_model_spec.coffee +0 -0
  10. data/spec/concerns_spec.coffee +88 -0
  11. data/spec/core/container_spec.coffee +74 -12
  12. data/spec/core/model_spec.coffee +6 -1
  13. data/spec/define_spec.coffee +0 -6
  14. data/spec/util_spec.coffee +24 -0
  15. data/src/components/application.coffee +32 -30
  16. data/src/components/base_toolbar.coffee +6 -4
  17. data/src/components/collection_loader_view.coffee +3 -1
  18. data/src/components/collection_view.coffee +42 -21
  19. data/src/components/controller.coffee +3 -1
  20. data/src/components/fields/button_field.coffee +19 -12
  21. data/src/components/fields/checkbox_array.coffee +8 -2
  22. data/src/components/fields/checkbox_field.coffee +18 -9
  23. data/src/components/fields/file_upload_field.coffee +5 -1
  24. data/src/components/fields/hidden_field.coffee +3 -1
  25. data/src/components/fields/label_field.coffee +4 -3
  26. data/src/components/fields/select_field.coffee +7 -8
  27. data/src/components/fields/text_field.coffee +3 -1
  28. data/src/components/fields/type_ahead_field.coffee +4 -2
  29. data/src/components/form_button_toolbar.coffee +4 -1
  30. data/src/components/form_view.coffee +49 -44
  31. data/src/components/grid_view.coffee +1 -1
  32. data/src/components/multi_collection_view.coffee +49 -22
  33. data/src/components/pagination_control.coffee +17 -13
  34. data/src/{modules → concerns}/application_event_bindings.coffee +1 -1
  35. data/src/{modules → concerns}/collection_event_bindings.coffee +1 -1
  36. data/src/{modules → concerns}/deferrable.coffee +1 -1
  37. data/src/{modules → concerns}/dom_helpers.coffee +11 -2
  38. data/src/{modules → concerns}/enhanced_properties.coffee +1 -1
  39. data/src/concerns/filterable.coffee +82 -0
  40. data/src/{modules → concerns}/grid_layout.coffee +1 -1
  41. data/src/{modules → concerns}/loadmaskable.coffee +1 -1
  42. data/src/{modules → concerns}/local_storage.coffee +0 -0
  43. data/src/{modules → concerns}/modal_view.coffee +1 -1
  44. data/src/concerns/model_presenter.coffee +23 -0
  45. data/src/concerns/paginatable.coffee +87 -0
  46. data/src/{modules → concerns}/state_model.coffee +1 -1
  47. data/src/{modules → concerns}/templating.coffee +1 -1
  48. data/src/concerns.coffee +70 -0
  49. data/src/containers/tab_view.coffee +7 -10
  50. data/src/core/collection.coffee +17 -1
  51. data/src/core/container.coffee +56 -31
  52. data/src/core/field.coffee +39 -38
  53. data/src/core/meta_data.coffee +37 -0
  54. data/src/core/model.coffee +18 -1
  55. data/src/core/view.coffee +25 -29
  56. data/src/define.coffee +54 -66
  57. data/src/framework.coffee +23 -18
  58. data/src/index.coffee +3 -1
  59. data/src/stylesheets/components/checkbox_array.scss +1 -1
  60. data/src/stylesheets/components/form_view.scss +5 -5
  61. data/src/stylesheets/components/viewport.scss +2 -1
  62. data/src/stylesheets/containers/container.scss +0 -5
  63. data/src/stylesheets/containers/tab_view.scss +5 -5
  64. data/src/tools/console.coffee +5 -5
  65. data/src/util.coffee +47 -0
  66. data/vendor/assets/javascripts/luca-ui-development-tools.js +5 -5
  67. data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
  68. data/vendor/assets/javascripts/luca-ui-full.js +905 -416
  69. data/vendor/assets/javascripts/luca-ui-full.min.js +5 -5
  70. data/vendor/assets/javascripts/luca-ui.js +905 -416
  71. data/vendor/assets/javascripts/luca-ui.min.js +5 -4
  72. data/vendor/assets/stylesheets/luca-ui.css +15 -15
  73. metadata +27 -17
  74. data/spec/mixin_spec.coffee +0 -49
  75. data/src/modules/filterable.coffee +0 -60
  76. data/src/modules/paginatable.coffee +0 -79
@@ -1,42 +1,28 @@
1
- defaultToolbar =
2
- buttons:[
3
- icon:"remove-sign"
4
- label: "Reset"
5
- eventId: "click:reset"
6
- className:"reset-button"
7
- align: 'right'
8
- ,
9
- icon:"ok-sign"
10
- white: true
11
- label: "Save Changes"
12
- eventId: "click:submit"
13
- color: "success"
14
- className: 'submit-button'
15
- align: 'right'
16
- ]
17
-
18
- _.def("Luca.components.FormView").extends('Luca.core.Container').with
19
-
1
+ #_.def("Luca.components.FormView").extends('Luca.core.Container').with
2
+
3
+ formView = Luca.register "Luca.components.FormView"
4
+ formView.extends "Luca.core.Container"
5
+
6
+ formView.triggers "before:submit",
7
+ "before:reset",
8
+ "before:load",
9
+ "before:load:new",
10
+ "before:load:existing",
11
+ "after:submit",
12
+ "after:reset",
13
+ "after:load",
14
+ "after:load:new",
15
+ "after:load:existing",
16
+ "after:submit:success",
17
+ "after:submit:fatal_error",
18
+ "after:submit:error"
19
+
20
+
21
+ formView.defines
20
22
  tagName: 'form'
21
23
 
22
24
  className: 'luca-ui-form-view'
23
25
 
24
- hooks:[
25
- "before:submit"
26
- "before:reset"
27
- "before:load"
28
- "before:load:new"
29
- "before:load:existing"
30
- "after:submit"
31
- "after:reset"
32
- "after:load"
33
- "after:load:new"
34
- "after:load:existing"
35
- "after:submit:success"
36
- "after:submit:fatal_error"
37
- "after:submit:error"
38
- ]
39
-
40
26
  events:
41
27
  "click .submit-button" : "submitHandler"
42
28
  "click .reset-button" : "resetHandler"
@@ -47,7 +33,7 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
47
33
 
48
34
  bodyClassName: "form-view-body"
49
35
 
50
- version: "0.9.33333333"
36
+ version: 1
51
37
 
52
38
  initialize: (@options={})->
53
39
  @loadMask = Luca.enableBootstrap unless @loadMask?
@@ -56,8 +42,7 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
56
42
 
57
43
  @components ||= @fields
58
44
 
59
- _.bindAll @, "submitHandler", "resetHandler", "renderToolbars", "applyLoadMask"
60
-
45
+ _.bindAll @, "submitHandler", "resetHandler", "renderToolbars"
61
46
  @state ||= new Backbone.Model
62
47
 
63
48
  @setupHooks( @hooks )
@@ -69,7 +54,7 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
69
54
  @bottomToolbar = @getDefaultToolbar() unless @toolbar is "top"
70
55
 
71
56
  getDefaultToolbar: ()->
72
- defaultToolbar
57
+ Luca.components.FormView.defaultFormViewToolbar
73
58
 
74
59
  applyStyleClasses: ()->
75
60
  if Luca.enableBootstrap
@@ -112,7 +97,7 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
112
97
  passOne = _( @getFields('name', name) ).first()
113
98
  return passOne if passOne?
114
99
 
115
- _( @getFields('input_name', name) ).first()
100
+ _( @getFields('input_name', name) ).first()
116
101
 
117
102
  getFields: (attr,value)->
118
103
  fields = @selectByAttribute("isField", true, true)
@@ -201,17 +186,17 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
201
186
  if options.skip_buttons and field.ctype is "button_field"
202
187
  skip = true
203
188
  else
204
- if valueIsBlank and allowBlankValues is false
205
- skip = true
189
+ if valueIsBlank and allowBlankValues is false
190
+ skip = true
206
191
 
207
192
  if field.input_name is "id" and valueIsBlank is true
208
193
  skip = true
209
194
 
210
195
  if options.debug
211
196
  console.log "Skip is true on #{ key }"
212
-
197
+
213
198
  if skip isnt true
214
- memo[ key ] = value
199
+ memo[ key ] = value
215
200
 
216
201
  memo
217
202
 
@@ -275,3 +260,23 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
275
260
  errorMessage: (message)->
276
261
  @$('.alert.alert-error').remove()
277
262
  @flash Luca.template("components/form_alert", className:"alert alert-error", message: message)
263
+
264
+
265
+ Luca.components.FormView.defaultFormViewToolbar =
266
+ buttons:[
267
+ icon:"remove-sign"
268
+ label: "Reset"
269
+ eventId: "click:reset"
270
+ className:"reset-button"
271
+ align: 'right'
272
+ ,
273
+ icon:"ok-sign"
274
+ white: true
275
+ label: "Save Changes"
276
+ eventId: "click:submit"
277
+ color: "success"
278
+ className: 'submit-button'
279
+ align: 'right'
280
+ ]
281
+
282
+
@@ -57,7 +57,7 @@ _.def('Luca.components.GridView').extend('Luca.components.Panel').with
57
57
 
58
58
  initialize: (@options={})->
59
59
  _.extend @, @options
60
- _.extend @, Luca.modules.Deferrable
60
+ _.extend @, Luca.concerns.Deferrable
61
61
 
62
62
  @loadMask = Luca.enableBootstrap unless @loadMask?
63
63
  @loadMaskEl ||= ".luca-ui-g-view-body" if @loadMask is true
@@ -1,4 +1,4 @@
1
- multiView = Luca.define "Luca.components.MultiCollectionView"
1
+ multiView = Luca.register "Luca.components.MultiCollectionView"
2
2
 
3
3
  # The CollectionMultiView is a collection view with multiple renderings
4
4
  # of the list. ( e.g. Icons, Table, List ). It works by maintaining
@@ -24,9 +24,9 @@ multiView = Luca.define "Luca.components.MultiCollectionView"
24
24
  # ]
25
25
  multiView.extends "Luca.containers.CardView"
26
26
 
27
- multiView.behavesAs "LoadMaskable",
28
- "Filterable",
29
- "Paginatable"
27
+ multiView.mixesIn "LoadMaskable",
28
+ "Filterable",
29
+ "Paginatable"
30
30
 
31
31
  multiView.triggers "before:refresh",
32
32
  "after:refresh",
@@ -48,29 +48,47 @@ multiView.defaultsTo
48
48
 
49
49
  validateComponent( view ) for view in @components
50
50
 
51
- @on "collection:change", @refresh, @
51
+ @on "refresh", @refresh, @
52
52
  @on "after:card:switch", @refresh, @
53
- @on "before:components", propagateCollectionComponents, @
54
- @on "after:components", bubbleCollectionEvents, @
53
+ @on "after:components", propagateCollectionComponents, @
54
+
55
+ @debug("multi collection , proto initialize")
55
56
 
56
57
  Luca.containers.CardView::initialize.apply(@, arguments)
57
58
 
59
+ relayAfterRefresh: (models,query,options)->
60
+ @trigger "after:refresh", models, query, options
61
+
58
62
  refresh: ()->
59
63
  @activeComponent()?.trigger("refresh")
60
64
 
61
- getQuery: Luca.components.CollectionView::getQuery
62
- getQueryOptions: Luca.components.CollectionView::getQueryOptions
63
- getCollection: Luca.components.CollectionView::getCollection
64
-
65
- #### Private Helpers
65
+ getCollection: ()->
66
+ @collection
66
67
 
67
- bubbleCollectionEvents = ()->
68
- container = @
69
- container.eachComponent (component)->
70
- for eventId in ['refresh','before:refresh','after:refresh','empty:results']
71
- component.on eventId, ()->
72
- if component is container.activeComponent()
73
- container.trigger(eventId)
68
+ applyQuery: (query={},queryOptions={})->
69
+ @query = query
70
+ @queryOptions = queryOptions
71
+ @
72
+
73
+ # Private: returns the query that is applied to the underlying collection.
74
+ # accepts the same options as Luca.Collection.query's initial query option.
75
+ getQuery: ()->
76
+ @debug("Get Query")
77
+ query = @query ||= {}
78
+ for querySource in @querySources
79
+ query = _.extend(query, (querySource()||{}) )
80
+ query
81
+
82
+ # Private: returns the query that is applied to the underlying collection.
83
+ # accepts the same options as Luca.Collection.query's initial query option.
84
+ getQueryOptions: ()->
85
+ @debug("Get Query Options")
86
+ options = @queryOptions ||= {}
87
+
88
+ for optionSource in @optionsSources
89
+ options = _.extend(options, (optionSource()||{}) )
90
+
91
+ options
74
92
 
75
93
  propagateCollectionComponents = ()->
76
94
  container = @
@@ -78,10 +96,19 @@ propagateCollectionComponents = ()->
78
96
  # in the multi view will share the same
79
97
  # collection, filter state, pagination options, etc
80
98
  for component in @components
99
+
100
+ component.on "after:refresh", (models,query,options)=>
101
+ @debug "collection member after refresh"
102
+ @trigger("after:refresh",models,query,options)
103
+
81
104
  _.extend component,
82
- collection: container.getCollection?() || @collection
83
- getQuery: container.getQuery
84
- getQueryOptions: container.getQueryOptions
105
+ collection: container.getCollection()
106
+
107
+ getQuery: ()->
108
+ container.getQuery.call(container)
109
+
110
+ getQueryOptions: ()->
111
+ container.getQueryOptions.call(container)
85
112
 
86
113
  validateComponent = (component)->
87
114
  type = (component.type || component.ctype)
@@ -9,15 +9,16 @@ paginationControl.defines
9
9
 
10
10
  autoBindEventHandlers: true
11
11
 
12
- events:
12
+ events:
13
13
  "click a[data-page-number]" : "selectPage"
14
14
  "click a.next" : "nextPage"
15
- "click a.prev" : "previousPage"
15
+ "click a.prev" : "previousPage"
16
16
 
17
17
  afterInitialize: ()->
18
- _.bindAll @, "refresh"
18
+ _.bindAll @, "updateWithPageCount"
19
19
 
20
- @state.on("change", @refresh, @)
20
+ @state?.on "change", (state, numberOfPages)=>
21
+ @updateWithPageCount( state.get('numberOfPages') )
21
22
 
22
23
  limit: ()->
23
24
  parseInt (@state.get('limit') || @collection?.length)
@@ -35,7 +36,7 @@ paginationControl.defines
35
36
 
36
37
  selectPage: (e)->
37
38
  me = my = @$( e.target )
38
- me = my = my.closest('a.page') unless me.is('a.page')
39
+ me = my = my.closest('a.page') unless me.is('a.page')
39
40
 
40
41
  my.siblings().removeClass('is-selected')
41
42
  me.addClass('is-selected')
@@ -50,9 +51,9 @@ paginationControl.defines
50
51
 
51
52
  pageButtonContainer: ()->
52
53
  @$ '.group'
53
-
54
+
54
55
  previousEnabled: ()->
55
- @page() > 1
56
+ @page() > 1
56
57
 
57
58
  nextEnabled: ()->
58
59
  @page() < @totalPages()
@@ -64,14 +65,17 @@ paginationControl.defines
64
65
  @$ 'a.page.next'
65
66
 
66
67
  pageButtons: ()->
67
- @$ 'a[data-page-number]', @pageButtonContainer()
68
+ @$ 'a[data-page-number]', @pageButtonContainer()
69
+
70
+ updateWithPageCount: (@pageCount, models=[])->
71
+ modelCount = models.length
68
72
 
69
- refresh: ()->
70
73
  @pageButtonContainer().empty()
71
74
 
72
- for page in [1..@totalPages()]
75
+ _( @pageCount ).times (index)=>
76
+ page = index + 1
73
77
  button = @make("a","data-page-number":page, class:"page", page )
74
- @pageButtonContainer().append(button)
78
+ @pageButtonContainer().append(button)
75
79
 
76
80
  @toggleNavigationButtons()
77
81
  @selectActivePageButton()
@@ -90,11 +94,11 @@ paginationControl.defines
90
94
  @pageButtons().filter("[data-page-number='#{ @page() }']")
91
95
 
92
96
  totalPages: ()->
93
- parseInt( Math.ceil(@totalItems() / @itemsPerPage()) )
97
+ @pageCount
94
98
 
95
99
  totalItems: ()->
96
100
  parseInt @collection?.length || 0
97
101
 
98
- itemsPerPage: (value, options={})->
102
+ itemsPerPage: (value, options={})->
99
103
  @state.set("limit", value, options) if value?
100
104
  parseInt @state.get("limit")
@@ -1,4 +1,4 @@
1
- Luca.modules.ApplicationEventBindings =
1
+ Luca.concerns.ApplicationEventBindings =
2
2
  __initializer: ()->
3
3
  return if _.isEmpty(@applicationEvents)
4
4
 
@@ -1,4 +1,4 @@
1
- Luca.modules.CollectionEventBindings =
1
+ Luca.concerns.CollectionEventBindings =
2
2
  __initializer: ()->
3
3
  return if _.isEmpty( @collectionEvents )
4
4
 
@@ -1,7 +1,7 @@
1
1
  # TODO
2
2
  #
3
3
  # This is horrendous code. I need to replace it ASAP
4
- Luca.modules.Deferrable =
4
+ Luca.concerns.Deferrable =
5
5
  configure_collection: (setAsDeferrable=true)->
6
6
  return unless @collection
7
7
 
@@ -1,4 +1,4 @@
1
- Luca.modules.DomHelpers =
1
+ Luca.concerns.DomHelpers =
2
2
  __initializer: ()->
3
3
  additionalClasses = _( @additionalClassNames || [] ).clone()
4
4
 
@@ -24,12 +24,21 @@ Luca.modules.DomHelpers =
24
24
  for additional in additionalClasses
25
25
  @$el.addClass( additional )
26
26
 
27
+ if Luca.config.autoApplyClassHierarchyAsCssClasses is true
28
+ classes = @componentMetaData?()?.styleHierarchy() || []
29
+
30
+ for cssClass in classes when (cssClass isnt "luca-view" and cssClass isnt "backbone-view")
31
+ @$el.addClass(cssClass)
32
+
27
33
  $wrap: (wrapper)->
28
34
  if _.isString(wrapper) and not wrapper.match(/[<>]/)
29
- wrapper = @make("div",class:wrapper)
35
+ wrapper = @make("div",class:wrapper,"data-wrapper":true)
30
36
 
31
37
  @$el.wrap( wrapper )
32
38
 
39
+ $wrapper: ()->
40
+ @$el.parent('[data-wrapper="true"]')
41
+
33
42
  $template: (template, variables={})->
34
43
  @$el.html( Luca.template(template,variables) )
35
44
 
@@ -1,4 +1,4 @@
1
- Luca.modules.EnhancedProperties =
1
+ Luca.concerns.EnhancedProperties =
2
2
  __initializer: ()->
3
3
  return unless Luca.config.enhancedViewProperties is true
4
4
 
@@ -0,0 +1,82 @@
1
+ Luca.concerns.Filterable =
2
+ __included: (component, module)->
3
+ _.extend(Luca.Collection::, __filters:{})
4
+
5
+ __initializer: (component, module)->
6
+ if @filterable is false
7
+ return
8
+
9
+ # TEMP HACK
10
+ unless Luca.isBackboneCollection(@collection)
11
+ @collection = Luca.CollectionManager.get?()?.getOrCreate(@collection)
12
+
13
+ unless Luca.isBackboneCollection(@collection)
14
+ @debug "Skipping Filterable due to no collection being present on #{ @name || @cid }"
15
+ @debug "Collection", @collection
16
+ return
17
+
18
+ @getCollection ||= ()-> @collection
19
+
20
+ filter = @getFilterState()
21
+
22
+ @querySources ||= []
23
+ @optionsSources ||= []
24
+ @query ||= {}
25
+ @queryOptions ||= {}
26
+
27
+ @querySources.push (()=> filter.toQuery())
28
+ @optionsSources.push (()=> filter.toOptions())
29
+
30
+ if @debugMode is true
31
+ console.log "Filterable"
32
+ console.log @querySources
33
+ console.log @optionsSources
34
+
35
+ filter.on "change", ()=>
36
+ if @isRemote()
37
+ merged = _.extend(@getQuery(), @getQueryOptions())
38
+ @collection.applyFilter(merged, @getQueryOptions())
39
+ else
40
+ @trigger "refresh"
41
+
42
+ module
43
+
44
+ isRemote: ()->
45
+ @getQueryOptions().remote is true
46
+
47
+ getFilterState: ()->
48
+ @collection.__filters[ @cid ] ||= new FilterModel(@filterable)
49
+
50
+ setSortBy: (sortBy, options={})->
51
+ @getFilterState().setOption('sortBy', sortBy, options)
52
+
53
+ applyFilter: (query={}, options={})->
54
+ options = _.defaults(options, @getQueryOptions())
55
+ query = _.defaults(query, @getQuery())
56
+
57
+ @getFilterState().set({query,options}, options)
58
+
59
+ class FilterModel extends Backbone.Model
60
+ defaults:
61
+ options: {}
62
+ query: {}
63
+
64
+ setOption: (option, value, options)->
65
+ payload = {}
66
+ payload[option] = value
67
+ @set 'options', _.extend(@toOptions(), payload), options
68
+
69
+ setQueryOption: (option, value, options)->
70
+ payload = {}
71
+ payload[option] = value
72
+ @set 'query', _.extend(@toQuery(), payload), options
73
+
74
+ toOptions: ()->
75
+ @toJSON().options
76
+
77
+ toQuery: ()->
78
+ @toJSON().query
79
+
80
+ toRemote: ()->
81
+ options = @toOptions()
82
+ _.extend( @toQuery(), limit: options.limit, page: options.page, sortBy: options.sortBy )
@@ -1,4 +1,4 @@
1
- Luca.modules.GridLayout =
1
+ Luca.concerns.GridLayout =
2
2
  _initializer: ()->
3
3
  if @gridSpan
4
4
  @$el.addClass "span#{ @gridSpan }"
@@ -1,4 +1,4 @@
1
- Luca.modules.LoadMaskable =
1
+ Luca.concerns.LoadMaskable =
2
2
  __initializer: ()->
3
3
  return unless @loadMask is true
4
4
 
File without changes
@@ -1,4 +1,4 @@
1
- Luca.modules.ModalView =
1
+ Luca.concerns.ModalView =
2
2
  closeOnEscape: true
3
3
 
4
4
  showOnInitialize: false
@@ -0,0 +1,23 @@
1
+ Luca.concerns.ModelPresenter =
2
+ classMethods:
3
+ getPresenter: (format)->
4
+ @presenters?[format]
5
+
6
+ registerPresenter: (format, config)->
7
+ @presenters ||= {}
8
+ @presenters[ format ] = config
9
+
10
+ presentAs: (format)->
11
+ try
12
+ attributeList = @componentMetaData().componentDefinition().getPresenter(format)
13
+
14
+ return @toJSON() unless attributeList?
15
+
16
+ _( attributeList ).reduce (memo, attribute)=>
17
+ memo[ attribute ] = @read(attribute)
18
+ memo
19
+ , {}
20
+
21
+ catch e
22
+ console.log "Error presentAs", e.stack, e.message
23
+ return @toJSON()
@@ -0,0 +1,87 @@
1
+ Luca.concerns.Paginatable =
2
+ paginatorViewClass: 'Luca.components.PaginationControl'
3
+ paginationSelector: ".toolbar.bottom"
4
+
5
+ __included: ()->
6
+ _.extend(Luca.Collection::, __paginators: {})
7
+
8
+ __initializer:()->
9
+ if @paginatable is false
10
+ return
11
+
12
+ # TEMP HACK
13
+ unless Luca.isBackboneCollection(@collection)
14
+ @collection = Luca.CollectionManager.get?()?.getOrCreate(@collection)
15
+
16
+ unless Luca.isBackboneCollection(@collection)
17
+ @debug "Skipping Paginatable due to no collection being present on #{ @name || @cid }"
18
+ @debug "collection", @collection
19
+ return
20
+
21
+ _.bindAll @, "paginationControl", "pager"
22
+
23
+ @getCollection ||= ()->
24
+ @collection
25
+
26
+ collection = @getCollection()
27
+
28
+ paginationState = @getPaginationState()
29
+
30
+ @optionsSources ||= []
31
+ @queryOptions ||= {}
32
+
33
+ @optionsSources.push ()=>
34
+ options = _( paginationState.toJSON() ).pick('limit','page','sortBy')
35
+ _.extend(options, pager: @pager)
36
+
37
+ paginationState.on "change:page", (state)=>
38
+ if @isRemote()
39
+ filter = _.extend(@toQuery(), @toQueryOptions())
40
+ @collection.applyFilter(filter, remote: true)
41
+ else
42
+ @trigger "refresh"
43
+
44
+ @on "before:render", @renderPaginationControl, @
45
+
46
+ pager: (numberOfPages, models)->
47
+ @getPaginationState().set(numberOfPages: numberOfPages, itemCount: models.length)
48
+ @paginationControl().updateWithPageCount( numberOfPages, models )
49
+
50
+ isRemote: ()->
51
+ @getQueryOptions().remote is true
52
+
53
+ getPaginationState: ()->
54
+ @collection.__paginators[ @cid ] ||= @paginationControl().state
55
+
56
+ paginationContainer: ()->
57
+ @$(">#{ @paginationSelector }")
58
+
59
+ setCurrentPage: (page=1, options={})->
60
+ @getPaginationState().set('page', page, options)
61
+
62
+ setPage: (page=1, options={})->
63
+ @getPaginationState().set('page', page, options)
64
+
65
+ setLimit: (limit=0,options={})->
66
+ @getPaginationState().set('limit', limit, options)
67
+
68
+ paginationControl: ()->
69
+ return @paginator if @paginator?
70
+
71
+ _.defaults(@paginatable ||= {}, page: 1, limit: 20)
72
+
73
+ @paginator = Luca.util.lazyComponent
74
+ type: "pagination_control"
75
+ collection: @getCollection()
76
+ defaultState: @paginatable
77
+ parent: (@name || @cid)
78
+ debugMode: @debugMode
79
+
80
+ @paginator
81
+
82
+ renderPaginationControl: ()->
83
+ control = @paginationControl()
84
+ @paginationContainer().append( control.render().$el )
85
+ control
86
+
87
+
@@ -1,4 +1,4 @@
1
- Luca.modules.StateModel =
1
+ Luca.concerns.StateModel =
2
2
  __initializer: ()->
3
3
  return unless @stateful is true
4
4
  return if @state? and not Luca.isBackboneModel(@state)
@@ -1,4 +1,4 @@
1
- Luca.modules.Templating =
1
+ Luca.concerns.Templating =
2
2
  __initializer: ()->
3
3
  templateVars = Luca.util.read.call(@, @bodyTemplateVars) || {}
4
4