rails-backbone-forms 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rails/backbone/forms/version.rb +1 -1
- data/vendor/assets/javascripts/backbone-forms/adapters/backbone.bootstrap-modal.js +76 -17
- data/vendor/assets/javascripts/backbone-forms/adapters/backbone.bootstrap-modal.min.js +1 -0
- data/vendor/assets/javascripts/backbone-forms/backbone-forms.js +331 -272
- data/vendor/assets/javascripts/backbone-forms/editors/list.js +84 -49
- data/vendor/assets/javascripts/backbone-forms/editors/list.min.js +1 -0
- data/vendor/assets/javascripts/backbone-forms/templates/bootstrap.js +6 -3
- data/vendor/assets/javascripts/backbone-forms/templates/default.js +2 -0
- data/vendor/assets/stylesheets/backbone-forms/templates/default.css +6 -0
- metadata +5 -6
- data/vendor/assets/javascripts/backbone-forms/editors/jquery-ui.js +0 -500
- data/vendor/assets/stylesheets/backbone-forms-bootstrap.css +0 -3
- data/vendor/assets/stylesheets/backbone-forms/editors/jquery-ui.css +0 -65
@@ -30,7 +30,7 @@
|
|
30
30
|
<h3>{{title}}</h3>\
|
31
31
|
</div>\
|
32
32
|
<% } %>\
|
33
|
-
<div class="modal-body"
|
33
|
+
<div class="modal-body">{{content}}</div>\
|
34
34
|
<div class="modal-footer">\
|
35
35
|
<% if (allowCancel) { %>\
|
36
36
|
<% if (cancelText) { %>\
|
@@ -54,19 +54,32 @@
|
|
54
54
|
event.preventDefault();
|
55
55
|
|
56
56
|
this.trigger('cancel');
|
57
|
-
|
57
|
+
|
58
|
+
if (this.options.content && this.options.content.trigger) {
|
59
|
+
this.options.content.trigger('cancel', this);
|
60
|
+
}
|
58
61
|
},
|
59
62
|
'click .cancel': function(event) {
|
60
63
|
event.preventDefault();
|
61
64
|
|
62
65
|
this.trigger('cancel');
|
63
|
-
|
66
|
+
|
67
|
+
if (this.options.content && this.options.content.trigger) {
|
68
|
+
this.options.content.trigger('cancel', this);
|
69
|
+
}
|
64
70
|
},
|
65
71
|
'click .ok': function(event) {
|
66
72
|
event.preventDefault();
|
67
73
|
|
68
74
|
this.trigger('ok');
|
69
|
-
|
75
|
+
|
76
|
+
if (this.options.content && this.options.content.trigger) {
|
77
|
+
this.options.content.trigger('ok', this);
|
78
|
+
}
|
79
|
+
|
80
|
+
if (this.options.okCloses) {
|
81
|
+
this.close();
|
82
|
+
}
|
70
83
|
}
|
71
84
|
},
|
72
85
|
|
@@ -89,6 +102,8 @@
|
|
89
102
|
this.options = _.extend({
|
90
103
|
title: null,
|
91
104
|
okText: 'OK',
|
105
|
+
focusOk: true,
|
106
|
+
okCloses: true,
|
92
107
|
cancelText: 'Cancel',
|
93
108
|
allowCancel: true,
|
94
109
|
escape: true,
|
@@ -110,11 +125,12 @@
|
|
110
125
|
//Create the modal container
|
111
126
|
$el.html(options.template(options));
|
112
127
|
|
113
|
-
var $content = this.$content = $el.find('.modal-body
|
128
|
+
var $content = this.$content = $el.find('.modal-body')
|
114
129
|
|
115
130
|
//Insert the main content if it's a view
|
116
131
|
if (content.$el) {
|
117
|
-
|
132
|
+
content.render();
|
133
|
+
$el.find('.modal-body').html(content.$el);
|
118
134
|
}
|
119
135
|
|
120
136
|
if (options.animate) $el.addClass('fade');
|
@@ -126,22 +142,30 @@
|
|
126
142
|
|
127
143
|
/**
|
128
144
|
* Renders and shows the modal
|
145
|
+
*
|
146
|
+
* @param {Function} [cb] Optional callback that runs only when OK is pressed.
|
129
147
|
*/
|
130
|
-
open: function() {
|
148
|
+
open: function(cb) {
|
131
149
|
if (!this.isRendered) this.render();
|
132
150
|
|
133
151
|
var self = this,
|
134
152
|
$el = this.$el;
|
135
153
|
|
136
154
|
//Create it
|
137
|
-
$el.modal({
|
155
|
+
$el.modal(_.extend({
|
138
156
|
keyboard: this.options.allowCancel,
|
139
157
|
backdrop: this.options.allowCancel ? true : 'static'
|
140
|
-
});
|
158
|
+
}, this.options.modalOptions));
|
141
159
|
|
142
160
|
//Focus OK button
|
143
161
|
$el.one('shown', function() {
|
144
|
-
|
162
|
+
if (self.options.focusOk) {
|
163
|
+
$el.find('.btn.ok').focus();
|
164
|
+
}
|
165
|
+
|
166
|
+
if (self.options.content && self.options.content.trigger) {
|
167
|
+
self.options.content.trigger('shown', self);
|
168
|
+
}
|
145
169
|
|
146
170
|
self.trigger('shown');
|
147
171
|
});
|
@@ -149,13 +173,40 @@
|
|
149
173
|
//Adjust the modal and backdrop z-index; for dealing with multiple modals
|
150
174
|
var numModals = Modal.count,
|
151
175
|
$backdrop = $('.modal-backdrop:eq('+numModals+')'),
|
152
|
-
backdropIndex = $backdrop.css('z-index'),
|
153
|
-
elIndex = $backdrop.css('z-index');
|
176
|
+
backdropIndex = parseInt($backdrop.css('z-index'),10),
|
177
|
+
elIndex = parseInt($backdrop.css('z-index'), 10);
|
154
178
|
|
155
179
|
$backdrop.css('z-index', backdropIndex + numModals);
|
156
180
|
this.$el.css('z-index', elIndex + numModals);
|
157
181
|
|
182
|
+
if (this.options.allowCancel) {
|
183
|
+
$backdrop.one('click', function() {
|
184
|
+
if (self.options.content && self.options.content.trigger) {
|
185
|
+
self.options.content.trigger('cancel', self);
|
186
|
+
}
|
187
|
+
|
188
|
+
self.trigger('cancel');
|
189
|
+
});
|
190
|
+
|
191
|
+
$(document).one('keyup.dismiss.modal', function (e) {
|
192
|
+
e.which == 27 && self.trigger('cancel');
|
193
|
+
|
194
|
+
if (self.options.content && self.options.content.trigger) {
|
195
|
+
e.which == 27 && self.options.content.trigger('shown', self);
|
196
|
+
}
|
197
|
+
});
|
198
|
+
}
|
199
|
+
|
200
|
+
this.on('cancel', function() {
|
201
|
+
self.close();
|
202
|
+
});
|
203
|
+
|
158
204
|
Modal.count++;
|
205
|
+
|
206
|
+
//Run callback on OK if provided
|
207
|
+
if (cb) {
|
208
|
+
self.on('ok', cb);
|
209
|
+
}
|
159
210
|
|
160
211
|
return this;
|
161
212
|
},
|
@@ -173,14 +224,22 @@
|
|
173
224
|
return;
|
174
225
|
}
|
175
226
|
|
176
|
-
$el.
|
177
|
-
|
178
|
-
|
227
|
+
$el.one('hidden', function onHidden(e) {
|
228
|
+
// Ignore events propagated from interior objects, like bootstrap tooltips
|
229
|
+
if(e.target !== e.currentTarget){
|
230
|
+
return $el.one('hidden', onHidden);
|
231
|
+
}
|
179
232
|
self.remove();
|
180
233
|
|
234
|
+
if (self.options.content && self.options.content.trigger) {
|
235
|
+
self.options.content.trigger('hidden', self);
|
236
|
+
}
|
237
|
+
|
181
238
|
self.trigger('hidden');
|
182
239
|
});
|
183
240
|
|
241
|
+
$el.modal('hide');
|
242
|
+
|
184
243
|
Modal.count--;
|
185
244
|
},
|
186
245
|
|
@@ -201,14 +260,14 @@
|
|
201
260
|
|
202
261
|
//EXPORTS
|
203
262
|
//CommonJS
|
204
|
-
if (typeof require == 'function' && module && exports) {
|
263
|
+
if (typeof require == 'function' && typeof module !== 'undefined' && exports) {
|
205
264
|
module.exports = Modal;
|
206
265
|
}
|
207
266
|
|
208
267
|
//AMD / RequireJS
|
209
268
|
if (typeof define === 'function' && define.amd) {
|
210
269
|
return define(function() {
|
211
|
-
|
270
|
+
Backbone.BootstrapModal = Modal;
|
212
271
|
})
|
213
272
|
}
|
214
273
|
|
@@ -0,0 +1 @@
|
|
1
|
+
(function(e,t,n){var r=t.templateSettings;t.templateSettings={interpolate:/\{\{(.+?)\}\}/g,evaluate:/<%([\s\S]+?)%>/g};var i=t.template(' <% if (title) { %> <div class="modal-header"> <% if (allowCancel) { %> <a class="close">×</a> <% } %> <h3>{{title}}</h3> </div> <% } %> <div class="modal-body">{{content}}</div> <div class="modal-footer"> <% if (allowCancel) { %> <% if (cancelText) { %> <a href="#" class="btn cancel">{{cancelText}}</a> <% } %> <% } %> <a href="#" class="btn ok btn-primary">{{okText}}</a> </div> ');t.templateSettings=r;var s=n.View.extend({className:"modal",events:{"click .close":function(e){e.preventDefault(),this.trigger("cancel"),this.options.content&&this.options.content.trigger&&this.options.content.trigger("cancel",this)},"click .cancel":function(e){e.preventDefault(),this.trigger("cancel"),this.options.content&&this.options.content.trigger&&this.options.content.trigger("cancel",this)},"click .ok":function(e){e.preventDefault(),this.trigger("ok"),this.options.content&&this.options.content.trigger&&this.options.content.trigger("ok",this),this.options.okCloses&&this.close()}},initialize:function(e){this.options=t.extend({title:null,okText:"OK",focusOk:!0,okCloses:!0,cancelText:"Cancel",allowCancel:!0,escape:!0,animate:!1,template:i},e)},render:function(){var e=this.$el,t=this.options,n=t.content;e.html(t.template(t));var r=this.$content=e.find(".modal-body");return n.$el&&(n.render(),e.find(".modal-body").html(n.$el)),t.animate&&e.addClass("fade"),this.isRendered=!0,this},open:function(n){this.isRendered||this.render();var r=this,i=this.$el;i.modal(t.extend({keyboard:this.options.allowCancel,backdrop:this.options.allowCancel?!0:"static"},this.options.modalOptions)),i.one("shown",function(){r.options.focusOk&&i.find(".btn.ok").focus(),r.options.content&&r.options.content.trigger&&r.options.content.trigger("shown",r),r.trigger("shown")});var o=s.count,u=e(".modal-backdrop:eq("+o+")"),a=parseInt(u.css("z-index"),10),f=parseInt(u.css("z-index"),10);return u.css("z-index",a+o),this.$el.css("z-index",f+o),this.options.allowCancel&&(u.one("click",function(){r.options.content&&r.options.content.trigger&&r.options.content.trigger("cancel",r),r.trigger("cancel")}),e(document).one("keyup.dismiss.modal",function(e){e.which==27&&r.trigger("cancel"),r.options.content&&r.options.content.trigger&&e.which==27&&r.options.content.trigger("shown",r)})),this.on("cancel",function(){r.close()}),s.count++,n&&r.on("ok",n),this},close:function(){var e=this,t=this.$el;if(this._preventClose){this._preventClose=!1;return}t.one("hidden",function n(r){if(r.target!==r.currentTarget)return t.one("hidden",n);e.remove(),e.options.content&&e.options.content.trigger&&e.options.content.trigger("hidden",e),e.trigger("hidden")}),t.modal("hide"),s.count--},preventClose:function(){this._preventClose=!0}},{count:0});typeof require=="function"&&typeof module!="undefined"&&exports&&(module.exports=s);if(typeof define=="function"&&define.amd)return define(function(){n.BootstrapModal=s});n.BootstrapModal=s})(jQuery,_,Backbone)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
|
-
* Backbone Forms v0.
|
2
|
+
* Backbone Forms v0.11.0
|
3
3
|
*
|
4
|
-
* Copyright (c)
|
4
|
+
* Copyright (c) 2013 Charles Davison, Pow Media Ltd
|
5
5
|
*
|
6
6
|
* License and more information at:
|
7
7
|
* http://github.com/powmedia/backbone-forms
|
@@ -29,11 +29,11 @@
|
|
29
29
|
//==================================================================================================
|
30
30
|
//FORM
|
31
31
|
//==================================================================================================
|
32
|
-
|
32
|
+
|
33
33
|
var Form = (function() {
|
34
34
|
|
35
35
|
return Backbone.View.extend({
|
36
|
-
|
36
|
+
|
37
37
|
hasFocus: false,
|
38
38
|
|
39
39
|
/**
|
@@ -43,7 +43,7 @@ var Form = (function() {
|
|
43
43
|
* @param {Model} [options.model] Model the form relates to. Required if options.data is not set
|
44
44
|
* @param {Object} [options.data] Date to populate the form. Required if options.model is not set
|
45
45
|
* @param {String[]} [options.fields] Fields to include in the form, in order
|
46
|
-
* @param {String[]|Object[]} [options.fieldsets] How to divide the fields up by section. E.g. [{ legend: 'Title', fields: ['field1', 'field2'] }]
|
46
|
+
* @param {String[]|Object[]} [options.fieldsets] How to divide the fields up by section. E.g. [{ legend: 'Title', fields: ['field1', 'field2'] }]
|
47
47
|
* @param {String} [options.idPrefix] Prefix for editor IDs. By default, the model's CID is used.
|
48
48
|
* @param {String} [options.template] Form template key/name
|
49
49
|
* @param {String} [options.fieldsetTemplate] Fieldset template key/name
|
@@ -51,19 +51,19 @@ var Form = (function() {
|
|
51
51
|
*
|
52
52
|
* @return {Form}
|
53
53
|
*/
|
54
|
-
initialize: function(options) {
|
54
|
+
initialize: function(options) {
|
55
55
|
//Check templates have been loaded
|
56
56
|
if (!Form.templates.form) throw new Error('Templates not loaded');
|
57
57
|
|
58
58
|
//Get the schema
|
59
59
|
this.schema = (function() {
|
60
60
|
if (options.schema) return options.schema;
|
61
|
-
|
61
|
+
|
62
62
|
var model = options.model;
|
63
63
|
if (!model) throw new Error('Could not find schema');
|
64
|
-
|
64
|
+
|
65
65
|
if (_.isFunction(model.schema)) return model.schema();
|
66
|
-
|
66
|
+
|
67
67
|
return model.schema;
|
68
68
|
})();
|
69
69
|
|
@@ -80,7 +80,7 @@ var Form = (function() {
|
|
80
80
|
|
81
81
|
options.fieldsets = [{ fields: fields }];
|
82
82
|
}
|
83
|
-
|
83
|
+
|
84
84
|
//Store main attributes
|
85
85
|
this.options = options;
|
86
86
|
this.model = options.model;
|
@@ -95,9 +95,9 @@ var Form = (function() {
|
|
95
95
|
var self = this,
|
96
96
|
options = this.options,
|
97
97
|
template = Form.templates[options.template];
|
98
|
-
|
98
|
+
|
99
99
|
//Create el from template
|
100
|
-
var $form =
|
100
|
+
var $form = Form.helpers.parseHTML(template({
|
101
101
|
fieldsets: '<b class="bbf-tmp"></b>'
|
102
102
|
}));
|
103
103
|
|
@@ -112,7 +112,7 @@ var Form = (function() {
|
|
112
112
|
|
113
113
|
//Set the template contents as the main element; removes the wrapper element
|
114
114
|
this.setElement($form);
|
115
|
-
|
115
|
+
|
116
116
|
if (this.hasFocus) this.trigger('blur', this);
|
117
117
|
|
118
118
|
return this;
|
@@ -126,7 +126,7 @@ var Form = (function() {
|
|
126
126
|
* { legend: 'Some Fieldset', fields: ['field1', 'field2'] }
|
127
127
|
*
|
128
128
|
* @param {Object|Array} fieldset A fieldset definition
|
129
|
-
*
|
129
|
+
*
|
130
130
|
* @return {jQuery} The fieldset DOM element
|
131
131
|
*/
|
132
132
|
renderFieldset: function(fieldset) {
|
@@ -141,7 +141,7 @@ var Form = (function() {
|
|
141
141
|
}
|
142
142
|
|
143
143
|
//Concatenating HTML as strings won't work so we need to insert field elements into a placeholder
|
144
|
-
var $fieldset =
|
144
|
+
var $fieldset = Form.helpers.parseHTML(template(_.extend({}, fieldset, {
|
145
145
|
legend: '<b class="bbf-tmp-legend"></b>',
|
146
146
|
fields: '<b class="bbf-tmp-fields"></b>'
|
147
147
|
})));
|
@@ -176,17 +176,17 @@ var Form = (function() {
|
|
176
176
|
|
177
177
|
//Render the fields with editors, apart from Hidden fields
|
178
178
|
var fieldEl = field.render().el;
|
179
|
-
|
179
|
+
|
180
180
|
field.editor.on('all', function(event) {
|
181
181
|
// args = ["change", editor]
|
182
|
-
args = _.toArray(arguments);
|
182
|
+
var args = _.toArray(arguments);
|
183
183
|
args[0] = key + ':' + event;
|
184
184
|
args.splice(1, 0, this);
|
185
185
|
// args = ["key:change", this=form, editor]
|
186
186
|
|
187
|
-
this.trigger.apply(this, args)
|
187
|
+
this.trigger.apply(this, args);
|
188
188
|
}, self);
|
189
|
-
|
189
|
+
|
190
190
|
field.editor.on('change', function() {
|
191
191
|
this.trigger('change', self);
|
192
192
|
}, self);
|
@@ -203,13 +203,13 @@ var Form = (function() {
|
|
203
203
|
self.trigger('blur', self);
|
204
204
|
}, 0);
|
205
205
|
}, self);
|
206
|
-
|
207
|
-
if (itemSchema.type
|
206
|
+
|
207
|
+
if (itemSchema.type !== 'Hidden') {
|
208
208
|
$fieldsContainer.append(fieldEl);
|
209
209
|
}
|
210
210
|
});
|
211
211
|
|
212
|
-
$fieldsContainer = $fieldsContainer.children().unwrap()
|
212
|
+
$fieldsContainer = $fieldsContainer.children().unwrap();
|
213
213
|
|
214
214
|
return $fieldset;
|
215
215
|
},
|
@@ -266,24 +266,25 @@ var Form = (function() {
|
|
266
266
|
//Get errors from default Backbone model validator
|
267
267
|
if (model && model.validate) {
|
268
268
|
var modelErrors = model.validate(this.getValue());
|
269
|
-
|
269
|
+
|
270
270
|
if (modelErrors) {
|
271
271
|
var isDictionary = _.isObject(modelErrors) && !_.isArray(modelErrors);
|
272
|
-
|
272
|
+
|
273
273
|
//If errors are not in object form then just store on the error object
|
274
274
|
if (!isDictionary) {
|
275
275
|
errors._others = errors._others || [];
|
276
276
|
errors._others.push(modelErrors);
|
277
277
|
}
|
278
|
-
|
278
|
+
|
279
279
|
//Merge programmatic errors (requires model.validate() to return an object e.g. { fieldKey: 'error' })
|
280
280
|
if (isDictionary) {
|
281
281
|
_.each(modelErrors, function(val, key) {
|
282
282
|
//Set error on field if there isn't one already
|
283
283
|
if (self.fields[key] && !errors[key]) {
|
284
284
|
self.fields[key].setError(val);
|
285
|
+
errors[key] = val;
|
285
286
|
}
|
286
|
-
|
287
|
+
|
287
288
|
else {
|
288
289
|
//Otherwise add to '_others' key
|
289
290
|
errors._others = errors._others || [];
|
@@ -302,20 +303,25 @@ var Form = (function() {
|
|
302
303
|
/**
|
303
304
|
* Update the model with all latest values.
|
304
305
|
*
|
306
|
+
* @param {Object} [options] Options to pass to Model#set (e.g. { silent: true })
|
307
|
+
*
|
305
308
|
* @return {Object} Validation errors
|
306
309
|
*/
|
307
|
-
commit: function() {
|
310
|
+
commit: function(options) {
|
308
311
|
//Validate
|
309
312
|
var errors = this.validate();
|
310
313
|
if (errors) return errors;
|
311
314
|
|
312
315
|
//Commit
|
313
316
|
var modelError;
|
314
|
-
|
317
|
+
|
318
|
+
var setOptions = _.extend({
|
315
319
|
error: function(model, e) {
|
316
320
|
modelError = e;
|
317
321
|
}
|
318
|
-
});
|
322
|
+
}, options);
|
323
|
+
|
324
|
+
this.model.set(this.getValue(), setOptions);
|
319
325
|
|
320
326
|
if (modelError) return modelError;
|
321
327
|
},
|
@@ -323,14 +329,14 @@ var Form = (function() {
|
|
323
329
|
/**
|
324
330
|
* Get all the field values as an object.
|
325
331
|
* Use this method when passing data instead of objects
|
326
|
-
*
|
332
|
+
*
|
327
333
|
* @param {String} [key] Specific field value to get
|
328
334
|
*/
|
329
335
|
getValue: function(key) {
|
330
336
|
//Return only given key if specified
|
331
337
|
if (key) return this.fields[key].getValue();
|
332
|
-
|
333
|
-
//Otherwise return entire form
|
338
|
+
|
339
|
+
//Otherwise return entire form
|
334
340
|
var values = {};
|
335
341
|
_.each(this.fields, function(field) {
|
336
342
|
values[field.key] = field.getValue();
|
@@ -338,22 +344,31 @@ var Form = (function() {
|
|
338
344
|
|
339
345
|
return values;
|
340
346
|
},
|
341
|
-
|
347
|
+
|
342
348
|
/**
|
343
349
|
* Update field values, referenced by key
|
344
|
-
* @param {Object}
|
350
|
+
* @param {Object|String} key New values to set, or property to set
|
351
|
+
* @param val Value to set
|
345
352
|
*/
|
346
|
-
setValue: function(
|
347
|
-
|
348
|
-
|
353
|
+
setValue: function(prop, val) {
|
354
|
+
var data = {};
|
355
|
+
if (typeof prop === 'string') {
|
356
|
+
data[prop] = val;
|
357
|
+
} else {
|
358
|
+
data = prop;
|
359
|
+
}
|
360
|
+
|
361
|
+
var key;
|
362
|
+
for (key in this.schema) {
|
363
|
+
if (data[key] !== undefined) {
|
349
364
|
this.fields[key].setValue(data[key]);
|
350
365
|
}
|
351
366
|
}
|
352
367
|
},
|
353
|
-
|
368
|
+
|
354
369
|
focus: function() {
|
355
370
|
if (this.hasFocus) return;
|
356
|
-
|
371
|
+
|
357
372
|
var fieldset = this.options.fieldsets[0];
|
358
373
|
if (fieldset) {
|
359
374
|
var field;
|
@@ -368,12 +383,12 @@ var Form = (function() {
|
|
368
383
|
}
|
369
384
|
}
|
370
385
|
},
|
371
|
-
|
386
|
+
|
372
387
|
blur: function() {
|
373
388
|
if (!this.hasFocus) return;
|
374
|
-
|
375
|
-
focusedField = _.find(this.fields, function(field) { return field.editor.hasFocus; });
|
376
|
-
|
389
|
+
|
390
|
+
var focusedField = _.find(this.fields, function(field) { return field.editor.hasFocus; });
|
391
|
+
|
377
392
|
if (focusedField) focusedField.editor.blur();
|
378
393
|
},
|
379
394
|
|
@@ -382,23 +397,22 @@ var Form = (function() {
|
|
382
397
|
*/
|
383
398
|
remove: function() {
|
384
399
|
var fields = this.fields;
|
385
|
-
|
400
|
+
|
386
401
|
for (var key in fields) {
|
387
402
|
fields[key].remove();
|
388
403
|
}
|
389
404
|
|
390
405
|
Backbone.View.prototype.remove.call(this);
|
391
406
|
},
|
392
|
-
|
393
|
-
|
407
|
+
|
394
408
|
trigger: function(event) {
|
395
|
-
if (event
|
409
|
+
if (event === 'focus') {
|
396
410
|
this.hasFocus = true;
|
397
411
|
}
|
398
|
-
else if (event
|
412
|
+
else if (event === 'blur') {
|
399
413
|
this.hasFocus = false;
|
400
414
|
}
|
401
|
-
|
415
|
+
|
402
416
|
return Backbone.View.prototype.trigger.apply(this, arguments);
|
403
417
|
}
|
404
418
|
});
|
@@ -429,7 +443,7 @@ Form.helpers = (function() {
|
|
429
443
|
result = result[fields[i]];
|
430
444
|
}
|
431
445
|
return result;
|
432
|
-
}
|
446
|
+
};
|
433
447
|
|
434
448
|
/**
|
435
449
|
* This function is used to transform the key from a schema into the title used in a label.
|
@@ -470,7 +484,7 @@ Form.helpers = (function() {
|
|
470
484
|
_.templateSettings.interpolate = _interpolateBackup;
|
471
485
|
|
472
486
|
return template;
|
473
|
-
}
|
487
|
+
};
|
474
488
|
|
475
489
|
/**
|
476
490
|
* Helper to create a template with the {{mustache}} style tags.
|
@@ -480,7 +494,7 @@ Form.helpers = (function() {
|
|
480
494
|
* @return {Template|String} Compiled template or the evaluated string
|
481
495
|
*/
|
482
496
|
helpers.createTemplate = function(str, context) {
|
483
|
-
var template = helpers.compileTemplate(str);
|
497
|
+
var template = helpers.compileTemplate($.trim(str));
|
484
498
|
|
485
499
|
if (!context) {
|
486
500
|
return template;
|
@@ -496,7 +510,7 @@ Form.helpers = (function() {
|
|
496
510
|
*/
|
497
511
|
helpers.setTemplateCompiler = function(compiler) {
|
498
512
|
helpers.compileTemplate = compiler;
|
499
|
-
}
|
513
|
+
};
|
500
514
|
|
501
515
|
|
502
516
|
/**
|
@@ -550,33 +564,6 @@ Form.helpers = (function() {
|
|
550
564
|
return new constructorFn(options);
|
551
565
|
};
|
552
566
|
|
553
|
-
/**
|
554
|
-
* Triggers an event that can be cancelled. Requires the user to invoke a callback. If false
|
555
|
-
* is passed to the callback, the action does not run.
|
556
|
-
*
|
557
|
-
* NOTE: This helper uses private Backbone apis so can break when Backbone is upgraded
|
558
|
-
*
|
559
|
-
* @param {Mixed} Instance of Backbone model, view, collection to trigger event on
|
560
|
-
* @param {String} Event name
|
561
|
-
* @param {Array} Arguments to pass to the event handlers
|
562
|
-
* @param {Function} Callback to run after the event handler has run.
|
563
|
-
* If any of them passed false or error, this callback won't run
|
564
|
-
*/
|
565
|
-
helpers.triggerCancellableEvent = function(subject, event, args, callback) {
|
566
|
-
//Return if there are no event listeners
|
567
|
-
if (!subject._callbacks || !subject._callbacks[event]) return callback();
|
568
|
-
|
569
|
-
var next = subject._callbacks[event].next;
|
570
|
-
if (!next) return callback();
|
571
|
-
|
572
|
-
var fn = next.callback,
|
573
|
-
context = next.context || this;
|
574
|
-
|
575
|
-
//Add the callback that will be used when done
|
576
|
-
args.push(callback);
|
577
|
-
|
578
|
-
fn.apply(context, args);
|
579
|
-
}
|
580
567
|
|
581
568
|
/**
|
582
569
|
* Returns a validation function based on the type defined in the schema
|
@@ -614,6 +601,20 @@ Form.helpers = (function() {
|
|
614
601
|
};
|
615
602
|
|
616
603
|
|
604
|
+
/**
|
605
|
+
* Given an HTML string, return a jQuery-wrapped array of DOM nodes.
|
606
|
+
*
|
607
|
+
* @param {String} html
|
608
|
+
* @return {Object}
|
609
|
+
*/
|
610
|
+
helpers.parseHTML = function(html) {
|
611
|
+
if ($.parseHTML !== undefined) {
|
612
|
+
return $($.parseHTML(html));
|
613
|
+
}
|
614
|
+
return $(html);
|
615
|
+
};
|
616
|
+
|
617
|
+
|
617
618
|
return helpers;
|
618
619
|
|
619
620
|
})();
|
@@ -633,7 +634,7 @@ Form.validators = (function() {
|
|
633
634
|
email: 'Invalid email address',
|
634
635
|
url: 'Invalid URL',
|
635
636
|
match: 'Must match field "{{field}}"'
|
636
|
-
}
|
637
|
+
};
|
637
638
|
|
638
639
|
validators.required = function(options) {
|
639
640
|
options = _.extend({
|
@@ -649,7 +650,7 @@ Form.validators = (function() {
|
|
649
650
|
message: Form.helpers.createTemplate(options.message, options)
|
650
651
|
};
|
651
652
|
|
652
|
-
if (value === null || value === undefined || value === '') return err;
|
653
|
+
if (value === null || value === undefined || value === false || value === '') return err;
|
653
654
|
};
|
654
655
|
};
|
655
656
|
|
@@ -690,7 +691,7 @@ Form.validators = (function() {
|
|
690
691
|
options = _.extend({
|
691
692
|
type: 'url',
|
692
693
|
message: this.errMessages.url,
|
693
|
-
regexp: /^(http|https):\/\/(([A-Z0-9][A-Z0-9_
|
694
|
+
regexp: /^(http|https):\/\/(([A-Z0-9][A-Z0-9_\-]*)(\.[A-Z0-9][A-Z0-9_\-]*)+)(:(\d+))?\/?/i
|
694
695
|
}, options);
|
695
696
|
|
696
697
|
return validators.regexp(options);
|
@@ -715,8 +716,8 @@ Form.validators = (function() {
|
|
715
716
|
//Don't check empty values (add a 'required' validator for this)
|
716
717
|
if (value === null || value === undefined || value === '') return;
|
717
718
|
|
718
|
-
if (value
|
719
|
-
}
|
719
|
+
if (value !== attrs[options.field]) return err;
|
720
|
+
};
|
720
721
|
};
|
721
722
|
|
722
723
|
|
@@ -748,7 +749,7 @@ Form.Field = (function() {
|
|
748
749
|
*/
|
749
750
|
/**
|
750
751
|
* Creates a new field
|
751
|
-
*
|
752
|
+
*
|
752
753
|
* @param {Object} options
|
753
754
|
* @param {Object} [options.schema] Field schema. Defaults to { type: 'Text' }
|
754
755
|
* @param {Model} [options.model] Model the field relates to. Required if options.data is not set.
|
@@ -768,7 +769,7 @@ Form.Field = (function() {
|
|
768
769
|
|
769
770
|
//Turn schema shorthand notation (e.g. 'Text') into schema object
|
770
771
|
if (_.isString(options.schema)) options.schema = { type: options.schema };
|
771
|
-
|
772
|
+
|
772
773
|
//Set schema defaults
|
773
774
|
this.schema = _.extend({
|
774
775
|
type: 'Text',
|
@@ -777,6 +778,29 @@ Form.Field = (function() {
|
|
777
778
|
}, options.schema);
|
778
779
|
},
|
779
780
|
|
781
|
+
|
782
|
+
/**
|
783
|
+
* Provides the context for rendering the field
|
784
|
+
* Override this to extend the default context
|
785
|
+
*
|
786
|
+
* @param {Object} schema
|
787
|
+
* @param {View} editor
|
788
|
+
*
|
789
|
+
* @return {Object} Locals passed to the template
|
790
|
+
*/
|
791
|
+
renderingContext: function(schema, editor) {
|
792
|
+
return {
|
793
|
+
key: this.key,
|
794
|
+
title: schema.title,
|
795
|
+
id: editor.id,
|
796
|
+
type: schema.type,
|
797
|
+
editor: '<b class="bbf-tmp-editor"></b>',
|
798
|
+
help: '<b class="bbf-tmp-help"></b>',
|
799
|
+
error: '<b class="bbf-tmp-error"></b>'
|
800
|
+
};
|
801
|
+
},
|
802
|
+
|
803
|
+
|
780
804
|
/**
|
781
805
|
* Renders the field
|
782
806
|
*/
|
@@ -802,17 +826,15 @@ Form.Field = (function() {
|
|
802
826
|
|
803
827
|
//Decide on the editor to use
|
804
828
|
var editor = this.editor = helpers.createEditor(schema.type, options);
|
805
|
-
|
829
|
+
|
806
830
|
//Create the element
|
807
|
-
var $field =
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
}));
|
815
|
-
|
831
|
+
var $field = Form.helpers.parseHTML(templates[schema.template](this.renderingContext(schema, editor)));
|
832
|
+
|
833
|
+
//Remove <label> if it's not wanted
|
834
|
+
if (schema.title === false) {
|
835
|
+
$field.find('label[for="'+editor.id+'"]').first().remove();
|
836
|
+
}
|
837
|
+
|
816
838
|
//Render editor
|
817
839
|
$field.find('.bbf-tmp-editor').replaceWith(editor.render().el);
|
818
840
|
|
@@ -820,13 +842,17 @@ Form.Field = (function() {
|
|
820
842
|
this.$help = $('.bbf-tmp-help', $field).parent();
|
821
843
|
this.$help.empty();
|
822
844
|
if (this.schema.help) this.$help.html(this.schema.help);
|
823
|
-
|
845
|
+
|
846
|
+
//Create error container
|
847
|
+
this.$error = $($('.bbf-tmp-error', $field).parent()[0]);
|
848
|
+
if (this.$error) this.$error.empty();
|
849
|
+
|
824
850
|
//Add custom CSS class names
|
825
851
|
if (this.schema.fieldClass) $field.addClass(this.schema.fieldClass);
|
826
|
-
|
852
|
+
|
827
853
|
//Add custom attributes
|
828
854
|
if (this.schema.fieldAttrs) $field.attr(this.schema.fieldAttrs);
|
829
|
-
|
855
|
+
|
830
856
|
//Replace the generated wrapper tag
|
831
857
|
this.setElement($field);
|
832
858
|
|
@@ -854,7 +880,7 @@ Form.Field = (function() {
|
|
854
880
|
|
855
881
|
return id;
|
856
882
|
},
|
857
|
-
|
883
|
+
|
858
884
|
/**
|
859
885
|
* Check the validity of the field
|
860
886
|
*
|
@@ -871,7 +897,7 @@ Form.Field = (function() {
|
|
871
897
|
|
872
898
|
return error;
|
873
899
|
},
|
874
|
-
|
900
|
+
|
875
901
|
/**
|
876
902
|
* Set the field into an error state, adding the error class and setting the error message
|
877
903
|
*
|
@@ -880,26 +906,32 @@ Form.Field = (function() {
|
|
880
906
|
setError: function(msg) {
|
881
907
|
//Object and NestedModel types set their own errors internally
|
882
908
|
if (this.editor.hasNestedForm) return;
|
883
|
-
|
909
|
+
|
884
910
|
var errClass = Form.classNames.error;
|
885
911
|
|
886
912
|
this.$el.addClass(errClass);
|
887
|
-
|
888
|
-
if (this.$
|
913
|
+
|
914
|
+
if (this.$error) {
|
915
|
+
this.$error.html(msg);
|
916
|
+
} else if (this.$help) {
|
917
|
+
this.$help.html(msg);
|
918
|
+
}
|
889
919
|
},
|
890
|
-
|
920
|
+
|
891
921
|
/**
|
892
922
|
* Clear the error state and reset the help message
|
893
923
|
*/
|
894
924
|
clearError: function() {
|
895
925
|
var errClass = Form.classNames.error;
|
896
|
-
|
926
|
+
|
897
927
|
this.$el.removeClass(errClass);
|
898
|
-
|
928
|
+
|
899
929
|
// some fields (e.g., Hidden), may not have a help el
|
900
|
-
if (this.$
|
930
|
+
if (this.$error) {
|
931
|
+
this.$error.empty();
|
932
|
+
} else if (this.$help) {
|
901
933
|
this.$help.empty();
|
902
|
-
|
934
|
+
|
903
935
|
//Reset help text if available
|
904
936
|
var helpMsg = this.schema.help;
|
905
937
|
if (helpMsg) this.$help.html(helpMsg);
|
@@ -921,7 +953,7 @@ Form.Field = (function() {
|
|
921
953
|
getValue: function() {
|
922
954
|
return this.editor.getValue();
|
923
955
|
},
|
924
|
-
|
956
|
+
|
925
957
|
/**
|
926
958
|
* Set/change the value of the editor
|
927
959
|
*
|
@@ -930,11 +962,11 @@ Form.Field = (function() {
|
|
930
962
|
setValue: function(value) {
|
931
963
|
this.editor.setValue(value);
|
932
964
|
},
|
933
|
-
|
965
|
+
|
934
966
|
focus: function() {
|
935
967
|
this.editor.focus();
|
936
968
|
},
|
937
|
-
|
969
|
+
|
938
970
|
blur: function() {
|
939
971
|
this.editor.blur();
|
940
972
|
},
|
@@ -952,6 +984,7 @@ Form.Field = (function() {
|
|
952
984
|
|
953
985
|
})();
|
954
986
|
|
987
|
+
|
955
988
|
//========================================================================
|
956
989
|
//EDITORS
|
957
990
|
//========================================================================
|
@@ -975,7 +1008,7 @@ Form.editors = (function() {
|
|
975
1008
|
editors.Base = Backbone.View.extend({
|
976
1009
|
|
977
1010
|
defaultValue: null,
|
978
|
-
|
1011
|
+
|
979
1012
|
hasFocus: false,
|
980
1013
|
|
981
1014
|
initialize: function(options) {
|
@@ -991,20 +1024,20 @@ Form.editors = (function() {
|
|
991
1024
|
else if (options.value) {
|
992
1025
|
this.value = options.value;
|
993
1026
|
}
|
994
|
-
|
1027
|
+
|
995
1028
|
if (this.value === undefined) this.value = this.defaultValue;
|
996
1029
|
|
997
1030
|
this.key = options.key;
|
998
1031
|
this.form = options.form;
|
999
1032
|
this.schema = options.schema || {};
|
1000
1033
|
this.validators = options.validators || this.schema.validators;
|
1001
|
-
|
1034
|
+
|
1002
1035
|
//Main attributes
|
1003
1036
|
this.$el.attr('name', this.getName());
|
1004
|
-
|
1037
|
+
|
1005
1038
|
//Add custom CSS class names
|
1006
1039
|
if (this.schema.editorClass) this.$el.addClass(this.schema.editorClass);
|
1007
|
-
|
1040
|
+
|
1008
1041
|
//Add custom attributes
|
1009
1042
|
if (this.schema.editorAttrs) this.$el.attr(this.schema.editorAttrs);
|
1010
1043
|
},
|
@@ -1012,15 +1045,15 @@ Form.editors = (function() {
|
|
1012
1045
|
getValue: function() {
|
1013
1046
|
throw 'Not implemented. Extend and override this method.';
|
1014
1047
|
},
|
1015
|
-
|
1048
|
+
|
1016
1049
|
setValue: function() {
|
1017
1050
|
throw 'Not implemented. Extend and override this method.';
|
1018
1051
|
},
|
1019
|
-
|
1052
|
+
|
1020
1053
|
focus: function() {
|
1021
1054
|
throw 'Not implemented. Extend and override this method.';
|
1022
1055
|
},
|
1023
|
-
|
1056
|
+
|
1024
1057
|
blur: function() {
|
1025
1058
|
throw 'Not implemented. Extend and override this method.';
|
1026
1059
|
},
|
@@ -1029,39 +1062,38 @@ Form.editors = (function() {
|
|
1029
1062
|
* Get the value for the form input 'name' attribute
|
1030
1063
|
*
|
1031
1064
|
* @return {String}
|
1032
|
-
*
|
1065
|
+
*
|
1033
1066
|
* @api private
|
1034
1067
|
*/
|
1035
1068
|
getName: function() {
|
1036
1069
|
var key = this.key || '';
|
1037
1070
|
|
1038
1071
|
//Replace periods with underscores (e.g. for when using paths)
|
1039
|
-
return key.replace(/\./g, '_')
|
1072
|
+
return key.replace(/\./g, '_');
|
1040
1073
|
},
|
1041
|
-
|
1074
|
+
|
1042
1075
|
/**
|
1043
1076
|
* Update the model with the current value
|
1044
1077
|
* NOTE: The method is defined on the editors so that they can be used independently of fields
|
1045
1078
|
*
|
1046
1079
|
* @return {Mixed} error
|
1047
1080
|
*/
|
1048
|
-
commit: function() {
|
1081
|
+
commit: function(options) {
|
1049
1082
|
var error = this.validate();
|
1050
1083
|
if (error) return error;
|
1051
|
-
|
1052
|
-
this.
|
1053
|
-
error
|
1054
|
-
error = e;
|
1055
|
-
}
|
1084
|
+
|
1085
|
+
this.listenTo(this.model, 'invalid', function(model, e) {
|
1086
|
+
error = e;
|
1056
1087
|
});
|
1057
|
-
|
1088
|
+
this.model.set(this.key, this.getValue(), options);
|
1089
|
+
|
1058
1090
|
if (error) return error;
|
1059
1091
|
},
|
1060
|
-
|
1092
|
+
|
1061
1093
|
/**
|
1062
1094
|
* Check validity
|
1063
1095
|
* NOTE: The method is defined on the editors so that they can be used independently of fields
|
1064
|
-
*
|
1096
|
+
*
|
1065
1097
|
* @return {String}
|
1066
1098
|
*/
|
1067
1099
|
validate: function() {
|
@@ -1077,22 +1109,22 @@ Form.editors = (function() {
|
|
1077
1109
|
_.every(validators, function(validator) {
|
1078
1110
|
error = getValidator(validator)(value, formValues);
|
1079
1111
|
|
1080
|
-
return
|
1112
|
+
return error ? false : true;
|
1081
1113
|
});
|
1082
1114
|
}
|
1083
1115
|
|
1084
1116
|
return error;
|
1085
1117
|
},
|
1086
|
-
|
1087
|
-
|
1118
|
+
|
1119
|
+
|
1088
1120
|
trigger: function(event) {
|
1089
|
-
if (event
|
1121
|
+
if (event === 'focus') {
|
1090
1122
|
this.hasFocus = true;
|
1091
1123
|
}
|
1092
|
-
else if (event
|
1124
|
+
else if (event === 'blur') {
|
1093
1125
|
this.hasFocus = false;
|
1094
1126
|
}
|
1095
|
-
|
1127
|
+
|
1096
1128
|
return Backbone.View.prototype.trigger.apply(this, arguments);
|
1097
1129
|
}
|
1098
1130
|
});
|
@@ -1102,11 +1134,11 @@ Form.editors = (function() {
|
|
1102
1134
|
editors.Text = editors.Base.extend({
|
1103
1135
|
|
1104
1136
|
tagName: 'input',
|
1105
|
-
|
1137
|
+
|
1106
1138
|
defaultValue: '',
|
1107
|
-
|
1139
|
+
|
1108
1140
|
previousValue: '',
|
1109
|
-
|
1141
|
+
|
1110
1142
|
events: {
|
1111
1143
|
'keyup': 'determineChange',
|
1112
1144
|
'keypress': function(event) {
|
@@ -1125,15 +1157,15 @@ Form.editors = (function() {
|
|
1125
1157
|
this.trigger('blur', this);
|
1126
1158
|
}
|
1127
1159
|
},
|
1128
|
-
|
1160
|
+
|
1129
1161
|
initialize: function(options) {
|
1130
1162
|
editors.Base.prototype.initialize.call(this, options);
|
1131
|
-
|
1163
|
+
|
1132
1164
|
var schema = this.schema;
|
1133
|
-
|
1165
|
+
|
1134
1166
|
//Allow customising text type (email, phone etc.) for HTML5 browsers
|
1135
1167
|
var type = 'text';
|
1136
|
-
|
1168
|
+
|
1137
1169
|
if (schema && schema.editorAttrs && schema.editorAttrs.type) type = schema.editorAttrs.type;
|
1138
1170
|
if (schema && schema.dataType) type = schema.dataType;
|
1139
1171
|
|
@@ -1148,14 +1180,14 @@ Form.editors = (function() {
|
|
1148
1180
|
|
1149
1181
|
return this;
|
1150
1182
|
},
|
1151
|
-
|
1183
|
+
|
1152
1184
|
determineChange: function(event) {
|
1153
1185
|
var currentValue = this.$el.val();
|
1154
|
-
var changed = (currentValue
|
1155
|
-
|
1186
|
+
var changed = (currentValue !== this.previousValue);
|
1187
|
+
|
1156
1188
|
if (changed) {
|
1157
1189
|
this.previousValue = currentValue;
|
1158
|
-
|
1190
|
+
|
1159
1191
|
this.trigger('change', this);
|
1160
1192
|
}
|
1161
1193
|
},
|
@@ -1167,27 +1199,27 @@ Form.editors = (function() {
|
|
1167
1199
|
getValue: function() {
|
1168
1200
|
return this.$el.val();
|
1169
1201
|
},
|
1170
|
-
|
1202
|
+
|
1171
1203
|
/**
|
1172
1204
|
* Sets the value of the form element
|
1173
1205
|
* @param {String}
|
1174
1206
|
*/
|
1175
|
-
setValue: function(value) {
|
1207
|
+
setValue: function(value) {
|
1176
1208
|
this.$el.val(value);
|
1177
1209
|
},
|
1178
|
-
|
1210
|
+
|
1179
1211
|
focus: function() {
|
1180
1212
|
if (this.hasFocus) return;
|
1181
1213
|
|
1182
1214
|
this.$el.focus();
|
1183
1215
|
},
|
1184
|
-
|
1216
|
+
|
1185
1217
|
blur: function() {
|
1186
1218
|
if (!this.hasFocus) return;
|
1187
1219
|
|
1188
1220
|
this.$el.blur();
|
1189
1221
|
},
|
1190
|
-
|
1222
|
+
|
1191
1223
|
select: function() {
|
1192
1224
|
this.$el.select();
|
1193
1225
|
}
|
@@ -1211,6 +1243,7 @@ Form.editors = (function() {
|
|
1211
1243
|
editors.Text.prototype.initialize.call(this, options);
|
1212
1244
|
|
1213
1245
|
this.$el.attr('type', 'number');
|
1246
|
+
this.$el.attr('step', 'any');
|
1214
1247
|
},
|
1215
1248
|
|
1216
1249
|
/**
|
@@ -1222,14 +1255,14 @@ Form.editors = (function() {
|
|
1222
1255
|
setTimeout(function() {
|
1223
1256
|
self.determineChange();
|
1224
1257
|
}, 0);
|
1225
|
-
}
|
1226
|
-
|
1258
|
+
};
|
1259
|
+
|
1227
1260
|
//Allow backspace
|
1228
|
-
if (event.charCode
|
1261
|
+
if (event.charCode === 0) {
|
1229
1262
|
delayedDetermineChange();
|
1230
1263
|
return;
|
1231
1264
|
}
|
1232
|
-
|
1265
|
+
|
1233
1266
|
//Get the whole new value so that we can prevent things like double decimals points etc.
|
1234
1267
|
var newVal = this.$el.val() + String.fromCharCode(event.charCode);
|
1235
1268
|
|
@@ -1243,12 +1276,12 @@ Form.editors = (function() {
|
|
1243
1276
|
}
|
1244
1277
|
},
|
1245
1278
|
|
1246
|
-
getValue: function() {
|
1279
|
+
getValue: function() {
|
1247
1280
|
var value = this.$el.val();
|
1248
|
-
|
1281
|
+
|
1249
1282
|
return value === "" ? null : parseFloat(value, 10);
|
1250
1283
|
},
|
1251
|
-
|
1284
|
+
|
1252
1285
|
setValue: function(value) {
|
1253
1286
|
value = (function() {
|
1254
1287
|
if (_.isNumber(value)) return value;
|
@@ -1259,7 +1292,7 @@ Form.editors = (function() {
|
|
1259
1292
|
})();
|
1260
1293
|
|
1261
1294
|
if (_.isNaN(value)) value = null;
|
1262
|
-
|
1295
|
+
|
1263
1296
|
editors.Text.prototype.setValue.call(this, value);
|
1264
1297
|
}
|
1265
1298
|
|
@@ -1284,15 +1317,15 @@ Form.editors = (function() {
|
|
1284
1317
|
tagName: 'textarea'
|
1285
1318
|
|
1286
1319
|
});
|
1287
|
-
|
1288
|
-
|
1320
|
+
|
1321
|
+
|
1289
1322
|
//CHECKBOX
|
1290
1323
|
editors.Checkbox = editors.Base.extend({
|
1291
|
-
|
1324
|
+
|
1292
1325
|
defaultValue: false,
|
1293
|
-
|
1326
|
+
|
1294
1327
|
tagName: 'input',
|
1295
|
-
|
1328
|
+
|
1296
1329
|
events: {
|
1297
1330
|
'click': function(event) {
|
1298
1331
|
this.trigger('change', this);
|
@@ -1304,10 +1337,10 @@ Form.editors = (function() {
|
|
1304
1337
|
this.trigger('blur', this);
|
1305
1338
|
}
|
1306
1339
|
},
|
1307
|
-
|
1340
|
+
|
1308
1341
|
initialize: function(options) {
|
1309
1342
|
editors.Base.prototype.initialize.call(this, options);
|
1310
|
-
|
1343
|
+
|
1311
1344
|
this.$el.attr('type', 'checkbox');
|
1312
1345
|
},
|
1313
1346
|
|
@@ -1319,35 +1352,35 @@ Form.editors = (function() {
|
|
1319
1352
|
|
1320
1353
|
return this;
|
1321
1354
|
},
|
1322
|
-
|
1355
|
+
|
1323
1356
|
getValue: function() {
|
1324
1357
|
return this.$el.prop('checked');
|
1325
1358
|
},
|
1326
|
-
|
1359
|
+
|
1327
1360
|
setValue: function(value) {
|
1328
1361
|
if (value) {
|
1329
1362
|
this.$el.prop('checked', true);
|
1330
1363
|
}
|
1331
1364
|
},
|
1332
|
-
|
1365
|
+
|
1333
1366
|
focus: function() {
|
1334
1367
|
if (this.hasFocus) return;
|
1335
1368
|
|
1336
1369
|
this.$el.focus();
|
1337
1370
|
},
|
1338
|
-
|
1371
|
+
|
1339
1372
|
blur: function() {
|
1340
1373
|
if (!this.hasFocus) return;
|
1341
1374
|
|
1342
1375
|
this.$el.blur();
|
1343
1376
|
}
|
1344
|
-
|
1377
|
+
|
1345
1378
|
});
|
1346
|
-
|
1347
|
-
|
1379
|
+
|
1380
|
+
|
1348
1381
|
//HIDDEN
|
1349
1382
|
editors.Hidden = editors.Base.extend({
|
1350
|
-
|
1383
|
+
|
1351
1384
|
defaultValue: '',
|
1352
1385
|
|
1353
1386
|
initialize: function(options) {
|
@@ -1355,21 +1388,21 @@ Form.editors = (function() {
|
|
1355
1388
|
|
1356
1389
|
this.$el.attr('type', 'hidden');
|
1357
1390
|
},
|
1358
|
-
|
1391
|
+
|
1359
1392
|
getValue: function() {
|
1360
1393
|
return this.value;
|
1361
1394
|
},
|
1362
|
-
|
1395
|
+
|
1363
1396
|
setValue: function(value) {
|
1364
1397
|
this.value = value;
|
1365
1398
|
},
|
1366
|
-
|
1399
|
+
|
1367
1400
|
focus: function() {
|
1368
|
-
|
1401
|
+
|
1369
1402
|
},
|
1370
|
-
|
1403
|
+
|
1371
1404
|
blur: function() {
|
1372
|
-
|
1405
|
+
|
1373
1406
|
}
|
1374
1407
|
|
1375
1408
|
});
|
@@ -1377,7 +1410,7 @@ Form.editors = (function() {
|
|
1377
1410
|
|
1378
1411
|
/**
|
1379
1412
|
* SELECT
|
1380
|
-
*
|
1413
|
+
*
|
1381
1414
|
* Renders a <select> with given options
|
1382
1415
|
*
|
1383
1416
|
* Requires an 'options' value on the schema.
|
@@ -1387,7 +1420,7 @@ Form.editors = (function() {
|
|
1387
1420
|
editors.Select = editors.Base.extend({
|
1388
1421
|
|
1389
1422
|
tagName: 'select',
|
1390
|
-
|
1423
|
+
|
1391
1424
|
events: {
|
1392
1425
|
'change': function(event) {
|
1393
1426
|
this.trigger('change', this);
|
@@ -1440,7 +1473,7 @@ Form.editors = (function() {
|
|
1440
1473
|
else if (_.isFunction(options)) {
|
1441
1474
|
options(function(result) {
|
1442
1475
|
self.renderOptions(result);
|
1443
|
-
});
|
1476
|
+
}, self);
|
1444
1477
|
}
|
1445
1478
|
|
1446
1479
|
//Otherwise, ready to go straight to renderOptions
|
@@ -1459,6 +1492,17 @@ Form.editors = (function() {
|
|
1459
1492
|
var $select = this.$el,
|
1460
1493
|
html;
|
1461
1494
|
|
1495
|
+
html = this._getOptionsHtml(options);
|
1496
|
+
|
1497
|
+
//Insert options
|
1498
|
+
$select.html(html);
|
1499
|
+
|
1500
|
+
//Select correct option
|
1501
|
+
this.setValue(this.value);
|
1502
|
+
},
|
1503
|
+
|
1504
|
+
_getOptionsHtml: function(options) {
|
1505
|
+
var html;
|
1462
1506
|
//Accept string of HTML
|
1463
1507
|
if (_.isString(options)) {
|
1464
1508
|
html = options;
|
@@ -1471,30 +1515,36 @@ Form.editors = (function() {
|
|
1471
1515
|
|
1472
1516
|
//Or Backbone collection
|
1473
1517
|
else if (options instanceof Backbone.Collection) {
|
1474
|
-
html = this._collectionToHtml(options)
|
1518
|
+
html = this._collectionToHtml(options);
|
1475
1519
|
}
|
1476
1520
|
|
1477
|
-
|
1478
|
-
|
1521
|
+
else if (_.isFunction(options)) {
|
1522
|
+
var newOptions;
|
1523
|
+
|
1524
|
+
options(function(opts) {
|
1525
|
+
newOptions = opts;
|
1526
|
+
}, this);
|
1527
|
+
|
1528
|
+
html = this._getOptionsHtml(newOptions);
|
1529
|
+
}
|
1479
1530
|
|
1480
|
-
|
1481
|
-
this.setValue(this.value);
|
1531
|
+
return html;
|
1482
1532
|
},
|
1483
1533
|
|
1484
1534
|
getValue: function() {
|
1485
1535
|
return this.$el.val();
|
1486
1536
|
},
|
1487
|
-
|
1537
|
+
|
1488
1538
|
setValue: function(value) {
|
1489
1539
|
this.$el.val(value);
|
1490
1540
|
},
|
1491
|
-
|
1541
|
+
|
1492
1542
|
focus: function() {
|
1493
1543
|
if (this.hasFocus) return;
|
1494
1544
|
|
1495
1545
|
this.$el.focus();
|
1496
1546
|
},
|
1497
|
-
|
1547
|
+
|
1498
1548
|
blur: function() {
|
1499
1549
|
if (!this.hasFocus) return;
|
1500
1550
|
|
@@ -1503,7 +1553,7 @@ Form.editors = (function() {
|
|
1503
1553
|
|
1504
1554
|
/**
|
1505
1555
|
* Transforms a collection into HTML ready to use in the renderOptions method
|
1506
|
-
* @param {Backbone.Collection}
|
1556
|
+
* @param {Backbone.Collection}
|
1507
1557
|
* @return {String}
|
1508
1558
|
*/
|
1509
1559
|
_collectionToHtml: function(collection) {
|
@@ -1531,13 +1581,19 @@ Form.editors = (function() {
|
|
1531
1581
|
//Generate HTML
|
1532
1582
|
_.each(array, function(option) {
|
1533
1583
|
if (_.isObject(option)) {
|
1534
|
-
|
1535
|
-
|
1584
|
+
if (option.group) {
|
1585
|
+
html.push('<optgroup label="'+option.group+'">');
|
1586
|
+
html.push(this._getOptionsHtml(option.options))
|
1587
|
+
html.push('</optgroup>');
|
1588
|
+
} else {
|
1589
|
+
var val = (option.val || option.val === 0) ? option.val : '';
|
1590
|
+
html.push('<option value="'+val+'">'+option.label+'</option>');
|
1591
|
+
}
|
1536
1592
|
}
|
1537
1593
|
else {
|
1538
1594
|
html.push('<option>'+option+'</option>');
|
1539
1595
|
}
|
1540
|
-
});
|
1596
|
+
}, this);
|
1541
1597
|
|
1542
1598
|
return html.join('');
|
1543
1599
|
}
|
@@ -1548,7 +1604,7 @@ Form.editors = (function() {
|
|
1548
1604
|
|
1549
1605
|
/**
|
1550
1606
|
* RADIO
|
1551
|
-
*
|
1607
|
+
*
|
1552
1608
|
* Renders a <ul> with given options represented as <li> objects containing radio buttons
|
1553
1609
|
*
|
1554
1610
|
* Requires an 'options' value on the schema.
|
@@ -1559,10 +1615,10 @@ Form.editors = (function() {
|
|
1559
1615
|
|
1560
1616
|
tagName: 'ul',
|
1561
1617
|
className: 'bbf-radio',
|
1562
|
-
|
1618
|
+
|
1563
1619
|
events: {
|
1564
|
-
'
|
1565
|
-
this.trigger('change', this)
|
1620
|
+
'change input[type=radio]': function() {
|
1621
|
+
this.trigger('change', this);
|
1566
1622
|
},
|
1567
1623
|
'focus input[type=radio]': function() {
|
1568
1624
|
if (this.hasFocus) return;
|
@@ -1585,22 +1641,22 @@ Form.editors = (function() {
|
|
1585
1641
|
setValue: function(value) {
|
1586
1642
|
this.$('input[type=radio]').val([value]);
|
1587
1643
|
},
|
1588
|
-
|
1644
|
+
|
1589
1645
|
focus: function() {
|
1590
1646
|
if (this.hasFocus) return;
|
1591
|
-
|
1647
|
+
|
1592
1648
|
var checked = this.$('input[type=radio]:checked');
|
1593
1649
|
if (checked[0]) {
|
1594
1650
|
checked.focus();
|
1595
1651
|
return;
|
1596
1652
|
}
|
1597
|
-
|
1653
|
+
|
1598
1654
|
this.$('input[type=radio]').first().focus();
|
1599
1655
|
},
|
1600
|
-
|
1656
|
+
|
1601
1657
|
blur: function() {
|
1602
1658
|
if (!this.hasFocus) return;
|
1603
|
-
|
1659
|
+
|
1604
1660
|
this.$('input[type=radio]:focus').blur();
|
1605
1661
|
},
|
1606
1662
|
|
@@ -1617,13 +1673,13 @@ Form.editors = (function() {
|
|
1617
1673
|
_.each(array, function(option, index) {
|
1618
1674
|
var itemHtml = '<li>';
|
1619
1675
|
if (_.isObject(option)) {
|
1620
|
-
var val = option.val ? option.val : '';
|
1621
|
-
itemHtml += ('<input type="radio" name="'+self.id+'" value="'+val+'" id="'+self.id+'-'+index+'" />')
|
1622
|
-
itemHtml += ('<label for="'+self.id+'-'+index+'">'+option.label+'</label>')
|
1676
|
+
var val = (option.val || option.val === 0) ? option.val : '';
|
1677
|
+
itemHtml += ('<input type="radio" name="'+self.id+'" value="'+val+'" id="'+self.id+'-'+index+'" />');
|
1678
|
+
itemHtml += ('<label for="'+self.id+'-'+index+'">'+option.label+'</label>');
|
1623
1679
|
}
|
1624
1680
|
else {
|
1625
|
-
itemHtml += ('<input type="radio" name="'+self.id+'" value="'+option+'" id="'+self.id+'-'+index+'" />')
|
1626
|
-
itemHtml += ('<label for="'+self.id+'-'+index+'">'+option+'</label>')
|
1681
|
+
itemHtml += ('<input type="radio" name="'+self.id+'" value="'+option+'" id="'+self.id+'-'+index+'" />');
|
1682
|
+
itemHtml += ('<label for="'+self.id+'-'+index+'">'+option+'</label>');
|
1627
1683
|
}
|
1628
1684
|
itemHtml += '</li>';
|
1629
1685
|
html.push(itemHtml);
|
@@ -1648,10 +1704,10 @@ Form.editors = (function() {
|
|
1648
1704
|
|
1649
1705
|
tagName: 'ul',
|
1650
1706
|
className: 'bbf-checkboxes',
|
1651
|
-
|
1707
|
+
|
1652
1708
|
events: {
|
1653
1709
|
'click input[type=checkbox]': function() {
|
1654
|
-
this.trigger('change', this)
|
1710
|
+
this.trigger('change', this);
|
1655
1711
|
},
|
1656
1712
|
'focus input[type=checkbox]': function() {
|
1657
1713
|
if (this.hasFocus) return;
|
@@ -1679,16 +1735,16 @@ Form.editors = (function() {
|
|
1679
1735
|
if (!_.isArray(values)) values = [values];
|
1680
1736
|
this.$('input[type=checkbox]').val(values);
|
1681
1737
|
},
|
1682
|
-
|
1738
|
+
|
1683
1739
|
focus: function() {
|
1684
1740
|
if (this.hasFocus) return;
|
1685
|
-
|
1741
|
+
|
1686
1742
|
this.$('input[type=checkbox]').first().focus();
|
1687
1743
|
},
|
1688
|
-
|
1744
|
+
|
1689
1745
|
blur: function() {
|
1690
1746
|
if (!this.hasFocus) return;
|
1691
|
-
|
1747
|
+
|
1692
1748
|
this.$('input[type=checkbox]:focus').blur();
|
1693
1749
|
},
|
1694
1750
|
|
@@ -1705,13 +1761,13 @@ Form.editors = (function() {
|
|
1705
1761
|
_.each(array, function(option, index) {
|
1706
1762
|
var itemHtml = '<li>';
|
1707
1763
|
if (_.isObject(option)) {
|
1708
|
-
var val = option.val ? option.val : '';
|
1709
|
-
itemHtml += ('<input type="checkbox" name="'+self.id+'" value="'+val+'" id="'+self.id+'-'+index+'" />')
|
1710
|
-
itemHtml += ('<label for="'+self.id+'-'+index+'">'+option.label+'</label>')
|
1764
|
+
var val = (option.val || option.val === 0) ? option.val : '';
|
1765
|
+
itemHtml += ('<input type="checkbox" name="'+self.id+'" value="'+val+'" id="'+self.id+'-'+index+'" />');
|
1766
|
+
itemHtml += ('<label for="'+self.id+'-'+index+'">'+option.label+'</label>');
|
1711
1767
|
}
|
1712
1768
|
else {
|
1713
|
-
itemHtml += ('<input type="checkbox" name="'+self.id+'" value="'+option+'" id="'+self.id+'-'+index+'" />')
|
1714
|
-
itemHtml += ('<label for="'+self.id+'-'+index+'">'+option+'</label>')
|
1769
|
+
itemHtml += ('<input type="checkbox" name="'+self.id+'" value="'+option+'" id="'+self.id+'-'+index+'" />');
|
1770
|
+
itemHtml += ('<label for="'+self.id+'-'+index+'">'+option+'</label>');
|
1715
1771
|
}
|
1716
1772
|
itemHtml += '</li>';
|
1717
1773
|
html.push(itemHtml);
|
@@ -1726,9 +1782,9 @@ Form.editors = (function() {
|
|
1726
1782
|
|
1727
1783
|
/**
|
1728
1784
|
* OBJECT
|
1729
|
-
*
|
1785
|
+
*
|
1730
1786
|
* Creates a child form. For editing Javascript objects
|
1731
|
-
*
|
1787
|
+
*
|
1732
1788
|
* @param {Object} options
|
1733
1789
|
* @param {Object} options.schema The schema for the object
|
1734
1790
|
* @param {Object} options.schema.subSchema The schema for the nested form
|
@@ -1750,7 +1806,7 @@ Form.editors = (function() {
|
|
1750
1806
|
if (!this.schema.subSchema) throw new Error("Missing required 'schema.subSchema' option for Object editor");
|
1751
1807
|
},
|
1752
1808
|
|
1753
|
-
render: function() {
|
1809
|
+
render: function() {
|
1754
1810
|
//Create the nested form
|
1755
1811
|
this.form = new Form({
|
1756
1812
|
schema: this.schema.subSchema,
|
@@ -1762,9 +1818,9 @@ Form.editors = (function() {
|
|
1762
1818
|
this._observeFormEvents();
|
1763
1819
|
|
1764
1820
|
this.$el.html(this.form.render().el);
|
1765
|
-
|
1821
|
+
|
1766
1822
|
if (this.hasFocus) this.trigger('blur', this);
|
1767
|
-
|
1823
|
+
|
1768
1824
|
return this;
|
1769
1825
|
},
|
1770
1826
|
|
@@ -1773,22 +1829,22 @@ Form.editors = (function() {
|
|
1773
1829
|
|
1774
1830
|
return this.value;
|
1775
1831
|
},
|
1776
|
-
|
1832
|
+
|
1777
1833
|
setValue: function(value) {
|
1778
1834
|
this.value = value;
|
1779
|
-
|
1835
|
+
|
1780
1836
|
this.render();
|
1781
1837
|
},
|
1782
|
-
|
1838
|
+
|
1783
1839
|
focus: function() {
|
1784
1840
|
if (this.hasFocus) return;
|
1785
|
-
|
1841
|
+
|
1786
1842
|
this.form.focus();
|
1787
1843
|
},
|
1788
|
-
|
1844
|
+
|
1789
1845
|
blur: function() {
|
1790
1846
|
if (!this.hasFocus) return;
|
1791
|
-
|
1847
|
+
|
1792
1848
|
this.form.blur();
|
1793
1849
|
},
|
1794
1850
|
|
@@ -1797,19 +1853,19 @@ Form.editors = (function() {
|
|
1797
1853
|
|
1798
1854
|
Backbone.View.prototype.remove.call(this);
|
1799
1855
|
},
|
1800
|
-
|
1856
|
+
|
1801
1857
|
validate: function() {
|
1802
1858
|
return this.form.validate();
|
1803
1859
|
},
|
1804
|
-
|
1860
|
+
|
1805
1861
|
_observeFormEvents: function() {
|
1806
1862
|
this.form.on('all', function() {
|
1807
1863
|
// args = ["key:change", form, fieldEditor]
|
1808
|
-
args = _.toArray(arguments);
|
1864
|
+
var args = _.toArray(arguments);
|
1809
1865
|
args[1] = this;
|
1810
1866
|
// args = ["key:change", this=objectEditor, fieldEditor]
|
1811
|
-
|
1812
|
-
this.trigger.apply(this, args)
|
1867
|
+
|
1868
|
+
this.trigger.apply(this, args);
|
1813
1869
|
}, this);
|
1814
1870
|
}
|
1815
1871
|
|
@@ -1819,9 +1875,9 @@ Form.editors = (function() {
|
|
1819
1875
|
|
1820
1876
|
/**
|
1821
1877
|
* NESTED MODEL
|
1822
|
-
*
|
1878
|
+
*
|
1823
1879
|
* Creates a child form. For editing nested Backbone models
|
1824
|
-
*
|
1880
|
+
*
|
1825
1881
|
* Special options:
|
1826
1882
|
* schema.model: Embedded model constructor
|
1827
1883
|
*/
|
@@ -1839,9 +1895,7 @@ Form.editors = (function() {
|
|
1839
1895
|
nestedModel = this.schema.model;
|
1840
1896
|
|
1841
1897
|
//Wrap the data in a model if it isn't already a model instance
|
1842
|
-
var modelInstance = (data.constructor
|
1843
|
-
? data
|
1844
|
-
: new nestedModel(data);
|
1898
|
+
var modelInstance = (data.constructor === nestedModel) ? data : new nestedModel(data);
|
1845
1899
|
|
1846
1900
|
this.form = new Form({
|
1847
1901
|
model: modelInstance,
|
@@ -1853,7 +1907,7 @@ Form.editors = (function() {
|
|
1853
1907
|
|
1854
1908
|
//Render form
|
1855
1909
|
this.$el.html(this.form.render().el);
|
1856
|
-
|
1910
|
+
|
1857
1911
|
if (this.hasFocus) this.trigger('blur', this);
|
1858
1912
|
|
1859
1913
|
return this;
|
@@ -1912,12 +1966,12 @@ Form.editors = (function() {
|
|
1912
1966
|
},
|
1913
1967
|
|
1914
1968
|
initialize: function(options) {
|
1915
|
-
options = options || {}
|
1969
|
+
options = options || {};
|
1916
1970
|
|
1917
1971
|
editors.Base.prototype.initialize.call(this, options);
|
1918
1972
|
|
1919
1973
|
var Self = editors.Date,
|
1920
|
-
today = new Date;
|
1974
|
+
today = new Date();
|
1921
1975
|
|
1922
1976
|
//Option defaults
|
1923
1977
|
this.options = _.extend({
|
@@ -1930,18 +1984,18 @@ Form.editors = (function() {
|
|
1930
1984
|
yearStart: today.getFullYear() - 100,
|
1931
1985
|
yearEnd: today.getFullYear()
|
1932
1986
|
}, options.schema || {});
|
1933
|
-
|
1987
|
+
|
1934
1988
|
//Cast to Date
|
1935
1989
|
if (this.value && !_.isDate(this.value)) {
|
1936
1990
|
this.value = new Date(this.value);
|
1937
1991
|
}
|
1938
|
-
|
1992
|
+
|
1939
1993
|
//Set default date
|
1940
1994
|
if (!this.value) {
|
1941
1995
|
var date = new Date();
|
1942
1996
|
date.setSeconds(0);
|
1943
1997
|
date.setMilliseconds(0);
|
1944
|
-
|
1998
|
+
|
1945
1999
|
this.value = date;
|
1946
2000
|
}
|
1947
2001
|
},
|
@@ -1959,12 +2013,15 @@ Form.editors = (function() {
|
|
1959
2013
|
return '<option value="'+month+'">' + value + '</option>';
|
1960
2014
|
});
|
1961
2015
|
|
1962
|
-
var
|
2016
|
+
var yearRange = schema.yearStart < schema.yearEnd ?
|
2017
|
+
_.range(schema.yearStart, schema.yearEnd + 1) :
|
2018
|
+
_.range(schema.yearStart, schema.yearEnd - 1, -1);
|
2019
|
+
var yearsOptions = _.map(yearRange, function(year) {
|
1963
2020
|
return '<option value="'+year+'">' + year + '</option>';
|
1964
2021
|
});
|
1965
2022
|
|
1966
2023
|
//Render the selects
|
1967
|
-
var $el =
|
2024
|
+
var $el = Form.helpers.parseHTML(Form.templates.date({
|
1968
2025
|
dates: datesOptions.join(''),
|
1969
2026
|
months: monthsOptions.join(''),
|
1970
2027
|
years: yearsOptions.join('')
|
@@ -1985,7 +2042,7 @@ Form.editors = (function() {
|
|
1985
2042
|
//Remove the wrapper tag
|
1986
2043
|
this.setElement($el);
|
1987
2044
|
this.$el.attr('id', this.id);
|
1988
|
-
|
2045
|
+
|
1989
2046
|
if (this.hasFocus) this.trigger('blur', this);
|
1990
2047
|
|
1991
2048
|
return this;
|
@@ -2003,7 +2060,7 @@ Form.editors = (function() {
|
|
2003
2060
|
|
2004
2061
|
return new Date(year, month, date);
|
2005
2062
|
},
|
2006
|
-
|
2063
|
+
|
2007
2064
|
/**
|
2008
2065
|
* @param {Date} date
|
2009
2066
|
*/
|
@@ -2014,16 +2071,16 @@ Form.editors = (function() {
|
|
2014
2071
|
|
2015
2072
|
this.updateHidden();
|
2016
2073
|
},
|
2017
|
-
|
2074
|
+
|
2018
2075
|
focus: function() {
|
2019
2076
|
if (this.hasFocus) return;
|
2020
|
-
|
2077
|
+
|
2021
2078
|
this.$('select').first().focus();
|
2022
2079
|
},
|
2023
|
-
|
2080
|
+
|
2024
2081
|
blur: function() {
|
2025
2082
|
if (!this.hasFocus) return;
|
2026
|
-
|
2083
|
+
|
2027
2084
|
this.$('select:focus').blur();
|
2028
2085
|
},
|
2029
2086
|
|
@@ -2052,7 +2109,7 @@ Form.editors = (function() {
|
|
2052
2109
|
|
2053
2110
|
/**
|
2054
2111
|
* DATETIME
|
2055
|
-
*
|
2112
|
+
*
|
2056
2113
|
* @param {Editor} [options.DateEditor] Date editor view to use (not definition)
|
2057
2114
|
* @param {Number} [options.schema.minsInterval] Interval between minutes. Default: 15
|
2058
2115
|
*/
|
@@ -2100,7 +2157,7 @@ Form.editors = (function() {
|
|
2100
2157
|
|
2101
2158
|
render: function() {
|
2102
2159
|
function pad(n) {
|
2103
|
-
return n < 10 ? '0' + n : n
|
2160
|
+
return n < 10 ? '0' + n : n;
|
2104
2161
|
}
|
2105
2162
|
|
2106
2163
|
var schema = this.schema;
|
@@ -2115,7 +2172,7 @@ Form.editors = (function() {
|
|
2115
2172
|
});
|
2116
2173
|
|
2117
2174
|
//Render time selects
|
2118
|
-
var $el =
|
2175
|
+
var $el = Form.helpers.parseHTML(Form.templates.dateTime({
|
2119
2176
|
date: '<b class="bbf-tmp"></b>',
|
2120
2177
|
hours: hoursOptions.join(),
|
2121
2178
|
mins: minsOptions.join()
|
@@ -2130,13 +2187,13 @@ Form.editors = (function() {
|
|
2130
2187
|
|
2131
2188
|
//Get the hidden date field to store values in case POSTed to server
|
2132
2189
|
this.$hidden = $el.find('input[type="hidden"]');
|
2133
|
-
|
2190
|
+
|
2134
2191
|
//Set time
|
2135
2192
|
this.setValue(this.value);
|
2136
2193
|
|
2137
2194
|
this.setElement($el);
|
2138
2195
|
this.$el.attr('id', this.id);
|
2139
|
-
|
2196
|
+
|
2140
2197
|
if (this.hasFocus) this.trigger('blur', this);
|
2141
2198
|
|
2142
2199
|
return this;
|
@@ -2158,27 +2215,27 @@ Form.editors = (function() {
|
|
2158
2215
|
|
2159
2216
|
return date;
|
2160
2217
|
},
|
2161
|
-
|
2218
|
+
|
2162
2219
|
setValue: function(date) {
|
2163
2220
|
if (!_.isDate(date)) date = new Date(date);
|
2164
|
-
|
2221
|
+
|
2165
2222
|
this.dateEditor.setValue(date);
|
2166
|
-
|
2223
|
+
|
2167
2224
|
this.$hour.val(date.getHours());
|
2168
2225
|
this.$min.val(date.getMinutes());
|
2169
2226
|
|
2170
2227
|
this.updateHidden();
|
2171
2228
|
},
|
2172
|
-
|
2229
|
+
|
2173
2230
|
focus: function() {
|
2174
2231
|
if (this.hasFocus) return;
|
2175
|
-
|
2232
|
+
|
2176
2233
|
this.$('select').first().focus();
|
2177
2234
|
},
|
2178
|
-
|
2235
|
+
|
2179
2236
|
blur: function() {
|
2180
2237
|
if (!this.hasFocus) return;
|
2181
|
-
|
2238
|
+
|
2182
2239
|
this.$('select:focus').blur();
|
2183
2240
|
},
|
2184
2241
|
|
@@ -2243,6 +2300,7 @@ Form.editors = (function() {
|
|
2243
2300
|
<label for="{{id}}">{{title}}</label>\
|
2244
2301
|
<div class="bbf-editor">{{editor}}</div>\
|
2245
2302
|
<div class="bbf-help">{{help}}</div>\
|
2303
|
+
<div class="bbf-error">{{error}}</div>\
|
2246
2304
|
</li>\
|
2247
2305
|
',
|
2248
2306
|
|
@@ -2251,6 +2309,7 @@ Form.editors = (function() {
|
|
2251
2309
|
<label for="{{id}}">{{title}}</label>\
|
2252
2310
|
<div class="bbf-editor">{{editor}}</div>\
|
2253
2311
|
<div class="bbf-help">{{help}}</div>\
|
2312
|
+
<div class="bbf-error">{{error}}</div>\
|
2254
2313
|
</li>\
|
2255
2314
|
',
|
2256
2315
|
|
@@ -2300,7 +2359,7 @@ Form.editors = (function() {
|
|
2300
2359
|
|
2301
2360
|
|
2302
2361
|
//Metadata
|
2303
|
-
Form.VERSION = '0.
|
2362
|
+
Form.VERSION = '0.11.0';
|
2304
2363
|
|
2305
2364
|
|
2306
2365
|
//Exports
|