Please find attached rebased patch.
--
*Harshal Dhumal*
*Sr. Software Engineer*
EnterpriseDB India: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
On Wed, Jun 7, 2017 at 6:59 PM, Dave Page <[email protected]> wrote:
> Can you rebase this please? I think Ashesh broke it :-p
>
> On Tue, Jun 6, 2017 at 7:42 AM, Harshal Dhumal
> <[email protected]> wrote:
> > Hi,
> >
> > On Mon, Jun 5, 2017 at 9:25 PM, Dave Page <[email protected]> wrote:
> >>
> >> Hi
> >>
> >> With this patch applied, it uses the field names instead of the labels
> >> in error messages - e.g.
> >>
> >> 'dirty_rate_limit' must be numeric
> >>
> >> instead of:
> >>
> >> 'Dirty Rate Limit (KB)' must be numeric.
> >
> > Fixed. Please find attached updated patch.
> >
> >>
> >>
> >> Thanks.
> >>
> >> On Tue, May 30, 2017 at 8:28 AM, Harshal Dhumal
> >> <[email protected]> wrote:
> >> > Hi,
> >> >
> >> > Please find updated patch.
> >> >
> >> > --
> >> > Harshal Dhumal
> >> > Sr. Software Engineer
> >> >
> >> > EnterpriseDB India: http://www.enterprisedb.com
> >> > The Enterprise PostgreSQL Company
> >> >
> >> > On Tue, May 30, 2017 at 12:30 PM, Harshal Dhumal
> >> > <[email protected]> wrote:
> >> >>
> >> >> Hi,
> >> >>
> >> >> Please ignore this patch as I forgot to include few changes. I'll
> send
> >> >> updated one.
> >> >>
> >> >> --
> >> >> Harshal Dhumal
> >> >> Sr. Software Engineer
> >> >>
> >> >> EnterpriseDB India: http://www.enterprisedb.com
> >> >> The Enterprise PostgreSQL Company
> >> >>
> >> >> On Mon, May 29, 2017 at 3:18 PM, Harshal Dhumal
> >> >> <[email protected]> wrote:
> >> >>>
> >> >>> Hi,
> >> >>>
> >> >>> Here is updated patch for RM2421.
> >> >>>
> >> >>> Now I have moved all Numeric control level validations to datamodel.
> >> >>> As
> >> >>> existing implementation was causing
> >> >>> issues with error messages in create/edit dialog when schema
> contains
> >> >>> two
> >> >>> or more Numeric controls.
> >> >>>
> >> >>> This is generic issue and not related to resource group. Also I have
> >> >>> updated all other nodes which uses Numeric controls
> >> >>>
> >> >>>
> >> >>>
> >> >>> --
> >> >>> Harshal Dhumal
> >> >>> Sr. Software Engineer
> >> >>>
> >> >>> EnterpriseDB India: http://www.enterprisedb.com
> >> >>> The Enterprise PostgreSQL Company
> >> >>>
> >> >>> On Fri, May 19, 2017 at 12:22 PM, Harshal Dhumal
> >> >>> <[email protected]> wrote:
> >> >>>>
> >> >>>> Hi,
> >> >>>>
> >> >>>> On Thu, May 18, 2017 at 7:57 PM, Joao Pedro De Almeida Pereira
> >> >>>> <[email protected]> wrote:
> >> >>>>>
> >> >>>>> Hello Harshal,
> >> >>>>>
> >> >>>>> We review the patch and have some questions:
> >> >>>>> 1) Is there any particular reason to initialize variables and
> >> >>>>> functions
> >> >>>>> in the same place? We believe that it would be more readable there
> >> >>>>> were no
> >> >>>>> chaining of variable creation, specially if those variables are
> >> >>>>> functions.
> >> >>>>> Check line:
> >> >>>>
> >> >>>> That function is only going to be used in checkNumeric function (in
> >> >>>> case
> >> >>>> of Number control) and checkInt function (in case of Integer
> control)
> >> >>>> so
> >> >>>> declared them locally.
> >> >>>> Anyway I'm going to refactor both the controls as Number and
> Integer
> >> >>>> shares some common properties.
> >> >>>>
> >> >>>>> +++ b/web/pgadmin/static/js/backform.pgadmin.js
> >> >>>>> @@ -1528,7 +1528,18 @@
> >> >>>>> max_value = field.max,
> >> >>>>> isValid = true,
> >> >>>>> intPattern = new RegExp("^-?[0-9]*$"),
> >> >>>>> - isMatched = intPattern.test(value);
> >> >>>>> + isMatched = intPattern.test(value),
> >> >>>>> + trigger_invalid_event = function(msg) {
> >> >>>>>
> >> >>>>> 2) The functions added in both places look very similar, can they
> be
> >> >>>>> merged and extracted? We are talking about the
> trigger_invalid_event
> >> >>>>> function.
> >> >>>>
> >> >>>> Yes they can be merged. As of now both NumericControl and
> >> >>>> IntegerControl
> >> >>>> are derived from InputControl. Ideally
> >> >>>> only NumericControl should be derived from InputControl and
> >> >>>> IntegerControl should be derive from NumericControl.
> >> >>>>
> >> >>>>
> >> >>>>>
> >> >>>>> 3) The following change is very similar to the
> >> >>>>> trigger_invalid_event,
> >> >>>>> was there a reason not to use it?
> >> >>>>
> >> >>>> Below code triggers "model valid" event; opposite to "model
> invalid"
> >> >>>> event (trigger_invalid_event)
> >> >>>>>
> >> >>>>> +++ b/web/pgadmin/static/js/backform.pgadmin.js
> >> >>>>> @@ -1573,25 +1584,23 @@
> >> >>>>> 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)
> >> >>>>> - );
> >> >>>>> + // Check if other fields of same model are valid before
> >> >>>>> + // triggering 'session:valid' event
> >> >>>>> + if(_.size(this.model.errorModel.attributes) == 0) {
> >> >>>>> + 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
> >> >>>>> + );
> >> >>>>> + }
> >> >>>>>
> >> >>>>> 4) We also noticed that the following change sets look very
> >> >>>>> similiar.
> >> >>>>> Is there any reason to have this code duplicated? If not this
> could
> >> >>>>> be a
> >> >>>>> good time to refactor it.
> >> >>>>
> >> >>>> As said earlier in response of point 2 code duplication is because
> >> >>>> the
> >> >>>> way controls are derived.
> >> >>>>
> >> >>>>>
> >> >>>>> +++ b/web/pgadmin/static/js/backform.pgadmin.js
> >> >>>>> @@ -1528,7 +1528,18 @@
> >> >>>>>
> >> >>>>> @@ -1573,25 +1584,23 @@
> >> >>>>>
> >> >>>>> @@ -1631,7 +1640,18 @@
> >> >>>>>
> >> >>>>> @@ -1676,25 +1696,23 @@
> >> >>>>>
> >> >>>>>
> >> >>>>> Thanks
> >> >>>>> Joao & Shruti
> >> >>>>>
> >> >>>>> On Thu, May 18, 2017 at 6:01 AM, Harshal Dhumal
> >> >>>>> <[email protected]> wrote:
> >> >>>>>>
> >> >>>>>> Hi,
> >> >>>>>>
> >> >>>>>> Please find attached patch for RM2421
> >> >>>>>>
> >> >>>>>> Issue fixed: 1. Integer/numeric Validation is not working
> properly.
> >> >>>>>> 2. Wrong CPU rate unit
> >> >>>>>> --
> >> >>>>>> Harshal Dhumal
> >> >>>>>> Sr. Software Engineer
> >> >>>>>>
> >> >>>>>> EnterpriseDB India: http://www.enterprisedb.com
> >> >>>>>> The Enterprise PostgreSQL Company
> >> >>>>>>
> >> >>>>>>
> >> >>>>>> --
> >> >>>>>> Sent via pgadmin-hackers mailing list
> >> >>>>>> ([email protected])
> >> >>>>>> To make changes to your subscription:
> >> >>>>>> http://www.postgresql.org/mailpref/pgadmin-hackers
> >> >>>>>>
> >> >>>>>
> >> >>>>
> >> >>>
> >> >>
> >> >
> >> >
> >> >
> >> > --
> >> > Sent via pgadmin-hackers mailing list ([email protected]
> )
> >> > To make changes to your subscription:
> >> > http://www.postgresql.org/mailpref/pgadmin-hackers
> >> >
> >>
> >>
> >>
> >> --
> >> Dave Page
> >> Blog: http://pgsnake.blogspot.com
> >> Twitter: @pgsnake
> >>
> >> EnterpriseDB UK: http://www.enterprisedb.com
> >> The Enterprise PostgreSQL Company
> >
> >
>
>
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>
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 b239970..0ea196a 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;
+ }
+
+ 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 ) {
- m.set('typlen', undefined);
+ // 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 9e6711e..e8d9ac9 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 cec3917..389a2e6 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 97f0738..e55761d 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 5ff911b..6bb827e 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 5b1c3a7..ad8f95f 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 = [];
@@ -153,6 +154,25 @@ function(_, pgAdmin, $, Backbone) {
_.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) {
diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js
index 0cc1e2f..a82205e 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([
- '<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"))
});
///////
--
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers