public inbox for [email protected]
help / color / mirror / Atom feedFrom: Harshal Dhumal <[email protected]>
To: Ashesh Vashi <[email protected]>
Cc: [email protected]
Subject: Variable control patch
Date: Thu, 7 Jan 2016 13:04:32 +0530
Message-ID: <CAFiP3vy4iZ_hiNhGJBYcZZnV-td=7K=hQLRgvKyrPHai0LSfzQ@mail.gmail.com> (raw)
List-Unsubscribe: <mailto:[email protected]?body=unsub%20pgadmin-hackers>
Hi,
Please find attached patch for Variable control.
Usage:
1] In variables tab
id: 'spcoptions', label: 'Variables', type: 'collection', group: "Variables",
model: pgAdmin.Browser.Node.VariableModel, control:
'variable-collection', mode: [ 'edit', 'create'],
canAdd: true, canDelete: true, uniqueCol : ['name'],
variableCol : 'name', url: "getvars",
2] In database tab
id: 'spcoptions', label: 'Variables', type: 'collection', group: "Variables",
model: pgAdmin.Browser.Node.VariableModel.extend({hasDatabase:true}),
control: 'variable-collection', mode: [ 'edit', 'create'],
canAdd: true, canDelete: true, uniqueCol : ['name','database'],
variableCol : 'name', url: "getvars",
3] In Use roles tab
id: 'spcoptions', label: 'Variables', type: 'collection', group: "Variables",
model: pgAdmin.Browser.Node.VariableModel.extend({hasRole:true}),
control: 'variable-collection', mode: [ 'edit', 'create'],
canAdd: true, canDelete: true, uniqueCol : ['name','role'],
variableCol : 'name', url: "getvars",
--
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers
Attachments:
[text/x-patch] variable_control_7_Jan.patch (26.1K, 3-variable_control_7_Jan.patch)
download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py
index d478526..0604202 100644
--- a/web/pgadmin/browser/server_groups/servers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/__init__.py
@@ -97,6 +97,11 @@ class ServerModule(sg.ServerGroupPluginModule):
'name': 'pgadmin.browser.server.privilege',
'path': url_for('browser.index') + 'server/static/js/privilege',
'when': self.node_type
+ },
+ {
+ 'name': 'pgadmin.browser.server.variable',
+ 'path': url_for('browser.index') + 'server/static/js/variable',
+ 'when': self.node_type
}])
for module in self.submodules:
diff --git a/web/pgadmin/browser/server_groups/servers/static/js/variable.js b/web/pgadmin/browser/server_groups/servers/static/js/variable.js
new file mode 100644
index 0000000..3d8353d
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/static/js/variable.js
@@ -0,0 +1,422 @@
+(function(root, factory) {
+ // Set up Backform appropriately for the environment. Start with AMD.
+ if (typeof define === 'function' && define.amd) {
+ define(['underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify', 'pgadmin.browser.node'],
+ function(_, $, Backbone, Backform, Backgrid, Alertify, pgNode) {
+ // 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, Backform, Alertify, pgNode);
+ });
+
+ // Next for Node.js or CommonJS. jQuery may not be needed as a module.
+ } else if (typeof exports !== 'undefined') {
+ var _ = require('underscore') || root._,
+ $ = root.jQuery || root.$ || root.Zepto || root.ender,
+ Backbone = require('backbone') || root.Backbone,
+ Backform = require('backform') || root.Backform;
+ Alertify = require('alertify') || root.Alertify;
+ pgAdmin = require('pgadmin.browser.node') || root.pgAdmin.Browser.Node;
+ factory(root, _, $, Backbone, Backform, Alertify, pgNode);
+
+ // Finally, as a browser global.
+ } else {
+ factory(root, root._, (root.jQuery || root.Zepto || root.ender || root.$), root.Backbone, root.Backform, root.pgAdmin.Browser.Node);
+ }
+} (this, function(root, _, $, Backbone, Backform, Alertify, pgNode) {
+ /**
+ * Variablemodel used to represent configuration parameters (variables tab) for database objects.
+ *
+ **/
+
+ var VariableModel = pgNode.VariableModel = pgNode.Model.extend({
+ hasDatabase : false,
+
+ hasRole : false,
+
+ defaults: {
+ name: undefined,
+ value: undefined,
+ role: undefined,
+ database: undefined,
+
+ /*
+ * The following information can be used to render the dynamic
+ * controls. It has nothing to with the data.
+ *
+ * These data needs to be fill in by the Variable Dynamic Control.
+ */
+ vartype: undefined,
+ max_val: undefined,
+ min_val: undefined,
+ enumvals: []
+ },
+ initialize: function(val, opts) {
+ pgNode.Model.prototype.initialize(arguments);
+ if (typeof val === 'string') {
+ var idx = val.indexOf('=');
+ this.set('name',idx > 0 ? val.substring(0, idx):'', {silent:true});
+ this.set('value',idx > 0 ? val.substring(idx+1):'', {silent:true});
+ }
+ },
+ schema: [
+ {id: 'name', label:'Name', type:'text', editable: false},
+ {id: 'value', label:'Value', type: 'text', cell: 'dynamic-variable', editable: true},
+ {id: 'database', label:'Database', type: 'select2', editable: true},
+ {id: 'role', label:'Role', type: 'select2', editable: true}
+ ],
+ toJSON: function() {
+ var d = Backbone.Model.prototype.toJSON.apply(this);
+ // Remove metadata before returning model values.
+ if (!this.hasDatabase) {
+ delete d.database;
+ }
+ if (!this.hasRole) {
+ delete d.role;
+ }
+ delete d.vartype;
+ delete d.max_val;
+ delete d.min_val;
+ delete d.enumvals;
+ return d;
+ }
+ });
+
+ /*
+ * Dynamic Variable cell. Used for variable data type column in Variables tab.
+ * Behaviour of cell depends on variable data type.
+ */
+ var DynamicVariableCell = Backgrid.Extension.DynamicVariableCell = Backgrid.Cell.extend({
+ /*
+ * Mapping of postgres data type to backgrid cell type.
+ */
+ variableCellMapper: {
+ "bool":Backgrid.Extension.SwitchCell,
+ "enum":Backgrid.Extension.Select2Cell,
+ "string":Backgrid.Cell,
+ "integer":Backgrid.IntegerCell,
+ "real":Backgrid.NumberCell
+ },
+
+ initialize: function () {
+
+ var vartype = this.model.get("vartype"),
+ cell = this.variableCellMapper[vartype] || Backgrid.Cell,
+ self = this;
+ /*
+ * Set properties for dynamic cell.
+ */
+ _.each(cell.prototype, function(v,k) {
+ self[k] = v;
+ });
+
+ DynamicVariableCell.__super__.initialize.apply(this, arguments);
+
+ switch(vartype) {
+ case "bool":
+ // There are no specific properties for BooleanCell.
+ break;
+ case "enum":
+ var options = [],
+ enumvals = this.model.get("enumvals");
+ _.each(enumvals, function(enumval) {
+ options.push([enumval,enumval]);
+ });
+ this.optionValues = options;
+ this.multiple = cell.prototype.multiple;
+ this.delimiter = cell.prototype.delimiter;
+ this.listenTo(this.model, "backgrid:edit", function (model, column, cell, editor) {
+ if (column.get("name") == this.column.get("name")) {
+ editor.setOptionValues(this.optionValues);
+ editor.setMultiple(this.multiple);
+ }
+ });
+ break;
+ case "integer":
+ this.decimals = 0;
+ this.decimalSeparator = cell.prototype.decimalSeparator;
+ this.orderSeparator = cell.prototype.orderSeparator;
+ var formatter = this.formatter;
+ formatter.decimals = this.decimals;
+ formatter.decimalSeparator = this.decimalSeparator;
+ formatter.orderSeparator = this.orderSeparator;
+ break;
+ case "real":
+ this.decimals = cell.prototype.decimals;
+ this.decimalSeparator = cell.prototype.decimalSeparator;
+ this.orderSeparator = cell.prototype.orderSeparator;
+ var formatter = this.formatter;
+ formatter.decimals = this.decimals;
+ formatter.decimalSeparator = this.decimalSeparator;
+ formatter.orderSeparator = this.orderSeparator;
+ break;
+ case "string":
+ default:
+ // There are no specific properties for StringCell and Cell.
+ }
+ }
+ });
+
+ /**
+ * Variable Tab Control to set/update configuration values for database object.
+ *
+ **/
+ var VariableCollectionControl = Backform.VariableCollectionControl = Backform.UniqueColCollectionControl.extend({
+ hasDatabase : false,
+
+ hasRole : false,
+
+ initialize: function() {
+ Backform.UniqueColCollectionControl.prototype.initialize.apply(this, arguments);
+ // Check if variableCol column name is provided.
+ if (!this.field.get('variableCol')) {
+ errorMsg = "Developer: 'variableCol' column name is not provided."
+ alert (errorMsg);
+ return null;
+ }
+
+ var collection = this.model.get(this.field.get("name"));
+ this.hasDatabase = collection.model.prototype.hasDatabase;
+ this.hasRole = collection.model.prototype.hasRole;
+ if (this.hasDatabase && this.hasRole){
+ alert('Developer: Both Database and Role columns can not be used together in `VariableCollectionControl`.');
+ return;
+ }
+
+ // get all available variable options for database object.
+ this.getVariableOptions();
+ /*
+ * Set the metadata vartype, min_var, max_var, enumvals for each model.
+ */
+ if (collection) {
+ collection.each(function(m) {
+ self.parseAndSetModelMetadata(m);
+ });
+ }
+ },
+ /*
+ * Get the variable options for this control.
+ */
+ getVariableOptions: function() {
+ self = this;
+ if (this.field.get('url')) {
+ var node = this.field.get('node'),
+ full_url = node.generate_url.apply(
+ node, [
+ null, this.field.get('url'), this.field.get('node_data'), true,
+ this.field.get('node_info')
+ ]);
+ $.ajax({
+ async: false,
+ url: full_url,
+ }).done(function (data) {
+ self.field.set("options",data.data);
+ });
+ }
+ },
+ /*
+ * Add the additional variable metadata to model instance.
+ * This metadata will be used to identify correct control for cell, cell value options,
+ * min value range and max value range.
+ */
+ parseAndSetModelMetadata: function(m) {
+ var availableVars = self.field.get("options") || [],
+ variableCol = self.field.get("variableCol"),
+ varName = m.get(variableCol),
+ modelData = {};
+
+ _.each(availableVars, function(v) {
+ if(varName == v[variableCol]) {
+ modelData["vartype"] = v["vartype"] || undefined;
+ modelData["max_val"] = v["max_val"] || undefined;
+ modelData["min_val"] = v["min_val"] || undefined;
+ modelData["enumvals"] = v["enumvals"] || undefined;
+
+ var val = m.get("value");
+ // Parse numeric values.
+ if (modelData["vartype"] == "integer" && !!val) {
+ modelData["value"] = parseInt(val);
+ } else if(modelData["vartype"] == "real" && !!val) {
+ modelData["value"] = parseFloat(val);
+ }
+ }
+ });
+
+ m.set(modelData, {silent: true});
+ },
+ getHeaderForm: function(){
+ if(this.hasDatabase){
+ return $(["<div class='subnode-header-form'>",
+ "<div class='container-fluid'>",
+ "<div class='row'>",
+ "<div class='col-md-4'>",
+ "<label class='control-label'>Variable name</label>",
+ "</div>",
+ "<div class='col-md-4'>",
+ "<select class='form-control' name='variable'></select>",
+ "</div>",
+ "<div class='col-md-4'>",
+ "<button class='btn-sm btn-default add'>Add</buttton>",
+ "</div>",
+ "</div>",
+ "<div class='row'>",
+ "<div class='col-md-4'>",
+ "<label class='control-label'>Database</label>",
+ "</div>",
+ "<div class='col-md-4'>",
+ "<select class='form-control' name='database'></select>",
+ "</div>",
+ "<div>",
+ "</div>",
+ "</div>"].join("\n"));
+ } else if (this.hasRole) {
+ return $(["<div class='subnode-header-form'>",
+ "<div class='container-fluid'>",
+ "<div class='row'>",
+ "<div class='col-md-4'>",
+ "<label class='control-label'>Variable name</label>",
+ "</div>",
+ "<div class='col-md-4'>",
+ "<select class='form-control' name='variable'></select>",
+ "</div>",
+ "<div class='col-md-4'>",
+ "<button class='btn-sm btn-default add'>Add</buttton>",
+ "</div>",
+ "</div>",
+ "<div class='row'>",
+ "<div class='col-md-4'>",
+ "<label class='control-label'>Role</label>",
+ "</div>",
+ "<div class='col-md-4'>",
+ "<select class='form-control' name='role'></select>",
+ "</div>",
+ "<div>",
+ "</div>",
+ "</div>"].join("\n"));
+ } else {
+ return $(["<div class='subnode-header-form'>",
+ "<div class='container-fluid'>",
+ "<div class='row'>",
+ "<div class='col-md-4'>",
+ "<label class='control-label'>Variable name</label>",
+ "</div>",
+ "<div class='col-md-4'>",
+ "<select class='form-control' name='variable'></select>",
+ "</div>",
+ "<div class='col-md-4'>",
+ "<button class='btn-sm btn-default add'>Add</buttton>",
+ "</div>",
+ "</div>",
+ "</div>",
+ "</div>"].join("\n"));
+ }
+ },
+ showGridControl: function(data) {
+ var self = this,
+ gridHeader = ["<div class='subnode-header'>",
+ "<label class='control-label'>" + data.label + "</label>",
+ "</div>"].join("\n"),
+ gridBody = $("<div class='pgadmin-control-group backgrid form-group col-xs-12 object subnode'></div>").append(gridHeader),
+ gridHeaderForm = this.getHeaderForm();
+ gridBody.append(gridHeaderForm);
+ var $selectVariable = gridHeaderForm.find('select[name=variable]').empty(),
+ availableVars = self.field.get("options") || [];
+ _.each(availableVars, function(option) {
+ $selectVariable.append($("<option></option>")
+ .attr("value", option.name).text(option.name));
+ })
+
+ $selectVariable.select2();
+ if(this.hasDatabase) {
+ $selectDatabase = gridHeaderForm.find('select[name=database]').empty();
+ $selectDatabase.append($("<option value='a'>a</option><option value='b'>b</option>"));
+ $selectDatabase.select2();
+ } else if(this.hasRole) {
+ $selectRole = gridHeaderForm.find('select[name=role]').empty();
+ $selectRole.append($("<option value='a'>a</option><option value='b'>b</option>"));
+ $selectRole.select2();
+ }
+
+ var subnode = data.subnode.schema ? data.subnode : data.subnode.prototype,
+ gridSchema = Backform.generateGridColumnsFromModel(
+ data.node_info, subnode, this.field.get('mode'), data.columns
+ ),
+ self = this;
+ // Set visibility of Add button
+ if (data.disabled || data.canAdd == false) {
+ $(gridBody).find("button.add").remove();
+ }
+
+ // Insert Delete Cell into Grid
+ if (data.disabled == false && data.canDelete) {
+ gridSchema.columns.unshift({
+ name: "pg-backform-delete", label: "",
+ cell: Backgrid.Extension.DeleteCell,
+ editable: false, cell_priority: -1
+ });
+ }
+
+ var collection = this.model.get(data.name);
+ // Initialize a new Grid instance
+ var gridcols = [];
+ _.each(gridSchema.columns, function(schema){
+ if (schema.name == 'database' || schema.name == 'role'){
+ if(self.hasDatabase && schema.name == 'database') {
+ gridcols.push(schema)
+ } else if (self.hasRole && schema.name == 'role') {
+ gridcols.push(schema)
+ }
+ } else {
+ gridcols.push(schema);
+ }
+ })
+ var grid = self.grid = new Backgrid.Grid({
+ columns: gridcols,
+ collection: collection,
+ className: "backgrid table-bordered"
+ });
+
+ // Render subNode grid
+ subNodeGrid = grid.render().$el;
+
+ // Combine Edit and Delete Cell
+ if (data.canDelete && data.canEdit) {
+ $(subNodeGrid).find("th.pg-backform-delete").remove();
+ }
+
+ $dialog = gridBody.append(subNodeGrid);
+
+ // Add button callback
+ if (!(data.disabled || data.canAdd == false)) {
+ $dialog.find('button.add').first().click(function(e) {
+ e.preventDefault();
+ var varName = $selectVariable.val(),
+ variableCol = self.field.get("variableCol"),
+ modelData = {};
+ modelData[variableCol] = varName;
+ if(self.hasDatabase){
+ modelData['database'] = $selectDatabase.val();
+ } else if (self.hasRole){
+ modelData['role'] = $selectRole.val();
+ }
+
+ $(grid.body.$el.find($("tr.new"))).removeClass("new");
+
+ var m = new (self.field.get('model'))(modelData, {silent: true});
+ self.parseAndSetModelMetadata(m);
+ collection.add(m);
+ var idx = collection.indexOf(m);
+ // idx may not be always > -1 because our UniqueColCollection may remove 'm' if duplicate value found.
+ if (idx > -1) {
+ var newRow = grid.body.rows[idx].$el;
+ newRow.addClass("new");
+ $(newRow).pgMakeVisible('backform-tab');
+ }
+ return false;
+ });
+ }
+ return $dialog;
+ }
+ })
+
+ return VariableModel
+}));
diff --git a/web/pgadmin/browser/static/js/node.ui.js b/web/pgadmin/browser/static/js/node.ui.js
index 1412cc8..d385b6f 100644
--- a/web/pgadmin/browser/static/js/node.ui.js
+++ b/web/pgadmin/browser/static/js/node.ui.js
@@ -176,5 +176,50 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) {
})
});
+ /*
+ * Global function to make visible particular dom element in it's parent
+ * with given class.
+ */
+ $.fn.pgMakeVisible = function( cls ) {
+ return this.each(function() {
+ if (!this || !$(this.length))
+ return;
+ var top, p = $(this), hasScrollbar = function(j) {
+ if (j && j.length > 0) {
+ return j.get(0).scrollHeight > j.height();
+ }
+ return false;
+ };
+
+ while(p) {
+ top = p.get(0).offsetTop + p.height();
+ p = p.parent();
+ if (hasScrollbar(p)) {
+ p.scrollTop(top);
+ }
+ if (p.hasClass(cls)) //'backform-tab'
+ return;
+ }
+ });
+ }
+
+ /*
+ * Backform Select2AjaxOptions control.
+ */
+ var Select2AjaxOptionsControl = Backform.Select2AjaxOptionsControl = Backform.NodeAjaxOptionsControl.extend({
+ render: function() {
+
+ var options = this.field.get('options') || [];
+
+ Backform.NodeAjaxOptionsControl.prototype.render.apply(this, arguments);
+
+ var col = _.defaults(this.field.toJSON(), this.defaults)
+ /* Add empty option as Select2 requires any empty '<option><option>' for
+ * some of its functionality to work and initialize select2 control.
+ */
+ this.$el.find("select").append($('<option></option>').select2(col.select2);
+ return this;
+ }
+ });
return Backform.NodeListControl;
});
diff --git a/web/pgadmin/static/css/overrides.css b/web/pgadmin/static/css/overrides.css
index 6d0f662..3ec4d6f 100755
--- a/web/pgadmin/static/css/overrides.css
+++ b/web/pgadmin/static/css/overrides.css
@@ -611,3 +611,20 @@ table.backgrid tr.new {
right: 0px;
bottom :0;
}
+.subnode-header-form {
+ background-color:#2c76b4;
+ color:#FFFFFF;
+ padding:3px 0 10px 0;
+}
+
+.subnode-header-form button.add {
+ float:right;
+ margin-right:15px;
+}
+
+.select2 {
+ width: 100% !important;
+}
+.select2-search__field, select{
+ background:inherit !important;
+}
\ No newline at end of file
diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js
index 35daaed..4893f45 100644
--- a/web/pgadmin/static/js/backform.pgadmin.js
+++ b/web/pgadmin/static/js/backform.pgadmin.js
@@ -74,7 +74,8 @@
'multiline': ['textarea', 'textarea', 'string'],
'collection': ['sub-node-collection', 'sub-node-collection', 'string'],
'uniqueColCollection': ['unique-col-collection', 'unique-col-collection', 'string'],
- 'switch' : 'switch'
+ 'switch' : 'switch',
+ 'select2': 'select2',
};
var getMappedControl = Backform.getMappedControl = function(type, mode) {
@@ -589,7 +590,7 @@
});
// Check if unique columns provided are also in model attributes.
- if (uniqueCol.length > _.intersection(columns, uniqueCol).length){
+ if (uniqueCol.length > _.intersection(columns, uniqueCol).length) {
errorMsg = "Developer: Unique column/s [ "+_.difference(uniqueCol, columns)+" ] not found in collection model [ " + columns +" ]."
alert (errorMsg);
}
@@ -610,11 +611,11 @@
collectionChanged: function(newModel, coll, op) {
var uniqueCol = this.field.get('uniqueCol') || [],
uniqueChangedAttr = [],
- changedAttr = newModel.changedAttributes();
+ self = this;
// Check if changed model attributes are also in unique columns. And then only check for uniqueness.
- if (changedAttr) {
+ if (newModel.attributes) {
_.each(uniqueCol, function(col) {
- if ( _.has(changedAttr,col))
+ if ( _.has(newModel.attributes,col))
{
uniqueChangedAttr.push(col);
}
@@ -629,7 +630,9 @@
var collection = this.model.get(this.field.get('name'));
this.stopListening(collection, "change", this.collectionChanged);
// Check if changed attribute's value of new/updated model also exist for another model in collection.
- // If duplicate value exists then set the attribute's value of new/updated model to it's previous values.
+ // If duplicate value exists then set the attribute's value of new/updated model to its previous values.
+ var m = undefined,
+ oldModel = undefined;
collection.each(function(model) {
if (newModel != model) {
var duplicateAttrValues = []
@@ -639,12 +642,41 @@
duplicateAttrValues.push(attrValue)
}
});
- if (duplicateAttrValues.length == uniqueCol.length){
- newModel.set(uniqueChangedAttr[0], newModel.previous(uniqueChangedAttr[0]), {silent: true});
- // TODO- Need to add notification in status bar for unique column.
+ if (duplicateAttrValues.length == uniqueCol.length) {
+ m = newModel;
+ // Keep reference of model to make it visible in dialog.
+ oldModel = model;
}
}
});
+ if (m) {
+ if (op && op.add) {
+ // Remove duplicate model.
+ setTimeout(function() {
+ collection.remove(m);
+ }, 0);
+
+ } else {
+ /*
+ * Set model value to its previous value as its new value is
+ * conflicting with another model value.
+ */
+
+ m.set(uniqueChangedAttr[0], m.previous(uniqueChangedAttr[0]), {silent: true});
+ }
+ if (oldModel) {
+ var idx = collection.indexOf(oldModel);
+ if (idx > -1) {
+ var newRow = self.grid.body.rows[idx].$el;
+ newRow.addClass("new");
+ $(newRow).pgMakeVisible('backform-tab');
+ setTimeout(function() {
+ newRow.removeClass("new");
+ }, 3000);
+ }
+ }
+ }
+
this.listenTo(collection, "change", this.collectionChanged);
},
render: function() {
@@ -709,7 +741,7 @@
var collection = this.model.get(data.name);
// Initialize a new Grid instance
- var grid = new Backgrid.Grid({
+ var grid = self.grid = new Backgrid.Grid({
columns: gridSchema.columns,
collection: collection,
className: "backgrid table-bordered"
@@ -733,18 +765,18 @@
// If allowMultipleEmptyRows is not set or is false then don't allow second new empty row.
// There should be only one empty row.
- if (!allowMultipleEmptyRows && collection){
+ if (!allowMultipleEmptyRows && collection) {
var isEmpty = false;
- collection.each(function(model){
+ collection.each(function(model) {
var modelValues = [];
- _.each(model.attributes, function(val, key){
+ _.each(model.attributes, function(val, key) {
modelValues.push(val);
})
- if(!_.some(modelValues, _.identity)){
+ if(!_.some(modelValues, _.identity)) {
isEmpty = true;
}
});
- if(isEmpty){
+ if(isEmpty) {
return false;
}
}
@@ -753,9 +785,10 @@
var m = new (data.model)(null, {silent: true});
collection.add(m);
- var idx = collection.indexOf(m);
- newRow = grid.body.rows[idx].$el;
+ var idx = collection.indexOf(m),
+ newRow = grid.body.rows[idx].$el;
newRow.addClass("new");
+ $(newRow).pgMakeVisible('backform-tab');
return false;
});
}
@@ -869,7 +902,7 @@
}
// Initialize a new Grid instance
- var grid = new Backgrid.Grid({
+ var grid = self.grid = new Backgrid.Grid({
columns: gridSchema.columns,
collection: collection,
className: "backgrid table-bordered"
@@ -890,10 +923,11 @@
$dialog.find('button.add').click(function(e) {
e.preventDefault();
grid.insertRow({});
- newRow = $(grid.body.rows[collection.length - 1].$el);
+ var newRow = $(grid.body.rows[collection.length - 1].$el);
newRow.attr("class", "new").click(function(e) {
$(this).attr("class", "");
});
+ $(newRow).pgMakeVisible('backform-tab');
return false;
});
@@ -1141,11 +1175,13 @@
schema_node: schema_node,
visible: (mode == 'properties'?
(ver_in_limit ?
- (s.version || true) : false) : s.version || true)
+ (s.version || true) : false) : s.version || true),
+ node: node,
+ node_data: treeData
});
delete o.id;
- // Temporarily store in dictionaly format for
+ // Temporarily store in dictionary format for
// utilizing it later.
groups[group].push(o);
}
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected]
Subject: Re: Variable control patch
In-Reply-To: <CAFiP3vy4iZ_hiNhGJBYcZZnV-td=7K=hQLRgvKyrPHai0LSfzQ@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox