mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-30 20:43:50 -06:00
6ef2384e7f
attribute value.
628 lines
22 KiB
JavaScript
628 lines
22 KiB
JavaScript
/*
|
|
Backform
|
|
http://github.com/amiliaapp/backform
|
|
|
|
Copyright (c) 2014 Amilia Inc.
|
|
Written by Martin Drapeau
|
|
Licensed under the MIT @license
|
|
*/
|
|
(function(root, factory) {
|
|
|
|
// Set up Backform appropriately for the environment. Start with AMD.
|
|
if (typeof define === 'function' && define.amd) {
|
|
define(['underscore', 'jquery', 'backbone'], function(_, $, Backbone) {
|
|
// Export global even in AMD case in case this script is loaded with
|
|
// others that may still expect a global Backform.
|
|
return factory(root, _, $, Backbone);
|
|
});
|
|
|
|
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
|
|
} else if (typeof exports !== 'undefined') {
|
|
var _ = require('underscore');
|
|
factory(root, _, (root.jQuery || root.$ || root.Zepto || root.ender), root.Backbone);
|
|
|
|
// Finally, as a browser global.
|
|
} else {
|
|
factory(root, root._, (root.jQuery || root.Zepto || root.ender || root.$), root.Backbone);
|
|
}
|
|
} (this, function(root, _, $, Backbone) {
|
|
|
|
// Backform namespace and global options
|
|
Backform = root.Backform = {
|
|
// HTML markup global class names. More can be added by individual controls
|
|
// using _.extend. Look at RadioControl as an example.
|
|
formClassName: "backform form-horizontal",
|
|
groupClassName: "form-group",
|
|
controlLabelClassName: "control-label col-sm-4",
|
|
controlsClassName: "col-sm-8",
|
|
controlClassName: "form-control",
|
|
helpClassName: "help-block",
|
|
errorClassName: "has-error",
|
|
helpMessageClassName: "help-block",
|
|
hiddenClassname: "hidden",
|
|
|
|
// Bootstrap 2.3 adapter
|
|
bootstrap2: function() {
|
|
_.extend(Backform, {
|
|
groupClassName: "control-group",
|
|
controlLabelClassName: "control-label",
|
|
controlsClassName: "controls",
|
|
controlClassName: "input-xlarge",
|
|
helpClassName: "text-error",
|
|
errorClassName: "error",
|
|
helpMessageClassName: "help-message small"
|
|
});
|
|
_.each(Backform, function(value, name) {
|
|
if (_.isFunction(Backform[name]) &&
|
|
_.isFunction(Backform[name].prototype["bootstrap2"]))
|
|
Backform[name].prototype["bootstrap2"]();
|
|
});
|
|
},
|
|
// https://github.com/wyuenho/backgrid/blob/master/lib/backgrid.js
|
|
resolveNameToClass: function(name, suffix) {
|
|
if (_.isString(name)) {
|
|
var key = _.map(name.split('-'), function(e) {
|
|
return e.slice(0, 1).toUpperCase() + e.slice(1);
|
|
}).join('') + suffix;
|
|
var klass = Backform[key];
|
|
if (_.isUndefined(klass)) {
|
|
throw new ReferenceError("Class '" + key + "' not found");
|
|
}
|
|
return klass;
|
|
}
|
|
return name;
|
|
}
|
|
};
|
|
|
|
// Backform Form view
|
|
// A collection of field models.
|
|
var Form = Backform.Form = Backbone.View.extend({
|
|
fields: undefined,
|
|
errorModel: undefined,
|
|
tagName: "form",
|
|
className: function() {
|
|
return Backform.formClassName;
|
|
},
|
|
initialize: function(options) {
|
|
if (!(options.fields instanceof Backbone.Collection))
|
|
options.fields = new Fields(options.fields || this.fields);
|
|
this.fields = options.fields;
|
|
this.model.errorModel = options.errorModel || this.model.errorModel || new Backbone.Model();
|
|
this.controls = [];
|
|
},
|
|
cleanup: function() {
|
|
_.each(this.controls, function(c) {
|
|
c.remove();
|
|
});
|
|
this.controls.length = 0;
|
|
},
|
|
remove: function() {
|
|
/* First do the clean up */
|
|
this.cleanup();
|
|
Backbone.View.prototype.remove.apply(this, arguments);
|
|
},
|
|
render: function() {
|
|
this.cleanup();
|
|
this.$el.empty();
|
|
|
|
var form = this,
|
|
$form = this.$el,
|
|
model = this.model,
|
|
controls = this.controls;
|
|
|
|
this.fields.each(function(field) {
|
|
var control = new (field.get("control"))({
|
|
field: field,
|
|
model: model
|
|
});
|
|
$form.append(control.render().$el);
|
|
controls.push(control);
|
|
});
|
|
|
|
return this;
|
|
}
|
|
});
|
|
|
|
// Converting data to/from Model/DOM.
|
|
// Stolen directly from Backgrid's CellFormatter.
|
|
// Source: http://backgridjs.com/ref/formatter.html
|
|
/**
|
|
Just a convenient class for interested parties to subclass.
|
|
|
|
The default Cell classes don't require the formatter to be a subclass of
|
|
Formatter as long as the fromRaw(rawData) and toRaw(formattedData) methods
|
|
are defined.
|
|
|
|
@abstract
|
|
@class Backform.ControlFormatter
|
|
@constructor
|
|
*/
|
|
var ControlFormatter = Backform.ControlFormatter = function() {};
|
|
_.extend(ControlFormatter.prototype, {
|
|
|
|
/**
|
|
Takes a raw value from a model and returns an optionally formatted string
|
|
for display. The default implementation simply returns the supplied value
|
|
as is without any type conversion.
|
|
|
|
@member Backform.ControlFormatter
|
|
@param {*} rawData
|
|
@param {Backbone.Model} model Used for more complicated formatting
|
|
@return {*}
|
|
*/
|
|
fromRaw: function (rawData, model) {
|
|
return rawData;
|
|
},
|
|
|
|
/**
|
|
Takes a formatted string, usually from user input, and returns a
|
|
appropriately typed value for persistence in the model.
|
|
|
|
If the user input is invalid or unable to be converted to a raw value
|
|
suitable for persistence in the model, toRaw must return `undefined`.
|
|
|
|
@member Backform.ControlFormatter
|
|
@param {string} formattedData
|
|
@param {Backbone.Model} model Used for more complicated formatting
|
|
@return {*|undefined}
|
|
*/
|
|
toRaw: function (formattedData, model) {
|
|
return formattedData;
|
|
}
|
|
|
|
});
|
|
|
|
// Store value in DOM as stringified JSON.
|
|
var JSONFormatter = Backform.JSONFormatter = function() {};
|
|
_.extend(JSONFormatter.prototype, {
|
|
fromRaw: function(rawData, model) {
|
|
return JSON.stringify(rawData);
|
|
},
|
|
toRaw: function(formattedData, model) {
|
|
return JSON.parse(formattedData);
|
|
}
|
|
});
|
|
|
|
// Field model and collection
|
|
//
|
|
// A field maps a model attriute to a control for rendering and capturing
|
|
// user input.
|
|
var Field = Backform.Field = Backbone.Model.extend({
|
|
defaults: {
|
|
// Name of the model attribute
|
|
// - It accepts "." nested path (e.g. x.y.z)
|
|
name: "",
|
|
// Placeholder for the input
|
|
placeholder: "",
|
|
// Disable the input control
|
|
// (Optional - true/false/function returning boolean)
|
|
// (Default Value: false)
|
|
disabled: false,
|
|
// Visible
|
|
// (Optional - true/false/function returning boolean)
|
|
// (Default Value: true)
|
|
visible: true,
|
|
// Value Required (validation)
|
|
// (Optional - true/false/function returning boolean)
|
|
// (Default Value: true)
|
|
required: false,
|
|
// Default value for the field
|
|
// (Optional)
|
|
value: undefined,
|
|
// Control or class name for the control representing this field
|
|
control: undefined,
|
|
formatter: undefined
|
|
},
|
|
initialize: function(attributes, options) {
|
|
var control = Backform.resolveNameToClass(this.get("control"), "Control");
|
|
this.set({control: control}, {silent: true});
|
|
}
|
|
});
|
|
|
|
var Fields = Backform.Fields = Backbone.Collection.extend({
|
|
model: Field
|
|
});
|
|
|
|
// Base Control class
|
|
var Control = Backform.Control = Backbone.View.extend({
|
|
// Additional field defaults
|
|
defaults: {},
|
|
className: function() {
|
|
return Backform.groupClassName;
|
|
},
|
|
template: _.template([
|
|
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
|
|
'<div class="<%=Backform.controlsClassName%>">',
|
|
' <span class="<%=Backform.controlClassName%> uneditable-input">',
|
|
' <%=value%>',
|
|
' </span>',
|
|
'</div>'
|
|
].join("\n")),
|
|
initialize: function(options) {
|
|
// Back-reference to the field
|
|
this.field = options.field;
|
|
|
|
var formatter = Backform.resolveNameToClass(this.field.get("formatter") || this.formatter, "Formatter");
|
|
if (!_.isFunction(formatter.fromRaw) && !_.isFunction(formatter.toRaw)) {
|
|
formatter = new formatter();
|
|
}
|
|
this.formatter = formatter;
|
|
|
|
var attrArr = this.field.get('name').split('.');
|
|
var name = attrArr.shift();
|
|
|
|
// Listen to the field in the model for any change
|
|
this.listenTo(this.model, "change:" + name, this.render);
|
|
|
|
// Listen for the field in the error model for any change
|
|
if (this.model.errorModel instanceof Backbone.Model)
|
|
this.listenTo(this.model.errorModel, "change:" + name, this.updateInvalid);
|
|
},
|
|
formatter: ControlFormatter,
|
|
getValueFromDOM: function() {
|
|
return this.formatter.toRaw(this.$el.find(".uneditable-input").text(), this.model);
|
|
},
|
|
onChange: function(e) {
|
|
var model = this.model,
|
|
$el = $(e.target),
|
|
attrArr = this.field.get("name").split('.'),
|
|
name = attrArr.shift(),
|
|
path = attrArr.join('.'),
|
|
value = this.getValueFromDOM(),
|
|
changes = {};
|
|
|
|
if (this.model.errorModel instanceof Backbone.Model) {
|
|
if (_.isEmpty(path)) {
|
|
this.model.errorModel.unset(name);
|
|
} else {
|
|
var nestedError = this.model.errorModel.get(name);
|
|
if (nestedError) {
|
|
this.keyPathSetter(nestedError, path, null);
|
|
this.model.errorModel.set(name, nestedError);
|
|
}
|
|
}
|
|
}
|
|
|
|
changes[name] = _.isEmpty(path) ? value : _.clone(model.get(name)) || {};
|
|
|
|
if (!_.isEmpty(path)) this.keyPathSetter(changes[name], path, value);
|
|
this.stopListening(this.model, "change:" + name, this.render);
|
|
model.set(changes);
|
|
this.listenTo(this.model, "change:" + name, this.render);
|
|
},
|
|
render: function() {
|
|
var field = _.defaults(this.field.toJSON(), this.defaults),
|
|
attributes = this.model.toJSON(),
|
|
attrArr = field.name.split('.'),
|
|
name = attrArr.shift(),
|
|
path = attrArr.join('.'),
|
|
rawValue = this.keyPathAccessor(attributes[name], path),
|
|
data = _.extend(field, {
|
|
rawValue: rawValue,
|
|
value: this.formatter.fromRaw(rawValue, this.model),
|
|
attributes: attributes,
|
|
formatter: this.formatter
|
|
}),
|
|
evalF = function(f, m) {
|
|
return (_.isFunction(f) ? !!f(m) : !!f);
|
|
};
|
|
|
|
// Evaluate the disabled, visible, and required option
|
|
_.extend(data, {
|
|
disabled: evalF(data.disabled, this.model),
|
|
visible: evalF(data.visible, this.model),
|
|
required: evalF(data.required, this.model)
|
|
});
|
|
|
|
// Clean up first
|
|
this.$el.removeClass(Backform.hiddenClassname);
|
|
|
|
if (!data.visible)
|
|
this.$el.addClass(Backform.hiddenClassname);
|
|
|
|
this.$el.html(this.template(data)).addClass(field.name);
|
|
this.updateInvalid();
|
|
|
|
return this;
|
|
},
|
|
clearInvalid: function() {
|
|
this.$el.removeClass(Backform.errorClassName)
|
|
.find("." + Backform.helpClassName + ".error").remove();
|
|
return this;
|
|
},
|
|
updateInvalid: function() {
|
|
var self = this;
|
|
var errorModel = this.model.errorModel;
|
|
if (!(errorModel instanceof Backbone.Model)) return this;
|
|
|
|
this.clearInvalid();
|
|
|
|
this.$el.find(':input').not('button').each(function(ix, el) {
|
|
var attrArr = $(el).attr('name').split('.'),
|
|
name = attrArr.shift(),
|
|
path = attrArr.join('.'),
|
|
error = self.keyPathAccessor(errorModel.toJSON(), $(el).attr('name'));
|
|
|
|
if (_.isEmpty(error)) return;
|
|
if (_.isEmpty(error)) return;
|
|
|
|
self.$el.addClass(Backform.errorClassName);
|
|
self.$el.find("." + Backform.controlsClassName)
|
|
.append('<span class="' + Backform.helpClassName + ' error">' + (_.isArray(error) ? error.join(", ") : error) + '</span>');
|
|
});
|
|
|
|
return this;
|
|
},
|
|
keyPathAccessor: function(obj, path) {
|
|
var res = obj;
|
|
path = path.split('.');
|
|
for (var i = 0; i < path.length; i++) {
|
|
if (_.isNull(res)) return null;
|
|
if (_.isEmpty(path[i])) continue;
|
|
if (!_.isUndefined(res[path[i]])) res = res[path[i]];
|
|
}
|
|
return _.isObject(res) && !_.isArray(res) ? null : res;
|
|
},
|
|
keyPathSetter: function(obj, path, value) {
|
|
path = path.split('.');
|
|
while (path.length > 1) {
|
|
if (!obj[path[0]]) obj[path[0]] = {};
|
|
obj = obj[path.shift()];
|
|
}
|
|
return obj[path.shift()] = value;
|
|
}
|
|
});
|
|
|
|
// Built-in controls
|
|
|
|
var UneditableInputControl = Backform.UneditableInputControl = Control;
|
|
|
|
var HelpControl = Backform.HelpControl = Control.extend({
|
|
template: _.template([
|
|
'<label class="<%=Backform.controlLabelClassName%>"> </label>',
|
|
'<div class="<%=Backform.controlsClassName%>">',
|
|
' <span class="<%=Backform.helpMessageClassName%> help-block"><%=label%></span>',
|
|
'</div>'
|
|
].join("\n"))
|
|
});
|
|
|
|
var SpacerControl = Backform.SpacerControl = Control.extend({
|
|
template: _.template([
|
|
'<label class="<%=Backform.controlLabelClassName%>"> </label>',
|
|
'<div class="<%=Backform.controlsClassName%>"></div>'
|
|
].join("\n"))
|
|
});
|
|
|
|
var TextareaControl = Backform.TextareaControl = Control.extend({
|
|
defaults: {
|
|
label: "",
|
|
maxlength: 4000,
|
|
extraClasses: [],
|
|
helpMessage: null
|
|
},
|
|
template: _.template([
|
|
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
|
|
'<div class="<%=Backform.controlsClassName%>">',
|
|
' <textarea class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>" name="<%=name%>" maxlength="<%=maxlength%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%>><%-value%></textarea>',
|
|
' <% if (helpMessage && helpMessage.length) { %>',
|
|
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
|
|
' <% } %>',
|
|
'</div>'
|
|
].join("\n")),
|
|
events: {
|
|
"change textarea": "onChange",
|
|
"focus textarea": "clearInvalid"
|
|
},
|
|
getValueFromDOM: function() {
|
|
return this.formatter.toRaw(this.$el.find("textarea").val(), this.model);
|
|
}
|
|
});
|
|
|
|
var SelectControl = Backform.SelectControl = Control.extend({
|
|
defaults: {
|
|
label: "",
|
|
options: [], // List of options as [{label:<label>, value:<value>}, ...]
|
|
extraClasses: []
|
|
},
|
|
template: _.template([
|
|
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
|
|
'<div class="<%=Backform.controlsClassName%>">',
|
|
' <select class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>" name="<%=name%>" value="<%-value%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> >',
|
|
' <% for (var i=0; i < options.length; i++) { %>',
|
|
' <% var option = options[i]; %>',
|
|
' <option value="<%-formatter.fromRaw(option.value)%>" <%=option.value === rawValue ? "selected=\'selected\'" : ""%> <%=option.disabled ? "disabled=\'disabled\'" : ""%>><%-option.label%></option>',
|
|
' <% } %>',
|
|
' </select>',
|
|
'</div>'
|
|
].join("\n")),
|
|
events: {
|
|
"change select": "onChange",
|
|
"focus select": "clearInvalid"
|
|
},
|
|
formatter: JSONFormatter,
|
|
getValueFromDOM: function() {
|
|
return this.formatter.toRaw(this.$el.find("select").val(), this.model);
|
|
}
|
|
});
|
|
|
|
// Note: Value here is null or an array. Since jQuery val() returns either.
|
|
var MultiSelectControl = Backform.MultiSelectControl = SelectControl.extend({
|
|
defaults: {
|
|
label: "",
|
|
options: [], // List of options as [{label:<label>, value:<value>}, ...]
|
|
extraClasses: [],
|
|
height: '78px'
|
|
},
|
|
template: _.template([
|
|
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
|
|
'<div class="<%=Backform.controlsClassName%>">',
|
|
' <select multiple="multiple" class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>" name="<%=name%>" value="<%-JSON.stringify(value)%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> style="height:<%=height%>">',
|
|
' <% for (var i=0; i < options.length; i++) { %>',
|
|
' <% var option = options[i]; %>',
|
|
' <option value="<%-option.value%>" <%=value != null && _.indexOf(value, option.value) != -1 ? "selected=\'selected\'" : ""%> <%=option.disabled ? "disabled=\'disabled\'" : ""%>><%-option.label%></option>',
|
|
' <% } %>',
|
|
' </select>',
|
|
'</div>'
|
|
].join("\n")),
|
|
events: {
|
|
"change select": "onChange",
|
|
"dblclick select": "onDoubleClick",
|
|
"focus select": "clearInvalid"
|
|
},
|
|
formatter: {
|
|
fromRaw: function(rawData, model) {
|
|
return rawData;
|
|
},
|
|
toRaw: function(formattedData, model) {
|
|
return typeof formattedData == "object" ? formattedData : JSON.parse(formattedData);
|
|
}
|
|
},
|
|
onDoubleClick: function(e) {
|
|
this.model.trigger('doubleclick', e);
|
|
}
|
|
});
|
|
|
|
var InputControl = Backform.InputControl = Control.extend({
|
|
defaults: {
|
|
type: "text",
|
|
label: "",
|
|
maxlength: 255,
|
|
extraClasses: [],
|
|
helpMessage: null
|
|
},
|
|
template: _.template([
|
|
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
|
|
'<div class="<%=Backform.controlsClassName%>">',
|
|
' <input type="<%=type%>" class="<%=Backform.controlClassName%> <%=extraClasses.join(\' \')%>" name="<%=name%>" maxlength="<%=maxlength%>" value="<%-value%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> />',
|
|
' <% if (helpMessage && helpMessage.length) { %>',
|
|
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
|
|
' <% } %>',
|
|
'</div>'
|
|
].join("\n")),
|
|
events: {
|
|
"change input": "onChange",
|
|
"focus input": "clearInvalid"
|
|
},
|
|
getValueFromDOM: function() {
|
|
return this.formatter.toRaw(this.$el.find("input").val(), this.model);
|
|
}
|
|
});
|
|
|
|
var BooleanControl = Backform.BooleanControl = InputControl.extend({
|
|
defaults: {
|
|
type: "checkbox",
|
|
label: "",
|
|
controlLabel: ' ',
|
|
extraClasses: []
|
|
},
|
|
template: _.template([
|
|
'<label class="<%=Backform.controlLabelClassName%>"><%=controlLabel%></label>',
|
|
'<div class="<%=Backform.controlsClassName%>">',
|
|
' <div class="checkbox">',
|
|
' <label>',
|
|
' <input type="<%=type%>" class="<%=extraClasses.join(\' \')%>" name="<%=name%>" <%=value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> /> <%=label%>',
|
|
' </label>',
|
|
' </div>',
|
|
'</div>'
|
|
].join("\n")),
|
|
getValueFromDOM: function() {
|
|
return this.formatter.toRaw(this.$el.find("input").is(":checked"), this.model);
|
|
}
|
|
});
|
|
|
|
var CheckboxControl = Backform.CheckboxControl = BooleanControl;
|
|
|
|
var RadioControl = Backform.RadioControl = InputControl.extend({
|
|
defaults: {
|
|
type: "radio",
|
|
label: "",
|
|
options: [],
|
|
extraClasses: [],
|
|
helpMessage: null
|
|
},
|
|
template: _.template([
|
|
'<label class="<%=Backform.controlLabelClassName%>"><%=label%></label>',
|
|
'<div class="<%=Backform.controlsClassName%> <%=Backform.radioControlsClassName%>">',
|
|
' <% for (var i=0; i < options.length; i++) { %>',
|
|
' <% var option = options[i]; %>',
|
|
' <label class="<%=Backform.radioLabelClassName%>">',
|
|
' <input type="<%=type%>" class="<%=extraClasses.join(\' \')%>" name="<%=name%>" value="<%-formatter.fromRaw(option.value)%>" <%=rawValue == option.value ? "checked=\'checked\'" : ""%> <%=disabled ? "disabled" : ""%> <%=required ? "required" : ""%> /> <%-option.label%>',
|
|
' </label>',
|
|
' <% } %>',
|
|
' <% if (helpMessage && helpMessage.length) { %>',
|
|
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
|
|
' <% } %>',
|
|
'</div>'
|
|
].join("\n")),
|
|
formatter: JSONFormatter,
|
|
getValueFromDOM: function() {
|
|
return this.formatter.toRaw(this.$el.find("input:checked").val(), this.model);
|
|
},
|
|
bootstrap2: function() {
|
|
Backform.radioControlsClassName = "controls";
|
|
Backform.radioLabelClassName = "radio inline";
|
|
}
|
|
});
|
|
_.extend(Backform, {
|
|
radioControlsClassName: "checkbox",
|
|
radioLabelClassName: "checkbox-inline"
|
|
});
|
|
|
|
// Requires the Bootstrap Datepicker to work.
|
|
var DatepickerControl = Backform.DatepickerControl = InputControl.extend({
|
|
defaults: {
|
|
type: "text",
|
|
label: "",
|
|
options: {},
|
|
extraClasses: [],
|
|
maxlength: 255,
|
|
helpMessage: null
|
|
},
|
|
events: {
|
|
"blur input": "onChange",
|
|
"change input": "onChange",
|
|
"changeDate input": "onChange",
|
|
"focus input": "clearInvalid"
|
|
},
|
|
render: function() {
|
|
InputControl.prototype.render.apply(this, arguments);
|
|
this.$el.find("input").datepicker(this.field.get("options"));
|
|
return this;
|
|
}
|
|
});
|
|
|
|
var ButtonControl = Backform.ButtonControl = Control.extend({
|
|
defaults: {
|
|
type: "submit",
|
|
label: "Submit",
|
|
status: undefined, // error or success
|
|
message: undefined,
|
|
extraClasses: []
|
|
},
|
|
template: _.template([
|
|
'<label class="<%=Backform.controlLabelClassName%>"> </label>',
|
|
'<div class="<%=Backform.controlsClassName%>">',
|
|
' <button type="<%=type%>" name="<%=name%>" class="btn <%=extraClasses.join(\' \')%>" <%=disabled ? "disabled" : ""%> ><%=label%></button>',
|
|
' <% var cls = ""; if (status == "error") cls = Backform.buttonStatusErrorClassName; if (status == "success") cls = Backform.buttonStatusSuccessClassname; %>',
|
|
' <span class="status <%=cls%>"><%=message%></span>',
|
|
'</div>'
|
|
].join("\n")),
|
|
initialize: function() {
|
|
Control.prototype.initialize.apply(this, arguments);
|
|
this.listenTo(this.field, "change:status", this.render);
|
|
this.listenTo(this.field, "change:message", this.render);
|
|
},
|
|
bootstrap2: function() {
|
|
Backform.buttonStatusErrorClassName = "text-error";
|
|
Backform.buttonStatusSuccessClassname = "text-success";
|
|
}
|
|
});
|
|
_.extend(Backform, {
|
|
buttonStatusErrorClassName: "text-danger",
|
|
buttonStatusSuccessClassname: "text-success"
|
|
});
|
|
|
|
return Backform;
|
|
|
|
}));
|