rails-backbone-forms 0.12.0 → 0.14.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e3fca4540b9490eebd58cf719e113313c678f9d0
4
- data.tar.gz: e92315755428a19d134e791441583d0f87c420b8
3
+ metadata.gz: c56e511a9e158536a237db64a312bf744aa7b989
4
+ data.tar.gz: a0ddf9aecbb89848898a430e018280877f6e0589
5
5
  SHA512:
6
- metadata.gz: c55094e51fd63d02d758de064e0ccb13e737f9b37752e8518e1155a4a4e9c39af45cb1afda324f1972ee3b12ab6700d3ad2f32e449d6c94d749909ce6bd469c2
7
- data.tar.gz: b7a499ac74e83c4e3b46b6ebfe6b94ca4742e0d0233143fd143b87b28ab9b4b4f555bdc3fb0dfea909a92dcd6a3d124c16b9fa71e07c620190bf489e1ef82586
6
+ metadata.gz: fbd88bd41a8c650006cdf0466e8b1b640b448b602979907e3071d02249016214719d24bbb5282062b81eda15b6e62e64cff0e10140fcc8a65c05ce1b8abcb865
7
+ data.tar.gz: 8e7c697f1d135df0f35336b62ede070317c46e3ee6344ac0f5fbeefd1e58945bc665d1c32ee4d84fee2c835eadbb8276a0c7403d42d313880612c52758963ac3
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ .DS_Store
data/README.md CHANGED
@@ -4,7 +4,7 @@ rails-backbone-forms
4
4
  This gem provides a version of the
5
5
  [backbone-forms library](https://github.com/powmedia/backbone-forms)
6
6
  designed to work with the Rails 3.1 asset pipeline. It is versioned to match
7
- the backbone-forms library and currently supports 0.10.1.
7
+ the backbone-forms library and currently supports 0.14.0.
8
8
 
9
9
  # <a name="installation"></a>Install
10
10
 
@@ -1,7 +1,7 @@
1
1
  module Rails
2
2
  module Backbone
3
3
  module Forms
4
- VERSION = '0.12.0'
4
+ VERSION = '0.14.0'
5
5
  end
6
6
  end
7
7
  end
@@ -1,2 +1,2 @@
1
1
  //= require backbone-forms/backbone-forms.js
2
- //= require backbone-forms/templates/default.js
2
+ //= require backbone-forms/templates/old.js
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Backbone Forms v0.12.0
2
+ * Backbone Forms v0.13.0
3
3
  *
4
4
  * Copyright (c) 2013 Charles Davison, Pow Media Ltd
5
5
  *
@@ -25,8 +25,7 @@
25
25
 
26
26
 
27
27
  //SOURCE
28
-
29
- //==================================================================================================
28
+ //==================================================================================================
30
29
  //FORM
31
30
  //==================================================================================================
32
31
 
@@ -71,14 +70,14 @@ var Form = Backbone.View.extend({
71
70
  })();
72
71
 
73
72
  //Store important data
74
- _.extend(this, _.pick(options, 'model', 'data', 'idPrefix'));
73
+ _.extend(this, _.pick(options, 'model', 'data', 'idPrefix', 'templateData'));
75
74
 
76
75
  //Override defaults
77
76
  var constructor = this.constructor;
78
- this.template = options.template || constructor.template;
79
- this.Fieldset = options.Fieldset || constructor.Fieldset;
80
- this.Field = options.Field || constructor.Field;
81
- this.NestedField = options.NestedField || constructor.NestedField;
77
+ this.template = options.template || this.template || constructor.template;
78
+ this.Fieldset = options.Fieldset || this.Fieldset || constructor.Fieldset;
79
+ this.Field = options.Field || this.Field || constructor.Field;
80
+ this.NestedField = options.NestedField || this.NestedField || constructor.NestedField;
82
81
 
83
82
  //Check which fields will be included (defaults to all)
84
83
  var selectedFields = this.selectedFields = options.fields || _.keys(schema);
@@ -158,7 +157,7 @@ var Form = Backbone.View.extend({
158
157
  //Re-trigger editor events on the form
159
158
  var formEvent = editor.key+':'+event;
160
159
 
161
- this.trigger.call(this, formEvent, this, editor);
160
+ this.trigger.call(this, formEvent, this, editor, Array.prototype.slice.call(arguments, 2));
162
161
 
163
162
  //Trigger additional events
164
163
  switch (event) {
@@ -259,12 +258,14 @@ var Form = Backbone.View.extend({
259
258
  *
260
259
  * @return {Object} Validation errors
261
260
  */
262
- validate: function() {
261
+ validate: function(options) {
263
262
  var self = this,
264
263
  fields = this.fields,
265
264
  model = this.model,
266
265
  errors = {};
267
266
 
267
+ options = options || {};
268
+
268
269
  //Collect errors from schema validation
269
270
  _.each(fields, function(field) {
270
271
  var error = field.validate();
@@ -274,7 +275,7 @@ var Form = Backbone.View.extend({
274
275
  });
275
276
 
276
277
  //Get errors from default Backbone model validator
277
- if (model && model.validate) {
278
+ if (!options.skipModelValidate && model && model.validate) {
278
279
  var modelErrors = model.validate(this.getValue());
279
280
 
280
281
  if (modelErrors) {
@@ -319,7 +320,13 @@ var Form = Backbone.View.extend({
319
320
  */
320
321
  commit: function(options) {
321
322
  //Validate
322
- var errors = this.validate();
323
+ options = options || {};
324
+
325
+ var validateOptions = {
326
+ skipModelValidate: !options.validate
327
+ };
328
+
329
+ var errors = this.validate(validateOptions);
323
330
  if (errors) return errors;
324
331
 
325
332
  //Commit
@@ -386,7 +393,7 @@ var Form = Backbone.View.extend({
386
393
  */
387
394
  getEditor: function(key) {
388
395
  var field = this.fields[key];
389
- if (!field) throw 'Field not found: '+key;
396
+ if (!field) throw new Error('Field not found: '+key);
390
397
 
391
398
  return field.editor;
392
399
  },
@@ -451,7 +458,7 @@ var Form = Backbone.View.extend({
451
458
  field.remove();
452
459
  });
453
460
 
454
- Backbone.View.prototype.remove.call(this);
461
+ return Backbone.View.prototype.remove.apply(this, arguments);
455
462
  }
456
463
 
457
464
  }, {
@@ -1027,13 +1034,13 @@ Form.Editor = Form.editors.Base = Backbone.View.extend({
1027
1034
 
1028
1035
  //Set initial value
1029
1036
  if (options.model) {
1030
- if (!options.key) throw "Missing option: 'key'";
1037
+ if (!options.key) throw new Error("Missing option: 'key'");
1031
1038
 
1032
1039
  this.model = options.model;
1033
1040
 
1034
1041
  this.value = this.model.get(options.key);
1035
1042
  }
1036
- else if (options.value) {
1043
+ else if (options.value !== undefined) {
1037
1044
  this.value = options.value;
1038
1045
  }
1039
1046
 
@@ -1092,7 +1099,7 @@ Form.Editor = Form.editors.Base = Backbone.View.extend({
1092
1099
  * Extend and override this method
1093
1100
  */
1094
1101
  focus: function() {
1095
- throw 'Not implemented';
1102
+ throw new Error('Not implemented');
1096
1103
  },
1097
1104
 
1098
1105
  /**
@@ -1100,7 +1107,7 @@ Form.Editor = Form.editors.Base = Backbone.View.extend({
1100
1107
  * Extend and override this method
1101
1108
  */
1102
1109
  blur: function() {
1103
- throw 'Not implemented';
1110
+ throw new Error('Not implemented');
1104
1111
  },
1105
1112
 
1106
1113
  /**
@@ -1346,8 +1353,15 @@ Form.editors.Number = Form.editors.Text.extend({
1346
1353
  initialize: function(options) {
1347
1354
  Form.editors.Text.prototype.initialize.call(this, options);
1348
1355
 
1356
+ var schema = this.schema;
1357
+
1349
1358
  this.$el.attr('type', 'number');
1350
- this.$el.attr('step', 'any');
1359
+
1360
+ if (!schema || !schema.editorAttrs || !schema.editorAttrs.step) {
1361
+ // provide a default for `step` attr,
1362
+ // but don't overwrite if already specified
1363
+ this.$el.attr('step', 'any');
1364
+ }
1351
1365
  },
1352
1366
 
1353
1367
  /**
@@ -1520,7 +1534,7 @@ Form.editors.Select = Form.editors.Base.extend({
1520
1534
  initialize: function(options) {
1521
1535
  Form.editors.Base.prototype.initialize.call(this, options);
1522
1536
 
1523
- if (!this.schema || !this.schema.options) throw "Missing required 'schema.options'";
1537
+ if (!this.schema || !this.schema.options) throw new Error("Missing required 'schema.options'");
1524
1538
  },
1525
1539
 
1526
1540
  render: function() {
@@ -1571,6 +1585,7 @@ Form.editors.Select = Form.editors.Base.extend({
1571
1585
  * @param {Mixed} Options as a simple array e.g. ['option1', 'option2']
1572
1586
  * or as an array of objects e.g. [{val: 543, label: 'Title for object 543'}]
1573
1587
  * or as a string of <option> HTML to insert into the <select>
1588
+ * or any object
1574
1589
  */
1575
1590
  renderOptions: function(options) {
1576
1591
  var $select = this.$el,
@@ -1604,17 +1619,21 @@ Form.editors.Select = Form.editors.Base.extend({
1604
1619
 
1605
1620
  else if (_.isFunction(options)) {
1606
1621
  var newOptions;
1607
-
1622
+
1608
1623
  options(function(opts) {
1609
1624
  newOptions = opts;
1610
1625
  }, this);
1611
-
1626
+
1612
1627
  html = this._getOptionsHtml(newOptions);
1628
+ //Or any object
1629
+ }else{
1630
+ html=this._objectToHtml(options);
1613
1631
  }
1614
1632
 
1615
1633
  return html;
1616
1634
  },
1617
1635
 
1636
+
1618
1637
  getValue: function() {
1619
1638
  return this.$el.val();
1620
1639
  },
@@ -1652,6 +1671,27 @@ Form.editors.Select = Form.editors.Base.extend({
1652
1671
 
1653
1672
  return html;
1654
1673
  },
1674
+ /**
1675
+ * Transforms an object into HTML ready to use in the renderOptions method
1676
+ * @param {Object}
1677
+ * @return {String}
1678
+ */
1679
+ _objectToHtml: function(obj) {
1680
+ //Convert object to array first
1681
+ var array = [];
1682
+ for(var key in obj){
1683
+ if( obj.hasOwnProperty( key ) ) {
1684
+ array.push({ val: key, label: obj[key] });
1685
+ }
1686
+ }
1687
+
1688
+ //Now convert to HTML
1689
+ var html = this._arrayToHtml(array);
1690
+
1691
+ return html;
1692
+ },
1693
+
1694
+
1655
1695
 
1656
1696
  /**
1657
1697
  * Create the <option> HTML
@@ -1784,6 +1824,8 @@ Form.editors.Checkboxes = Form.editors.Select.extend({
1784
1824
 
1785
1825
  tagName: 'ul',
1786
1826
 
1827
+ groupNumber: 0,
1828
+
1787
1829
  events: {
1788
1830
  'click input[type=checkbox]': function() {
1789
1831
  this.trigger('change', this);
@@ -1839,16 +1881,29 @@ Form.editors.Checkboxes = Form.editors.Select.extend({
1839
1881
 
1840
1882
  _.each(array, function(option, index) {
1841
1883
  var itemHtml = '<li>';
1884
+ var close = true;
1842
1885
  if (_.isObject(option)) {
1843
- var val = (option.val || option.val === 0) ? option.val : '';
1844
- itemHtml += ('<input type="checkbox" name="'+self.getName()+'" value="'+val+'" id="'+self.id+'-'+index+'" />');
1845
- itemHtml += ('<label for="'+self.id+'-'+index+'">'+option.label+'</label>');
1886
+ if (option.group) {
1887
+ var originalId = self.id;
1888
+ self.id += "-" + self.groupNumber++;
1889
+ itemHtml = ('<fieldset class="group"> <legend>'+option.group+'</legend>');
1890
+ itemHtml += (self._arrayToHtml(option.options));
1891
+ itemHtml += ('</fieldset>');
1892
+ self.id = originalId;
1893
+ close = false;
1894
+ }else{
1895
+ var val = (option.val || option.val === 0) ? option.val : '';
1896
+ itemHtml += ('<input type="checkbox" name="'+self.getName()+'" value="'+val+'" id="'+self.id+'-'+index+'" />');
1897
+ itemHtml += ('<label for="'+self.id+'-'+index+'">'+option.label+'</label>');
1898
+ }
1846
1899
  }
1847
1900
  else {
1848
1901
  itemHtml += ('<input type="checkbox" name="'+self.getName()+'" value="'+option+'" id="'+self.id+'-'+index+'" />');
1849
1902
  itemHtml += ('<label for="'+self.id+'-'+index+'">'+option+'</label>');
1850
1903
  }
1851
- itemHtml += '</li>';
1904
+ if(close){
1905
+ itemHtml += '</li>';
1906
+ }
1852
1907
  html.push(itemHtml);
1853
1908
  });
1854
1909
 
@@ -1879,7 +1934,7 @@ Form.editors.Object = Form.editors.Base.extend({
1879
1934
  Form.editors.Base.prototype.initialize.call(this, options);
1880
1935
 
1881
1936
  //Check required options
1882
- if (!this.form) throw 'Missing required option "form"';
1937
+ if (!this.form) throw new Error('Missing required option "form"');
1883
1938
  if (!this.schema.subSchema) throw new Error("Missing required 'schema.subSchema' option for Object editor");
1884
1939
  },
1885
1940
 
@@ -1965,8 +2020,8 @@ Form.editors.NestedModel = Form.editors.Object.extend({
1965
2020
  initialize: function(options) {
1966
2021
  Form.editors.Base.prototype.initialize.call(this, options);
1967
2022
 
1968
- if (!this.form) throw 'Missing required option "form"';
1969
- if (!options.schema.model) throw 'Missing required "schema.model" option for NestedModel editor';
2023
+ if (!this.form) throw new Error('Missing required option "form"');
2024
+ if (!options.schema.model) throw new Error('Missing required "schema.model" option for NestedModel editor');
1970
2025
  },
1971
2026
 
1972
2027
  render: function() {
@@ -2379,10 +2434,11 @@ Form.editors.DateTime = Form.editors.Base.extend({
2379
2434
 
2380
2435
 
2381
2436
  //Metadata
2382
- Form.VERSION = '0.12.0';
2437
+ Form.VERSION = '0.13.0';
2383
2438
 
2384
2439
 
2385
2440
  //Exports
2386
2441
  Backbone.Form = Form;
2442
+ if (typeof exports !== 'undefined') exports = Form;
2387
2443
 
2388
- })(this);
2444
+ })(window || global || this);
@@ -26,7 +26,7 @@
26
26
  editors.Base.prototype.initialize.call(this, options);
27
27
 
28
28
  var schema = this.schema;
29
- if (!schema) throw "Missing required option 'schema'";
29
+ if (!schema) throw new Error("Missing required option 'schema'");
30
30
 
31
31
  this.template = options.template || this.constructor.template;
32
32
 
@@ -417,10 +417,10 @@
417
417
  Form.editors.Base.prototype.initialize.call(this, options);
418
418
 
419
419
  //Dependencies
420
- if (!Form.editors.List.Modal.ModalAdapter) throw 'A ModalAdapter is required';
420
+ if (!Form.editors.List.Modal.ModalAdapter) throw new Error('A ModalAdapter is required');
421
421
 
422
422
  this.form = options.form;
423
- if (!options.form) throw 'Missing required option: "form"';
423
+ if (!options.form) throw new Error('Missing required option: "form"');
424
424
 
425
425
  //Template
426
426
  this.template = options.template || this.constructor.template;
@@ -610,7 +610,7 @@
610
610
 
611
611
  var schema = this.schema;
612
612
 
613
- if (!schema.subSchema) throw 'Missing required option "schema.subSchema"';
613
+ if (!schema.subSchema) throw new Error('Missing required option "schema.subSchema"');
614
614
 
615
615
  this.nestedSchema = schema.subSchema;
616
616
  }
@@ -623,7 +623,7 @@
623
623
 
624
624
  var schema = this.schema;
625
625
 
626
- if (!schema.model) throw 'Missing required option "schema.model"';
626
+ if (!schema.model) throw new Error('Missing required option "schema.model"');
627
627
 
628
628
  var nestedSchema = schema.model.prototype.schema;
629
629
 
@@ -1 +1 @@
1
- (function(e){e.editors.List=e.editors.Base.extend({events:{'click [data-action="add"]':function(e){e.preventDefault(),this.addItem(null,!0)}},initialize:function(t){t=t||{};var n=e.editors;n.Base.prototype.initialize.call(this,t);var r=this.schema;if(!r)throw"Missing required option 'schema'";this.template=t.template||this.constructor.template,this.Editor=function(){var e=r.itemType;return e?n.List[e]?n.List[e]:n[e]:n.Text}(),this.items=[]},render:function(){var e=this,t=this.value||[],n=$($.trim(this.template()));return this.$list=n.is("[data-items]")?n:n.find("[data-items]"),t.length?_.each(t,function(t){e.addItem(t)}):this.Editor.isAsync||this.addItem(),this.setElement(n),this.$el.attr("id",this.id),this.$el.attr("name",this.key),this.hasFocus&&this.trigger("blur",this),this},addItem:function(t,n){var r=this,i=e.editors,s=(new i.List.Item({list:this,form:this.form,schema:this.schema,value:t,Editor:this.Editor,key:this.key})).render(),o=function(){r.items.push(s),r.$list.append(s.el),s.editor.on("all",function(e){if(e==="change")return;var t=_.toArray(arguments);t[0]="item:"+e,t.splice(1,0,r),i.List.prototype.trigger.apply(this,t)},r),s.editor.on("change",function(){s.addEventTriggered||(s.addEventTriggered=!0,this.trigger("add",this,s.editor)),this.trigger("item:change",this,s.editor),this.trigger("change",this)},r),s.editor.on("focus",function(){if(this.hasFocus)return;this.trigger("focus",this)},r),s.editor.on("blur",function(){if(!this.hasFocus)return;var e=this;setTimeout(function(){if(_.find(e.items,function(e){return e.editor.hasFocus}))return;e.trigger("blur",e)},0)},r);if(n||t)s.addEventTriggered=!0;n&&(r.trigger("add",r,s.editor),r.trigger("change",r))};return this.Editor.isAsync?s.editor.on("readyToAdd",o,this):(o(),s.editor.focus()),s},removeItem:function(e){var t=this.schema.confirmDelete;if(t&&!confirm(t))return;var n=_.indexOf(this.items,e);this.items[n].remove(),this.items.splice(n,1),e.addEventTriggered&&(this.trigger("remove",this,e.editor),this.trigger("change",this)),!this.items.length&&!this.Editor.isAsync&&this.addItem()},getValue:function(){var e=_.map(this.items,function(e){return e.getValue()});return _.without(e,undefined,"")},setValue:function(e){this.value=e,this.render()},focus:function(){if(this.hasFocus)return;this.items[0]&&this.items[0].editor.focus()},blur:function(){if(!this.hasFocus)return;var e=_.find(this.items,function(e){return e.editor.hasFocus});e&&e.editor.blur()},remove:function(){_.invoke(this.items,"remove"),e.editors.Base.prototype.remove.call(this)},validate:function(){if(!this.validators)return null;var e=_.map(this.items,function(e){return e.validate()}),t=_.compact(e).length?!0:!1;if(!t)return null;var n={type:"list",message:"Some of the items in the list failed validation",errors:e};return n}},{template:_.template(' <div> <div data-items></div> <button type="button" data-action="add">Add</button> </div> ',null,e.templateSettings)}),e.editors.List.Item=e.editors.Base.extend({events:{'click [data-action="remove"]':function(e){e.preventDefault(),this.list.removeItem(this)},"keydown input[type=text]":function(e){if(e.keyCode!==13)return;e.preventDefault(),this.list.addItem(),this.list.$list.find("> li:last input").focus()}},initialize:function(t){this.list=t.list,this.schema=t.schema||this.list.schema,this.value=t.value,this.Editor=t.Editor||e.editors.Text,this.key=t.key,this.template=t.template||this.schema.itemTemplate||this.constructor.template,this.errorClassName=t.errorClassName||this.constructor.errorClassName,this.form=t.form},render:function(){this.editor=(new this.Editor({key:this.key,schema:this.schema,value:this.value,list:this.list,item:this,form:this.form})).render();var e=$($.trim(this.template()));return e.find("[data-editor]").append(this.editor.el),this.setElement(e),this},getValue:function(){return this.editor.getValue()},setValue:function(e){this.editor.setValue(e)},focus:function(){this.editor.focus()},blur:function(){this.editor.blur()},remove:function(){this.editor.remove(),Backbone.View.prototype.remove.call(this)},validate:function(){var e=this.getValue(),t=this.list.form?this.list.form.getValue():{},n=this.schema.validators,r=this.getValidator;if(!n)return null;var i=null;return _.every(n,function(n){return i=r(n)(e,t),i?!1:!0}),i?this.setError(i):this.clearError(),i?i:null},setError:function(e){this.$el.addClass(this.errorClassName),this.$el.attr("title",e.message)},clearError:function(){this.$el.removeClass(this.errorClassName),this.$el.attr("title",null)}},{template:_.template(' <div> <span data-editor></span> <button type="button" data-action="remove">&times;</button> </div> ',null,e.templateSettings),errorClassName:"error"}),e.editors.List.Modal=e.editors.Base.extend({events:{click:"openEditor"},initialize:function(t){t=t||{},e.editors.Base.prototype.initialize.call(this,t);if(!e.editors.List.Modal.ModalAdapter)throw"A ModalAdapter is required";this.form=t.form;if(!t.form)throw'Missing required option: "form"';this.template=t.template||this.constructor.template},render:function(){var e=this;return _.isEmpty(this.value)?this.openEditor():(this.renderSummary(),setTimeout(function(){e.trigger("readyToAdd")},0)),this.hasFocus&&this.trigger("blur",this),this},renderSummary:function(){this.$el.html($.trim(this.template({summary:this.getStringValue()})))},itemToString:function(t){var n=function(t){var n={key:t};return e.Field.prototype.createTitle.call(n)};t=t||{};var r=[];return _.each(this.nestedSchema,function(e,i){var s=e.title?e.title:n(i),o=t[i];if(_.isUndefined(o)||_.isNull(o))o="";r.push(s+": "+o)}),r.join("<br />")},getStringValue:function(){var e=this.schema,t=this.getValue();return _.isEmpty(t)?"[Empty]":e.itemToString?e.itemToString(t):this.itemToString(t)},openEditor:function(){var t=this,n=this.form.constructor,r=this.modalForm=new n({schema:this.nestedSchema,data:this.value}),i=this.modal=new e.editors.List.Modal.ModalAdapter({content:r,animate:!0});i.open(),this.trigger("open",this),this.trigger("focus",this),i.on("cancel",this.onModalClosed,this),i.on("ok",_.bind(this.onModalSubmitted,this))},onModalSubmitted:function(){var e=this.modal,t=this.modalForm,n=!this.value,r=t.validate();if(r)return e.preventClose();this.value=t.getValue(),this.renderSummary(),n&&this.trigger("readyToAdd"),this.trigger("change",this),this.onModalClosed()},onModalClosed:function(){this.modal=null,this.modalForm=null,this.trigger("close",this),this.trigger("blur",this)},getValue:function(){return this.value},setValue:function(e){this.value=e},focus:function(){if(this.hasFocus)return;this.openEditor()},blur:function(){if(!this.hasFocus)return;this.modal&&this.modal.trigger("cancel")}},{template:_.template(" <div><%= summary %></div> ",null,e.templateSettings),ModalAdapter:Backbone.BootstrapModal,isAsync:!0}),e.editors.List.Object=e.editors.List.Modal.extend({initialize:function(){e.editors.List.Modal.prototype.initialize.apply(this,arguments);var t=this.schema;if(!t.subSchema)throw'Missing required option "schema.subSchema"';this.nestedSchema=t.subSchema}}),e.editors.List.NestedModel=e.editors.List.Modal.extend({initialize:function(){e.editors.List.Modal.prototype.initialize.apply(this,arguments);var t=this.schema;if(!t.model)throw'Missing required option "schema.model"';var n=t.model.prototype.schema;this.nestedSchema=_.isFunction(n)?n():n},getStringValue:function(){var e=this.schema,t=this.getValue();return _.isEmpty(t)?null:e.itemToString?e.itemToString(t):(new e.model(t)).toString()}})})(Backbone.Form)
1
+ (function(e){e.editors.List=e.editors.Base.extend({events:{'click [data-action="add"]':function(e){e.preventDefault(),this.addItem(null,!0)}},initialize:function(t){t=t||{};var n=e.editors;n.Base.prototype.initialize.call(this,t);var r=this.schema;if(!r)throw new Error("Missing required option 'schema'");this.template=t.template||this.constructor.template,this.Editor=function(){var e=r.itemType;return e?n.List[e]?n.List[e]:n[e]:n.Text}(),this.items=[]},render:function(){var e=this,t=this.value||[],n=$($.trim(this.template()));return this.$list=n.is("[data-items]")?n:n.find("[data-items]"),t.length?_.each(t,function(t){e.addItem(t)}):this.Editor.isAsync||this.addItem(),this.setElement(n),this.$el.attr("id",this.id),this.$el.attr("name",this.key),this.hasFocus&&this.trigger("blur",this),this},addItem:function(t,n){var r=this,i=e.editors,s=(new i.List.Item({list:this,form:this.form,schema:this.schema,value:t,Editor:this.Editor,key:this.key})).render(),o=function(){r.items.push(s),r.$list.append(s.el),s.editor.on("all",function(e){if(e==="change")return;var t=_.toArray(arguments);t[0]="item:"+e,t.splice(1,0,r),i.List.prototype.trigger.apply(this,t)},r),s.editor.on("change",function(){s.addEventTriggered||(s.addEventTriggered=!0,this.trigger("add",this,s.editor)),this.trigger("item:change",this,s.editor),this.trigger("change",this)},r),s.editor.on("focus",function(){if(this.hasFocus)return;this.trigger("focus",this)},r),s.editor.on("blur",function(){if(!this.hasFocus)return;var e=this;setTimeout(function(){if(_.find(e.items,function(e){return e.editor.hasFocus}))return;e.trigger("blur",e)},0)},r);if(n||t)s.addEventTriggered=!0;n&&(r.trigger("add",r,s.editor),r.trigger("change",r))};return this.Editor.isAsync?s.editor.on("readyToAdd",o,this):(o(),s.editor.focus()),s},removeItem:function(e){var t=this.schema.confirmDelete;if(t&&!confirm(t))return;var n=_.indexOf(this.items,e);this.items[n].remove(),this.items.splice(n,1),e.addEventTriggered&&(this.trigger("remove",this,e.editor),this.trigger("change",this)),!this.items.length&&!this.Editor.isAsync&&this.addItem()},getValue:function(){var e=_.map(this.items,function(e){return e.getValue()});return _.without(e,undefined,"")},setValue:function(e){this.value=e,this.render()},focus:function(){if(this.hasFocus)return;this.items[0]&&this.items[0].editor.focus()},blur:function(){if(!this.hasFocus)return;var e=_.find(this.items,function(e){return e.editor.hasFocus});e&&e.editor.blur()},remove:function(){_.invoke(this.items,"remove"),e.editors.Base.prototype.remove.call(this)},validate:function(){if(!this.validators)return null;var e=_.map(this.items,function(e){return e.validate()}),t=_.compact(e).length?!0:!1;if(!t)return null;var n={type:"list",message:"Some of the items in the list failed validation",errors:e};return n}},{template:_.template(' <div> <div data-items></div> <button type="button" data-action="add">Add</button> </div> ',null,e.templateSettings)}),e.editors.List.Item=e.editors.Base.extend({events:{'click [data-action="remove"]':function(e){e.preventDefault(),this.list.removeItem(this)},"keydown input[type=text]":function(e){if(e.keyCode!==13)return;e.preventDefault(),this.list.addItem(),this.list.$list.find("> li:last input").focus()}},initialize:function(t){this.list=t.list,this.schema=t.schema||this.list.schema,this.value=t.value,this.Editor=t.Editor||e.editors.Text,this.key=t.key,this.template=t.template||this.schema.itemTemplate||this.constructor.template,this.errorClassName=t.errorClassName||this.constructor.errorClassName,this.form=t.form},render:function(){this.editor=(new this.Editor({key:this.key,schema:this.schema,value:this.value,list:this.list,item:this,form:this.form})).render();var e=$($.trim(this.template()));return e.find("[data-editor]").append(this.editor.el),this.setElement(e),this},getValue:function(){return this.editor.getValue()},setValue:function(e){this.editor.setValue(e)},focus:function(){this.editor.focus()},blur:function(){this.editor.blur()},remove:function(){this.editor.remove(),Backbone.View.prototype.remove.call(this)},validate:function(){var e=this.getValue(),t=this.list.form?this.list.form.getValue():{},n=this.schema.validators,r=this.getValidator;if(!n)return null;var i=null;return _.every(n,function(n){return i=r(n)(e,t),i?!1:!0}),i?this.setError(i):this.clearError(),i?i:null},setError:function(e){this.$el.addClass(this.errorClassName),this.$el.attr("title",e.message)},clearError:function(){this.$el.removeClass(this.errorClassName),this.$el.attr("title",null)}},{template:_.template(' <div> <span data-editor></span> <button type="button" data-action="remove">&times;</button> </div> ',null,e.templateSettings),errorClassName:"error"}),e.editors.List.Modal=e.editors.Base.extend({events:{click:"openEditor"},initialize:function(t){t=t||{},e.editors.Base.prototype.initialize.call(this,t);if(!e.editors.List.Modal.ModalAdapter)throw new Error("A ModalAdapter is required");this.form=t.form;if(!t.form)throw new Error('Missing required option: "form"');this.template=t.template||this.constructor.template},render:function(){var e=this;return _.isEmpty(this.value)?this.openEditor():(this.renderSummary(),setTimeout(function(){e.trigger("readyToAdd")},0)),this.hasFocus&&this.trigger("blur",this),this},renderSummary:function(){this.$el.html($.trim(this.template({summary:this.getStringValue()})))},itemToString:function(t){var n=function(t){var n={key:t};return e.Field.prototype.createTitle.call(n)};t=t||{};var r=[];return _.each(this.nestedSchema,function(e,i){var s=e.title?e.title:n(i),o=t[i];if(_.isUndefined(o)||_.isNull(o))o="";r.push(s+": "+o)}),r.join("<br />")},getStringValue:function(){var e=this.schema,t=this.getValue();return _.isEmpty(t)?"[Empty]":e.itemToString?e.itemToString(t):this.itemToString(t)},openEditor:function(){var t=this,n=this.form.constructor,r=this.modalForm=new n({schema:this.nestedSchema,data:this.value}),i=this.modal=new e.editors.List.Modal.ModalAdapter({content:r,animate:!0});i.open(),this.trigger("open",this),this.trigger("focus",this),i.on("cancel",this.onModalClosed,this),i.on("ok",_.bind(this.onModalSubmitted,this))},onModalSubmitted:function(){var e=this.modal,t=this.modalForm,n=!this.value,r=t.validate();if(r)return e.preventClose();this.value=t.getValue(),this.renderSummary(),n&&this.trigger("readyToAdd"),this.trigger("change",this),this.onModalClosed()},onModalClosed:function(){this.modal=null,this.modalForm=null,this.trigger("close",this),this.trigger("blur",this)},getValue:function(){return this.value},setValue:function(e){this.value=e},focus:function(){if(this.hasFocus)return;this.openEditor()},blur:function(){if(!this.hasFocus)return;this.modal&&this.modal.trigger("cancel")}},{template:_.template(" <div><%= summary %></div> ",null,e.templateSettings),ModalAdapter:Backbone.BootstrapModal,isAsync:!0}),e.editors.List.Object=e.editors.List.Modal.extend({initialize:function(){e.editors.List.Modal.prototype.initialize.apply(this,arguments);var t=this.schema;if(!t.subSchema)throw new Error('Missing required option "schema.subSchema"');this.nestedSchema=t.subSchema}}),e.editors.List.NestedModel=e.editors.List.Modal.extend({initialize:function(){e.editors.List.Modal.prototype.initialize.apply(this,arguments);var t=this.schema;if(!t.model)throw new Error('Missing required option "schema.model"');var n=t.model.prototype.schema;this.nestedSchema=_.isFunction(n)?n():n},getStringValue:function(){var e=this.schema,t=this.getValue();return _.isEmpty(t)?null:e.itemToString?e.itemToString(t):(new e.model(t)).toString()}})})(Backbone.Form)
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
  /**
10
- * Bootstrap templates for Backbone Forms
10
+ * Bootstrap 2 templates
11
11
  */
12
12
  Form.template = _.template('\
13
13
  <form class="form-horizontal" data-fieldsets></form>\
@@ -46,25 +46,29 @@
46
46
  ');
47
47
 
48
48
 
49
- Form.editors.List.template = _.template('\
50
- <div class="bbf-list">\
51
- <ul class="unstyled clearfix" data-items></ul>\
52
- <button class="btn bbf-add" data-action="add">Add</button>\
53
- </div>\
54
- ');
49
+ if (Form.editors.List) {
55
50
 
51
+ Form.editors.List.template = _.template('\
52
+ <div class="bbf-list">\
53
+ <ul class="unstyled clearfix" data-items></ul>\
54
+ <button type="button" class="btn bbf-add" data-action="add">Add</button>\
55
+ </div>\
56
+ ');
56
57
 
57
- Form.editors.List.Item.template = _.template('\
58
- <li class="clearfix">\
59
- <div class="pull-left" data-editor></div>\
60
- <button type="button" class="btn bbf-del" data-action="remove">&times;</button>\
61
- </li>\
62
- ');
63
-
64
58
 
65
- Form.editors.List.Object.template = Form.editors.List.NestedModel.template = _.template('\
66
- <div class="bbf-list-modal"><%= summary %></div>\
67
- ');
59
+ Form.editors.List.Item.template = _.template('\
60
+ <li class="clearfix">\
61
+ <div class="pull-left" data-editor></div>\
62
+ <button type="button" class="btn bbf-del" data-action="remove">&times;</button>\
63
+ </li>\
64
+ ');
65
+
66
+
67
+ Form.editors.List.Object.template = Form.editors.List.NestedModel.template = _.template('\
68
+ <div class="bbf-list-modal"><%= summary %></div>\
69
+ ');
70
+
71
+ }
68
72
 
69
73
 
70
74
  })(Backbone.Form);
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Include this template file after backbone-forms.amd.js to override the default templates
3
+ *
4
+ * 'data-*' attributes control where elements are placed
5
+ */
6
+ ;(function(Form) {
7
+
8
+
9
+ /**
10
+ * Bootstrap 3 templates
11
+ */
12
+ Form.template = _.template('\
13
+ <form class="form-horizontal" role="form" data-fieldsets></form>\
14
+ ');
15
+
16
+
17
+ Form.Fieldset.template = _.template('\
18
+ <fieldset data-fields>\
19
+ <% if (legend) { %>\
20
+ <legend><%= legend %></legend>\
21
+ <% } %>\
22
+ </fieldset>\
23
+ ');
24
+
25
+
26
+ Form.Field.template = _.template('\
27
+ <div class="form-group field-<%= key %>">\
28
+ <label class="col-sm-2 control-label" for="<%= editorId %>"><%= title %></label>\
29
+ <div class="col-sm-10">\
30
+ <span data-editor></span>\
31
+ <p class="help-block" data-error></p>\
32
+ <p class="help-block"><%= help %></p>\
33
+ </div>\
34
+ </div>\
35
+ ');
36
+
37
+
38
+ Form.NestedField.template = _.template('\
39
+ <div class="field-<%= key %>">\
40
+ <div title="<%= title %>" class="input-xlarge">\
41
+ <span data-editor></span>\
42
+ <div class="help-inline" data-error></div>\
43
+ </div>\
44
+ <div class="help-block"><%= help %></div>\
45
+ </div>\
46
+ ');
47
+
48
+ Form.editors.Base.prototype.className = 'form-control';
49
+ Form.Field.errorClassName = 'has-error';
50
+
51
+
52
+ if (Form.editors.List) {
53
+
54
+ Form.editors.List.template = _.template('\
55
+ <div class="bbf-list">\
56
+ <ul class="unstyled clearfix" data-items></ul>\
57
+ <button type="button" class="btn bbf-add" data-action="add">Add</button>\
58
+ </div>\
59
+ ');
60
+
61
+
62
+ Form.editors.List.Item.template = _.template('\
63
+ <li class="clearfix">\
64
+ <div class="pull-left" data-editor></div>\
65
+ <button type="button" class="btn bbf-del" data-action="remove">&times;</button>\
66
+ </li>\
67
+ ');
68
+
69
+
70
+ Form.editors.List.Object.template = Form.editors.List.NestedModel.template = _.template('\
71
+ <div class="bbf-list-modal"><%= summary %></div>\
72
+ ');
73
+
74
+ }
75
+
76
+
77
+ })(Backbone.Form);
@@ -64,25 +64,30 @@
64
64
  ');
65
65
 
66
66
 
67
- Form.editors.List.template = _.template('\
68
- <div class="bbf-list">\
69
- <ul data-items></ul>\
70
- <div class="bbf-actions"><button type="button" data-action="add">Add</div>\
71
- </div>\
72
- ');
73
-
74
-
75
- Form.editors.List.Item.template = _.template('\
76
- <li>\
77
- <button type="button" data-action="remove" class="bbf-remove">&times;</button>\
78
- <div class="bbf-editor-container" data-editor></div>\
79
- </li>\
80
- ');
67
+ if (Form.editors.List) {
81
68
 
69
+ Form.editors.List.template = _.template('\
70
+ <div class="bbf-list">\
71
+ <ul data-items></ul>\
72
+ <div class="bbf-actions"><button type="button" data-action="add">Add</div>\
73
+ </div>\
74
+ ');
75
+
76
+
77
+ Form.editors.List.Item.template = _.template('\
78
+ <li>\
79
+ <button type="button" data-action="remove" class="bbf-remove">&times;</button>\
80
+ <div class="bbf-editor-container" data-editor></div>\
81
+ </li>\
82
+ ');
83
+
84
+
85
+ Form.editors.List.Object.template = Form.editors.List.NestedModel.template = _.template('\
86
+ <div class="bbf-list-modal"><%= summary %></div>\
87
+ ');
88
+
89
+ }
82
90
 
83
- Form.editors.List.Object.template = Form.editors.List.NestedModel.template = _.template('\
84
- <div class="bbf-list-modal"><%= summary %></div>\
85
- ');
86
91
 
87
92
 
88
93
  })(Backbone.Form);
@@ -1,3 +1,3 @@
1
1
  /*
2
- *= require backbone-forms/templates/default.css
2
+ *= require backbone-forms/templates/old.css
3
3
  */
@@ -0,0 +1,43 @@
1
+ /* Date */
2
+ .bbf-date .bbf-date {
3
+ width: 4em
4
+ }
5
+
6
+ .bbf-date .bbf-month {
7
+ width: 9em;
8
+ }
9
+
10
+ .bbf-date .bbf-year {
11
+ width: 5em;
12
+ }
13
+
14
+
15
+ /* DateTime */
16
+ .bbf-datetime select {
17
+ width: 4em;
18
+ }
19
+
20
+
21
+ /* List */
22
+ .bbf-list .bbf-add {
23
+ margin-top: -10px
24
+ }
25
+
26
+ .bbf-list li {
27
+ margin-bottom: 5px
28
+ }
29
+
30
+ .bbf-list .bbf-del {
31
+ margin-left: 4px
32
+ }
33
+
34
+
35
+ /* List.Modal */
36
+ .bbf-list-modal {
37
+ cursor: pointer;
38
+ border: 1px solid #ccc;
39
+ width: 208px;
40
+ border-radius: 3px;
41
+ padding: 4px;
42
+ color: #555;
43
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-backbone-forms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aubrey Holland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-18 00:00:00.000000000 Z
11
+ date: 2014-03-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Rails 3.1 support for the backbone-forms library
14
14
  email:
@@ -17,7 +17,7 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - .gitignore
20
+ - ".gitignore"
21
21
  - Gemfile
22
22
  - README.md
23
23
  - Rakefile
@@ -33,10 +33,12 @@ files:
33
33
  - vendor/assets/javascripts/backbone-forms/editors/list.js
34
34
  - vendor/assets/javascripts/backbone-forms/editors/list.min.js
35
35
  - vendor/assets/javascripts/backbone-forms/templates/bootstrap.js
36
+ - vendor/assets/javascripts/backbone-forms/templates/bootstrap3.js
36
37
  - vendor/assets/javascripts/backbone-forms/templates/old.js
37
38
  - vendor/assets/stylesheets/backbone-forms-bootstrap.css
38
39
  - vendor/assets/stylesheets/backbone-forms.css
39
40
  - vendor/assets/stylesheets/backbone-forms/templates/bootstrap.css
41
+ - vendor/assets/stylesheets/backbone-forms/templates/bootstrap3.css
40
42
  - vendor/assets/stylesheets/backbone-forms/templates/old.css
41
43
  homepage: ''
42
44
  licenses: []
@@ -47,17 +49,17 @@ require_paths:
47
49
  - lib
48
50
  required_ruby_version: !ruby/object:Gem::Requirement
49
51
  requirements:
50
- - - '>='
52
+ - - ">="
51
53
  - !ruby/object:Gem::Version
52
54
  version: '0'
53
55
  required_rubygems_version: !ruby/object:Gem::Requirement
54
56
  requirements:
55
- - - '>='
57
+ - - ">="
56
58
  - !ruby/object:Gem::Version
57
59
  version: '0'
58
60
  requirements: []
59
61
  rubyforge_project: rails-backbone-forms
60
- rubygems_version: 2.0.3
62
+ rubygems_version: 2.2.2
61
63
  signing_key:
62
64
  specification_version: 4
63
65
  summary: A wrapper for backbone-forms in the Rails asset pipeline