Fix integer/numeric validation on various dialogues. Fixes #2421

This commit is contained in:
Harshal Dhumal 2017-06-08 14:59:26 +01:00 committed by Dave Page
parent 3bcbc50525
commit aa400cbc12
7 changed files with 323 additions and 279 deletions

View File

@ -102,34 +102,56 @@ define([
cell: 'string', group: gettext('Definition'),
type: 'int', deps: ['datatype'],
disabled: function(m) {
// We will store type from selected from combobox
var val = m.get('typlen');
// We will store type from selected from combobox
if(!(_.isUndefined(m.get('inheritedid'))
|| _.isNull(m.get('inheritedid'))
|| _.isUndefined(m.get('inheritedfrom'))
|| _.isNull(m.get('inheritedfrom')))) { return true; }
|| _.isNull(m.get('inheritedfrom')))) {
var of_type = m.get('datatype');
if(m.type_options) {
m.set('is_tlength', false, {silent: true});
if (!_.isUndefined(val)) {
setTimeout(function() {
m.set('typlen', undefined);
}, 10);
}
return true;
}
// iterating over all the types
_.each(m.type_options, function(o) {
// if type from selected from combobox matches in options
if ( of_type == o.value ) {
m.set('typlen', undefined);
var of_type = m.get('datatype'),
has_length = false;
if(m.type_options) {
m.set('is_tlength', false, {silent: true});
// iterating over all the types
_.each(m.type_options, function(o) {
// if type from selected from combobox matches in options
if ( of_type == o.value ) {
// if length is allowed for selected type
if(o.length)
{
// set the values in model
has_length = true;
m.set('is_tlength', true, {silent: true});
m.set('min_val', o.min_val, {silent: true});
m.set('max_val', o.max_val, {silent: true});
}
}
});
if (!has_length && !_.isUndefined(val)) {
setTimeout(function() {
m.set('typlen', undefined);
}, 10);
}
});
return !(m.get('is_tlength'));
}
return true;
return !(m.get('is_tlength'));
}
if (!has_length && !_.isUndefined(val)) {
setTimeout(function() {
m.set('typlen', undefined);
}, 10);
}
return true;
},
cellHeaderClasses: 'width_percent_10'
},{
@ -137,33 +159,54 @@ define([
type: 'int', deps: ['datatype'],
cell: 'string', group: gettext('Definition'),
disabled: function(m) {
var val = m.get('precision');
if(!(_.isUndefined(m.get('inheritedid'))
|| _.isNull(m.get('inheritedid'))
|| _.isUndefined(m.get('inheritedfrom'))
|| _.isNull(m.get('inheritedfrom')))) { return true; }
|| _.isNull(m.get('inheritedfrom')))) {
if (!_.isUndefined(val)) {
setTimeout(function() {
m.set('precision', undefined);
}, 10);
}
return true;
}
var of_type = m.get('datatype'),
has_precision = false;
var of_type = m.get('datatype');
if(m.type_options) {
m.set('is_precision', false, {silent: true});
// iterating over all the types
_.each(m.type_options, function(o) {
// if type from selected from combobox matches in options
if ( of_type == o.value ) {
m.set('precision', undefined);
// if precession is allowed for selected type
if(o.precision)
{
has_precision = true;
// set the values in model
m.set('is_precision', true, {silent: true});
m.set('min_val', o.min_val, {silent: true});
m.set('max_val', o.max_val, {silent: true});
}
}
});
if (!has_precision && !_.isUndefined(val)) {
setTimeout(function() {
m.set('precision', undefined);
}, 10);
}
});
return !(m.get('is_precision'));
}
return true;
}, cellHeaderClasses: 'width_percent_10'
return !(m.get('is_precision'));
}
if (!has_precision && !_.isUndefined(val)) {
setTimeout(function() {
m.set('precision', undefined);
}, 10);
}
return true;
}, cellHeaderClasses: 'width_percent_10'
},{
id: 'typdefault', label: gettext('Default'), type: 'text',
cell: 'string', min_version: 90300, group: gettext('Definition'),
@ -217,22 +260,23 @@ define([
min_version: 90200
}],
validate: function() {
var err = {},
errmsg;
var errmsg = null;
if (_.isUndefined(this.get('attname')) || String(this.get('attname')).replace(/^\s+|\s+$/g, '') == '') {
err['name'] = gettext('Column Name cannot be empty!');
errmsg = errmsg || err['attname'];
errmsg = gettext('Column Name cannot be empty!');
this.errorModel.set('attname', errmsg);
} else {
this.errorModel.unset('attname');
}
if (_.isUndefined(this.get('datatype')) || String(this.get('datatype'))
.replace(/^\s+|\s+$/g, '') == '') {
err['basensp'] = gettext('Column Datatype cannot be empty!');
errmsg = errmsg || err['datatype'];
errmsg = gettext('Column Datatype cannot be empty!');
this.errorModel.set('datatype', errmsg);
} else {
this.errorModel.unset('datatype');
}
this.errorModel.clear().set(err);
return errmsg;
},
is_editable_column: function(m) {

View File

@ -154,7 +154,10 @@ define([
min: 1
},{
id: 'start', label: gettext('Start'), type: 'int',
mode: ['properties', 'create'], group: gettext('Definition')
mode: ['properties', 'create'], group: gettext('Definition'),
disabled: function(m) {
return !m.isNew();
}
},{
id: 'minimum', label: gettext('Minimum'), type: 'int',
mode: ['properties', 'create', 'edit'], group: gettext('Definition')
@ -200,14 +203,14 @@ define([
minimum = this.get('minimum'),
maximum = this.get('maximum');
start = this.get('start');
// Clear any existing error msg.
this.errorModel.clear();
if (_.isUndefined(this.get('name'))
|| String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
msg = gettext('Name cannot be empty.');
this.errorModel.set('name', msg);
return msg;
} else {
this.errorModel.unset('name');
}
if (_.isUndefined(this.get('seqowner'))
@ -215,6 +218,8 @@ define([
msg = gettext('Owner cannot be empty.');
this.errorModel.set('seqowner', msg);
return msg;
} else {
this.errorModel.unset('seqowner');
}
if (_.isUndefined(this.get('schema'))
@ -222,26 +227,80 @@ define([
msg = gettext('Schema cannot be empty.');
this.errorModel.set('schema', msg);
return msg;
} else {
this.errorModel.unset('schema');
}
if (!this.isNew()) {
if (_.isUndefined(this.get('current_value'))
|| String(this.get('current_value')).replace(/^\s+|\s+$/g, '') == '') {
msg = '{{ _('Current value cannot be empty.') }}';
this.errorModel.set('current_value', msg);
return msg;
} else {
this.errorModel.unset('current_value');
}
if (_.isUndefined(this.get('increment'))
|| String(this.get('increment')).replace(/^\s+|\s+$/g, '') == '') {
msg = '{{ _('Increment value cannot be empty.') }}';
this.errorModel.set('increment', msg);
return msg;
} else {
this.errorModel.unset('increment');
}
if (_.isUndefined(this.get('minimum'))
|| String(this.get('minimum')).replace(/^\s+|\s+$/g, '') == '') {
msg = '{{ _('Minimum value cannot be empty.') }}';
this.errorModel.set('minimum', msg);
return msg;
} else {
this.errorModel.unset('minimum');
}
if (_.isUndefined(this.get('maximum'))
|| String(this.get('maximum')).replace(/^\s+|\s+$/g, '') == '') {
msg = '{{ _('Maximum value cannot be empty.') }}';
this.errorModel.set('maximum', msg);
return msg;
} else {
this.errorModel.unset('maximum');
}
if (_.isUndefined(this.get('cache'))
|| String(this.get('cache')).replace(/^\s+|\s+$/g, '') == '') {
msg = '{{ _('Cache value cannot be empty.') }}';
this.errorModel.set('cache', msg);
return msg;
} else {
this.errorModel.unset('cache');
}
}
var min_lt = gettext('Minimum value must be less than maximum value.'),
start_lt = gettext('Start value cannot be less than minimum value.'),
start_gt = gettext('Start value cannot be greater than maximum value.');
if ((minimum == 0 && maximum == 0) ||
(parseInt(minimum, 10) >= parseInt(maximum, 10))) {
msg = min_lt
this.errorModel.set('minimum', msg);
return msg;
this.errorModel.set('minimum', min_lt);
return min_lt;
} else {
this.errorModel.unset('minimum');
}
else if (start < minimum) {
msg = start_lt
this.errorModel.set('start', msg);
return msg;
if (start && minimum && parseInt(start) < parseInt(minimum)) {
this.errorModel.set('start', start_lt);
return start_lt;
} else {
this.errorModel.unset('start');
}
else if (start > maximum) {
msg = start_gt
this.errorModel.set('start', msg);
return msg;
if (start && maximum && parseInt(start) > parseInt(maximum)) {
this.errorModel.set('start', start_gt);
return start_gt;
} else {
this.errorModel.unset('start');
}
return null;
}

View File

@ -86,53 +86,36 @@ define([
* the GUI for the respective control.
*/
validate: function(keys) {
var msg, cpu_rate_limit, dirty_rate_limit, name;
/* Check whether 'name' is present in 'keys', if it is present
* it means there is a change in that field from the GUI, so we
* need to validate it.
*/
if (_.indexOf(keys, 'name') >= 0) {
name = this.get('name');
if (_.isUndefined(name) || _.isNull(name) ||
String(name).replace(/^\s+|\s+$/g, '') === '') {
msg = gettext('Name cannot be empty.');
this.errorModel.set('name', msg);
return msg;
}
var msg, cpu_rate_limit, dirty_rate_limit, name,
name = this.get('name');
if (_.isUndefined(name) || _.isNull(name) ||
String(name).replace(/^\s+|\s+$/g, '') == '') {
var msg = gettext('Name cannot be empty.');
this.errorModel.set('name', msg);
return msg;
} else {
this.errorModel.unset('name');
}
/* Check whether 'cpu_rate_limit' is present in 'keys', if it is present
* it means there is a change in that field from the GUI, so we
* need to validate it.
*/
if (_.indexOf(keys, 'cpu_rate_limit') >= 0) {
cpu_rate_limit = this.get('cpu_rate_limit');
if (_.isUndefined(cpu_rate_limit) || _.isNull(cpu_rate_limit) ||
String(cpu_rate_limit).replace(/^\s+|\s+$/g, '') === '') {
msg = gettext('CPU rate limit cannot be empty.');
this.errorModel.set('cpu_rate_limit', msg);
return msg;
}
var cpu_rate_limit = this.get('cpu_rate_limit');
if (_.isUndefined(cpu_rate_limit) || _.isNull(cpu_rate_limit) ||
String(cpu_rate_limit).replace(/^\s+|\s+$/g, '') == '') {
var msg = gettext('CPU rate limit cannot be empty.');
this.errorModel.set('cpu_rate_limit', msg);
return msg;
} else {
this.errorModel.unset('cpu_rate_limit');
}
/* Check whether 'dirty_rate_limit' is present in 'keys', if it is present
* it means there is a change in that field from the GUI, so we
* need to validate it.
*/
if (_.indexOf(keys, 'dirty_rate_limit') >= 0) {
dirty_rate_limit = this.get('dirty_rate_limit');
if (_.isUndefined(dirty_rate_limit) || _.isNull(dirty_rate_limit) ||
String(dirty_rate_limit).replace(/^\s+|\s+$/g, '') === '') {
msg = gettext('Dirty rate limit cannot be empty.');
this.errorModel.set('dirty_rate_limit', msg);
return msg;
}
var dirty_rate_limit = this.get('dirty_rate_limit');
if (_.isUndefined(dirty_rate_limit) || _.isNull(dirty_rate_limit) ||
String(dirty_rate_limit).replace(/^\s+|\s+$/g, '') == '') {
var msg = gettext('Dirty rate limit cannot be empty.');
this.errorModel.set('dirty_rate_limit', msg);
return msg;
} else {
this.errorModel.unset('dirty_rate_limit');
}
return null;
}
})

View File

@ -426,7 +426,7 @@ define([
deps: ['rolcanlogin'], options: {format: 'YYYY-MM-DD HH:mm:ss Z'}
},{
id: 'rolconnlimit', type: 'int', group: gettext('Definition'),
label: gettext('Connection limit'), cell: 'number',
label: gettext('Connection limit'), cell: 'number', min : -1,
mode: ['properties', 'edit', 'create'], disabled: 'readonly'
},{
id: 'rolcanlogin', label: gettext('Can login?'), type: 'switch',

View File

@ -721,6 +721,9 @@ define([
check_for_empty(
'username', gettext('Username must be specified.')
);
check_for_empty(
'port', '{{ _('Port must be specified.') }}'
);
this.errorModel.set(err);
if (_.size(err)) {

View File

@ -1,6 +1,6 @@
define(
['underscore', 'pgadmin', 'jquery', 'backbone'],
function(_, pgAdmin, $, Backbone) {
['underscore', 'underscore.string', 'pgadmin', 'jquery', 'backbone'],
function(_, S, pgAdmin, $, Backbone) {
var pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {};
pgBrowser.DataModel = Backbone.Model.extend({
@ -136,6 +136,7 @@ function(_, pgAdmin, $, Backbone) {
}
self.sessAttrs = {};
self.fieldData = {};
self.origSessAttrs = {};
self.objects = [];
self.arrays = [];
@ -152,6 +153,25 @@ function(_, pgAdmin, $, Backbone) {
if (schema && _.isArray(schema)) {
_.each(schema, function(s) {
switch(s.type) {
case 'int':
case 'numeric':
self.fieldData[s.id] = {
id: s.id,
label: s.label,
type: s.type,
min: s.min || undefined,
max: s.max || undefined
}
break;
default:
self.fieldData[s.id] = {
id: s.id,
label: s.label,
type: s.type
}
}
switch(s.type) {
case 'array':
self.arrays.push(s.id);
@ -280,6 +300,12 @@ function(_, pgAdmin, $, Backbone) {
},
sessValid: function() {
var self = this;
// Perform default validations.
if ('default_validate' in self && typeof(self.default_validate) == 'function' &&
_.isString(self.default_validate())) {
return false;
}
if ('validate' in self && _.isFunction(self.validate) &&
_.isString(self.validate.apply(self))) {
return false;
@ -301,8 +327,9 @@ function(_, pgAdmin, $, Backbone) {
}
if (key != null && res) {
var attrs = {};
var self = this;
var attrs = {},
self = this,
msg;
attrChanged = function(v, k) {
if (k in self.objects) {
@ -327,9 +354,18 @@ function(_, pgAdmin, $, Backbone) {
if (!options || !options.silent) {
self.trigger('change', self, options);
}
// Perform default validations.
if ('default_validate' in self && typeof(self.default_validate) == 'function') {
msg = self.default_validate();
}
if ('validate' in self && typeof(self['validate']) === 'function') {
var msg = self.validate(_.keys(attrs));
if (!msg) {
msg = self.validate(_.keys(attrs));
}
/*
* If any parent present, we will need to inform the parent - that
@ -562,6 +598,13 @@ function(_, pgAdmin, $, Backbone) {
var msg = null,
validate = function(m, attrs) {
if ('default_validate' in m && typeof(m.default_validate) == 'function') {
msg = m.default_validate();
if (_.isString(msg)) {
return msg;
}
}
if ('validate' in m && typeof(m.validate) == 'function') {
msg = m.validate(attrs);
@ -655,6 +698,79 @@ function(_, pgAdmin, $, Backbone) {
});
self.trigger('pgadmin-session:stop');
},
default_validate: function() {
var msg, field, value, type;
for (var i = 0, keys = _.keys(this.attributes), l = keys.length;
i<l;
i++) {
value = this.attributes[keys[i]];
field = this.fieldData[keys[i]]
msg = null;
if (!(_.isUndefined(value) || _.isNull(value) ||
String(value).replace(/^\s+|\s+$/g, '') == '')) {
if (!field) {
continue;
}
type = field.type || undefined;
if (!type) {
continue;
}
switch(type) {
case 'int':
msg = this.integer_validate(value, field);
break;
case 'numeric':
msg = this.number_validate(value, field);
break;
}
if (msg) {
this.errorModel.set(field.id, msg);
return msg;
} else {
this.errorModel.unset(field.id);
}
} else {
if (field) {
this.errorModel.unset(field.id);
}
}
}
return null;
},
check_min_max: function (value, field) {
var label = field.label,
min_value = field.min,
max_value = field.max;
if (min_value && value < min_value) {
return S(pgAdmin.Browser.messages.MUST_GR_EQ).sprintf(label, min_value).value();
} else if (max_value && value > max_value) {
return S(pgAdmin.Browser.messages.MUST_LESS_EQ).sprintf(label, max_value).value();
}
return null;
},
number_validate: function (value, field) {
var pattern = new RegExp("^-?[0-9]+(\.?[0-9]*)?$");
if (!pattern.test(value)) {
return S(pgAdmin.Browser.messages.MUST_BE_NUM).sprintf(field.label).value()
}
return this.check_min_max(value, field)
},
integer_validate: function(value, field) {
var pattern = new RegExp("^-?[0-9]*$");
if (!pattern.test(value)) {
return S(pgAdmin.Browser.messages.MUST_BE_INT).sprintf(field.label).value()
}
return this.check_min_max(value, field)
}
});
@ -696,7 +812,8 @@ function(_, pgAdmin, $, Backbone) {
return self;
},
startNewSession: function() {
var self = this;
var self = this,
msg;
if (self.trackChanges) {
// We're stopping the existing session.
@ -718,8 +835,15 @@ function(_, pgAdmin, $, Backbone) {
if ('startNewSession' in m && _.isFunction(m.startNewSession)) {
m.startNewSession();
}
if ('validate' in m && typeof(m.validate) === 'function') {
var msg = m.validate();
if ('default_validate' in m && typeof(m.default_validate) == 'function') {
msg = m.default_validate();
}
if (_.isString(msg)) {
self.sessAttrs['invalid'][m.cid] = msg;
} else if ('validate' in m && typeof(m.validate) === 'function') {
msg = m.validate();
if (msg) {
self.sessAttrs['invalid'][m.cid] = msg;
@ -900,7 +1024,14 @@ function(_, pgAdmin, $, Backbone) {
(self.handler || self).trigger('pgadmin-session:added', self, obj);
if ('validate' in obj && typeof(obj.validate) === 'function') {
if ('default_validate' in obj && typeof(obj.default_validate) == 'function') {
msg = obj.default_validate();
}
if (_.isString(msg)) {
(self.sessAttrs['invalid'])[obj.cid] = msg;
} else if ('validate' in obj && typeof(obj.validate) === 'function') {
msg = obj.validate();
if (msg) {
@ -908,7 +1039,14 @@ function(_, pgAdmin, $, Backbone) {
}
}
} else {
if ('validate' in obj && typeof(obj.validate) === 'function') {
if ('default_validate' in obj && typeof(obj.default_validate) == 'function') {
msg = obj.default_validate();
}
if (_.isString(msg)) {
(self.sessAttrs['invalid'])[obj.cid] = msg;
} else if ('validate' in obj && typeof(obj.validate) === 'function') {
msg = obj.validate();
if (msg) {

View File

@ -58,7 +58,7 @@
});
var controlMapper = Backform.controlMapper = {
'int': ['uneditable-input', 'integer', 'integer'],
'int': ['uneditable-input', 'numeric', 'numeric'],
'text': ['uneditable-input', 'input', 'string'],
'numeric': ['uneditable-input', 'numeric', 'numeric'],
'date': 'datepicker',
@ -1493,110 +1493,6 @@
Backform.Control.__super__.remove.apply(this, arguments);
}
});
/*
* Integer input Control functionality just like backgrid
*/
var IntegerControl = Backform.IntegerControl = Backform.InputControl.extend({
defaults: {
type: "number",
label: "",
min: undefined,
max: undefined,
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%>" min="<%=min%>" max="<%=max%>"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": "checkInt",
"focus input": "clearInvalid"
},
checkInt: function(e) {
var field = _.defaults(this.field.toJSON(), this.defaults),
attrArr = this.field.get("name").split('.'),
name = attrArr.shift(),
value = this.getValueFromDOM(),
min_value = field.min,
max_value = field.max,
isValid = true,
intPattern = new RegExp("^-?[0-9]*$"),
isMatched = intPattern.test(value);
// Below logic will validate input
if (!isMatched) {
isValid = false;
this.model.errorModel.unset(name);
this.model.errorModel.set(
name,
S(gettext("'%s' must be an integer.")).sprintf(
field.label
).value()
);
}
// Below will check if entered value is in-between min & max range
if (isValid && (!_.isUndefined(min_value) && value < min_value)) {
isValid = false;
this.model.errorModel.unset(name);
this.model.errorModel.set(
name,
S(gettext("%s' must be greater than or equal to %d.")).sprintf(
field.label,
min_value
).value()
);
}
if (isValid && (!_.isUndefined(max_value) && value > max_value)) {
isValid = false;
this.model.errorModel.unset(name);
this.model.errorModel.set(
name,
S(gettext("'%s' must be less than or equal to %d.")).sprintf(
field.label,
max_value
).value()
);
}
// After validation we need to set that value into model (only if all flags are true)
if (isValid) {
this.stopListening(this.model, "change:" + name, this.render);
this.model.errorModel.unset(name);
this.model.set(name, value);
this.listenTo(this.model, "change:" + name, this.render);
if (this.model.collection || this.model.handler) {
(this.model.collection || this.model.handler).trigger(
'pgadmin-session:model:valid', this.model, (this.model.collection || this.model.handler)
);
} else {
(this.model).trigger(
'pgadmin-session:valid', this.model.sessChanged(), this.model
);
}
} else {
if (this.model.collection || this.model.handler) {
(this.model.collection || this.model.handler).trigger(
'pgadmin-session:model:invalid', this.model.errorModel.get(name), this.model
);
} else {
(this.model).trigger(
'pgadmin-session:invalid', this.model.errorModel.get(name), this.model
);
}
}
}
});
/*
* Numeric input Control functionality just like backgrid
*/
@ -1618,86 +1514,7 @@
' <span class="<%=Backform.helpMessageClassName%>"><%=helpMessage%></span>',
' <% } %>',
'</div>'
].join("\n")),
events: {
"change input": "checkNumeric",
"focus input": "clearInvalid"
},
checkNumeric: function(e) {
var field = _.defaults(this.field.toJSON(), this.defaults),
attrArr = this.field.get("name").split('.'),
name = attrArr.shift(),
value = this.getValueFromDOM(),
min_value = field.min,
max_value = field.max,
isValid = true,
intPattern = new RegExp("^-?[0-9]+(\.?[0-9]*)?$"),
isMatched = intPattern.test(value);
// Below logic will validate input
if (!isMatched) {
isValid = false;
this.model.errorModel.unset(name);
this.model.errorModel.set(
name,
S(gettext("'%s' must be a numeric.")).sprintf(
field.label
).value()
);
}
// Below will check if entered value is in-between min & max range
if (isValid && (!_.isUndefined(min_value) && value < min_value)) {
isValid = false;
this.model.errorModel.unset(name);
this.model.errorModel.set(
name,
S(gettext("%s' must be greater than or equal to %d.")).sprintf(
field.label,
min_value
).value()
);
}
if (isValid && (!_.isUndefined(max_value) && value > max_value)) {
isValid = false;
this.model.errorModel.unset(name);
this.model.errorModel.set(
name,
S(gettext("'%s' must be less than or equal to %d.")).sprintf(
field.label,
max_value
).value()
);
}
// After validation we need to set that value into model (only if all flags are true)
if (isValid) {
this.stopListening(this.model, "change:" + name, this.render);
this.model.errorModel.unset(name);
this.model.set(name, value);
this.listenTo(this.model, "change:" + name, this.render);
if (this.model.collection || this.model.handler) {
(this.model.collection || this.model.handler).trigger(
'pgadmin-session:model:valid', this.model, (this.model.collection || this.model.handler)
);
} else {
(this.model).trigger(
'pgadmin-session:valid', this.model.sessChanged(), this.model
);
}
} else {
if (this.model.collection || this.model.handler) {
(this.model.collection || this.model.handler).trigger(
'pgadmin-session:model:invalid', this.model.errorModel.get(name), this.model
);
} else {
(this.model).trigger(
'pgadmin-session:invalid', this.model.errorModel.get(name), this.model
);
}
}
}
].join("\n"))
});
///////