luca 0.7.0 → 0.7.2
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/lib/luca/rails/version.rb +1 -1
- data/spec/components/form_view_spec.coffee +200 -12
- data/spec/framework_spec.coffee +29 -4
- data/src/components/form_view.coffee +73 -46
- data/src/core/view.coffee +2 -0
- data/src/framework.coffee +10 -1
- data/vendor/assets/javascripts/luca-ui-base.js +15 -2
- data/vendor/assets/javascripts/luca-ui-spec.js +341 -43
- data/vendor/assets/javascripts/luca-ui.js +59 -25
- data/vendor/assets/javascripts/luca-ui.min.js +3 -3
- metadata +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
_.mixin(_.string);
|
|
4
4
|
|
|
5
5
|
window.Luca = {
|
|
6
|
-
VERSION: "0.7.
|
|
6
|
+
VERSION: "0.7.2",
|
|
7
7
|
core: {},
|
|
8
8
|
containers: {},
|
|
9
9
|
components: {},
|
|
@@ -22,6 +22,18 @@
|
|
|
22
22
|
|
|
23
23
|
Luca.enableBootstrap = true;
|
|
24
24
|
|
|
25
|
+
Luca.isBackboneModel = function(obj) {
|
|
26
|
+
return _.isFunction(obj != null ? obj.set : void 0) && _.isFunction(obj != null ? obj.get : void 0) && _.isObject(obj != null ? obj.attributes : void 0);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
Luca.isBackboneView = function(obj) {
|
|
30
|
+
return _.isFunction(obj != null ? obj.render : void 0) && !_.isUndefined(obj != null ? obj.el : void 0);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
Luca.isBackboneCollection = function(obj) {
|
|
34
|
+
return _.isFunction(obj != null ? obj.fetch : void 0) && _.isFunction(obj != null ? obj.reset : void 0);
|
|
35
|
+
};
|
|
36
|
+
|
|
25
37
|
Luca.registry.addNamespace = function(identifier) {
|
|
26
38
|
Luca.registry.namespaces.push(identifier);
|
|
27
39
|
return Luca.registry.namespaces = _(Luca.registry.namespaces).uniq();
|
|
@@ -408,7 +420,8 @@
|
|
|
408
420
|
});
|
|
409
421
|
}
|
|
410
422
|
this.trigger("after:initialize", this);
|
|
411
|
-
|
|
423
|
+
this.registerCollectionEvents();
|
|
424
|
+
return this.delegateEvents();
|
|
412
425
|
},
|
|
413
426
|
$container: function() {
|
|
414
427
|
return $(this.container);
|
|
@@ -2239,8 +2252,7 @@
|
|
|
2239
2252
|
return fields;
|
|
2240
2253
|
},
|
|
2241
2254
|
loadModel: function(current_model) {
|
|
2242
|
-
var event, fields, form
|
|
2243
|
-
_this = this;
|
|
2255
|
+
var event, fields, form;
|
|
2244
2256
|
this.current_model = current_model;
|
|
2245
2257
|
form = this;
|
|
2246
2258
|
fields = this.getFields();
|
|
@@ -2249,14 +2261,7 @@
|
|
|
2249
2261
|
event = "before:load:" + (this.current_model.isNew() ? "new" : "existing");
|
|
2250
2262
|
this.trigger(event, this, this.current_model);
|
|
2251
2263
|
}
|
|
2252
|
-
|
|
2253
|
-
var field_name, value;
|
|
2254
|
-
field_name = field.input_name || field.name;
|
|
2255
|
-
value = _.isFunction(_this.current_model[field_name]) ? _this.current_model[field_name].apply(_this, form) : _this.current_model.get(field_name);
|
|
2256
|
-
if (field.readOnly !== true) {
|
|
2257
|
-
return field != null ? field.setValue(value) : void 0;
|
|
2258
|
-
}
|
|
2259
|
-
});
|
|
2264
|
+
this.setValues(this.current_model);
|
|
2260
2265
|
this.trigger("after:load", this, this.current_model);
|
|
2261
2266
|
if (this.current_model) {
|
|
2262
2267
|
return this.trigger("after:load:" + (this.current_model.isNew() ? "new" : "existing"), this, this.current_model);
|
|
@@ -2276,31 +2281,52 @@
|
|
|
2276
2281
|
}
|
|
2277
2282
|
});
|
|
2278
2283
|
},
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2284
|
+
setValues: function(source, options) {
|
|
2285
|
+
var fields,
|
|
2286
|
+
_this = this;
|
|
2287
|
+
if (options == null) options = {};
|
|
2288
|
+
source || (source = this.currentModel());
|
|
2289
|
+
fields = this.getFields();
|
|
2290
|
+
_(fields).each(function(field) {
|
|
2291
|
+
var field_name, value;
|
|
2292
|
+
field_name = field.input_name || field.name;
|
|
2293
|
+
if (value = source[field_name]) {
|
|
2294
|
+
if (_.isFunction(value)) value = value.apply(_this);
|
|
2295
|
+
}
|
|
2296
|
+
if (!value && Luca.isBackboneModel(source)) value = source.get(field_name);
|
|
2297
|
+
if (field.readOnly !== true) {
|
|
2298
|
+
return field != null ? field.setValue(value) : void 0;
|
|
2299
|
+
}
|
|
2300
|
+
});
|
|
2301
|
+
if ((options.silent != null) !== true) return this.syncFormWithModel();
|
|
2302
|
+
},
|
|
2303
|
+
getValues: function(options) {
|
|
2304
|
+
options || (options = {});
|
|
2305
|
+
if (options.reject_blank == null) options.reject_blank = true;
|
|
2306
|
+
if (options.skip_buttons == null) options.skip_buttons = true;
|
|
2282
2307
|
return _(this.getFields()).inject(function(memo, field) {
|
|
2283
|
-
var skip, value;
|
|
2308
|
+
var key, skip, value;
|
|
2284
2309
|
value = field.getValue();
|
|
2310
|
+
key = field.input_name || field.name;
|
|
2285
2311
|
skip = false;
|
|
2286
|
-
if (skip_buttons && field.ctype === "button_field") skip = true;
|
|
2287
|
-
if (reject_blank && _.isBlank(value)) skip = true;
|
|
2312
|
+
if (options.skip_buttons && field.ctype === "button_field") skip = true;
|
|
2313
|
+
if (options.reject_blank === true && _.isBlank(value)) skip = true;
|
|
2288
2314
|
if (field.input_name === "id" && _.isBlank(value)) skip = true;
|
|
2289
|
-
if (
|
|
2315
|
+
if (skip !== true) memo[key] = value;
|
|
2290
2316
|
return memo;
|
|
2291
2317
|
}, {});
|
|
2292
2318
|
},
|
|
2293
2319
|
submit_success_handler: function(model, response, xhr) {
|
|
2294
2320
|
this.trigger("after:submit", this, model, response);
|
|
2295
|
-
if (response && response.success) {
|
|
2321
|
+
if (response && (response != null ? response.success : void 0) === true) {
|
|
2296
2322
|
return this.trigger("after:submit:success", this, model, response);
|
|
2297
2323
|
} else {
|
|
2298
2324
|
return this.trigger("after:submit:error", this, model, response);
|
|
2299
2325
|
}
|
|
2300
2326
|
},
|
|
2301
|
-
submit_fatal_error_handler: function() {
|
|
2302
|
-
this.trigger
|
|
2303
|
-
return this.trigger
|
|
2327
|
+
submit_fatal_error_handler: function(model, response, xhr) {
|
|
2328
|
+
this.trigger("after:submit", this, model, response);
|
|
2329
|
+
return this.trigger("after:submit:fatal_error", this, model, response);
|
|
2304
2330
|
},
|
|
2305
2331
|
submit: function(save, saveOptions) {
|
|
2306
2332
|
if (save == null) save = true;
|
|
@@ -2308,13 +2334,21 @@
|
|
|
2308
2334
|
_.bindAll(this, "submit_success_handler", "submit_fatal_error_handler");
|
|
2309
2335
|
saveOptions.success || (saveOptions.success = this.submit_success_handler);
|
|
2310
2336
|
saveOptions.error || (saveOptions.error = this.submit_fatal_error_handler);
|
|
2311
|
-
this.
|
|
2337
|
+
this.syncFormWithModel();
|
|
2312
2338
|
if (!save) return;
|
|
2313
2339
|
return this.current_model.save(this.current_model.toJSON(), saveOptions);
|
|
2314
2340
|
},
|
|
2315
|
-
currentModel: function() {
|
|
2341
|
+
currentModel: function(options) {
|
|
2342
|
+
if (options == null) options = {};
|
|
2343
|
+
if (options === true || (options != null ? options.refresh : void 0) === true) {
|
|
2344
|
+
this.syncFormWithModel();
|
|
2345
|
+
}
|
|
2316
2346
|
return this.current_model;
|
|
2317
2347
|
},
|
|
2348
|
+
syncFormWithModel: function() {
|
|
2349
|
+
var _ref;
|
|
2350
|
+
return (_ref = this.current_model) != null ? _ref.set(this.getValues()) : void 0;
|
|
2351
|
+
},
|
|
2318
2352
|
setLegend: function(legend) {
|
|
2319
2353
|
this.legend = legend;
|
|
2320
2354
|
return $('fieldset legend', this.el).first().html(this.legend);
|
|
@@ -2792,25 +2826,261 @@
|
|
|
2792
2826
|
(function() {
|
|
2793
2827
|
|
|
2794
2828
|
describe('The Form View', function() {
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2829
|
+
beforeEach(function() {
|
|
2830
|
+
var FormView, Model;
|
|
2831
|
+
FormView = Luca.components.FormView.extend({
|
|
2832
|
+
components: [
|
|
2833
|
+
{
|
|
2834
|
+
ctype: 'hidden_field',
|
|
2835
|
+
name: 'id'
|
|
2836
|
+
}, {
|
|
2837
|
+
ctype: "text_field",
|
|
2838
|
+
label: "Field Two",
|
|
2839
|
+
name: "field2"
|
|
2840
|
+
}, {
|
|
2841
|
+
ctype: "text_field",
|
|
2842
|
+
label: "Field One",
|
|
2843
|
+
name: "field1"
|
|
2844
|
+
}, {
|
|
2845
|
+
ctype: "checkbox_field",
|
|
2846
|
+
label: "Field Three",
|
|
2847
|
+
name: "field3"
|
|
2848
|
+
}, {
|
|
2849
|
+
name: "field4",
|
|
2850
|
+
label: "Field Four",
|
|
2851
|
+
ctype: "text_area_field"
|
|
2852
|
+
}, {
|
|
2853
|
+
name: "field5",
|
|
2854
|
+
ctype: "button_field",
|
|
2855
|
+
label: "Click Me"
|
|
2807
2856
|
}
|
|
2857
|
+
]
|
|
2858
|
+
});
|
|
2859
|
+
Model = Backbone.Model.extend({
|
|
2860
|
+
schema: {
|
|
2861
|
+
field0: "hidden",
|
|
2862
|
+
field2: "text",
|
|
2863
|
+
field1: "text",
|
|
2864
|
+
field3: "boolean",
|
|
2865
|
+
field4: "blob",
|
|
2866
|
+
field5: {
|
|
2867
|
+
collection: "sample"
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
});
|
|
2871
|
+
this.form = new FormView();
|
|
2872
|
+
return this.model = new Model({
|
|
2873
|
+
field0: 1,
|
|
2874
|
+
field1: "jonathan",
|
|
2875
|
+
field3: true,
|
|
2876
|
+
field4: "what up player?"
|
|
2877
|
+
});
|
|
2878
|
+
});
|
|
2879
|
+
it("should create a form", function() {
|
|
2880
|
+
return expect(this.form).toBeDefined();
|
|
2881
|
+
});
|
|
2882
|
+
it("should load the model", function() {
|
|
2883
|
+
this.form.loadModel(this.model);
|
|
2884
|
+
return expect(this.form.currentModel()).toEqual(this.model);
|
|
2885
|
+
});
|
|
2886
|
+
it("should set the field values from the model when loaded", function() {
|
|
2887
|
+
var values;
|
|
2888
|
+
this.form.render();
|
|
2889
|
+
this.form.loadModel(this.model);
|
|
2890
|
+
values = this.form.getValues();
|
|
2891
|
+
return expect(values.field1).toEqual("jonathan");
|
|
2892
|
+
});
|
|
2893
|
+
it("should render the components", function() {
|
|
2894
|
+
this.form.render();
|
|
2895
|
+
expect(this.form.$el.html()).toContain("Field Four");
|
|
2896
|
+
expect(this.form.$el.html()).toContain("Field One");
|
|
2897
|
+
return expect(this.form.$el.html()).toContain("Click Me");
|
|
2898
|
+
});
|
|
2899
|
+
it("should allow me to set the values of the form fields with a hash", function() {
|
|
2900
|
+
var values;
|
|
2901
|
+
this.form.render();
|
|
2902
|
+
this.form.setValues({
|
|
2903
|
+
field1: "yes",
|
|
2904
|
+
field2: "no"
|
|
2905
|
+
});
|
|
2906
|
+
values = this.form.getValues();
|
|
2907
|
+
expect(values.field1).toEqual("yes");
|
|
2908
|
+
return expect(values.field2).toEqual("no");
|
|
2909
|
+
});
|
|
2910
|
+
it("should sync the model with the form field values", function() {
|
|
2911
|
+
this.form.render();
|
|
2912
|
+
this.form.loadModel(this.model);
|
|
2913
|
+
this.form.setValues({
|
|
2914
|
+
field1: "yes"
|
|
2915
|
+
});
|
|
2916
|
+
return expect(this.form.getValues().field1).toEqual("yes");
|
|
2917
|
+
});
|
|
2918
|
+
describe("Loading A New Model", function() {
|
|
2919
|
+
beforeEach(function() {
|
|
2920
|
+
this.form.spiedEvents = {};
|
|
2921
|
+
this.form.render();
|
|
2922
|
+
return this.form.loadModel(this.model);
|
|
2923
|
+
});
|
|
2924
|
+
it("should have triggered before load", function() {
|
|
2925
|
+
return expect(this.form).toHaveTriggered("before:load");
|
|
2926
|
+
});
|
|
2927
|
+
it("should have triggered after load", function() {
|
|
2928
|
+
return expect(this.form).toHaveTriggered("after:load");
|
|
2929
|
+
});
|
|
2930
|
+
it("should have triggered before:load:new", function() {
|
|
2931
|
+
return expect(this.form).toHaveTriggered("before:load:new");
|
|
2932
|
+
});
|
|
2933
|
+
return it("should have triggered after:load:new", function() {
|
|
2934
|
+
return expect(this.form).toHaveTriggered("after:load:new");
|
|
2935
|
+
});
|
|
2936
|
+
});
|
|
2937
|
+
describe("Loading An Existing Model", function() {
|
|
2938
|
+
beforeEach(function() {
|
|
2939
|
+
this.form.spiedEvents = {};
|
|
2940
|
+
this.form.render();
|
|
2941
|
+
this.model.set({
|
|
2942
|
+
id: "one"
|
|
2943
|
+
});
|
|
2944
|
+
return this.form.loadModel(this.model);
|
|
2945
|
+
});
|
|
2946
|
+
it("should have triggered before:load:existing", function() {
|
|
2947
|
+
return expect(this.form).toHaveTriggered("before:load:existing");
|
|
2948
|
+
});
|
|
2949
|
+
it("should have triggered after:load:new", function() {
|
|
2950
|
+
return expect(this.form).toHaveTriggered("after:load:existing");
|
|
2951
|
+
});
|
|
2952
|
+
return it("should apply the form values in the currentModel call if specified", function() {
|
|
2953
|
+
this.form.getField("field1").setValue("sup baby?");
|
|
2954
|
+
expect(this.form.currentModel().get("field1")).not.toEqual("sup baby?");
|
|
2955
|
+
this.form.getField("field1").setValue("sup baby boo?");
|
|
2956
|
+
expect(this.form.currentModel({
|
|
2957
|
+
refresh: false
|
|
2958
|
+
}).get("field1")).not.toEqual("sup baby boo?");
|
|
2959
|
+
return expect(this.form.currentModel({
|
|
2960
|
+
refresh: true
|
|
2961
|
+
}).get("field1")).toEqual("sup baby boo?");
|
|
2962
|
+
});
|
|
2963
|
+
});
|
|
2964
|
+
describe("The Fields Accessors", function() {
|
|
2965
|
+
beforeEach(function() {
|
|
2966
|
+
return this.form.render();
|
|
2967
|
+
});
|
|
2968
|
+
it("should provide access to fields", function() {
|
|
2969
|
+
return expect(this.form.getFields().length).toEqual(6);
|
|
2970
|
+
});
|
|
2971
|
+
return it("should allow me to access a field by its name", function() {
|
|
2972
|
+
return expect(this.form.getField("field1")).toBeDefined();
|
|
2973
|
+
});
|
|
2974
|
+
});
|
|
2975
|
+
describe("The Set Values Function", function() {
|
|
2976
|
+
beforeEach(function() {
|
|
2977
|
+
this.form.render();
|
|
2978
|
+
return this.form.loadModel(this.model);
|
|
2979
|
+
});
|
|
2980
|
+
it("should set the values on the field", function() {
|
|
2981
|
+
this.form.setValues({
|
|
2982
|
+
field1: "andyadontstop"
|
|
2983
|
+
});
|
|
2984
|
+
return expect(this.form.getField("field1").getValue()).toEqual("andyadontstop");
|
|
2985
|
+
});
|
|
2986
|
+
it("should set the values on the model", function() {
|
|
2987
|
+
this.form.setValues({
|
|
2988
|
+
field1: "krs-one"
|
|
2989
|
+
});
|
|
2990
|
+
expect(this.form.getField("field1").getValue()).toEqual("krs-one");
|
|
2991
|
+
return expect(this.model.get("field1")).toEqual("krs-one");
|
|
2992
|
+
});
|
|
2993
|
+
return it("should skip syncing with the model if passed silent", function() {
|
|
2994
|
+
this.form.setValues({
|
|
2995
|
+
field1: "yesyesyall"
|
|
2996
|
+
}, {
|
|
2997
|
+
silent: true
|
|
2998
|
+
});
|
|
2999
|
+
expect(this.form.getField("field1").getValue()).toEqual("yesyesyall");
|
|
3000
|
+
return expect(this.model.get("field1")).not.toEqual("yesyesyall");
|
|
3001
|
+
});
|
|
3002
|
+
});
|
|
3003
|
+
describe("The Get Values Function", function() {
|
|
3004
|
+
beforeEach(function() {
|
|
3005
|
+
this.model.set({
|
|
3006
|
+
field1: "one",
|
|
3007
|
+
field2: "two",
|
|
3008
|
+
field3: void 0,
|
|
3009
|
+
field4: ""
|
|
3010
|
+
});
|
|
3011
|
+
this.form.render();
|
|
3012
|
+
this.form.loadModel(this.model);
|
|
3013
|
+
return this.values = this.form.getValues();
|
|
3014
|
+
});
|
|
3015
|
+
it("should skip the button fields by default", function() {
|
|
3016
|
+
return expect(_(this.values).keys()).not.toContain("field5");
|
|
3017
|
+
});
|
|
3018
|
+
it("should include the button fields if asked", function() {
|
|
3019
|
+
var values;
|
|
3020
|
+
values = this.form.getValues({
|
|
3021
|
+
skip_buttons: false
|
|
2808
3022
|
});
|
|
2809
|
-
return
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
3023
|
+
return expect(_(values).keys()).toContain("field5");
|
|
3024
|
+
});
|
|
3025
|
+
it("should skip blank fields by default", function() {
|
|
3026
|
+
var values;
|
|
3027
|
+
values = this.form.getValues();
|
|
3028
|
+
return expect(_(values).keys()).not.toContain("field4");
|
|
3029
|
+
});
|
|
3030
|
+
it("should include blank fields if asked", function() {
|
|
3031
|
+
var values;
|
|
3032
|
+
values = this.form.getValues({
|
|
3033
|
+
reject_blank: false
|
|
3034
|
+
});
|
|
3035
|
+
return expect(_(values).keys()).toContain("field4");
|
|
3036
|
+
});
|
|
3037
|
+
return it("should skip blank id fields", function() {
|
|
3038
|
+
return expect(_(this.values).keys()).not.toContain("id");
|
|
3039
|
+
});
|
|
3040
|
+
});
|
|
3041
|
+
return describe("Events", function() {
|
|
3042
|
+
beforeEach(function() {
|
|
3043
|
+
this.form.render();
|
|
3044
|
+
return this.form.loadModel(this.model);
|
|
3045
|
+
});
|
|
3046
|
+
describe("Submit Handlers", function() {
|
|
3047
|
+
beforeEach(function() {
|
|
3048
|
+
return this.form.spiedEvents = {};
|
|
3049
|
+
});
|
|
3050
|
+
it("should trigger after submit events", function() {
|
|
3051
|
+
this.form.submit_success_handler(this.model, {
|
|
3052
|
+
success: true
|
|
3053
|
+
});
|
|
3054
|
+
expect(this.form).toHaveTriggered("after:submit");
|
|
3055
|
+
return expect(this.form).toHaveTriggered("after:submit:success");
|
|
3056
|
+
});
|
|
3057
|
+
it("should trigger after submit error events", function() {
|
|
3058
|
+
this.form.submit_success_handler(this.model, {
|
|
3059
|
+
success: false
|
|
3060
|
+
});
|
|
3061
|
+
expect(this.form).toHaveTriggered("after:submit");
|
|
3062
|
+
return expect(this.form).toHaveTriggered("after:submit:error");
|
|
3063
|
+
});
|
|
3064
|
+
return it("should trigger fatal error events", function() {
|
|
3065
|
+
this.form.submit_fatal_error_handler();
|
|
3066
|
+
expect(this.form).toHaveTriggered("after:submit");
|
|
3067
|
+
return expect(this.form).toHaveTriggered("after:submit:fatal_error");
|
|
3068
|
+
});
|
|
3069
|
+
});
|
|
3070
|
+
return describe("Resetting the Form", function() {
|
|
3071
|
+
it("should trigger before and after reset", function() {
|
|
3072
|
+
this.form.resetHandler({
|
|
3073
|
+
currentTarget: 1
|
|
3074
|
+
});
|
|
3075
|
+
expect(this.form).toHaveTriggered("before:reset");
|
|
3076
|
+
return expect(this.form).toHaveTriggered("after:reset");
|
|
3077
|
+
});
|
|
3078
|
+
return it("should call reset", function() {
|
|
3079
|
+
this.form.reset = sinon.spy();
|
|
3080
|
+
this.form.resetHandler({
|
|
3081
|
+
currentTarget: 1
|
|
3082
|
+
});
|
|
3083
|
+
return expect(this.form.reset).toHaveBeenCalled();
|
|
2814
3084
|
});
|
|
2815
3085
|
});
|
|
2816
3086
|
});
|
|
@@ -3626,7 +3896,7 @@
|
|
|
3626
3896
|
component = Luca.util.lazyComponent(object);
|
|
3627
3897
|
return expect(_.isFunction(component.render)).toBeTruthy();
|
|
3628
3898
|
});
|
|
3629
|
-
|
|
3899
|
+
it("should find a created view in the cache", function() {
|
|
3630
3900
|
var template;
|
|
3631
3901
|
template = new Luca.components.Template({
|
|
3632
3902
|
template: "components/form_view",
|
|
@@ -3634,6 +3904,34 @@
|
|
|
3634
3904
|
});
|
|
3635
3905
|
return expect(Luca.cache("test_template")).toBeDefined();
|
|
3636
3906
|
});
|
|
3907
|
+
it("should detect if an object is probably a backbone view", function() {
|
|
3908
|
+
var obj;
|
|
3909
|
+
obj = {
|
|
3910
|
+
render: sinon.spy(),
|
|
3911
|
+
el: true
|
|
3912
|
+
};
|
|
3913
|
+
expect(Luca.isBackboneView(obj)).toEqual(true);
|
|
3914
|
+
return expect(Luca.isBackboneView({})).toEqual(false);
|
|
3915
|
+
});
|
|
3916
|
+
it("should detect if an object is probably a backbone collection", function() {
|
|
3917
|
+
var obj;
|
|
3918
|
+
obj = {
|
|
3919
|
+
fetch: sinon.spy(),
|
|
3920
|
+
reset: sinon.spy()
|
|
3921
|
+
};
|
|
3922
|
+
expect(Luca.isBackboneCollection(obj)).toEqual(true);
|
|
3923
|
+
return expect(Luca.isBackboneCollection({})).toEqual(false);
|
|
3924
|
+
});
|
|
3925
|
+
return it("should detect if an object is probably a backbone model", function() {
|
|
3926
|
+
var obj;
|
|
3927
|
+
obj = {
|
|
3928
|
+
set: sinon.spy(),
|
|
3929
|
+
get: sinon.spy(),
|
|
3930
|
+
attributes: {}
|
|
3931
|
+
};
|
|
3932
|
+
expect(Luca.isBackboneModel(obj)).toEqual(true);
|
|
3933
|
+
return expect(Luca.isBackboneModel({})).toEqual(false);
|
|
3934
|
+
});
|
|
3637
3935
|
});
|
|
3638
3936
|
|
|
3639
3937
|
describe;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
_.mixin(_.string);
|
|
4
4
|
|
|
5
5
|
window.Luca = {
|
|
6
|
-
VERSION: "0.7.
|
|
6
|
+
VERSION: "0.7.2",
|
|
7
7
|
core: {},
|
|
8
8
|
containers: {},
|
|
9
9
|
components: {},
|
|
@@ -22,6 +22,18 @@
|
|
|
22
22
|
|
|
23
23
|
Luca.enableBootstrap = true;
|
|
24
24
|
|
|
25
|
+
Luca.isBackboneModel = function(obj) {
|
|
26
|
+
return _.isFunction(obj != null ? obj.set : void 0) && _.isFunction(obj != null ? obj.get : void 0) && _.isObject(obj != null ? obj.attributes : void 0);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
Luca.isBackboneView = function(obj) {
|
|
30
|
+
return _.isFunction(obj != null ? obj.render : void 0) && !_.isUndefined(obj != null ? obj.el : void 0);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
Luca.isBackboneCollection = function(obj) {
|
|
34
|
+
return _.isFunction(obj != null ? obj.fetch : void 0) && _.isFunction(obj != null ? obj.reset : void 0);
|
|
35
|
+
};
|
|
36
|
+
|
|
25
37
|
Luca.registry.addNamespace = function(identifier) {
|
|
26
38
|
Luca.registry.namespaces.push(identifier);
|
|
27
39
|
return Luca.registry.namespaces = _(Luca.registry.namespaces).uniq();
|
|
@@ -408,7 +420,8 @@
|
|
|
408
420
|
});
|
|
409
421
|
}
|
|
410
422
|
this.trigger("after:initialize", this);
|
|
411
|
-
|
|
423
|
+
this.registerCollectionEvents();
|
|
424
|
+
return this.delegateEvents();
|
|
412
425
|
},
|
|
413
426
|
$container: function() {
|
|
414
427
|
return $(this.container);
|
|
@@ -2239,8 +2252,7 @@
|
|
|
2239
2252
|
return fields;
|
|
2240
2253
|
},
|
|
2241
2254
|
loadModel: function(current_model) {
|
|
2242
|
-
var event, fields, form
|
|
2243
|
-
_this = this;
|
|
2255
|
+
var event, fields, form;
|
|
2244
2256
|
this.current_model = current_model;
|
|
2245
2257
|
form = this;
|
|
2246
2258
|
fields = this.getFields();
|
|
@@ -2249,14 +2261,7 @@
|
|
|
2249
2261
|
event = "before:load:" + (this.current_model.isNew() ? "new" : "existing");
|
|
2250
2262
|
this.trigger(event, this, this.current_model);
|
|
2251
2263
|
}
|
|
2252
|
-
|
|
2253
|
-
var field_name, value;
|
|
2254
|
-
field_name = field.input_name || field.name;
|
|
2255
|
-
value = _.isFunction(_this.current_model[field_name]) ? _this.current_model[field_name].apply(_this, form) : _this.current_model.get(field_name);
|
|
2256
|
-
if (field.readOnly !== true) {
|
|
2257
|
-
return field != null ? field.setValue(value) : void 0;
|
|
2258
|
-
}
|
|
2259
|
-
});
|
|
2264
|
+
this.setValues(this.current_model);
|
|
2260
2265
|
this.trigger("after:load", this, this.current_model);
|
|
2261
2266
|
if (this.current_model) {
|
|
2262
2267
|
return this.trigger("after:load:" + (this.current_model.isNew() ? "new" : "existing"), this, this.current_model);
|
|
@@ -2276,31 +2281,52 @@
|
|
|
2276
2281
|
}
|
|
2277
2282
|
});
|
|
2278
2283
|
},
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2284
|
+
setValues: function(source, options) {
|
|
2285
|
+
var fields,
|
|
2286
|
+
_this = this;
|
|
2287
|
+
if (options == null) options = {};
|
|
2288
|
+
source || (source = this.currentModel());
|
|
2289
|
+
fields = this.getFields();
|
|
2290
|
+
_(fields).each(function(field) {
|
|
2291
|
+
var field_name, value;
|
|
2292
|
+
field_name = field.input_name || field.name;
|
|
2293
|
+
if (value = source[field_name]) {
|
|
2294
|
+
if (_.isFunction(value)) value = value.apply(_this);
|
|
2295
|
+
}
|
|
2296
|
+
if (!value && Luca.isBackboneModel(source)) value = source.get(field_name);
|
|
2297
|
+
if (field.readOnly !== true) {
|
|
2298
|
+
return field != null ? field.setValue(value) : void 0;
|
|
2299
|
+
}
|
|
2300
|
+
});
|
|
2301
|
+
if ((options.silent != null) !== true) return this.syncFormWithModel();
|
|
2302
|
+
},
|
|
2303
|
+
getValues: function(options) {
|
|
2304
|
+
options || (options = {});
|
|
2305
|
+
if (options.reject_blank == null) options.reject_blank = true;
|
|
2306
|
+
if (options.skip_buttons == null) options.skip_buttons = true;
|
|
2282
2307
|
return _(this.getFields()).inject(function(memo, field) {
|
|
2283
|
-
var skip, value;
|
|
2308
|
+
var key, skip, value;
|
|
2284
2309
|
value = field.getValue();
|
|
2310
|
+
key = field.input_name || field.name;
|
|
2285
2311
|
skip = false;
|
|
2286
|
-
if (skip_buttons && field.ctype === "button_field") skip = true;
|
|
2287
|
-
if (reject_blank && _.isBlank(value)) skip = true;
|
|
2312
|
+
if (options.skip_buttons && field.ctype === "button_field") skip = true;
|
|
2313
|
+
if (options.reject_blank === true && _.isBlank(value)) skip = true;
|
|
2288
2314
|
if (field.input_name === "id" && _.isBlank(value)) skip = true;
|
|
2289
|
-
if (
|
|
2315
|
+
if (skip !== true) memo[key] = value;
|
|
2290
2316
|
return memo;
|
|
2291
2317
|
}, {});
|
|
2292
2318
|
},
|
|
2293
2319
|
submit_success_handler: function(model, response, xhr) {
|
|
2294
2320
|
this.trigger("after:submit", this, model, response);
|
|
2295
|
-
if (response && response.success) {
|
|
2321
|
+
if (response && (response != null ? response.success : void 0) === true) {
|
|
2296
2322
|
return this.trigger("after:submit:success", this, model, response);
|
|
2297
2323
|
} else {
|
|
2298
2324
|
return this.trigger("after:submit:error", this, model, response);
|
|
2299
2325
|
}
|
|
2300
2326
|
},
|
|
2301
|
-
submit_fatal_error_handler: function() {
|
|
2302
|
-
this.trigger
|
|
2303
|
-
return this.trigger
|
|
2327
|
+
submit_fatal_error_handler: function(model, response, xhr) {
|
|
2328
|
+
this.trigger("after:submit", this, model, response);
|
|
2329
|
+
return this.trigger("after:submit:fatal_error", this, model, response);
|
|
2304
2330
|
},
|
|
2305
2331
|
submit: function(save, saveOptions) {
|
|
2306
2332
|
if (save == null) save = true;
|
|
@@ -2308,13 +2334,21 @@
|
|
|
2308
2334
|
_.bindAll(this, "submit_success_handler", "submit_fatal_error_handler");
|
|
2309
2335
|
saveOptions.success || (saveOptions.success = this.submit_success_handler);
|
|
2310
2336
|
saveOptions.error || (saveOptions.error = this.submit_fatal_error_handler);
|
|
2311
|
-
this.
|
|
2337
|
+
this.syncFormWithModel();
|
|
2312
2338
|
if (!save) return;
|
|
2313
2339
|
return this.current_model.save(this.current_model.toJSON(), saveOptions);
|
|
2314
2340
|
},
|
|
2315
|
-
currentModel: function() {
|
|
2341
|
+
currentModel: function(options) {
|
|
2342
|
+
if (options == null) options = {};
|
|
2343
|
+
if (options === true || (options != null ? options.refresh : void 0) === true) {
|
|
2344
|
+
this.syncFormWithModel();
|
|
2345
|
+
}
|
|
2316
2346
|
return this.current_model;
|
|
2317
2347
|
},
|
|
2348
|
+
syncFormWithModel: function() {
|
|
2349
|
+
var _ref;
|
|
2350
|
+
return (_ref = this.current_model) != null ? _ref.set(this.getValues()) : void 0;
|
|
2351
|
+
},
|
|
2318
2352
|
setLegend: function(legend) {
|
|
2319
2353
|
this.legend = legend;
|
|
2320
2354
|
return $('fieldset legend', this.el).first().html(this.legend);
|