luca 0.7.92 → 0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/assets/javascripts/luca-ui-base.coffee +1 -0
- data/lib/luca/rails/version.rb +1 -1
- data/spec/components/form_view_spec.coffee +1 -136
- data/spec/core/model_spec.coffee +50 -0
- data/src/components/development_console.coffee +1 -0
- data/src/components/fields/text_field.coffee +1 -0
- data/src/components/grid_view.coffee +3 -0
- data/src/core/model.coffee +28 -0
- data/src/core/view.coffee +10 -2
- data/src/framework.coffee +1 -1
- data/src/templates/fields/text_field.luca +1 -1
- data/vendor/assets/javascripts/luca-ui-base.js +48 -5
- data/vendor/assets/javascripts/luca-ui-spec.js +132 -183
- data/vendor/assets/javascripts/luca-ui.js +53 -5
- data/vendor/assets/javascripts/luca-ui.min.js +3 -3
- metadata +4 -2
data/lib/luca/rails/version.rb
CHANGED
@@ -71,139 +71,4 @@ describe 'The Form View', ->
|
|
71
71
|
@form.render()
|
72
72
|
@form.loadModel(@model)
|
73
73
|
@form.setValues(field1:"yes")
|
74
|
-
expect( @form.getValues().field1 ).toEqual "yes"
|
75
|
-
|
76
|
-
describe "Loading A New Model", ->
|
77
|
-
beforeEach ->
|
78
|
-
@form.spiedEvents = {}
|
79
|
-
@form.render()
|
80
|
-
@model.beforeFormLoad = sinon.spy()
|
81
|
-
@form.loadModel(@model)
|
82
|
-
|
83
|
-
it "should call before form load", ->
|
84
|
-
expect( @model.beforeFormLoad ).toHaveBeenCalled()
|
85
|
-
|
86
|
-
it "should have triggered before load", ->
|
87
|
-
expect( @form ).toHaveTriggered("before:load")
|
88
|
-
|
89
|
-
it "should have triggered after load", ->
|
90
|
-
expect( @form ).toHaveTriggered("after:load")
|
91
|
-
|
92
|
-
it "should have triggered before:load:new", ->
|
93
|
-
expect( @form ).toHaveTriggered("before:load:new")
|
94
|
-
|
95
|
-
it "should have triggered after:load:new", ->
|
96
|
-
expect( @form ).toHaveTriggered("after:load:new")
|
97
|
-
|
98
|
-
describe "Loading An Existing Model", ->
|
99
|
-
beforeEach ->
|
100
|
-
@form.spiedEvents = {}
|
101
|
-
@form.render()
|
102
|
-
@model.set(id:"one")
|
103
|
-
@model.beforeFormLoad = sinon.spy()
|
104
|
-
@form.loadModel(@model)
|
105
|
-
|
106
|
-
it "should call before form load", ->
|
107
|
-
expect( @model.beforeFormLoad ).toHaveBeenCalled()
|
108
|
-
|
109
|
-
it "should have triggered before:load:existing", ->
|
110
|
-
expect( @form ).toHaveTriggered("before:load:existing")
|
111
|
-
|
112
|
-
it "should have triggered after:load:new", ->
|
113
|
-
expect( @form ).toHaveTriggered("after:load:existing")
|
114
|
-
|
115
|
-
it "should apply the form values in the currentModel call if specified", ->
|
116
|
-
@form.getField("field1").setValue("sup baby?")
|
117
|
-
expect( @form.currentModel().get("field1") ).not.toEqual("sup baby?")
|
118
|
-
@form.getField("field1").setValue("sup baby boo?")
|
119
|
-
expect( @form.currentModel(refresh:false).get("field1") ).not.toEqual("sup baby boo?")
|
120
|
-
expect( @form.currentModel(refresh:true).get("field1") ).toEqual("sup baby boo?")
|
121
|
-
|
122
|
-
describe "The Fields Accessors", ->
|
123
|
-
beforeEach ->
|
124
|
-
@form.render()
|
125
|
-
|
126
|
-
it "should provide access to fields", ->
|
127
|
-
expect( @form.getFields().length ).toEqual 6
|
128
|
-
|
129
|
-
it "should allow me to access a field by its name",->
|
130
|
-
expect( @form.getField("field1") ).toBeDefined()
|
131
|
-
|
132
|
-
describe "The Set Values Function", ->
|
133
|
-
beforeEach ->
|
134
|
-
@form.render()
|
135
|
-
@form.loadModel(@model)
|
136
|
-
|
137
|
-
it "should set the values on the field", ->
|
138
|
-
@form.setValues({field1:"andyadontstop"})
|
139
|
-
expect( @form.getField("field1").getValue() ).toEqual "andyadontstop"
|
140
|
-
|
141
|
-
it "should set the values on the model", ->
|
142
|
-
@form.setValues(field1:"krs-one")
|
143
|
-
expect( @form.getField("field1").getValue() ).toEqual "krs-one"
|
144
|
-
expect( @model.get("field1") ).toEqual "krs-one"
|
145
|
-
|
146
|
-
it "should skip syncing with the model if passed silent", ->
|
147
|
-
@form.setValues({field1:"yesyesyall"},silent:true)
|
148
|
-
expect( @form.getField("field1").getValue() ).toEqual "yesyesyall"
|
149
|
-
expect( @model.get("field1") ).not.toEqual "yesyesyall"
|
150
|
-
|
151
|
-
describe "The Get Values Function", ->
|
152
|
-
beforeEach ->
|
153
|
-
@model.set(field1:"one",field2:"two",field3:undefined,field4:"")
|
154
|
-
@form.render()
|
155
|
-
@form.loadModel(@model)
|
156
|
-
@values = @form.getValues()
|
157
|
-
|
158
|
-
it "should skip the button fields by default", ->
|
159
|
-
expect( _(@values).keys() ).not.toContain("field5")
|
160
|
-
|
161
|
-
it "should include the button fields if asked", ->
|
162
|
-
values = @form.getValues(skip_buttons:false)
|
163
|
-
expect( _(values).keys() ).toContain("field5")
|
164
|
-
|
165
|
-
it "should skip blank fields by default", ->
|
166
|
-
values = @form.getValues()
|
167
|
-
expect( _(values).keys() ).not.toContain("field4")
|
168
|
-
|
169
|
-
it "should include blank fields if asked", ->
|
170
|
-
values = @form.getValues(reject_blank:false)
|
171
|
-
expect( _(values).keys() ).toContain("field4")
|
172
|
-
|
173
|
-
it "should skip blank id fields", ->
|
174
|
-
expect( _(@values).keys() ).not.toContain("id")
|
175
|
-
|
176
|
-
describe "Events", ->
|
177
|
-
beforeEach ->
|
178
|
-
@form.render()
|
179
|
-
@form.loadModel(@model)
|
180
|
-
|
181
|
-
describe "Submit Handlers", ->
|
182
|
-
beforeEach ->
|
183
|
-
@form.spiedEvents = {}
|
184
|
-
|
185
|
-
it "should trigger after submit events", ->
|
186
|
-
@form.submit_success_handler(@model,success:true)
|
187
|
-
expect( @form ).toHaveTriggered("after:submit")
|
188
|
-
expect( @form ).toHaveTriggered("after:submit:success")
|
189
|
-
|
190
|
-
it "should trigger after submit error events", ->
|
191
|
-
@form.submit_success_handler(@model,success:false)
|
192
|
-
expect( @form ).toHaveTriggered("after:submit")
|
193
|
-
expect( @form ).toHaveTriggered("after:submit:error")
|
194
|
-
|
195
|
-
it "should trigger fatal error events", ->
|
196
|
-
@form.submit_fatal_error_handler()
|
197
|
-
expect( @form ).toHaveTriggered("after:submit")
|
198
|
-
expect( @form ).toHaveTriggered("after:submit:fatal_error")
|
199
|
-
|
200
|
-
describe "Resetting the Form", ->
|
201
|
-
it "should trigger before and after reset", ->
|
202
|
-
@form.resetHandler(currentTarget:1)
|
203
|
-
expect( @form ).toHaveTriggered "before:reset"
|
204
|
-
expect( @form ).toHaveTriggered "after:reset"
|
205
|
-
|
206
|
-
it "should call reset", ->
|
207
|
-
@form.reset = sinon.spy()
|
208
|
-
@form.resetHandler(currentTarget:1)
|
209
|
-
expect( @form.reset ).toHaveBeenCalled()
|
74
|
+
expect( @form.getValues().field1 ).toEqual "yes"
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#### Luca.Model
|
2
|
+
describe "Luca.Model with computed attribute", ->
|
3
|
+
App =
|
4
|
+
models: {}
|
5
|
+
|
6
|
+
App.models.Sample = Luca.Model.extend
|
7
|
+
computed:
|
8
|
+
fullName: ['firstName', 'lastName']
|
9
|
+
|
10
|
+
fullName: ()->
|
11
|
+
"#{@get("firstName")} #{@get("lastName")}"
|
12
|
+
|
13
|
+
App.models.SampleWithoutCallback = Luca.Model.extend
|
14
|
+
computed:
|
15
|
+
fullName: ['firstName', 'lastName']
|
16
|
+
|
17
|
+
it "should have it undefined if dependences are not set", ->
|
18
|
+
model = new App.models.Sample
|
19
|
+
expect(model.get("fullName")).toEqual(undefined)
|
20
|
+
|
21
|
+
it "should have it undefined if callback function is not present", ->
|
22
|
+
model = new App.models.SampleWithoutCallback
|
23
|
+
expect(model.get("fullName")).toEqual(undefined)
|
24
|
+
|
25
|
+
it "should not call it's callback if dependences are not set", ->
|
26
|
+
model = new App.models.Sample
|
27
|
+
spy = sinon.spy(model, "fullName")
|
28
|
+
expect( spy.called ).toEqual(false)
|
29
|
+
|
30
|
+
it "should not call it's callback if dependencies stay the same", ->
|
31
|
+
model = new App.models.Sample
|
32
|
+
model.set({firstName:"Nickolay", lastName: "Schwarz"})
|
33
|
+
spy = sinon.spy(model, "fullName")
|
34
|
+
model.set({lastName: "Schwarz"})
|
35
|
+
expect( spy.called ).toEqual(false)
|
36
|
+
|
37
|
+
it "should call it's callback when dependencies change", ->
|
38
|
+
model = new App.models.Sample
|
39
|
+
spy = sinon.spy(model, "fullName")
|
40
|
+
model.set({firstName:"Nickolay"})
|
41
|
+
expect( spy.called ).toEqual(true)
|
42
|
+
|
43
|
+
it "should be gettable as a value of the callback", ->
|
44
|
+
model = new App.models.Sample
|
45
|
+
model.set({firstName:"Nickolay", lastName: "Schwarz"})
|
46
|
+
expect(model.get("fullName")).toEqual(model.fullName())
|
47
|
+
|
48
|
+
it "should have it set on constructor if dependencies are supplied", ->
|
49
|
+
model = new App.models.Sample({firstName:"Nickolay", lastName: "Schwarz"})
|
50
|
+
expect(model.get("fullName")).toEqual('Nickolay Schwarz')
|
@@ -163,6 +163,9 @@ Luca.components.GridView = Luca.View.extend
|
|
163
163
|
|
164
164
|
@header.append("<tr>#{ headers }</tr>")
|
165
165
|
|
166
|
+
getRowEl: (id)->
|
167
|
+
@$ "[data-record-id=#{ id }]", 'table'
|
168
|
+
|
166
169
|
render_row: (row,row_index)->
|
167
170
|
model_id = if row?.get and row?.attributes then row.get('id') else ''
|
168
171
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Luca.Model
|
2
|
+
#
|
3
|
+
# Luca.Model is an extenstion of Backbone.Model which provides
|
4
|
+
# few useful patterns:
|
5
|
+
#
|
6
|
+
# - computed properties support
|
7
|
+
Luca.Model = Backbone.Model.extend
|
8
|
+
initialize: ()->
|
9
|
+
Backbone.Model::initialize @, arguments
|
10
|
+
|
11
|
+
return if _.isUndefined(@computed)
|
12
|
+
|
13
|
+
@_computed = {}
|
14
|
+
|
15
|
+
for attr, dependencies of @computed
|
16
|
+
@on "change:#{attr}", ()=>
|
17
|
+
@_computed[attr] = @[attr].call @
|
18
|
+
|
19
|
+
_(dependencies).each (dep)=>
|
20
|
+
@on "change:#{dep}", ()=>
|
21
|
+
@trigger "change:#{attr}"
|
22
|
+
@trigger "change:#{attr}" if @has(dep)
|
23
|
+
|
24
|
+
get: (attr)->
|
25
|
+
if @computed?.hasOwnProperty(attr)
|
26
|
+
@_computed[attr]
|
27
|
+
else
|
28
|
+
Backbone.Model::get.call @, attr
|
data/src/core/view.coffee
CHANGED
@@ -30,10 +30,9 @@ Luca.View.extend = (definition)->
|
|
30
30
|
|
31
31
|
return @ unless $(container) and @$el
|
32
32
|
|
33
|
-
|
34
33
|
$(container).append( @$el )
|
35
|
-
@
|
36
34
|
|
35
|
+
return @
|
37
36
|
|
38
37
|
definition.render = ()->
|
39
38
|
if @deferrable
|
@@ -56,11 +55,15 @@ Luca.View.extend = (definition)->
|
|
56
55
|
@bind @deferrable_trigger, _.once ()=>
|
57
56
|
@deferrable.fetch()
|
58
57
|
|
58
|
+
return @
|
59
|
+
|
59
60
|
else
|
60
61
|
@trigger "before:render", @
|
61
62
|
_base.apply(@, arguments)
|
62
63
|
@trigger "after:render", @
|
63
64
|
|
65
|
+
return @
|
66
|
+
|
64
67
|
Luca.View.originalExtend.apply @, [definition]
|
65
68
|
|
66
69
|
_.extend Luca.View.prototype,
|
@@ -190,3 +193,8 @@ _.extend Luca.View.prototype,
|
|
190
193
|
catch e
|
191
194
|
console.log "Error Binding To Collection in registerCollectionEvents", @
|
192
195
|
throw e
|
196
|
+
|
197
|
+
registerEvent: (selector, handler)->
|
198
|
+
@events ||= {}
|
199
|
+
@events[ selector ] = handler
|
200
|
+
@delegateEvents()
|
data/src/framework.coffee
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
%span.add-on
|
6
6
|
<%= addOn %>
|
7
7
|
<% } %>
|
8
|
-
%input{:style=>"<%= inputStyles %>",:id=>"<%= input_id %>",:type=>"text",:name=>"<%= input_name %>",:placeholder=>"<%= placeHolder %>"}
|
8
|
+
%input{:style=>"<%= inputStyles %>",:id=>"<%= input_id %>",:type=>"text",:name=>"<%= input_name %>",:placeholder=>"<%= placeHolder %>", :class=>"<%= input_class %>"}
|
9
9
|
|
10
10
|
<% if(helperText) { %>
|
11
11
|
%p.helper-text.help-block
|
@@ -3,7 +3,7 @@
|
|
3
3
|
_.mixin(_.string);
|
4
4
|
|
5
5
|
window.Luca = {
|
6
|
-
VERSION: "0.
|
6
|
+
VERSION: "0.8",
|
7
7
|
core: {},
|
8
8
|
containers: {},
|
9
9
|
components: {},
|
@@ -288,7 +288,7 @@
|
|
288
288
|
}).call(this);
|
289
289
|
(function() {
|
290
290
|
Luca.templates || (Luca.templates = {});
|
291
|
-
Luca.templates["fields/text_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label class=\'control-label\' for=\'', input_id ,'\'>\n ', label ,'\n</label>\n'); if( typeof(addOn) !== "undefined" ) { __p.push('\n<span class=\'add-on\'>\n ', addOn ,'\n</span>\n'); } __p.push('\n<input id=\'', input_id ,'\' name=\'', input_name ,'\' placeholder=\'', placeHolder ,'\' style=\'', inputStyles ,'\' type=\'text\' />\n'); if(helperText) { __p.push('\n<p class=\'helper-text help-block\'>\n ', helperText ,'\n</p>\n'); } __p.push('\n');}return __p.join('');};
|
291
|
+
Luca.templates["fields/text_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label class=\'control-label\' for=\'', input_id ,'\'>\n ', label ,'\n</label>\n'); if( typeof(addOn) !== "undefined" ) { __p.push('\n<span class=\'add-on\'>\n ', addOn ,'\n</span>\n'); } __p.push('\n<input class=\'', input_class ,'\' id=\'', input_id ,'\' name=\'', input_name ,'\' placeholder=\'', placeHolder ,'\' style=\'', inputStyles ,'\' type=\'text\' />\n'); if(helperText) { __p.push('\n<p class=\'helper-text help-block\'>\n ', helperText ,'\n</p>\n'); } __p.push('\n');}return __p.join('');};
|
292
292
|
}).call(this);
|
293
293
|
(function() {
|
294
294
|
Luca.templates || (Luca.templates = {});
|
@@ -368,16 +368,18 @@
|
|
368
368
|
}));
|
369
369
|
if (!this.deferrable_trigger) this.immediate_trigger = true;
|
370
370
|
if (this.immediate_trigger === true) {
|
371
|
-
|
371
|
+
this.deferrable.fetch();
|
372
372
|
} else {
|
373
|
-
|
373
|
+
this.bind(this.deferrable_trigger, _.once(function() {
|
374
374
|
return _this.deferrable.fetch();
|
375
375
|
}));
|
376
376
|
}
|
377
|
+
return this;
|
377
378
|
} else {
|
378
379
|
this.trigger("before:render", this);
|
379
380
|
_base.apply(this, arguments);
|
380
|
-
|
381
|
+
this.trigger("after:render", this);
|
382
|
+
return this;
|
381
383
|
}
|
382
384
|
};
|
383
385
|
return Luca.View.originalExtend.apply(this, [definition]);
|
@@ -464,6 +466,47 @@
|
|
464
466
|
throw e;
|
465
467
|
}
|
466
468
|
});
|
469
|
+
},
|
470
|
+
registerEvent: function(selector, handler) {
|
471
|
+
this.events || (this.events = {});
|
472
|
+
this.events[selector] = handler;
|
473
|
+
return this.delegateEvents();
|
474
|
+
}
|
475
|
+
});
|
476
|
+
|
477
|
+
}).call(this);
|
478
|
+
(function() {
|
479
|
+
|
480
|
+
Luca.Model = Backbone.Model.extend({
|
481
|
+
initialize: function() {
|
482
|
+
var attr, dependencies, _ref, _results,
|
483
|
+
_this = this;
|
484
|
+
Backbone.Model.prototype.initialize(this, arguments);
|
485
|
+
if (_.isUndefined(this.computed)) return;
|
486
|
+
this._computed = {};
|
487
|
+
_ref = this.computed;
|
488
|
+
_results = [];
|
489
|
+
for (attr in _ref) {
|
490
|
+
dependencies = _ref[attr];
|
491
|
+
this.on("change:" + attr, function() {
|
492
|
+
return _this._computed[attr] = _this[attr].call(_this);
|
493
|
+
});
|
494
|
+
_results.push(_(dependencies).each(function(dep) {
|
495
|
+
_this.on("change:" + dep, function() {
|
496
|
+
return _this.trigger("change:" + attr);
|
497
|
+
});
|
498
|
+
if (_this.has(dep)) return _this.trigger("change:" + attr);
|
499
|
+
}));
|
500
|
+
}
|
501
|
+
return _results;
|
502
|
+
},
|
503
|
+
get: function(attr) {
|
504
|
+
var _ref;
|
505
|
+
if ((_ref = this.computed) != null ? _ref.hasOwnProperty(attr) : void 0) {
|
506
|
+
return this._computed[attr];
|
507
|
+
} else {
|
508
|
+
return Backbone.Model.prototype.get.call(this, attr);
|
509
|
+
}
|
467
510
|
}
|
468
511
|
});
|
469
512
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
_.mixin(_.string);
|
4
4
|
|
5
5
|
window.Luca = {
|
6
|
-
VERSION: "0.
|
6
|
+
VERSION: "0.8",
|
7
7
|
core: {},
|
8
8
|
containers: {},
|
9
9
|
components: {},
|
@@ -288,7 +288,7 @@
|
|
288
288
|
}).call(this);
|
289
289
|
(function() {
|
290
290
|
Luca.templates || (Luca.templates = {});
|
291
|
-
Luca.templates["fields/text_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label class=\'control-label\' for=\'', input_id ,'\'>\n ', label ,'\n</label>\n'); if( typeof(addOn) !== "undefined" ) { __p.push('\n<span class=\'add-on\'>\n ', addOn ,'\n</span>\n'); } __p.push('\n<input id=\'', input_id ,'\' name=\'', input_name ,'\' placeholder=\'', placeHolder ,'\' style=\'', inputStyles ,'\' type=\'text\' />\n'); if(helperText) { __p.push('\n<p class=\'helper-text help-block\'>\n ', helperText ,'\n</p>\n'); } __p.push('\n');}return __p.join('');};
|
291
|
+
Luca.templates["fields/text_field"] = function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('<label class=\'control-label\' for=\'', input_id ,'\'>\n ', label ,'\n</label>\n'); if( typeof(addOn) !== "undefined" ) { __p.push('\n<span class=\'add-on\'>\n ', addOn ,'\n</span>\n'); } __p.push('\n<input class=\'', input_class ,'\' id=\'', input_id ,'\' name=\'', input_name ,'\' placeholder=\'', placeHolder ,'\' style=\'', inputStyles ,'\' type=\'text\' />\n'); if(helperText) { __p.push('\n<p class=\'helper-text help-block\'>\n ', helperText ,'\n</p>\n'); } __p.push('\n');}return __p.join('');};
|
292
292
|
}).call(this);
|
293
293
|
(function() {
|
294
294
|
Luca.templates || (Luca.templates = {});
|
@@ -368,16 +368,18 @@
|
|
368
368
|
}));
|
369
369
|
if (!this.deferrable_trigger) this.immediate_trigger = true;
|
370
370
|
if (this.immediate_trigger === true) {
|
371
|
-
|
371
|
+
this.deferrable.fetch();
|
372
372
|
} else {
|
373
|
-
|
373
|
+
this.bind(this.deferrable_trigger, _.once(function() {
|
374
374
|
return _this.deferrable.fetch();
|
375
375
|
}));
|
376
376
|
}
|
377
|
+
return this;
|
377
378
|
} else {
|
378
379
|
this.trigger("before:render", this);
|
379
380
|
_base.apply(this, arguments);
|
380
|
-
|
381
|
+
this.trigger("after:render", this);
|
382
|
+
return this;
|
381
383
|
}
|
382
384
|
};
|
383
385
|
return Luca.View.originalExtend.apply(this, [definition]);
|
@@ -464,6 +466,47 @@
|
|
464
466
|
throw e;
|
465
467
|
}
|
466
468
|
});
|
469
|
+
},
|
470
|
+
registerEvent: function(selector, handler) {
|
471
|
+
this.events || (this.events = {});
|
472
|
+
this.events[selector] = handler;
|
473
|
+
return this.delegateEvents();
|
474
|
+
}
|
475
|
+
});
|
476
|
+
|
477
|
+
}).call(this);
|
478
|
+
(function() {
|
479
|
+
|
480
|
+
Luca.Model = Backbone.Model.extend({
|
481
|
+
initialize: function() {
|
482
|
+
var attr, dependencies, _ref, _results,
|
483
|
+
_this = this;
|
484
|
+
Backbone.Model.prototype.initialize(this, arguments);
|
485
|
+
if (_.isUndefined(this.computed)) return;
|
486
|
+
this._computed = {};
|
487
|
+
_ref = this.computed;
|
488
|
+
_results = [];
|
489
|
+
for (attr in _ref) {
|
490
|
+
dependencies = _ref[attr];
|
491
|
+
this.on("change:" + attr, function() {
|
492
|
+
return _this._computed[attr] = _this[attr].call(_this);
|
493
|
+
});
|
494
|
+
_results.push(_(dependencies).each(function(dep) {
|
495
|
+
_this.on("change:" + dep, function() {
|
496
|
+
return _this.trigger("change:" + attr);
|
497
|
+
});
|
498
|
+
if (_this.has(dep)) return _this.trigger("change:" + attr);
|
499
|
+
}));
|
500
|
+
}
|
501
|
+
return _results;
|
502
|
+
},
|
503
|
+
get: function(attr) {
|
504
|
+
var _ref;
|
505
|
+
if ((_ref = this.computed) != null ? _ref.hasOwnProperty(attr) : void 0) {
|
506
|
+
return this._computed[attr];
|
507
|
+
} else {
|
508
|
+
return Backbone.Model.prototype.get.call(this, attr);
|
509
|
+
}
|
467
510
|
}
|
468
511
|
});
|
469
512
|
|
@@ -1813,6 +1856,7 @@
|
|
1813
1856
|
return valid;
|
1814
1857
|
},
|
1815
1858
|
returnValue: function(val) {
|
1859
|
+
if (val == null) return "undefined";
|
1816
1860
|
return val != null ? val.toString() : void 0;
|
1817
1861
|
},
|
1818
1862
|
parseLine: function(line) {
|
@@ -2130,6 +2174,7 @@
|
|
2130
2174
|
this.input_id || (this.input_id = _.uniqueId('field'));
|
2131
2175
|
this.input_name || (this.input_name = this.name);
|
2132
2176
|
this.label || (this.label = this.name);
|
2177
|
+
this.input_class || (this.input_class = this["class"]);
|
2133
2178
|
if (this.prepend) {
|
2134
2179
|
this.$el.addClass('input-prepend');
|
2135
2180
|
this.addOn = this.prepend;
|
@@ -2587,6 +2632,9 @@
|
|
2587
2632
|
});
|
2588
2633
|
return this.header.append("<tr>" + headers + "</tr>");
|
2589
2634
|
},
|
2635
|
+
getRowEl: function(id) {
|
2636
|
+
return this.$("[data-record-id=" + id + "]", 'table');
|
2637
|
+
},
|
2590
2638
|
render_row: function(row, row_index) {
|
2591
2639
|
var altClass, cells, model_id, _ref,
|
2592
2640
|
_this = this;
|
@@ -2984,7 +3032,7 @@
|
|
2984
3032
|
expect(values.field1).toEqual("yes");
|
2985
3033
|
return expect(values.field2).toEqual("no");
|
2986
3034
|
});
|
2987
|
-
it("should sync the model with the form field values", function() {
|
3035
|
+
return it("should sync the model with the form field values", function() {
|
2988
3036
|
this.form.render();
|
2989
3037
|
this.form.loadModel(this.model);
|
2990
3038
|
this.form.setValues({
|
@@ -2992,183 +3040,6 @@
|
|
2992
3040
|
});
|
2993
3041
|
return expect(this.form.getValues().field1).toEqual("yes");
|
2994
3042
|
});
|
2995
|
-
describe("Loading A New Model", function() {
|
2996
|
-
beforeEach(function() {
|
2997
|
-
this.form.spiedEvents = {};
|
2998
|
-
this.form.render();
|
2999
|
-
this.model.beforeFormLoad = sinon.spy();
|
3000
|
-
return this.form.loadModel(this.model);
|
3001
|
-
});
|
3002
|
-
it("should call before form load", function() {
|
3003
|
-
return expect(this.model.beforeFormLoad).toHaveBeenCalled();
|
3004
|
-
});
|
3005
|
-
it("should have triggered before load", function() {
|
3006
|
-
return expect(this.form).toHaveTriggered("before:load");
|
3007
|
-
});
|
3008
|
-
it("should have triggered after load", function() {
|
3009
|
-
return expect(this.form).toHaveTriggered("after:load");
|
3010
|
-
});
|
3011
|
-
it("should have triggered before:load:new", function() {
|
3012
|
-
return expect(this.form).toHaveTriggered("before:load:new");
|
3013
|
-
});
|
3014
|
-
return it("should have triggered after:load:new", function() {
|
3015
|
-
return expect(this.form).toHaveTriggered("after:load:new");
|
3016
|
-
});
|
3017
|
-
});
|
3018
|
-
describe("Loading An Existing Model", function() {
|
3019
|
-
beforeEach(function() {
|
3020
|
-
this.form.spiedEvents = {};
|
3021
|
-
this.form.render();
|
3022
|
-
this.model.set({
|
3023
|
-
id: "one"
|
3024
|
-
});
|
3025
|
-
this.model.beforeFormLoad = sinon.spy();
|
3026
|
-
return this.form.loadModel(this.model);
|
3027
|
-
});
|
3028
|
-
it("should call before form load", function() {
|
3029
|
-
return expect(this.model.beforeFormLoad).toHaveBeenCalled();
|
3030
|
-
});
|
3031
|
-
it("should have triggered before:load:existing", function() {
|
3032
|
-
return expect(this.form).toHaveTriggered("before:load:existing");
|
3033
|
-
});
|
3034
|
-
it("should have triggered after:load:new", function() {
|
3035
|
-
return expect(this.form).toHaveTriggered("after:load:existing");
|
3036
|
-
});
|
3037
|
-
return it("should apply the form values in the currentModel call if specified", function() {
|
3038
|
-
this.form.getField("field1").setValue("sup baby?");
|
3039
|
-
expect(this.form.currentModel().get("field1")).not.toEqual("sup baby?");
|
3040
|
-
this.form.getField("field1").setValue("sup baby boo?");
|
3041
|
-
expect(this.form.currentModel({
|
3042
|
-
refresh: false
|
3043
|
-
}).get("field1")).not.toEqual("sup baby boo?");
|
3044
|
-
return expect(this.form.currentModel({
|
3045
|
-
refresh: true
|
3046
|
-
}).get("field1")).toEqual("sup baby boo?");
|
3047
|
-
});
|
3048
|
-
});
|
3049
|
-
describe("The Fields Accessors", function() {
|
3050
|
-
beforeEach(function() {
|
3051
|
-
return this.form.render();
|
3052
|
-
});
|
3053
|
-
it("should provide access to fields", function() {
|
3054
|
-
return expect(this.form.getFields().length).toEqual(6);
|
3055
|
-
});
|
3056
|
-
return it("should allow me to access a field by its name", function() {
|
3057
|
-
return expect(this.form.getField("field1")).toBeDefined();
|
3058
|
-
});
|
3059
|
-
});
|
3060
|
-
describe("The Set Values Function", function() {
|
3061
|
-
beforeEach(function() {
|
3062
|
-
this.form.render();
|
3063
|
-
return this.form.loadModel(this.model);
|
3064
|
-
});
|
3065
|
-
it("should set the values on the field", function() {
|
3066
|
-
this.form.setValues({
|
3067
|
-
field1: "andyadontstop"
|
3068
|
-
});
|
3069
|
-
return expect(this.form.getField("field1").getValue()).toEqual("andyadontstop");
|
3070
|
-
});
|
3071
|
-
it("should set the values on the model", function() {
|
3072
|
-
this.form.setValues({
|
3073
|
-
field1: "krs-one"
|
3074
|
-
});
|
3075
|
-
expect(this.form.getField("field1").getValue()).toEqual("krs-one");
|
3076
|
-
return expect(this.model.get("field1")).toEqual("krs-one");
|
3077
|
-
});
|
3078
|
-
return it("should skip syncing with the model if passed silent", function() {
|
3079
|
-
this.form.setValues({
|
3080
|
-
field1: "yesyesyall"
|
3081
|
-
}, {
|
3082
|
-
silent: true
|
3083
|
-
});
|
3084
|
-
expect(this.form.getField("field1").getValue()).toEqual("yesyesyall");
|
3085
|
-
return expect(this.model.get("field1")).not.toEqual("yesyesyall");
|
3086
|
-
});
|
3087
|
-
});
|
3088
|
-
describe("The Get Values Function", function() {
|
3089
|
-
beforeEach(function() {
|
3090
|
-
this.model.set({
|
3091
|
-
field1: "one",
|
3092
|
-
field2: "two",
|
3093
|
-
field3: void 0,
|
3094
|
-
field4: ""
|
3095
|
-
});
|
3096
|
-
this.form.render();
|
3097
|
-
this.form.loadModel(this.model);
|
3098
|
-
return this.values = this.form.getValues();
|
3099
|
-
});
|
3100
|
-
it("should skip the button fields by default", function() {
|
3101
|
-
return expect(_(this.values).keys()).not.toContain("field5");
|
3102
|
-
});
|
3103
|
-
it("should include the button fields if asked", function() {
|
3104
|
-
var values;
|
3105
|
-
values = this.form.getValues({
|
3106
|
-
skip_buttons: false
|
3107
|
-
});
|
3108
|
-
return expect(_(values).keys()).toContain("field5");
|
3109
|
-
});
|
3110
|
-
it("should skip blank fields by default", function() {
|
3111
|
-
var values;
|
3112
|
-
values = this.form.getValues();
|
3113
|
-
return expect(_(values).keys()).not.toContain("field4");
|
3114
|
-
});
|
3115
|
-
it("should include blank fields if asked", function() {
|
3116
|
-
var values;
|
3117
|
-
values = this.form.getValues({
|
3118
|
-
reject_blank: false
|
3119
|
-
});
|
3120
|
-
return expect(_(values).keys()).toContain("field4");
|
3121
|
-
});
|
3122
|
-
return it("should skip blank id fields", function() {
|
3123
|
-
return expect(_(this.values).keys()).not.toContain("id");
|
3124
|
-
});
|
3125
|
-
});
|
3126
|
-
return describe("Events", function() {
|
3127
|
-
beforeEach(function() {
|
3128
|
-
this.form.render();
|
3129
|
-
return this.form.loadModel(this.model);
|
3130
|
-
});
|
3131
|
-
describe("Submit Handlers", function() {
|
3132
|
-
beforeEach(function() {
|
3133
|
-
return this.form.spiedEvents = {};
|
3134
|
-
});
|
3135
|
-
it("should trigger after submit events", function() {
|
3136
|
-
this.form.submit_success_handler(this.model, {
|
3137
|
-
success: true
|
3138
|
-
});
|
3139
|
-
expect(this.form).toHaveTriggered("after:submit");
|
3140
|
-
return expect(this.form).toHaveTriggered("after:submit:success");
|
3141
|
-
});
|
3142
|
-
it("should trigger after submit error events", function() {
|
3143
|
-
this.form.submit_success_handler(this.model, {
|
3144
|
-
success: false
|
3145
|
-
});
|
3146
|
-
expect(this.form).toHaveTriggered("after:submit");
|
3147
|
-
return expect(this.form).toHaveTriggered("after:submit:error");
|
3148
|
-
});
|
3149
|
-
return it("should trigger fatal error events", function() {
|
3150
|
-
this.form.submit_fatal_error_handler();
|
3151
|
-
expect(this.form).toHaveTriggered("after:submit");
|
3152
|
-
return expect(this.form).toHaveTriggered("after:submit:fatal_error");
|
3153
|
-
});
|
3154
|
-
});
|
3155
|
-
return describe("Resetting the Form", function() {
|
3156
|
-
it("should trigger before and after reset", function() {
|
3157
|
-
this.form.resetHandler({
|
3158
|
-
currentTarget: 1
|
3159
|
-
});
|
3160
|
-
expect(this.form).toHaveTriggered("before:reset");
|
3161
|
-
return expect(this.form).toHaveTriggered("after:reset");
|
3162
|
-
});
|
3163
|
-
return it("should call reset", function() {
|
3164
|
-
this.form.reset = sinon.spy();
|
3165
|
-
this.form.resetHandler({
|
3166
|
-
currentTarget: 1
|
3167
|
-
});
|
3168
|
-
return expect(this.form.reset).toHaveBeenCalled();
|
3169
|
-
});
|
3170
|
-
});
|
3171
|
-
});
|
3172
3043
|
});
|
3173
3044
|
|
3174
3045
|
}).call(this);
|
@@ -3649,6 +3520,84 @@
|
|
3649
3520
|
|
3650
3521
|
|
3651
3522
|
|
3523
|
+
}).call(this);
|
3524
|
+
(function() {
|
3525
|
+
|
3526
|
+
describe("Luca.Model with computed attribute", function() {
|
3527
|
+
var App;
|
3528
|
+
App = {
|
3529
|
+
models: {}
|
3530
|
+
};
|
3531
|
+
App.models.Sample = Luca.Model.extend({
|
3532
|
+
computed: {
|
3533
|
+
fullName: ['firstName', 'lastName']
|
3534
|
+
},
|
3535
|
+
fullName: function() {
|
3536
|
+
return "" + (this.get("firstName")) + " " + (this.get("lastName"));
|
3537
|
+
}
|
3538
|
+
});
|
3539
|
+
App.models.SampleWithoutCallback = Luca.Model.extend({
|
3540
|
+
computed: {
|
3541
|
+
fullName: ['firstName', 'lastName']
|
3542
|
+
}
|
3543
|
+
});
|
3544
|
+
it("should have it undefined if dependences are not set", function() {
|
3545
|
+
var model;
|
3546
|
+
model = new App.models.Sample;
|
3547
|
+
return expect(model.get("fullName")).toEqual(void 0);
|
3548
|
+
});
|
3549
|
+
it("should have it undefined if callback function is not present", function() {
|
3550
|
+
var model;
|
3551
|
+
model = new App.models.SampleWithoutCallback;
|
3552
|
+
return expect(model.get("fullName")).toEqual(void 0);
|
3553
|
+
});
|
3554
|
+
it("should not call it's callback if dependences are not set", function() {
|
3555
|
+
var model, spy;
|
3556
|
+
model = new App.models.Sample;
|
3557
|
+
spy = sinon.spy(model, "fullName");
|
3558
|
+
return expect(spy.called).toEqual(false);
|
3559
|
+
});
|
3560
|
+
it("should not call it's callback if dependencies stay the same", function() {
|
3561
|
+
var model, spy;
|
3562
|
+
model = new App.models.Sample;
|
3563
|
+
model.set({
|
3564
|
+
firstName: "Nickolay",
|
3565
|
+
lastName: "Schwarz"
|
3566
|
+
});
|
3567
|
+
spy = sinon.spy(model, "fullName");
|
3568
|
+
model.set({
|
3569
|
+
lastName: "Schwarz"
|
3570
|
+
});
|
3571
|
+
return expect(spy.called).toEqual(false);
|
3572
|
+
});
|
3573
|
+
it("should call it's callback when dependencies change", function() {
|
3574
|
+
var model, spy;
|
3575
|
+
model = new App.models.Sample;
|
3576
|
+
spy = sinon.spy(model, "fullName");
|
3577
|
+
model.set({
|
3578
|
+
firstName: "Nickolay"
|
3579
|
+
});
|
3580
|
+
return expect(spy.called).toEqual(true);
|
3581
|
+
});
|
3582
|
+
it("should be gettable as a value of the callback", function() {
|
3583
|
+
var model;
|
3584
|
+
model = new App.models.Sample;
|
3585
|
+
model.set({
|
3586
|
+
firstName: "Nickolay",
|
3587
|
+
lastName: "Schwarz"
|
3588
|
+
});
|
3589
|
+
return expect(model.get("fullName")).toEqual(model.fullName());
|
3590
|
+
});
|
3591
|
+
return it("should have it set on constructor if dependencies are supplied", function() {
|
3592
|
+
var model;
|
3593
|
+
model = new App.models.Sample({
|
3594
|
+
firstName: "Nickolay",
|
3595
|
+
lastName: "Schwarz"
|
3596
|
+
});
|
3597
|
+
return expect(model.get("fullName")).toEqual('Nickolay Schwarz');
|
3598
|
+
});
|
3599
|
+
});
|
3600
|
+
|
3652
3601
|
}).call(this);
|
3653
3602
|
(function() {
|
3654
3603
|
|