luca 0.6.6
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/.gitignore +5 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +77 -0
- data/Guardfile +22 -0
- data/README.md +291 -0
- data/Rakefile +28 -0
- data/app.rb +46 -0
- data/assets/images/glyphicons-halflings-white.png +0 -0
- data/assets/images/glyphicons-halflings.png +0 -0
- data/assets/javascripts/dependencies/backbone-min.js +37 -0
- data/assets/javascripts/dependencies/backbone-query.min.js +1 -0
- data/assets/javascripts/dependencies/bootstrap.min.js +1 -0
- data/assets/javascripts/dependencies/jasmine-html.js +190 -0
- data/assets/javascripts/dependencies/jasmine.js +2476 -0
- data/assets/javascripts/dependencies/jquery.js +4 -0
- data/assets/javascripts/dependencies/modal.js +698 -0
- data/assets/javascripts/dependencies/modernizr.min.js +30 -0
- data/assets/javascripts/dependencies/prettify.js +28 -0
- data/assets/javascripts/dependencies/sinon.js +3469 -0
- data/assets/javascripts/dependencies/spin-min.js +2 -0
- data/assets/javascripts/dependencies/underscore-min.js +31 -0
- data/assets/javascripts/dependencies/underscore-string.min.js +14 -0
- data/assets/javascripts/dependencies.coffee +7 -0
- data/assets/javascripts/luca-ui-base.coffee +12 -0
- data/assets/javascripts/luca-ui-spec.coffee +2 -0
- data/assets/javascripts/luca-ui.coffee +3 -0
- data/assets/javascripts/sandbox/collections/sample.coffee +0 -0
- data/assets/javascripts/sandbox/config.coffee +7 -0
- data/assets/javascripts/sandbox/sandbox.coffee +16 -0
- data/assets/javascripts/sandbox/templates/features/collection_helpers.luca +33 -0
- data/assets/javascripts/sandbox/templates/features/form_demo_code.luca +48 -0
- data/assets/javascripts/sandbox/templates/features/grid_demo_code.luca +24 -0
- data/assets/javascripts/sandbox/templates/features/introduction.luca +11 -0
- data/assets/javascripts/sandbox/templates/features/view_helpers.luca +43 -0
- data/assets/javascripts/sandbox/templates/navigation.luca +8 -0
- data/assets/javascripts/sandbox/views/form_demo.coffee +47 -0
- data/assets/javascripts/sandbox/views/grid_demo.coffee +23 -0
- data/assets/javascripts/sandbox/views/pages/collection_events_sample.coffee +1 -0
- data/assets/javascripts/sandbox/views/pages/pages_controller.coffee +28 -0
- data/assets/javascripts/sandbox.coffee +4 -0
- data/assets/javascripts/spec-dependencies.coffee +4 -0
- data/assets/stylesheets/bootstrap-responsive.min.css +3 -0
- data/assets/stylesheets/bootstrap.min.css +610 -0
- data/assets/stylesheets/jasmine.css +166 -0
- data/assets/stylesheets/luca-ui-bootstrap.css +5 -0
- data/assets/stylesheets/luca-ui-spec.css +3 -0
- data/assets/stylesheets/luca-ui.css +3 -0
- data/assets/stylesheets/prettify.css +40 -0
- data/assets/stylesheets/sandbox/sandbox.scss +4 -0
- data/assets/stylesheets/sandbox.css +3 -0
- data/config.ru +11 -0
- data/lib/luca/command_line.rb +69 -0
- data/lib/luca/rails/engine.rb +12 -0
- data/lib/luca/rails/version.rb +6 -0
- data/lib/luca/rails.rb +9 -0
- data/lib/luca/template.rb +51 -0
- data/lib/luca/test_harness.rb +106 -0
- data/lib/luca.rb +1 -0
- data/lib/sprockets/luca_template.rb +49 -0
- data/lib/templates/spec_manifest_javascripts.erb +7 -0
- data/lib/templates/spec_manifest_stylesheets.erb +11 -0
- data/luca.gemspec +26 -0
- data/public/jasmine/index.html +26 -0
- data/public/sandbox/api.js +1 -0
- data/spec/components/application_spec.coffee +0 -0
- data/spec/components/collection_loader_view_spec.coffee +0 -0
- data/spec/components/controller_spec.coffee +0 -0
- data/spec/components/form_view_spec.coffee +13 -0
- data/spec/components/grid_view_spec.coffee +0 -0
- data/spec/components/record_manager_spec.coffee +0 -0
- data/spec/components/template_spec.coffee +0 -0
- data/spec/containers/card_view_spec.coffee +1 -0
- data/spec/containers/column_view_spec.coffee +0 -0
- data/spec/containers/modal_view_spec.coffee +0 -0
- data/spec/containers/panel_view_spec.coffee +0 -0
- data/spec/containers/split_view_spec.coffee +0 -0
- data/spec/containers/tab_view_spec.coffee +0 -0
- data/spec/containers/viewport_spec.coffee +0 -0
- data/spec/core/collection_spec.coffee +215 -0
- data/spec/core/container_spec.coffee +0 -0
- data/spec/core/field_spec.coffee +0 -0
- data/spec/core/observer_spec.coffee +0 -0
- data/spec/core/view_spec.coffee +87 -0
- data/spec/framework_spec.coffee +48 -0
- data/spec/helper.coffee +120 -0
- data/spec/managers/collection_manager_spec.coffee +95 -0
- data/spec/managers/socket_manager_spec.coffee +0 -0
- data/src/components/application.coffee +83 -0
- data/src/components/base_toolbar.coffee +16 -0
- data/src/components/collection_loader_view.coffee +37 -0
- data/src/components/controller.coffee +41 -0
- data/src/components/fields/button_field.coffee +40 -0
- data/src/components/fields/checkbox_field.coffee +41 -0
- data/src/components/fields/file_upload_field.coffee +15 -0
- data/src/components/fields/hidden_field.coffee +18 -0
- data/src/components/fields/select_field.coffee +100 -0
- data/src/components/fields/text_area_field.coffee +43 -0
- data/src/components/fields/text_field.coffee +42 -0
- data/src/components/fields/type_ahead_field.coffee +10 -0
- data/src/components/form_button_toolbar.coffee +26 -0
- data/src/components/form_view.coffee +205 -0
- data/src/components/grid_view.coffee +208 -0
- data/src/components/record_manager.coffee +215 -0
- data/src/components/router.coffee +34 -0
- data/src/components/template.coffee +19 -0
- data/src/containers/card_view.coffee +89 -0
- data/src/containers/column_view.coffee +48 -0
- data/src/containers/modal_view.coffee +85 -0
- data/src/containers/panel_view.coffee +24 -0
- data/src/containers/split_view.coffee +12 -0
- data/src/containers/tab_view.coffee +77 -0
- data/src/containers/viewport.coffee +16 -0
- data/src/core/collection.coffee +319 -0
- data/src/core/container.coffee +256 -0
- data/src/core/field.coffee +68 -0
- data/src/core/observer.coffee +17 -0
- data/src/core/view.coffee +190 -0
- data/src/framework.coffee +110 -0
- data/src/index.coffee +255 -0
- data/src/managers/collection_manager.coffee +168 -0
- data/src/managers/socket_manager.coffee +54 -0
- data/src/modules/deferrable.coffee +18 -0
- data/src/modules/local_storage.coffee +50 -0
- data/src/stylesheets/base.scss +78 -0
- data/src/stylesheets/components/form_view.scss +54 -0
- data/src/stylesheets/components/grid_view.scss +111 -0
- data/src/stylesheets/components/toolbar.scss +15 -0
- data/src/stylesheets/containers/container.scss +7 -0
- data/src/stylesheets/containers/modal_view.scss +0 -0
- data/src/stylesheets/containers/tab_view.scss +33 -0
- data/src/stylesheets/normalize.scss +430 -0
- data/src/templates/components/bootstrap_form_controls.luca +7 -0
- data/src/templates/components/collection_loader_view.luca +5 -0
- data/src/templates/components/form_view.luca +15 -0
- data/src/templates/components/grid_view.luca +9 -0
- data/src/templates/components/grid_view_empty_text.luca +3 -0
- data/src/templates/containers/basic.luca +1 -0
- data/src/templates/containers/tab_selector_container.luca +8 -0
- data/src/templates/containers/tab_view.luca +1 -0
- data/src/templates/containers/toolbar_wrapper.luca +1 -0
- data/src/templates/fields/button_field.luca +2 -0
- data/src/templates/fields/button_field_link.luca +5 -0
- data/src/templates/fields/checkbox_field.luca +9 -0
- data/src/templates/fields/file_upload_field.luca +8 -0
- data/src/templates/fields/hidden_field.luca +1 -0
- data/src/templates/fields/select_field.luca +7 -0
- data/src/templates/fields/text_area_field.luca +8 -0
- data/src/templates/fields/text_field.luca +13 -0
- data/src/templates/sample/contents.luca +1 -0
- data/src/templates/sample/welcome.luca +1 -0
- data/vendor/assets/images/glyphicons-halflings-white.png +0 -0
- data/vendor/assets/images/glyphicons-halflings.png +0 -0
- data/vendor/assets/javascripts/luca-spec-dependencies.js +6135 -0
- data/vendor/assets/javascripts/luca-ui-base.js +1527 -0
- data/vendor/assets/javascripts/luca-ui-spec.js +3654 -0
- data/vendor/assets/javascripts/luca-ui.js +2763 -0
- data/vendor/assets/luca-ui/base.css +85 -0
- data/vendor/assets/luca-ui/components/application.js +91 -0
- data/vendor/assets/luca-ui/components/base_toolbar.js +23 -0
- data/vendor/assets/luca-ui/components/controller.js +38 -0
- data/vendor/assets/luca-ui/components/fields/button_field.js +45 -0
- data/vendor/assets/luca-ui/components/fields/checkbox_field.js +43 -0
- data/vendor/assets/luca-ui/components/fields/file_upload_field.js +20 -0
- data/vendor/assets/luca-ui/components/fields/hidden_field.js +20 -0
- data/vendor/assets/luca-ui/components/fields/select_field.js +97 -0
- data/vendor/assets/luca-ui/components/fields/text_area_field.js +48 -0
- data/vendor/assets/luca-ui/components/fields/text_field.js +46 -0
- data/vendor/assets/luca-ui/components/fields/type_ahead_field.js +13 -0
- data/vendor/assets/luca-ui/components/form_button_toolbar.js +32 -0
- data/vendor/assets/luca-ui/components/form_view.css +32 -0
- data/vendor/assets/luca-ui/components/form_view.js +207 -0
- data/vendor/assets/luca-ui/components/grid_view.css +76 -0
- data/vendor/assets/luca-ui/components/grid_view.js +202 -0
- data/vendor/assets/luca-ui/components/record_manager.js +207 -0
- data/vendor/assets/luca-ui/components/router.js +36 -0
- data/vendor/assets/luca-ui/components/template.js +26 -0
- data/vendor/assets/luca-ui/components/toolbar.css +11 -0
- data/vendor/assets/luca-ui/containers/card_view.js +98 -0
- data/vendor/assets/luca-ui/containers/column_view.js +52 -0
- data/vendor/assets/luca-ui/containers/container.css +3 -0
- data/vendor/assets/luca-ui/containers/modal_view.css +0 -0
- data/vendor/assets/luca-ui/containers/modal_view.js +87 -0
- data/vendor/assets/luca-ui/containers/panel_view.js +34 -0
- data/vendor/assets/luca-ui/containers/split_view.js +13 -0
- data/vendor/assets/luca-ui/containers/tab_view.css +16 -0
- data/vendor/assets/luca-ui/containers/tab_view.js +80 -0
- data/vendor/assets/luca-ui/containers/viewport.js +18 -0
- data/vendor/assets/luca-ui/core/collection.js +221 -0
- data/vendor/assets/luca-ui/core/container.js +205 -0
- data/vendor/assets/luca-ui/core/field.js +59 -0
- data/vendor/assets/luca-ui/core/observer.js +42 -0
- data/vendor/assets/luca-ui/core/view.js +127 -0
- data/vendor/assets/luca-ui/framework.js +110 -0
- data/vendor/assets/luca-ui/index.js +5 -0
- data/vendor/assets/luca-ui/managers/collection_manager.js +98 -0
- data/vendor/assets/luca-ui/managers/socket_manager.js +52 -0
- data/vendor/assets/luca-ui/modules/deferrable.js +21 -0
- data/vendor/assets/luca-ui/modules/local_storage.js +81 -0
- data/vendor/assets/luca-ui/normalize.css +359 -0
- data/vendor/assets/luca-ui/stylesheets/base.css +85 -0
- data/vendor/assets/luca-ui/stylesheets/components/form_view.css +32 -0
- data/vendor/assets/luca-ui/stylesheets/components/grid_view.css +76 -0
- data/vendor/assets/luca-ui/stylesheets/components/toolbar.css +11 -0
- data/vendor/assets/luca-ui/stylesheets/containers/container.css +3 -0
- data/vendor/assets/luca-ui/stylesheets/containers/modal_view.css +0 -0
- data/vendor/assets/luca-ui/stylesheets/containers/tab_view.css +16 -0
- data/vendor/assets/luca-ui/stylesheets/normalize.css +359 -0
- data/vendor/assets/luca-ui/templates/components/bootstrap_form_controls.js +4 -0
- data/vendor/assets/luca-ui/templates/components/form_view.js +4 -0
- data/vendor/assets/luca-ui/templates/components/grid_view.js +4 -0
- data/vendor/assets/luca-ui/templates/components/grid_view_empty_text.js +4 -0
- data/vendor/assets/luca-ui/templates/containers/basic.js +4 -0
- data/vendor/assets/luca-ui/templates/containers/tab_selector_container.js +4 -0
- data/vendor/assets/luca-ui/templates/containers/tab_view.js +4 -0
- data/vendor/assets/luca-ui/templates/containers/toolbar_wrapper.js +4 -0
- data/vendor/assets/luca-ui/templates/fields/button_field.js +4 -0
- data/vendor/assets/luca-ui/templates/fields/button_field_link.js +4 -0
- data/vendor/assets/luca-ui/templates/fields/checkbox_field.js +4 -0
- data/vendor/assets/luca-ui/templates/fields/file_upload_field.js +4 -0
- data/vendor/assets/luca-ui/templates/fields/hidden_field.js +4 -0
- data/vendor/assets/luca-ui/templates/fields/select_field.js +4 -0
- data/vendor/assets/luca-ui/templates/fields/text_area_field.js +4 -0
- data/vendor/assets/luca-ui/templates/fields/text_field.js +4 -0
- data/vendor/assets/luca-ui/templates/sample/contents.js +4 -0
- data/vendor/assets/luca-ui/templates/sample/welcome.js +4 -0
- data/vendor/assets/stylesheets/luca-spec-dependencies.css +166 -0
- data/vendor/assets/stylesheets/luca-ui-bootstrap.css +1201 -0
- data/vendor/assets/stylesheets/luca-ui-spec.css +586 -0
- data/vendor/assets/stylesheets/luca-ui.css +586 -0
- data/views/index.erb +20 -0
- data/views/jasmine.erb +22 -0
- data/views/spec_harness.erb +29 -0
- metadata +361 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
Luca.components.FormView = Luca.core.Container.extend
|
|
2
|
+
tagName: 'form'
|
|
3
|
+
|
|
4
|
+
className: 'luca-ui-form-view'
|
|
5
|
+
|
|
6
|
+
hooks:[
|
|
7
|
+
"before:submit"
|
|
8
|
+
"before:reset"
|
|
9
|
+
"before:load"
|
|
10
|
+
"before:load:new"
|
|
11
|
+
"before:load:existing"
|
|
12
|
+
"after:submit"
|
|
13
|
+
"after:reset"
|
|
14
|
+
"after:load"
|
|
15
|
+
"after:load:new"
|
|
16
|
+
"after:load:existing"
|
|
17
|
+
"after:submit:success"
|
|
18
|
+
"after:submit:fatal_error"
|
|
19
|
+
"after:submit:error"
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
events:
|
|
23
|
+
"click .submit-button" : "submitHandler"
|
|
24
|
+
"click .reset-button" : "resetHandler"
|
|
25
|
+
|
|
26
|
+
toolbar: true
|
|
27
|
+
|
|
28
|
+
initialize: (@options={})->
|
|
29
|
+
Luca.core.Container::initialize.apply @, arguments
|
|
30
|
+
|
|
31
|
+
_.bindAll @, "submitHandler", "resetHandler", "renderToolbars"
|
|
32
|
+
|
|
33
|
+
@state ||= new Backbone.Model
|
|
34
|
+
|
|
35
|
+
@setupHooks( @hooks )
|
|
36
|
+
|
|
37
|
+
@legend ||= ""
|
|
38
|
+
|
|
39
|
+
@configureToolbars()
|
|
40
|
+
@applyStyles()
|
|
41
|
+
|
|
42
|
+
addBootstrapFormControls: ()->
|
|
43
|
+
@bind "after:render", ()=>
|
|
44
|
+
el = @$('.toolbar-container.bottom')
|
|
45
|
+
|
|
46
|
+
el.addClass('form-controls')
|
|
47
|
+
el.html @formControlsTemplate || Luca.templates["components/bootstrap_form_controls"](@)
|
|
48
|
+
|
|
49
|
+
applyStyles: ()->
|
|
50
|
+
@applyBootstrapStyles() if Luca.enableBootstrap
|
|
51
|
+
|
|
52
|
+
@$el.addClass( "label-align-#{ @labelAlign }") if @labelAlign
|
|
53
|
+
@$el.addClass( @fieldLayoutClass ) if @fieldLayoutClass
|
|
54
|
+
|
|
55
|
+
applyBootstrapStyles: ()->
|
|
56
|
+
@inlineForm = true if @labelAlign is "left"
|
|
57
|
+
|
|
58
|
+
@$el.addClass('well') if @well
|
|
59
|
+
@$el.addClass('form-search') if @searchForm
|
|
60
|
+
@$el.addClass('form-horizontal') if @horizontalForm
|
|
61
|
+
@$el.addClass('form-inline') if @inlineForm
|
|
62
|
+
|
|
63
|
+
configureToolbars: ()->
|
|
64
|
+
return @addBootstrapFormControls() if Luca.enableBootstrap and @toolbar is true
|
|
65
|
+
|
|
66
|
+
if @toolbar is true
|
|
67
|
+
@toolbars = [
|
|
68
|
+
ctype: 'form_button_toolbar'
|
|
69
|
+
includeReset: true
|
|
70
|
+
position: 'bottom'
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
if @toolbars and @toolbars.length
|
|
74
|
+
@bind "after:render", _.once @renderToolbars
|
|
75
|
+
|
|
76
|
+
resetHandler: (e)->
|
|
77
|
+
me = my = $( e.currentTarget )
|
|
78
|
+
@trigger "before:reset", @
|
|
79
|
+
@reset()
|
|
80
|
+
@trigger "after:reset", @
|
|
81
|
+
|
|
82
|
+
submitHandler: (e)->
|
|
83
|
+
me = my = $( e.currentTarget )
|
|
84
|
+
@trigger "before:submit", @
|
|
85
|
+
@submit()
|
|
86
|
+
|
|
87
|
+
beforeLayout: ()->
|
|
88
|
+
Luca.core.Container::beforeLayout?.apply @, arguments
|
|
89
|
+
@$el.html Luca.templates["components/form_view"]( @ )
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
prepareComponents: ()->
|
|
93
|
+
container = $('.form-view-body', @el)
|
|
94
|
+
_( @components ).each (component)->
|
|
95
|
+
component.container = container
|
|
96
|
+
|
|
97
|
+
render: ()->
|
|
98
|
+
$( @container ).append( @$el )
|
|
99
|
+
|
|
100
|
+
wrapper: ()->
|
|
101
|
+
@$el.parents('.luca-ui-form-view-wrapper')
|
|
102
|
+
|
|
103
|
+
toolbarContainers: (position="bottom")->
|
|
104
|
+
$(".toolbar-container.#{ position }", @wrapper() ).first()
|
|
105
|
+
|
|
106
|
+
renderToolbars: ()->
|
|
107
|
+
_( @toolbars ).each (toolbar)=>
|
|
108
|
+
toolbar.container = $("##{ @cid }-#{ toolbar.position }-toolbar-container")
|
|
109
|
+
toolbar = Luca.util.lazyComponent(toolbar)
|
|
110
|
+
toolbar.render()
|
|
111
|
+
|
|
112
|
+
getField: (name)->
|
|
113
|
+
_( @getFields('name', name) ).first()
|
|
114
|
+
|
|
115
|
+
getFields: (attr,value)->
|
|
116
|
+
# do a deep search of all of the nested components
|
|
117
|
+
# to find the fields
|
|
118
|
+
fields = @select("isField", true, true)
|
|
119
|
+
|
|
120
|
+
# if an optional attribute and value pair is passed
|
|
121
|
+
# then you can limit the array of fields even further
|
|
122
|
+
if fields.length > 0 and attr and value
|
|
123
|
+
fields = _(fields).select (field)->
|
|
124
|
+
property = field[ attr ]
|
|
125
|
+
return false unless property?
|
|
126
|
+
propvalue = if _.isFunction(property) then property() else property
|
|
127
|
+
value is propvalue
|
|
128
|
+
|
|
129
|
+
fields
|
|
130
|
+
|
|
131
|
+
loadModel: (@current_model)->
|
|
132
|
+
form = @
|
|
133
|
+
fields = @getFields()
|
|
134
|
+
|
|
135
|
+
@trigger "before:load", @, @current_model
|
|
136
|
+
if @current_model
|
|
137
|
+
event = "before:load:#{ (if @current_model.isNew() then "new" else "existing")}"
|
|
138
|
+
@trigger event, @, @current_model
|
|
139
|
+
|
|
140
|
+
_( fields ).each (field) =>
|
|
141
|
+
field_name = field.input_name || field.name
|
|
142
|
+
value = if _.isFunction(@current_model[ field_name ]) then @current_model[field_name].apply(@, form) else @current_model.get( field_name )
|
|
143
|
+
field?.setValue( value ) unless field.readOnly is true
|
|
144
|
+
|
|
145
|
+
@trigger "after:load", @, @current_model
|
|
146
|
+
|
|
147
|
+
if @current_model
|
|
148
|
+
@trigger "after:load:#{ (if @current_model.isNew() then "new" else "existing")}", @, @current_model
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
reset: ()->
|
|
152
|
+
@loadModel( @current_model )
|
|
153
|
+
|
|
154
|
+
clear: ()->
|
|
155
|
+
@current_model = if @defaultModel? then @defaultModel() else undefined
|
|
156
|
+
|
|
157
|
+
_( @getFields() ).each (field)=>
|
|
158
|
+
try
|
|
159
|
+
field.setValue('')
|
|
160
|
+
catch e
|
|
161
|
+
console.log "Error Clearing", @, field
|
|
162
|
+
|
|
163
|
+
getValues: (reject_blank=false,skip_buttons=true)->
|
|
164
|
+
_( @getFields() ).inject (memo,field)->
|
|
165
|
+
value = field.getValue()
|
|
166
|
+
|
|
167
|
+
skip = false
|
|
168
|
+
skip = true if skip_buttons and field.ctype is "button_field"
|
|
169
|
+
skip = true if reject_blank and _.isBlank(value)
|
|
170
|
+
skip = true if field.input_name is "id" and _.isBlank(value)
|
|
171
|
+
|
|
172
|
+
memo[ field.input_name || name ] = value unless skip
|
|
173
|
+
|
|
174
|
+
memo
|
|
175
|
+
, {}
|
|
176
|
+
|
|
177
|
+
submit_success_handler: (model, response, xhr)->
|
|
178
|
+
@trigger "after:submit", @, model, response
|
|
179
|
+
|
|
180
|
+
if response and response.success
|
|
181
|
+
@trigger "after:submit:success", @, model, response
|
|
182
|
+
else
|
|
183
|
+
@trigger "after:submit:error", @, model, response
|
|
184
|
+
|
|
185
|
+
submit_fatal_error_handler: ()->
|
|
186
|
+
@trigger.apply ["after:submit", @].concat(arguments)
|
|
187
|
+
@trigger.apply ["after:submit:fatal_error", @].concat(arguments)
|
|
188
|
+
|
|
189
|
+
submit: (save=true, saveOptions={})->
|
|
190
|
+
_.bindAll @, "submit_success_handler", "submit_fatal_error_handler"
|
|
191
|
+
|
|
192
|
+
saveOptions.success ||= @submit_success_handler
|
|
193
|
+
saveOptions.error ||= @submit_fatal_error_handler
|
|
194
|
+
|
|
195
|
+
@current_model.set( @getValues() )
|
|
196
|
+
return unless save
|
|
197
|
+
@current_model.save( @current_model.toJSON(), saveOptions )
|
|
198
|
+
|
|
199
|
+
currentModel: ()->
|
|
200
|
+
@current_model
|
|
201
|
+
|
|
202
|
+
setLegend: (@legend)->
|
|
203
|
+
$('fieldset legend', @el).first().html(@legend)
|
|
204
|
+
|
|
205
|
+
Luca.register 'form_view', 'Luca.components.FormView'
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Luca.components.GridView = Luca.View.extend
|
|
2
|
+
events:
|
|
3
|
+
"dblclick .grid-view-row" : "double_click_handler"
|
|
4
|
+
"click .grid-view-row": "click_handler"
|
|
5
|
+
|
|
6
|
+
className: 'luca-ui-grid-view'
|
|
7
|
+
|
|
8
|
+
scrollable: true
|
|
9
|
+
|
|
10
|
+
emptyText: 'No Results To display'
|
|
11
|
+
|
|
12
|
+
# available options are striped, condensed, bordered
|
|
13
|
+
# or any combination of these, split up by space
|
|
14
|
+
tableStyle: 'striped'
|
|
15
|
+
|
|
16
|
+
hooks:[
|
|
17
|
+
"before:grid:render",
|
|
18
|
+
"before:render:header",
|
|
19
|
+
"before:render:row",
|
|
20
|
+
"after:grid:render",
|
|
21
|
+
"row:double:click",
|
|
22
|
+
"row:click",
|
|
23
|
+
"after:collection:load"
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
initialize: (@options={})->
|
|
27
|
+
_.extend @, @options
|
|
28
|
+
_.extend @, Luca.modules.Deferrable
|
|
29
|
+
|
|
30
|
+
Luca.View::initialize.apply( @, arguments )
|
|
31
|
+
|
|
32
|
+
_.bindAll @, "double_click_handler", "click_handler"
|
|
33
|
+
|
|
34
|
+
@configure_collection()
|
|
35
|
+
|
|
36
|
+
@collection.bind "reset", (collection) =>
|
|
37
|
+
@refresh()
|
|
38
|
+
@trigger "after:collection:load", collection
|
|
39
|
+
|
|
40
|
+
beforeRender: ()->
|
|
41
|
+
@trigger "before:grid:render", @
|
|
42
|
+
|
|
43
|
+
@$el.addClass 'scrollable-grid-view' if @scrollable
|
|
44
|
+
|
|
45
|
+
@$el.html Luca.templates["components/grid_view"]()
|
|
46
|
+
|
|
47
|
+
@table = $('table.luca-ui-grid-view', @el)
|
|
48
|
+
@header = $("thead", @table)
|
|
49
|
+
@body = $("tbody", @table)
|
|
50
|
+
@footer = $("tfoot", @table)
|
|
51
|
+
|
|
52
|
+
if Luca.enableBootstrap
|
|
53
|
+
@table.addClass('table')
|
|
54
|
+
|
|
55
|
+
_( @tableStyle?.split(" ") ).each (style)=>
|
|
56
|
+
@table.addClass("table-#{ style }")
|
|
57
|
+
|
|
58
|
+
@setDimensions() if @scrollable
|
|
59
|
+
|
|
60
|
+
@renderHeader()
|
|
61
|
+
|
|
62
|
+
@emptyMessage()
|
|
63
|
+
|
|
64
|
+
@renderToolbars()
|
|
65
|
+
|
|
66
|
+
$(@container).append @$el
|
|
67
|
+
|
|
68
|
+
toolbarContainers:(position="bottom")->
|
|
69
|
+
$(".toolbar-container.#{ position }", @el)
|
|
70
|
+
|
|
71
|
+
renderToolbars: ()->
|
|
72
|
+
_( @toolbars ).each (toolbar)=>
|
|
73
|
+
toolbar = Luca.util.lazyComponent(toolbar)
|
|
74
|
+
toolbar.container = @toolbarContainers( toolbar.position )
|
|
75
|
+
toolbar.render()
|
|
76
|
+
|
|
77
|
+
setDimensions: (offset)->
|
|
78
|
+
@height ||= 285
|
|
79
|
+
|
|
80
|
+
$('.grid-view-body', @el).height( @height )
|
|
81
|
+
$('tbody.scrollable', @el).height( @height - 23 )
|
|
82
|
+
|
|
83
|
+
@container_width = do => $(@container).width()
|
|
84
|
+
@width = if @container_width > 0 then @container_width else 756
|
|
85
|
+
|
|
86
|
+
#@width += offset if offset
|
|
87
|
+
|
|
88
|
+
$('.grid-view-body', @el).width( @width )
|
|
89
|
+
$('.grid-view-body table', @el).width( @width )
|
|
90
|
+
|
|
91
|
+
@setDefaultColumnWidths()
|
|
92
|
+
|
|
93
|
+
resize: (newWidth)->
|
|
94
|
+
difference = newWidth - @width
|
|
95
|
+
@width = newWidth
|
|
96
|
+
|
|
97
|
+
$('.grid-view-body', @el).width( @width )
|
|
98
|
+
$('.grid-view-body table', @el).width( @width )
|
|
99
|
+
|
|
100
|
+
if @columns.length > 0
|
|
101
|
+
distribution = difference / @columns.length
|
|
102
|
+
|
|
103
|
+
_(@columns).each (col,index)=>
|
|
104
|
+
column = $(".column-#{ index }", @el )
|
|
105
|
+
column.width( col.width = col.width + distribution )
|
|
106
|
+
|
|
107
|
+
padLastColumn: ()->
|
|
108
|
+
configured_column_widths = _(@columns).inject (sum, column)->
|
|
109
|
+
sum = (column.width) + sum
|
|
110
|
+
, 0
|
|
111
|
+
|
|
112
|
+
unused_width = @width - configured_column_widths
|
|
113
|
+
|
|
114
|
+
if unused_width > 0
|
|
115
|
+
@lastColumn().width += unused_width
|
|
116
|
+
|
|
117
|
+
setDefaultColumnWidths: ()->
|
|
118
|
+
default_column_width = if @columns.length > 0 then @width / @columns.length else 200
|
|
119
|
+
|
|
120
|
+
_( @columns ).each (column)->
|
|
121
|
+
parseInt(column.width ||= default_column_width)
|
|
122
|
+
|
|
123
|
+
@padLastColumn()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
lastColumn: ()->
|
|
127
|
+
@columns[ @columns.length - 1 ]
|
|
128
|
+
|
|
129
|
+
afterRender: ()->
|
|
130
|
+
@refresh()
|
|
131
|
+
@trigger "after:grid:render", @
|
|
132
|
+
|
|
133
|
+
emptyMessage: (text="")->
|
|
134
|
+
text ||= @emptyText
|
|
135
|
+
@body.html('')
|
|
136
|
+
@body.append Luca.templates["components/grid_view_empty_text"](colspan:@columns.length,text:text)
|
|
137
|
+
|
|
138
|
+
refresh: ()->
|
|
139
|
+
@body.html('')
|
|
140
|
+
@collection.each (model,index)=>
|
|
141
|
+
@render_row.apply(@, [model,index])
|
|
142
|
+
|
|
143
|
+
if @collection.models.length == 0
|
|
144
|
+
@emptyMessage()
|
|
145
|
+
|
|
146
|
+
ifLoaded: (fn, scope)->
|
|
147
|
+
scope ||= @
|
|
148
|
+
fn ||= ()-> true
|
|
149
|
+
|
|
150
|
+
@collection.ifLoaded(fn,scope)
|
|
151
|
+
|
|
152
|
+
applyFilter: (values, options={auto:true,refresh:true})->
|
|
153
|
+
@collection.applyFilter(values, options)
|
|
154
|
+
|
|
155
|
+
renderHeader: ()->
|
|
156
|
+
@trigger "before:render:header"
|
|
157
|
+
|
|
158
|
+
headers = _(@columns).map (column,column_index) =>
|
|
159
|
+
# temporary hack for scrollable grid dimensions.
|
|
160
|
+
style = if column.width then "width:#{ column.width }px;" else ""
|
|
161
|
+
|
|
162
|
+
"<th style='#{ style }' class='column-#{ column_index }'>#{ column.header}</th>"
|
|
163
|
+
|
|
164
|
+
@header.append("<tr>#{ headers }</tr>")
|
|
165
|
+
|
|
166
|
+
render_row: (row,row_index)->
|
|
167
|
+
model_id = if row?.get and row?.attributes then row.get('id') else ''
|
|
168
|
+
|
|
169
|
+
@trigger "before:render:row", row, row_index
|
|
170
|
+
|
|
171
|
+
cells = _( @columns ).map (column,col_index) =>
|
|
172
|
+
value = @cell_renderer(row, column, col_index)
|
|
173
|
+
style = if column.width then "width:#{ column.width }px;" else ""
|
|
174
|
+
|
|
175
|
+
display = if _.isUndefined(value) then "" else value
|
|
176
|
+
|
|
177
|
+
"<td style='#{ style }' class='column-#{ col_index }'>#{ display }</td>"
|
|
178
|
+
|
|
179
|
+
if @alternateRowClasses
|
|
180
|
+
alt_class = if row_index % 2 is 0 then "even" else "odd"
|
|
181
|
+
|
|
182
|
+
@body?.append("<tr data-record-id='#{ model_id }' data-row-index='#{ row_index }' class='grid-view-row #{ alt_class }' id='row-#{ row_index }'>#{ cells }</tr>")
|
|
183
|
+
|
|
184
|
+
cell_renderer: (row, column, columnIndex )->
|
|
185
|
+
if _.isFunction column.renderer
|
|
186
|
+
return column.renderer.apply @, [row,column,columnIndex]
|
|
187
|
+
else if column.data.match(/\w+\.\w+/)
|
|
188
|
+
source = row.attributes || row
|
|
189
|
+
return Luca.util.nestedValue( column.data, source )
|
|
190
|
+
else
|
|
191
|
+
return row.get?( column.data ) || row[ column.data ]
|
|
192
|
+
|
|
193
|
+
double_click_handler: (e)->
|
|
194
|
+
me = my = $( e.currentTarget )
|
|
195
|
+
rowIndex = my.data('row-index')
|
|
196
|
+
record = @collection.at( rowIndex )
|
|
197
|
+
@trigger "row:double:click", @, record, rowIndex
|
|
198
|
+
|
|
199
|
+
click_handler: (e)->
|
|
200
|
+
me = my = $( e.currentTarget )
|
|
201
|
+
rowIndex = my.data('row-index')
|
|
202
|
+
record = @collection.at( rowIndex )
|
|
203
|
+
@trigger "row:click", @, record, rowIndex
|
|
204
|
+
|
|
205
|
+
$('.grid-view-row', @body ).removeClass('selected-row')
|
|
206
|
+
me.addClass('selected-row')
|
|
207
|
+
|
|
208
|
+
Luca.register "grid_view","Luca.components.GridView"
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# The RecordManager is a high level component which incorporates
|
|
2
|
+
# a filterable grid, and an editor form responsible for editing
|
|
3
|
+
# the records in that grid.
|
|
4
|
+
#
|
|
5
|
+
# it provides convenience methods for accesing those components.
|
|
6
|
+
#
|
|
7
|
+
# this represents a clean pattern for having multiple components
|
|
8
|
+
# which work together. inter-component communication should be handled
|
|
9
|
+
# by parent containers, and not individual components, which should
|
|
10
|
+
# usually not be aware of other components.
|
|
11
|
+
|
|
12
|
+
# Work in progress
|
|
13
|
+
Luca.components.RecordManager = Luca.containers.CardView.extend
|
|
14
|
+
|
|
15
|
+
events:
|
|
16
|
+
"click .record-manager-grid .edit-link" : "edit_handler"
|
|
17
|
+
"click .record-manager-filter .filter-button" : "filter_handler"
|
|
18
|
+
"click .record-manager-filter .reset-button" : "reset_filter_handler"
|
|
19
|
+
"click .add-button" : "add_handler"
|
|
20
|
+
"click .refresh-button" : "filter_handler"
|
|
21
|
+
"click .back-to-search-button" : "back_to_search_handler"
|
|
22
|
+
|
|
23
|
+
record_manager: true
|
|
24
|
+
|
|
25
|
+
initialize: (@options={})->
|
|
26
|
+
Luca.containers.CardView::initialize.apply @, arguments
|
|
27
|
+
|
|
28
|
+
throw "Record Managers must specify a name" unless @name
|
|
29
|
+
|
|
30
|
+
_.bindAll @, "add_handler", "edit_handler", "filter_handler", "reset_filter_handler"
|
|
31
|
+
|
|
32
|
+
_.extend @components[0][0], @filterConfig if @filterConfig
|
|
33
|
+
_.extend @components[0][1], @gridConfig if @gridConfig
|
|
34
|
+
_.extend @components[1][0], @editorConfig if @editorConfig
|
|
35
|
+
|
|
36
|
+
@bind "after:card:switch", () =>
|
|
37
|
+
@trigger("activation:search", @) if @activeCard is 0
|
|
38
|
+
@trigger("activation:editor", @) if @activeCard is 1
|
|
39
|
+
|
|
40
|
+
components:[
|
|
41
|
+
ctype: 'split_view',
|
|
42
|
+
relayFirstActivation: true
|
|
43
|
+
components:[
|
|
44
|
+
ctype: 'form_view'
|
|
45
|
+
,
|
|
46
|
+
ctype: 'grid_view'
|
|
47
|
+
]
|
|
48
|
+
,
|
|
49
|
+
ctype: 'form_view'
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
getSearch: (activate=false, reset=true)->
|
|
53
|
+
@activate(0) if activate is true
|
|
54
|
+
@getEditor().clear() if reset is true
|
|
55
|
+
|
|
56
|
+
_.first(@components)
|
|
57
|
+
|
|
58
|
+
getFilter: ()->
|
|
59
|
+
_.first @getSearch().components
|
|
60
|
+
|
|
61
|
+
getGrid: ()->
|
|
62
|
+
_.last @getSearch().components
|
|
63
|
+
|
|
64
|
+
getCollection: ()->
|
|
65
|
+
@getGrid().collection
|
|
66
|
+
|
|
67
|
+
getEditor: (activate=false,reset=false)->
|
|
68
|
+
if activate is true
|
|
69
|
+
@activate 1, (activator,previous,current)=>
|
|
70
|
+
current.reset()
|
|
71
|
+
|
|
72
|
+
_.last(@components)
|
|
73
|
+
|
|
74
|
+
beforeRender: ()->
|
|
75
|
+
@$el.addClass("#{ @resource }-manager")
|
|
76
|
+
Luca.containers.CardView::beforeRender?.apply @, arguments
|
|
77
|
+
|
|
78
|
+
@$el.addClass("#{ @resource } record-manager")
|
|
79
|
+
@$el.data('resource', @resource)
|
|
80
|
+
|
|
81
|
+
$(@getGrid().el).addClass("#{ @resource } record-manager-grid")
|
|
82
|
+
$(@getFilter().el).addClass("#{ @resource } record-manager-filter")
|
|
83
|
+
$(@getEditor().el).addClass("#{ @resource } record-manager-editor")
|
|
84
|
+
|
|
85
|
+
# This is an example of a best practice from ExtJS
|
|
86
|
+
# that we incorporate in Luca, which is that container
|
|
87
|
+
# components are responsible for component communication.
|
|
88
|
+
#
|
|
89
|
+
# child components should not be aware of other components
|
|
90
|
+
# in the layout. Their parents should be responsible for
|
|
91
|
+
# controlling how they interact. listening to events on one,
|
|
92
|
+
# changing state, inducing effects in the others
|
|
93
|
+
afterRender: ()->
|
|
94
|
+
Luca.containers.CardView::afterRender?.apply @, arguments
|
|
95
|
+
|
|
96
|
+
manager = @
|
|
97
|
+
grid = @getGrid()
|
|
98
|
+
filter = @getFilter()
|
|
99
|
+
editor = @getEditor()
|
|
100
|
+
collection = @getCollection()
|
|
101
|
+
|
|
102
|
+
# when a row is double clicked on the grid
|
|
103
|
+
# then we edit that row
|
|
104
|
+
grid.bind "row:double:click", (grid,model,index)->
|
|
105
|
+
manager.getEditor(true)
|
|
106
|
+
editor.loadModel( model )
|
|
107
|
+
|
|
108
|
+
editor.bind "before:submit", ()=>
|
|
109
|
+
$('.form-view-flash-container', @el).html('')
|
|
110
|
+
$('.form-view-body', @el).spin("large")
|
|
111
|
+
|
|
112
|
+
editor.bind "after:submit", ()=>
|
|
113
|
+
$('.form-view-body', @el).spin(false)
|
|
114
|
+
|
|
115
|
+
editor.bind "after:submit:fatal_error", ()=>
|
|
116
|
+
$('.form-view-flash-container', @el ).append "<li class='error'>There was an internal server error saving this record. Please contact developers@benchprep.com to report this error.</li>"
|
|
117
|
+
$('.form-view-body', @el).spin(false)
|
|
118
|
+
|
|
119
|
+
editor.bind "after:submit:error", (form, model, response)=>
|
|
120
|
+
_( response.errors ).each (error)=>
|
|
121
|
+
$('.form-view-flash-container', @el ).append "<li class='error'>#{ error }</li>"
|
|
122
|
+
|
|
123
|
+
editor.bind "after:submit:success", (form, model, response)=>
|
|
124
|
+
$('.form-view-flash-container', @el).append "<li class='success'>Successfully Saved Record</li>"
|
|
125
|
+
|
|
126
|
+
model.set( response.result )
|
|
127
|
+
form.loadModel( model )
|
|
128
|
+
|
|
129
|
+
grid.refresh()
|
|
130
|
+
|
|
131
|
+
_.delay ()=>
|
|
132
|
+
$('.form-view-flash-container li.success', @el).fadeOut(1000)
|
|
133
|
+
$('.form-view-flash-container', @el).html('')
|
|
134
|
+
, 4000
|
|
135
|
+
|
|
136
|
+
filter.eachComponent (component)=>
|
|
137
|
+
try
|
|
138
|
+
component.bind "on:change", @filter_handler
|
|
139
|
+
catch e
|
|
140
|
+
undefined
|
|
141
|
+
|
|
142
|
+
firstActivation: ()->
|
|
143
|
+
@getGrid().trigger "first:activation", @, @getGrid()
|
|
144
|
+
@getFilter().trigger "first:activation", @, @getGrid()
|
|
145
|
+
|
|
146
|
+
reload: ()->
|
|
147
|
+
manager = @
|
|
148
|
+
|
|
149
|
+
grid = @getGrid()
|
|
150
|
+
filter = @getFilter()
|
|
151
|
+
editor = @getEditor()
|
|
152
|
+
|
|
153
|
+
# refresh the select fields in the filter
|
|
154
|
+
filter.clear()
|
|
155
|
+
|
|
156
|
+
grid.applyFilter()
|
|
157
|
+
|
|
158
|
+
manageRecord: (record_id)->
|
|
159
|
+
model = @getCollection().get(record_id)
|
|
160
|
+
return @loadModel(model) if model
|
|
161
|
+
|
|
162
|
+
console.log "Could Not Find Model, building and fetching"
|
|
163
|
+
|
|
164
|
+
model = @buildModel()
|
|
165
|
+
model.set({id:record_id},{silent:true})
|
|
166
|
+
|
|
167
|
+
model.fetch
|
|
168
|
+
success: (model,response)=>
|
|
169
|
+
@loadModel(model)
|
|
170
|
+
|
|
171
|
+
loadModel: (@current_model)->
|
|
172
|
+
@getEditor(true).loadModel( @current_model )
|
|
173
|
+
@trigger "model:loaded", @current_model
|
|
174
|
+
|
|
175
|
+
currentModel: ()->
|
|
176
|
+
@getEditor(false).currentModel()
|
|
177
|
+
|
|
178
|
+
buildModel: ()->
|
|
179
|
+
editor = @getEditor(false)
|
|
180
|
+
collection = @getCollection()
|
|
181
|
+
|
|
182
|
+
collection.add([{}], silent:true, at: 0)
|
|
183
|
+
|
|
184
|
+
model = collection.at(0)
|
|
185
|
+
|
|
186
|
+
createModel: ()->
|
|
187
|
+
@loadModel(@buildModel())
|
|
188
|
+
|
|
189
|
+
##### DOM Event Handlers
|
|
190
|
+
reset_filter_handler: (e)->
|
|
191
|
+
@getFilter().clear()
|
|
192
|
+
@getGrid().applyFilter( @getFilter().getValues() )
|
|
193
|
+
|
|
194
|
+
filter_handler: (e)->
|
|
195
|
+
@getGrid().applyFilter( @getFilter().getValues() )
|
|
196
|
+
|
|
197
|
+
edit_handler: (e)->
|
|
198
|
+
me = my = $( e.currentTarget )
|
|
199
|
+
record_id = my.parents('tr').data('record-id')
|
|
200
|
+
|
|
201
|
+
if record_id
|
|
202
|
+
model = @getGrid().collection.get( record_id )
|
|
203
|
+
|
|
204
|
+
model ||= @getGrid().collection.at( row_index )
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
add_handler: (e)->
|
|
208
|
+
me = my = $( e.currentTarget )
|
|
209
|
+
resource = my.parents('.record-manager').eq(0).data('resource')
|
|
210
|
+
|
|
211
|
+
destroy_handler: (e)->
|
|
212
|
+
#destroy handler
|
|
213
|
+
|
|
214
|
+
back_to_search_handler: ()->
|
|
215
|
+
# search handler
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Luca.Router = Backbone.Router.extend
|
|
2
|
+
routes:
|
|
3
|
+
"" : "default"
|
|
4
|
+
|
|
5
|
+
initialize: (@options)->
|
|
6
|
+
_.extend @, @options
|
|
7
|
+
|
|
8
|
+
@routeHandlers = _( @routes ).values()
|
|
9
|
+
|
|
10
|
+
# when a route handler is fired, the route:route_name event is triggered by the router
|
|
11
|
+
# unfortunately this doesn't apply to calls to @navigate() so we override Backbone.Router.navigate
|
|
12
|
+
# and trigger an event separately.
|
|
13
|
+
_( @routeHandlers ).each (route_id) =>
|
|
14
|
+
@bind "route:#{ route_id }", ()=>
|
|
15
|
+
@trigger.apply @, ["change:navigation", route_id ].concat( _( arguments ).flatten() )
|
|
16
|
+
|
|
17
|
+
#### Router Functions
|
|
18
|
+
|
|
19
|
+
# Intercept calls to Backbone.Router.navigate so that we can at least
|
|
20
|
+
# build a path from the route, even if we don't trigger the route handler
|
|
21
|
+
navigate: (route, triggerRoute=false)->
|
|
22
|
+
Backbone.Router.prototype.navigate.apply @, arguments
|
|
23
|
+
@buildPathFrom( Backbone.history.getFragment() )
|
|
24
|
+
|
|
25
|
+
# given a url fragment, construct an argument chain similar to what would be
|
|
26
|
+
# emitted from a normal route:#{ name } event that gets triggered
|
|
27
|
+
# when a route is actually fired. This is used to trap route changes that happen
|
|
28
|
+
# through calls to @navigate()
|
|
29
|
+
buildPathFrom: (matchedRoute)->
|
|
30
|
+
_(@routes).each (route_id, route)=>
|
|
31
|
+
regex = @_routeToRegExp(route)
|
|
32
|
+
if regex.test(matchedRoute)
|
|
33
|
+
args = @_extractParameters(regex, matchedRoute)
|
|
34
|
+
@trigger.apply @, ["change:navigation", route_id].concat( args )
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Luca.components.Template = Luca.View.extend
|
|
2
|
+
initialize: (@options={})->
|
|
3
|
+
Luca.View::initialize.apply @, arguments
|
|
4
|
+
throw "Templates must specify which template / markup to use" unless @template or @markup
|
|
5
|
+
|
|
6
|
+
if _.isString(@templateContainer)
|
|
7
|
+
@templateContainer = eval("(window || global).#{ @templateContainer }")
|
|
8
|
+
|
|
9
|
+
templateContainer: "Luca.templates"
|
|
10
|
+
|
|
11
|
+
beforeRender: ()->
|
|
12
|
+
@templateContainer = JST if _.isUndefined( @templateContainer)
|
|
13
|
+
@$el.html(@markup || @templateContainer[ @template ](@options) )
|
|
14
|
+
|
|
15
|
+
render: ()->
|
|
16
|
+
$(@container).append( @$el )
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
Luca.register "template", "Luca.components.Template"
|