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.
@@ -3,7 +3,7 @@
3
3
  _.mixin(_.string);
4
4
 
5
5
  window.Luca = {
6
- VERSION: "0.7.0",
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
- return this.registerCollectionEvents();
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
- _(fields).each(function(field) {
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
- getValues: function(reject_blank, skip_buttons) {
2280
- if (reject_blank == null) reject_blank = false;
2281
- if (skip_buttons == null) skip_buttons = true;
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 (!skip) memo[field.input_name || name] = value;
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.apply(["after:submit", this].concat(arguments));
2303
- return this.trigger.apply(["after:submit:fatal_error", this].concat(arguments));
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.current_model.set(this.getValues());
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
- return describe('Generating a form from a model', function() {
2796
- return beforeEach(function() {
2797
- var Model;
2798
- Model = Backbone.Model.extend({
2799
- schema: {
2800
- field0: "hidden",
2801
- field1: "text",
2802
- field3: "boolean",
2803
- field4: "blob",
2804
- field5: {
2805
- collection: "sample"
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 this.model = new Model({
2810
- field0: 1,
2811
- field1: "jonathan",
2812
- field3: true,
2813
- field4: "what up player?"
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
- return it("should find a created view in the cache", function() {
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.0",
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
- return this.registerCollectionEvents();
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
- _(fields).each(function(field) {
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
- getValues: function(reject_blank, skip_buttons) {
2280
- if (reject_blank == null) reject_blank = false;
2281
- if (skip_buttons == null) skip_buttons = true;
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 (!skip) memo[field.input_name || name] = value;
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.apply(["after:submit", this].concat(arguments));
2303
- return this.trigger.apply(["after:submit:fatal_error", this].concat(arguments));
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.current_model.set(this.getValues());
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);