From aa400cbc12f34f219322a2b62f9f51e21d031f0e Mon Sep 17 00:00:00 2001 From: Harshal Dhumal Date: Thu, 8 Jun 2017 14:59:26 +0100 Subject: [PATCH] Fix integer/numeric validation on various dialogues. Fixes #2421 --- .../foreign_tables/js/foreign_tables.js | 104 +++++++--- .../templates/sequence/js/sequence.js | 87 ++++++-- .../resource_groups/js/resource_groups.js | 61 +++--- .../servers/roles/templates/role/js/role.js | 2 +- .../servers/templates/servers/servers.js | 3 + web/pgadmin/browser/static/js/datamodel.js | 158 ++++++++++++++- web/pgadmin/static/js/backform.pgadmin.js | 187 +----------------- 7 files changed, 323 insertions(+), 279 deletions(-) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/js/foreign_tables.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/js/foreign_tables.js index b23997015..0ea196ae0 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/js/foreign_tables.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/js/foreign_tables.js @@ -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) { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/js/sequence.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/js/sequence.js index 9e6711eb0..e8d9ac9c9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/js/sequence.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/js/sequence.js @@ -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; } diff --git a/web/pgadmin/browser/server_groups/servers/resource_groups/templates/resource_groups/js/resource_groups.js b/web/pgadmin/browser/server_groups/servers/resource_groups/templates/resource_groups/js/resource_groups.js index cec391799..389a2e68c 100644 --- a/web/pgadmin/browser/server_groups/servers/resource_groups/templates/resource_groups/js/resource_groups.js +++ b/web/pgadmin/browser/server_groups/servers/resource_groups/templates/resource_groups/js/resource_groups.js @@ -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; } }) diff --git a/web/pgadmin/browser/server_groups/servers/roles/templates/role/js/role.js b/web/pgadmin/browser/server_groups/servers/roles/templates/role/js/role.js index 97f073803..e55761dc2 100644 --- a/web/pgadmin/browser/server_groups/servers/roles/templates/role/js/role.js +++ b/web/pgadmin/browser/server_groups/servers/roles/templates/role/js/role.js @@ -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', diff --git a/web/pgadmin/browser/server_groups/servers/templates/servers/servers.js b/web/pgadmin/browser/server_groups/servers/templates/servers/servers.js index 5ff911b6f..6bb827ed5 100644 --- a/web/pgadmin/browser/server_groups/servers/templates/servers/servers.js +++ b/web/pgadmin/browser/server_groups/servers/templates/servers/servers.js @@ -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)) { diff --git a/web/pgadmin/browser/static/js/datamodel.js b/web/pgadmin/browser/static/js/datamodel.js index 5b1c3a76f..ad8f95f1d 100644 --- a/web/pgadmin/browser/static/js/datamodel.js +++ b/web/pgadmin/browser/static/js/datamodel.js @@ -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 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) { diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js index 0cc1e2fc1..a82205e81 100644 --- a/web/pgadmin/static/js/backform.pgadmin.js +++ b/web/pgadmin/static/js/backform.pgadmin.js @@ -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([ - '', - '
', - ' <%=required ? "required" : ""%> />', - ' <% if (helpMessage && helpMessage.length) { %>', - ' <%=helpMessage%>', - ' <% } %>', - '
' - ].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 @@ ' <%=helpMessage%>', ' <% } %>', '' - ].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")) }); ///////