diff --git a/web/pgadmin/browser/static/js/node.ui.js b/web/pgadmin/browser/static/js/node.ui.js
index 722cab320..aa7314ea0 100644
--- a/web/pgadmin/browser/static/js/node.ui.js
+++ b/web/pgadmin/browser/static/js/node.ui.js
@@ -4,7 +4,6 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) {
var pgBrowser = pgAdmin.Browser;
-
// Store value in DOM as stringified JSON.
var StringOrJSONFormatter = function() {};
_.extend(StringOrJSONFormatter.prototype, {
@@ -183,7 +182,7 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) {
var NodeListByIdControl = Backform.NodeListByIdControl = NodeAjaxOptionsControl.extend({
controlClassName: 'pgadmin-node-select form-control',
- defaults: _.extend(NodeAjaxOptionsControl.prototype.defaults, {
+ defaults: _.extend({}, NodeAjaxOptionsControl.prototype.defaults, {
first_empty: true,
empty_value: '-- None --',
url: 'nodes',
@@ -229,7 +228,7 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) {
var NodeListByNameControl = Backform.NodeListByNameControl = NodeListByIdControl.extend({
- defaults: _.extend(NodeListByIdControl.prototype.defaults, {
+ defaults: _.extend({}, NodeListByIdControl.prototype.defaults, {
transform: function(rows) {
var self = this,
node = self.field.get('schema_node'),
@@ -288,5 +287,273 @@ function($, _, pgAdmin, Backbone, Backform, Alertify, Node) {
});
};
+
+ /*
+ * NodeAjaxOptionsCell
+ * This cell will fetch the options required to render the select
+ * cell, from the url specific to the pgAdmin.Browser node object.
+ *
+ * In order to use this properly, schema require to set the 'url' property,
+ * which exposes the data for this node.
+ *
+ * In case the url is not providing the data in proper format, we can
+ * specify the 'transform' function too, which will convert the fetched
+ * data to proper 'label', 'value' format.
+ */
+ var NodeAjaxOptionsCell = Backgrid.Extension.NodeAjaxOptionsCell = Backgrid.Extension.Select2Cell.extend({
+ defaults: _.extend({}, Backgrid.Extension.Select2Cell.prototype.defaults, {
+ url: undefined,
+ transform: undefined,
+ url_with_id: false,
+ select2: {
+ allowClear: true,
+ placeholder: 'Select from the list',
+ width: 'style'
+ }
+ }),
+ template: _.template(
+ ''
+ ),
+ initialize: function () {
+ Backgrid.Extension.Select2Cell.prototype.initialize.apply(this, arguments);
+
+ var col = _.defaults(this.column.toJSON(), this.defaults),
+ model = this.model, column = this.column,
+ editable = Backgrid.callByNeed(col.editable, column, model),
+ optionValues = _.clone(this.optionValues || this.column.get('options'));
+
+
+ var self = this,
+ url = self.column.get('url') || self.defaults.url,
+ m = self.model.handler || self.model;
+
+ // Hmm - we found the url option.
+ // That means - we needs to fetch the options from that node.
+ if (url) {
+ var node = this.column.get('schema_node'),
+ node_info = this.column.get('node_info'),
+ full_url = node.generate_url.apply(
+ node, [
+ null, url, this.column.get('node_data'),
+ this.column.get('url_with_id') || false, node_info
+ ]),
+ cache_level = this.column.get('cache_level') || node.type,
+ cache_node = this.column.get('cache_node');
+
+ cache_node = (cache_node && pgAdmin.Browser.Nodes['cache_node']) || node;
+
+ /*
+ * We needs to check, if we have already cached data for this url.
+ * If yes - use that, and do not bother about fetching it again,
+ * and use it.
+ */
+ var data = cache_node.cache(url, node_info, cache_level);
+
+ if (this.column.get('version_compitible') &&
+ (_.isUndefined(data) || _.isNull(data))) {
+ m.trigger('pgadmin:view:fetching', m, self.column);
+ $.ajax({
+ async: false,
+ url: full_url,
+ success: function(res) {
+ /*
+ * We will cache this data for short period of time for avoiding
+ * same calls.
+ */
+ data = cache_node.cache(url, node_info, cache_level, res.data);
+ },
+ error: function() {
+ m.trigger('pgadmin:view:fetch:error', m, self.column);
+ }
+ });
+ m.trigger('pgadmin:view:fetched', m, self.column);
+ }
+ // To fetch only options from cache, we do not need time from 'at'
+ // attribute but only options.
+ //
+ // It is feasible that the data may not have been fetched.
+ data = (data && data.data) || [];
+
+ /*
+ * Transform the data
+ */
+ transform = this.column.get('transform') || self.defaults.transform;
+ if (transform && _.isFunction(transform)) {
+ // We will transform the data later, when rendering.
+ // It will allow us to generate different data based on the
+ // dependencies.
+ self.column.set('options', transform.bind(self, data));
+ } else {
+ self.column.set('options', data);
+ }
+ }
+ },
+ render: function() {
+ /*
+ * Let SelectCell render it, we will do our magic on the
+ * select control in it.
+ */
+
+ var col = _.defaults(this.column.toJSON(), this.defaults),
+ model = this.model, column = this.column,
+ editable = Backgrid.callByNeed(col.editable, column, model),
+ optionValues = _.clone(this.optionValues ||
+ _.isFunction(this.column.get('options')) ?
+ this.column.get('options').apply(this) :
+ this.column.get(' options')),
+ select2_opts = _.defaults({}, col.select2, this.defaults.select2),
+ evalF = function(f, col, m) {
+ return (_.isFunction(f) ? !!f.apply(col, [m]) : !!f);
+ };
+
+ this.$el.empty();
+
+ if (!_.isArray(optionValues)) throw new TypeError("optionValues must be an array");
+
+ /*
+ * Add empty option as Select2 requires any empty '