luca 0.9.42 → 0.9.65
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +50 -9
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/README.md +5 -0
- data/assets/javascripts/dependencies/underscore-min.js +5 -31
- data/lib/generators/luca/application/application_generator.rb +71 -0
- data/lib/generators/luca/application/templates/controller.rb +6 -0
- data/lib/generators/luca/application/templates/index.html.erb +7 -0
- data/lib/generators/luca/application/templates/index.html.haml +6 -0
- data/lib/generators/luca/application/templates/javascripts/application.js +28 -0
- data/lib/generators/luca/application/templates/javascripts/application.js.coffee +20 -0
- data/lib/generators/luca/application/templates/javascripts/config.js +15 -0
- data/lib/generators/luca/application/templates/javascripts/config.js.coffee +9 -0
- data/lib/generators/luca/application/templates/javascripts/dependencies.js +5 -0
- data/lib/generators/luca/application/templates/javascripts/dependencies.js.coffee +5 -0
- data/lib/generators/luca/application/templates/javascripts/index.js +9 -0
- data/lib/generators/luca/application/templates/javascripts/index.js.coffee +9 -0
- data/lib/generators/luca/application/templates/javascripts/main.js +8 -0
- data/lib/generators/luca/application/templates/javascripts/main.js.coffee +3 -0
- data/lib/generators/luca/application/templates/javascripts/main.jst.ejs +1 -0
- data/lib/generators/luca/application/templates/javascripts/router.js +12 -0
- data/lib/generators/luca/application/templates/javascripts/router.js.coffee +7 -0
- data/lib/luca/rails/version.rb +1 -1
- data/spec/components/collection_view_spec.coffee +59 -0
- data/spec/components/multi_collection_view_spec.coffee +5 -0
- data/{src/templates/components/form_alert → spec/components/pagination_control_spec.coffee} +0 -0
- data/spec/components/table_view_spec.coffee +17 -0
- data/spec/core/container_spec.coffee +127 -5
- data/spec/core/model_spec.coffee +21 -3
- data/spec/define_spec.coffee +19 -0
- data/spec/mixin_spec.coffee +49 -0
- data/spec/modules/filterable_spec.coffee +25 -0
- data/spec/modules/paginatable_spec.coffee +0 -0
- data/spec/modules/state_model_spec.coffee +0 -0
- data/src/components/application.coffee +52 -38
- data/src/components/collection_view.coffee +118 -45
- data/src/components/fields/checkbox_field.coffee +2 -2
- data/src/components/fields/file_upload_field.coffee +0 -3
- data/src/components/fields/hidden_field.coffee +0 -3
- data/src/components/fields/label_field.coffee +1 -4
- data/src/components/fields/select_field.coffee +6 -6
- data/src/components/fields/text_area_field.coffee +1 -0
- data/src/components/fields/text_field.coffee +4 -0
- data/src/components/fields/type_ahead_field.coffee +5 -9
- data/src/components/form_view.coffee +28 -23
- data/src/components/multi_collection_view.coffee +121 -0
- data/src/components/pagination_control.coffee +106 -0
- data/src/components/table_view.coffee +22 -13
- data/src/containers/card_view.coffee +44 -11
- data/src/containers/panel_toolbar.coffee +88 -82
- data/src/containers/tab_view.coffee +3 -3
- data/src/core/collection.coffee +11 -4
- data/src/core/container.coffee +206 -122
- data/src/core/field.coffee +13 -10
- data/src/core/model.coffee +23 -27
- data/src/core/registry.coffee +42 -29
- data/src/core/view.coffee +63 -149
- data/src/define.coffee +91 -19
- data/src/framework.coffee +11 -9
- data/src/managers/collection_manager.coffee +24 -8
- data/src/modules/application_event_bindings.coffee +19 -0
- data/src/modules/collection_event_bindings.coffee +26 -0
- data/src/modules/deferrable.coffee +3 -1
- data/src/modules/dom_helpers.coffee +49 -0
- data/src/modules/enhanced_properties.coffee +23 -0
- data/src/modules/filterable.coffee +82 -0
- data/src/modules/grid_layout.coffee +13 -1
- data/src/modules/{load_mask.coffee → loadmaskable.coffee} +10 -4
- data/src/modules/modal_view.coffee +38 -0
- data/src/modules/paginatable.coffee +87 -0
- data/src/modules/state_model.coffee +16 -0
- data/src/modules/templating.coffee +8 -0
- data/src/plugins/events.coffee +30 -2
- data/src/templates/components/bootstrap_form_controls.jst.ejs +10 -0
- data/src/templates/components/collection_loader_view.jst.ejs +6 -0
- data/src/templates/components/form_alert.jst.ejs +4 -0
- data/src/templates/components/grid_view.jst.ejs +11 -0
- data/src/templates/components/grid_view_empty_text.jst.ejs +3 -0
- data/src/templates/components/load_mask.jst.ejs +5 -0
- data/src/templates/components/nav_bar.jst.ejs +4 -0
- data/src/templates/components/pagination.jst.ejs +10 -0
- data/src/templates/containers/basic.jst.ejs +1 -0
- data/src/templates/containers/tab_selector_container.jst.ejs +12 -0
- data/src/templates/containers/tab_view.jst.ejs +2 -0
- data/src/templates/containers/toolbar_wrapper.jst.ejs +1 -0
- data/src/templates/fields/button_field.jst.ejs +2 -0
- data/src/templates/fields/button_field_link.jst.ejs +6 -0
- data/src/templates/fields/checkbox_array.jst.ejs +4 -0
- data/src/templates/fields/checkbox_array_item.jst.ejs +3 -0
- data/src/templates/fields/checkbox_field.jst.ejs +10 -0
- data/src/templates/fields/file_upload_field.jst.ejs +10 -0
- data/src/templates/fields/hidden_field.jst.ejs +1 -0
- data/src/templates/fields/select_field.jst.ejs +11 -0
- data/src/templates/fields/text_area_field.jst.ejs +11 -0
- data/src/templates/fields/text_field.jst.ejs +16 -0
- data/src/templates/table_view.jst.ejs +4 -0
- data/src/tools/console.coffee +51 -21
- data/src/util.coffee +17 -4
- data/vendor/assets/javascripts/luca-ui-base.js +5304 -0
- data/vendor/assets/javascripts/luca-ui-bootstrap.js +9 -0
- data/vendor/assets/javascripts/luca-ui-development-tools.js +52 -24
- data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
- data/vendor/assets/javascripts/luca-ui-full.js +1700 -595
- data/vendor/assets/javascripts/luca-ui-full.min.js +7 -6
- data/vendor/assets/javascripts/luca-ui-spec.js +6815 -0
- data/vendor/assets/javascripts/luca-ui-templates.js +92 -24
- data/vendor/assets/javascripts/luca-ui.js +1695 -564
- data/vendor/assets/javascripts/luca-ui.min.js +4 -4
- metadata +69 -28
- data/src/templates/components/bootstrap_form_controls.luca +0 -7
- data/src/templates/components/collection_loader_view.luca +0 -5
- data/src/templates/components/form_alert.luca +0 -3
- data/src/templates/components/grid_view.luca +0 -7
- data/src/templates/components/grid_view_empty_text.luca +0 -3
- data/src/templates/components/load_mask.luca +0 -3
- data/src/templates/components/nav_bar.luca +0 -2
- data/src/templates/containers/basic.luca +0 -1
- data/src/templates/containers/tab_selector_container.luca +0 -8
- data/src/templates/containers/tab_view.luca +0 -2
- data/src/templates/containers/toolbar_wrapper.luca +0 -1
- data/src/templates/fields/button_field.luca +0 -2
- data/src/templates/fields/button_field_link.luca +0 -5
- data/src/templates/fields/checkbox_array.luca +0 -4
- data/src/templates/fields/checkbox_array_item.luca +0 -4
- data/src/templates/fields/checkbox_field.luca +0 -9
- data/src/templates/fields/file_upload_field.luca +0 -8
- data/src/templates/fields/hidden_field.luca +0 -1
- data/src/templates/fields/select_field.luca +0 -8
- data/src/templates/fields/text_area_field.luca +0 -8
- data/src/templates/fields/text_field.luca +0 -17
- data/src/templates/sample/contents.luca +0 -1
- data/src/templates/sample/welcome.luca +0 -1
- data/src/templates/table_view.luca +0 -4
@@ -1,15 +1,33 @@
|
|
1
|
-
|
1
|
+
collectionView = Luca.define "Luca.components.CollectionView"
|
2
|
+
# The CollectionView facilitates the rendering of a Collection
|
3
|
+
# of models into a group of many rendered templates
|
2
4
|
#
|
3
|
-
#
|
5
|
+
# Example:
|
4
6
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
7
|
+
# new Luca.components.CollectionView
|
8
|
+
# itemTemplate: "template_name"
|
9
|
+
# collection: "collection_class_name"
|
10
|
+
# pagination:
|
11
|
+
# page: 1
|
12
|
+
# limit: 15
|
13
|
+
# filterable:
|
14
|
+
# query:
|
15
|
+
# default: 'value'
|
9
16
|
#
|
17
|
+
collectionView.extends "Luca.components.Panel"
|
10
18
|
|
11
|
-
|
12
|
-
|
19
|
+
collectionView.behavesAs "LoadMaskable",
|
20
|
+
"Filterable",
|
21
|
+
"Paginatable"
|
22
|
+
|
23
|
+
collectionView.triggers "before:refresh",
|
24
|
+
"after:refresh",
|
25
|
+
"refresh",
|
26
|
+
"empty:results"
|
27
|
+
|
28
|
+
collectionView.defaults
|
29
|
+
|
30
|
+
tagName: "ol"
|
13
31
|
|
14
32
|
className: "luca-ui-collection-view"
|
15
33
|
|
@@ -25,89 +43,147 @@ _.def("Luca.components.CollectionView").extends("Luca.components.Panel").with
|
|
25
43
|
|
26
44
|
itemClassName: 'collection-item'
|
27
45
|
|
28
|
-
|
29
|
-
"empty:results"
|
30
|
-
]
|
31
|
-
|
46
|
+
|
32
47
|
initialize: (@options={})->
|
33
48
|
_.extend(@, @options)
|
34
49
|
|
35
50
|
_.bindAll @, "refresh"
|
36
51
|
|
52
|
+
|
37
53
|
unless @collection? or @options.collection
|
54
|
+
console.log "Error on initialize of collection view", @
|
38
55
|
throw "Collection Views must specify a collection"
|
39
56
|
|
40
57
|
unless @itemTemplate? || @itemRenderer? || @itemProperty?
|
41
58
|
throw "Collection Views must specify an item template or item renderer function"
|
42
59
|
|
43
|
-
|
60
|
+
if _.isString(@collection)
|
61
|
+
if Luca.CollectionManager.get()
|
62
|
+
@collection = Luca.CollectionManager.get().getOrCreate(@collection)
|
63
|
+
else
|
64
|
+
console.log "String Collection but no collection manager"
|
44
65
|
|
45
|
-
|
46
|
-
@
|
66
|
+
unless Luca.isBackboneCollection(@collection)
|
67
|
+
console.log "Missing Collection on #{ @name || @cid }", @, @collection
|
68
|
+
throw "Collection Views must have a valid backbone collection"
|
47
69
|
|
48
|
-
if Luca.isBackboneCollection(@collection)
|
49
70
|
@collection.on "before:fetch", ()=>
|
50
|
-
@trigger "enable:loadmask"
|
71
|
+
@trigger "enable:loadmask"
|
51
72
|
|
52
73
|
@collection.bind "reset", ()=>
|
53
|
-
@
|
74
|
+
@refresh()
|
75
|
+
@trigger "disable:loadmask"
|
76
|
+
|
77
|
+
@collection.bind "remove", ()=>
|
54
78
|
@refresh()
|
55
79
|
|
56
|
-
@collection.bind "add",
|
57
|
-
|
80
|
+
@collection.bind "add", ()=>
|
81
|
+
@refresh()
|
58
82
|
|
59
83
|
if @observeChanges is true
|
60
|
-
|
84
|
+
@collection.on "change", @refreshModel, @
|
61
85
|
|
62
|
-
|
63
|
-
|
86
|
+
Luca.components.Panel::initialize.apply(@, arguments)
|
87
|
+
|
88
|
+
unless @autoRefreshOnModelsPresent is false
|
89
|
+
@defer ()=>
|
90
|
+
@refresh() if @collection.length > 0
|
91
|
+
.until("after:render")
|
64
92
|
|
65
|
-
|
66
|
-
@refresh()
|
93
|
+
@on "refresh", @refresh, @
|
67
94
|
|
68
95
|
attributesForItem: (item, model)->
|
69
96
|
_.extend {}, class: @itemClassName, "data-index": item.index, "data-model-id": item.model.get('id')
|
70
97
|
|
71
98
|
contentForItem: (item={})->
|
72
99
|
if @itemTemplate? and templateFn = Luca.template(@itemTemplate)
|
73
|
-
|
74
|
-
content = templateFn.call(@, item)
|
100
|
+
return content = templateFn.call(@, item)
|
75
101
|
|
76
102
|
if @itemRenderer? and _.isFunction( @itemRenderer )
|
77
|
-
content = @itemRenderer.call(@, item, item.model, item.index)
|
103
|
+
return content = @itemRenderer.call(@, item, item.model, item.index)
|
78
104
|
|
79
|
-
if @itemProperty
|
80
|
-
content = item.model.
|
81
|
-
content = content() if _.isFunction(content)
|
105
|
+
if @itemProperty and item.model?
|
106
|
+
return content = item.model.read( @itemProperty )
|
82
107
|
|
83
|
-
|
108
|
+
""
|
84
109
|
|
85
110
|
makeItem: (model, index)->
|
86
111
|
item = if @prepareItem? then @prepareItem.call(@, model, index) else (model:model, index: index)
|
87
|
-
|
112
|
+
attributes = @attributesForItem(item, model)
|
113
|
+
content = @contentForItem(item)
|
114
|
+
# TEMP
|
115
|
+
# Figure out why calls to make are failing with an unexpected string error
|
116
|
+
try
|
117
|
+
make(@itemTagName, attributes, content)
|
118
|
+
catch e
|
119
|
+
console.log "Error generating DOM element for CollectionView", @, model, index
|
120
|
+
#no op
|
121
|
+
|
122
|
+
getCollection: ()->
|
123
|
+
@collection
|
124
|
+
|
125
|
+
applyQuery: (query={},queryOptions={})->
|
126
|
+
@query = query
|
127
|
+
@queryOptions = queryOptions
|
128
|
+
@refresh()
|
129
|
+
@
|
88
130
|
|
89
|
-
|
90
|
-
|
91
|
-
|
131
|
+
# Private: returns the query that is applied to the underlying collection.
|
132
|
+
# accepts the same options as Luca.Collection.query's initial query option.
|
133
|
+
getQuery: ()->
|
134
|
+
query = @query ||= {}
|
135
|
+
for querySource in _( @querySources || [] ).compact()
|
136
|
+
query = _.extend(query, (querySource()||{}) )
|
137
|
+
query
|
138
|
+
|
139
|
+
# Private: returns the query that is applied to the underlying collection.
|
140
|
+
# accepts the same options as Luca.Collection.query's initial query option.
|
141
|
+
getQueryOptions: ()->
|
142
|
+
options = @queryOptions ||= {}
|
143
|
+
|
144
|
+
for optionSource in _( @optionsSources || [] ).compact()
|
145
|
+
options = _.extend(options, (optionSource()||{}) )
|
146
|
+
|
147
|
+
options
|
148
|
+
|
149
|
+
# Private: returns the models to be rendered. If the underlying collection
|
150
|
+
# responds to @query() then it will use that interface.
|
151
|
+
getModels: (query,options)->
|
152
|
+
if @collection?.query
|
153
|
+
query ||= @getQuery()
|
154
|
+
options ||= @getQueryOptions()
|
155
|
+
|
156
|
+
@collection.query(query, options)
|
92
157
|
else
|
93
158
|
@collection.models
|
94
159
|
|
95
|
-
|
96
160
|
locateItemElement: (id)->
|
97
161
|
@$(".#{ @itemClassName }[data-model-id='#{ id }']")
|
98
162
|
|
99
163
|
refreshModel: (model)->
|
100
164
|
index = @collection.indexOf( model )
|
101
165
|
@locateItemElement(model.get('id')).empty().append( @contentForItem({model,index}, model) )
|
166
|
+
@trigger("model:refreshed", index, model)
|
167
|
+
|
168
|
+
refresh: (query,options,models)->
|
169
|
+
query ||= @getQuery()
|
170
|
+
options ||= @getQueryOptions()
|
171
|
+
models ||= @getModels(query, options)
|
102
172
|
|
103
|
-
refresh: ()->
|
104
173
|
@$bodyEl().empty()
|
105
174
|
|
106
|
-
|
175
|
+
@trigger("before:refresh", models, query, options)
|
176
|
+
|
177
|
+
if models.length is 0
|
107
178
|
@trigger("empty:results")
|
108
179
|
|
109
|
-
|
110
|
-
|
180
|
+
index = 0
|
181
|
+
for model in models
|
182
|
+
@$append @makeItem(model, index++)
|
183
|
+
|
184
|
+
@trigger("after:refresh", models, query, options)
|
185
|
+
|
186
|
+
@
|
111
187
|
|
112
188
|
registerEvent: (domEvent, selector, handler)->
|
113
189
|
if !handler? and _.isFunction(selector)
|
@@ -124,8 +200,5 @@ _.def("Luca.components.CollectionView").extends("Luca.components.Panel").with
|
|
124
200
|
|
125
201
|
# Private Helpers
|
126
202
|
|
127
|
-
make = Luca.View::make
|
128
203
|
|
129
|
-
|
130
|
-
@collection.on "change", (model)=>
|
131
|
-
@refreshModel(model)
|
204
|
+
make = Luca.View::make
|
@@ -31,7 +31,7 @@ _.def('Luca.fields.CheckboxField').extends('Luca.core.Field').with
|
|
31
31
|
@label ||= @name
|
32
32
|
|
33
33
|
setValue: (checked)->
|
34
|
-
@
|
34
|
+
@getInputElement().attr('checked', checked)
|
35
35
|
|
36
36
|
getValue:()->
|
37
|
-
@
|
37
|
+
@getInputElement().is(":checked")
|
@@ -2,9 +2,6 @@ _.def('Luca.fields.FileUploadField').extends('Luca.core.Field').with
|
|
2
2
|
|
3
3
|
template: 'fields/file_upload_field'
|
4
4
|
|
5
|
-
initialize: (@options={})->
|
6
|
-
Luca.core.Field::initialize.apply @, arguments
|
7
|
-
|
8
5
|
afterInitialize: ()->
|
9
6
|
@input_id ||= _.uniqueId('field')
|
10
7
|
@input_name ||= @name
|
@@ -2,9 +2,6 @@ _.def('Luca.fields.HiddenField').extends('Luca.core.Field').with
|
|
2
2
|
|
3
3
|
template: 'fields/hidden_field'
|
4
4
|
|
5
|
-
initialize: (@options={})->
|
6
|
-
Luca.core.Field::initialize.apply @, arguments
|
7
|
-
|
8
5
|
afterInitialize: ()->
|
9
6
|
@input_id ||= _.uniqueId('field')
|
10
7
|
@input_name ||= @name
|
@@ -1,14 +1,11 @@
|
|
1
1
|
_.def("Luca.components.LabelField").extends("Luca.core.Field").with
|
2
2
|
className: "luca-ui-field luca-ui-label-field"
|
3
3
|
|
4
|
-
getValue: ()->
|
5
|
-
@$('input').attr('value')
|
6
|
-
|
7
4
|
formatter: (value)->
|
8
5
|
value ||= @getValue()
|
9
6
|
_.str.titleize( value )
|
10
7
|
|
11
8
|
setValue: (value)->
|
12
9
|
@trigger("change", value, @getValue())
|
13
|
-
|
10
|
+
@getInputElement().attr('value', value)
|
14
11
|
@$('.value').html( @formatter(value) )
|
@@ -57,9 +57,10 @@ _.def('Luca.fields.SelectField').extends('Luca.core.Field').with
|
|
57
57
|
|
58
58
|
hash
|
59
59
|
|
60
|
-
|
61
|
-
@input
|
60
|
+
getInputElement: ()->
|
61
|
+
@input ||= @$('select').eq(0)
|
62
62
|
|
63
|
+
afterRender: ()->
|
63
64
|
if @collection?.models?.length > 0
|
64
65
|
@populateOptions()
|
65
66
|
else
|
@@ -76,11 +77,10 @@ _.def('Luca.fields.SelectField').extends('Luca.core.Field').with
|
|
76
77
|
@trigger "on:change", @, e
|
77
78
|
|
78
79
|
resetOptions: ()->
|
79
|
-
@
|
80
|
+
@getInputElement().html('')
|
80
81
|
|
81
82
|
if @includeBlank
|
82
|
-
@
|
83
|
-
|
83
|
+
@getInputElement().append("<option value='#{ @blankValue }'>#{ @blankText }</option>")
|
84
84
|
|
85
85
|
populateOptions: ()->
|
86
86
|
@resetOptions()
|
@@ -91,7 +91,7 @@ _.def('Luca.fields.SelectField').extends('Luca.core.Field').with
|
|
91
91
|
display = model.get( @displayField )
|
92
92
|
selected = "selected" if @selected and value is @selected
|
93
93
|
option = "<option #{ selected } value='#{ value }'>#{ display }</option>"
|
94
|
-
@
|
94
|
+
@getInputElement().append( option )
|
95
95
|
|
96
96
|
@trigger "after:populate:options", @
|
97
97
|
@setValue( @currentValue )
|
@@ -21,7 +21,11 @@ _.def('Luca.fields.TextField').extends('Luca.core.Field').with
|
|
21
21
|
@input_name ||= @name
|
22
22
|
@label ||= @name
|
23
23
|
@input_class ||= @class
|
24
|
+
@input_value ||= @value || ""
|
24
25
|
|
26
|
+
# TODO
|
27
|
+
# Placeholder?
|
28
|
+
|
25
29
|
if @prepend
|
26
30
|
@$el.addClass('input-prepend')
|
27
31
|
@addOn = @prepend
|
@@ -2,21 +2,17 @@ _.def('Luca.fields.TypeAheadField').extends('Luca.fields.TextField').with
|
|
2
2
|
className: 'luca-ui-field'
|
3
3
|
|
4
4
|
getSource: ()->
|
5
|
-
|
6
|
-
@source || []
|
5
|
+
Luca.util.read(@source) || []
|
7
6
|
|
8
7
|
matcher: (item)->
|
9
|
-
# IMPLEMENT
|
10
|
-
# return true where item matches @query
|
11
8
|
true
|
12
9
|
|
13
10
|
beforeRender: ()->
|
14
|
-
|
15
|
-
|
11
|
+
Luca.fields.TextField::beforeRender.apply(@, arguments)
|
12
|
+
@getInputElement().attr('data-provide','typeahead')
|
16
13
|
|
17
14
|
afterRender: ()->
|
18
|
-
|
19
|
-
|
20
|
-
@$('input').typeahead
|
15
|
+
Luca.fields.TextField::afterRender.apply(@, arguments)
|
16
|
+
@getInputElement().typeahead
|
21
17
|
matcher: @matcher
|
22
18
|
source: @getSource()
|
@@ -1,20 +1,3 @@
|
|
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
1
|
_.def("Luca.components.FormView").extends('Luca.core.Container').with
|
19
2
|
|
20
3
|
tagName: 'form'
|
@@ -54,6 +37,8 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
|
|
54
37
|
|
55
38
|
Luca.core.Container::initialize.apply @, arguments
|
56
39
|
|
40
|
+
@components ||= @fields
|
41
|
+
|
57
42
|
_.bindAll @, "submitHandler", "resetHandler", "renderToolbars", "applyLoadMask"
|
58
43
|
|
59
44
|
@state ||= new Backbone.Model
|
@@ -67,7 +52,7 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
|
|
67
52
|
@bottomToolbar = @getDefaultToolbar() unless @toolbar is "top"
|
68
53
|
|
69
54
|
getDefaultToolbar: ()->
|
70
|
-
|
55
|
+
Luca.components.FormView.defaultFormViewToolbar
|
71
56
|
|
72
57
|
applyStyleClasses: ()->
|
73
58
|
if Luca.enableBootstrap
|
@@ -110,7 +95,7 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
|
|
110
95
|
passOne = _( @getFields('name', name) ).first()
|
111
96
|
return passOne if passOne?
|
112
97
|
|
113
|
-
_( @getFields('input_name', name) ).first()
|
98
|
+
_( @getFields('input_name', name) ).first()
|
114
99
|
|
115
100
|
getFields: (attr,value)->
|
116
101
|
fields = @selectByAttribute("isField", true, true)
|
@@ -199,17 +184,17 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
|
|
199
184
|
if options.skip_buttons and field.ctype is "button_field"
|
200
185
|
skip = true
|
201
186
|
else
|
202
|
-
if valueIsBlank and allowBlankValues is false
|
203
|
-
skip = true
|
187
|
+
if valueIsBlank and allowBlankValues is false
|
188
|
+
skip = true
|
204
189
|
|
205
190
|
if field.input_name is "id" and valueIsBlank is true
|
206
191
|
skip = true
|
207
192
|
|
208
193
|
if options.debug
|
209
194
|
console.log "Skip is true on #{ key }"
|
210
|
-
|
195
|
+
|
211
196
|
if skip isnt true
|
212
|
-
memo[ key ] = value
|
197
|
+
memo[ key ] = value
|
213
198
|
|
214
199
|
memo
|
215
200
|
|
@@ -273,3 +258,23 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
|
|
273
258
|
errorMessage: (message)->
|
274
259
|
@$('.alert.alert-error').remove()
|
275
260
|
@flash Luca.template("components/form_alert", className:"alert alert-error", message: message)
|
261
|
+
|
262
|
+
|
263
|
+
Luca.components.FormView.defaultFormViewToolbar =
|
264
|
+
buttons:[
|
265
|
+
icon:"remove-sign"
|
266
|
+
label: "Reset"
|
267
|
+
eventId: "click:reset"
|
268
|
+
className:"reset-button"
|
269
|
+
align: 'right'
|
270
|
+
,
|
271
|
+
icon:"ok-sign"
|
272
|
+
white: true
|
273
|
+
label: "Save Changes"
|
274
|
+
eventId: "click:submit"
|
275
|
+
color: "success"
|
276
|
+
className: 'submit-button'
|
277
|
+
align: 'right'
|
278
|
+
]
|
279
|
+
|
280
|
+
|
@@ -0,0 +1,121 @@
|
|
1
|
+
multiView = Luca.define "Luca.components.MultiCollectionView"
|
2
|
+
|
3
|
+
# The CollectionMultiView is a collection view with multiple renderings
|
4
|
+
# of the list. ( e.g. Icons, Table, List ). It works by maintaining
|
5
|
+
# a current view, and rendering that view. It refreshes the views
|
6
|
+
# whenever they are activated.
|
7
|
+
#
|
8
|
+
# The MultiView allows you to share one collection, filter, pagination setup
|
9
|
+
# but render multiple versions of a model. To do this, you are expected to
|
10
|
+
# define one or more objects in the @views property of the component.
|
11
|
+
|
12
|
+
# Example:
|
13
|
+
# multiView = new Luca.components.MultiCollectionView
|
14
|
+
# collection: "my_collection"
|
15
|
+
# paginatable:
|
16
|
+
# page: 1
|
17
|
+
# limit: 20
|
18
|
+
# views:[
|
19
|
+
# type: "table"
|
20
|
+
# columns:[
|
21
|
+
# header: "Header"
|
22
|
+
# reader: "attribute"
|
23
|
+
# ]
|
24
|
+
# ]
|
25
|
+
multiView.extends "Luca.containers.CardView"
|
26
|
+
|
27
|
+
multiView.behavesAs "LoadMaskable",
|
28
|
+
"Filterable",
|
29
|
+
"Paginatable"
|
30
|
+
|
31
|
+
multiView.triggers "before:refresh",
|
32
|
+
"after:refresh",
|
33
|
+
"refresh",
|
34
|
+
"empty:results"
|
35
|
+
|
36
|
+
multiView.defaultsTo
|
37
|
+
version: 1
|
38
|
+
|
39
|
+
stateful: true
|
40
|
+
|
41
|
+
defaultState:
|
42
|
+
activeView: 0
|
43
|
+
|
44
|
+
viewContainerClass: "luca-ui-multi-view-container"
|
45
|
+
|
46
|
+
initialize: (@options={})->
|
47
|
+
@components ||= @views
|
48
|
+
|
49
|
+
validateComponent( view ) for view in @components
|
50
|
+
|
51
|
+
@on "refresh", @refresh, @
|
52
|
+
@on "after:card:switch", @refresh, @
|
53
|
+
@on "after:components", propagateCollectionComponents, @
|
54
|
+
|
55
|
+
@debug("multi collection , proto initialize")
|
56
|
+
|
57
|
+
Luca.containers.CardView::initialize.apply(@, arguments)
|
58
|
+
|
59
|
+
relayAfterRefresh: (models,query,options)->
|
60
|
+
@trigger "after:refresh", models, query, options
|
61
|
+
|
62
|
+
refresh: ()->
|
63
|
+
@activeComponent()?.trigger("refresh")
|
64
|
+
|
65
|
+
getCollection: ()->
|
66
|
+
@collection
|
67
|
+
|
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
|
92
|
+
|
93
|
+
propagateCollectionComponents = ()->
|
94
|
+
container = @
|
95
|
+
|
96
|
+
# in the multi view will share the same
|
97
|
+
# collection, filter state, pagination options, etc
|
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
|
+
|
104
|
+
_.extend component,
|
105
|
+
collection: container.getCollection()
|
106
|
+
|
107
|
+
getQuery: ()->
|
108
|
+
container.getQuery.call(container)
|
109
|
+
|
110
|
+
getQueryOptions: ()->
|
111
|
+
container.getQueryOptions.call(container)
|
112
|
+
|
113
|
+
validateComponent = (component)->
|
114
|
+
type = (component.type || component.ctype)
|
115
|
+
|
116
|
+
return if type is "collection" or
|
117
|
+
type is "collection_view" or
|
118
|
+
type is "table" or
|
119
|
+
type is "table_view"
|
120
|
+
|
121
|
+
throw "The MultiCollectionView expects to contain multiple collection views"
|
@@ -0,0 +1,106 @@
|
|
1
|
+
paginationControl = Luca.register "Luca.components.PaginationControl"
|
2
|
+
|
3
|
+
paginationControl.extends "Luca.View"
|
4
|
+
|
5
|
+
paginationControl.defines
|
6
|
+
template: "components/pagination"
|
7
|
+
|
8
|
+
stateful: true
|
9
|
+
|
10
|
+
autoBindEventHandlers: true
|
11
|
+
|
12
|
+
events:
|
13
|
+
"click a[data-page-number]" : "selectPage"
|
14
|
+
"click a.next" : "nextPage"
|
15
|
+
"click a.prev" : "previousPage"
|
16
|
+
|
17
|
+
afterInitialize: ()->
|
18
|
+
_.bindAll @, "updateWithPageCount"
|
19
|
+
|
20
|
+
@state.on "change", (state, numberOfPages)=>
|
21
|
+
@updateWithPageCount( state.get('numberOfPages') )
|
22
|
+
|
23
|
+
limit: ()->
|
24
|
+
parseInt (@state.get('limit') || @collection?.length)
|
25
|
+
|
26
|
+
page: ()->
|
27
|
+
parseInt (@state.get('page') || 1)
|
28
|
+
|
29
|
+
nextPage: ()->
|
30
|
+
return unless @nextEnabled()
|
31
|
+
@state.set('page', @page() + 1 )
|
32
|
+
|
33
|
+
previousPage: ()->
|
34
|
+
return unless @previousEnabled()
|
35
|
+
@state.set('page', @page() - 1 )
|
36
|
+
|
37
|
+
selectPage: (e)->
|
38
|
+
me = my = @$( e.target )
|
39
|
+
me = my = my.closest('a.page') unless me.is('a.page')
|
40
|
+
|
41
|
+
my.siblings().removeClass('is-selected')
|
42
|
+
me.addClass('is-selected')
|
43
|
+
|
44
|
+
@setPage( my.data('page-number') )
|
45
|
+
|
46
|
+
setPage: (page=1,options={})->
|
47
|
+
@state.set('page', page, options)
|
48
|
+
|
49
|
+
setLimit: (limit=1,options={})->
|
50
|
+
@state.set('limit', limit, options)
|
51
|
+
|
52
|
+
pageButtonContainer: ()->
|
53
|
+
@$ '.group'
|
54
|
+
|
55
|
+
previousEnabled: ()->
|
56
|
+
@page() > 1
|
57
|
+
|
58
|
+
nextEnabled: ()->
|
59
|
+
@page() < @totalPages()
|
60
|
+
|
61
|
+
previousButton: ()->
|
62
|
+
@$ 'a.page.prev'
|
63
|
+
|
64
|
+
nextButton: ()->
|
65
|
+
@$ 'a.page.next'
|
66
|
+
|
67
|
+
pageButtons: ()->
|
68
|
+
@$ 'a[data-page-number]', @pageButtonContainer()
|
69
|
+
|
70
|
+
updateWithPageCount: (@pageCount, models=[])->
|
71
|
+
modelCount = models.length
|
72
|
+
|
73
|
+
console.log "Update With Page Count", @pageCount, modelCount
|
74
|
+
|
75
|
+
@pageButtonContainer().empty()
|
76
|
+
|
77
|
+
_( @pageCount ).times (index)=>
|
78
|
+
page = index + 1
|
79
|
+
button = @make("a","data-page-number":page, class:"page", page )
|
80
|
+
@pageButtonContainer().append(button)
|
81
|
+
|
82
|
+
@toggleNavigationButtons()
|
83
|
+
@selectActivePageButton()
|
84
|
+
|
85
|
+
@
|
86
|
+
|
87
|
+
toggleNavigationButtons: ()->
|
88
|
+
@$('a.next, a.prev').addClass('disabled')
|
89
|
+
@nextButton().removeClass('disabled') if @nextEnabled()
|
90
|
+
@previousButton().removeClass('disabled') if @previousEnabled()
|
91
|
+
|
92
|
+
selectActivePageButton: ()->
|
93
|
+
@activePageButton().addClass('is-selected')
|
94
|
+
|
95
|
+
activePageButton: ()->
|
96
|
+
@pageButtons().filter("[data-page-number='#{ @page() }']")
|
97
|
+
|
98
|
+
totalPages: ()->
|
99
|
+
@pageCount
|
100
|
+
|
101
|
+
totalItems: ()->
|
102
|
+
parseInt @collection?.length || 0
|
103
|
+
|
104
|
+
itemsPerPage: (value, options={})->
|
105
|
+
@state.set("limit", value, options) if value?
|
106
|
+
parseInt @state.get("limit")
|